qmldom: support qmltypes
read qmltypes files using the QmlCompiler provided reader Change-Id: Ifb091a1d645e697cd3b648da96c69868f240d037 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
This commit is contained in:
parent
42aa1d5102
commit
0b0afa576a
|
@ -32,11 +32,12 @@ qt_internal_add_module(QmlDomPrivate
|
|||
qqmldomstringdumper.cpp qqmldomstringdumper_p.h
|
||||
qqmldomreformatter.cpp qqmldomreformatter_p.h
|
||||
qqmldomtop.cpp qqmldomtop_p.h
|
||||
qqmldomtypesreader.cpp qqmldomtypesreader_p.h
|
||||
DEFINES
|
||||
QMLDOM_LIBRARY
|
||||
PUBLIC_LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::QmlPrivate
|
||||
Qt::QmlCompilerPrivate
|
||||
)
|
||||
|
||||
#### Keys ignored in scope 1:.:.:qmldom.pro:<TRUE>:
|
||||
|
|
|
@ -1105,6 +1105,11 @@ bool QmltypesComponent::iterateDirectSubpaths(DomItem &self, DirectVisitor visit
|
|||
cont = cont && self.dvValueField(visitor, Fields::metaRevisions, m_metaRevisions);
|
||||
if (!fileName().isEmpty())
|
||||
cont = cont && self.dvValueField(visitor, Fields::fileName, fileName()); // remove?
|
||||
cont = cont && self.dvValueField(visitor, Fields::interfaceNames, m_interfaceNames);
|
||||
cont = cont && self.dvValueField(visitor, Fields::hasCustomParser, m_hasCustomParser);
|
||||
cont = cont && self.dvValueField(visitor, Fields::valueTypeName, m_valueTypeName);
|
||||
cont = cont && self.dvValueField(visitor, Fields::extensionTypeName, m_extensionTypeName);
|
||||
cont = cont && self.dvValueField(visitor, Fields::accessSemantics, int(m_accessSemantics));
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
@ -1610,6 +1615,7 @@ bool MethodInfo::iterateDirectSubpaths(DomItem &self, DirectVisitor visitor)
|
|||
if (methodType == MethodType::Method) {
|
||||
cont = cont && self.dvValueField(visitor, Fields::preCode, preCode(self));
|
||||
cont = cont && self.dvValueField(visitor, Fields::postCode, postCode(self));
|
||||
cont = cont && self.dvValueField(visitor, Fields::isConstructor, isConstructor);
|
||||
}
|
||||
if (body)
|
||||
cont = cont && self.dvWrapField(visitor, Fields::body, body);
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QPair>
|
||||
|
||||
#include <private/qqmljsscope_p.h>
|
||||
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
|
||||
|
@ -187,7 +189,8 @@ class QMLDOM_EXPORT Version
|
|||
{
|
||||
public:
|
||||
constexpr static DomType kindValue = DomType::Version;
|
||||
enum { Undefined = -1, Latest = -2 };
|
||||
constexpr static qint32 Undefined = -1;
|
||||
constexpr static qint32 Latest = -2;
|
||||
|
||||
Version(qint32 majorVersion = Undefined, qint32 minorVersion = Undefined);
|
||||
static Version fromString(QStringView v);
|
||||
|
@ -607,9 +610,14 @@ public:
|
|||
{
|
||||
bool cont = AttributeInfo::iterateDirectSubpaths(self, visitor);
|
||||
cont = cont && self.dvValueField(visitor, Fields::isPointer, isPointer);
|
||||
cont = cont && self.dvValueField(visitor, Fields::isFinal, isFinal);
|
||||
cont = cont && self.dvValueField(visitor, Fields::isAlias, isAlias);
|
||||
cont = cont && self.dvValueField(visitor, Fields::isDefaultMember, isDefaultMember);
|
||||
cont = cont && self.dvValueField(visitor, Fields::isRequired, isRequired);
|
||||
cont = cont && self.dvValueField(visitor, Fields::read, read);
|
||||
cont = cont && self.dvValueField(visitor, Fields::write, write);
|
||||
cont = cont && self.dvValueField(visitor, Fields::bindable, bindable);
|
||||
cont = cont && self.dvValueField(visitor, Fields::notify, notify);
|
||||
cont = cont && self.dvReferenceField(visitor, Fields::type, typePath());
|
||||
return cont;
|
||||
}
|
||||
|
@ -624,6 +632,11 @@ public:
|
|||
|
||||
void writeOut(DomItem &self, OutWriter &lw) const;
|
||||
|
||||
QString read;
|
||||
QString write;
|
||||
QString bindable;
|
||||
QString notify;
|
||||
bool isFinal = false;
|
||||
bool isPointer = false;
|
||||
bool isAlias = false;
|
||||
bool isDefaultMember = false;
|
||||
|
@ -692,6 +705,7 @@ public:
|
|||
QList<MethodParameter> parameters;
|
||||
MethodType methodType = Method;
|
||||
std::shared_ptr<ScriptExpression> body;
|
||||
bool isConstructor = false;
|
||||
};
|
||||
|
||||
class QMLDOM_EXPORT EnumItem
|
||||
|
@ -993,11 +1007,25 @@ public:
|
|||
void setFileName(QString fileName) { m_fileName = fileName; }
|
||||
QList<int> metaRevisions() const { return m_metaRevisions; }
|
||||
void setMetaRevisions(QList<int> metaRevisions) { m_metaRevisions = metaRevisions; }
|
||||
|
||||
void setInterfaceNames(const QStringList& interfaces) { m_interfaceNames = interfaces; }
|
||||
QStringList interfaceNames() const { return m_interfaceNames; }
|
||||
QString extensionTypeName() const { return m_extensionTypeName; }
|
||||
void setExtensionTypeName(const QString &name) { m_extensionTypeName = name; }
|
||||
QString valueTypeName() const { return m_valueTypeName; }
|
||||
void setValueTypeName(const QString &name) { m_valueTypeName = name; }
|
||||
bool hasCustomParser() const { return m_hasCustomParser; }
|
||||
void setHasCustomParser(bool v) { m_hasCustomParser = v; }
|
||||
QQmlJSScope::AccessSemantics accessSemantics() const { return m_accessSemantics; }
|
||||
void setAccessSemantics(QQmlJSScope::AccessSemantics v) { m_accessSemantics = v; }
|
||||
private:
|
||||
QList<Export> m_exports;
|
||||
QList<int> m_metaRevisions;
|
||||
QString m_fileName; // remove?
|
||||
QStringList m_interfaceNames;
|
||||
bool m_hasCustomParser = false;
|
||||
QString m_valueTypeName;
|
||||
QString m_extensionTypeName;
|
||||
QQmlJSScope::AccessSemantics m_accessSemantics;
|
||||
};
|
||||
|
||||
class QMLDOM_EXPORT QmlComponent final : public Component
|
||||
|
|
|
@ -474,6 +474,7 @@ public:
|
|||
// namespace, so it cam be reopened to add more entries
|
||||
namespace Fields{
|
||||
QMLDOM_FIELD(access);
|
||||
QMLDOM_FIELD(accessSemantics);
|
||||
QMLDOM_FIELD(allSources);
|
||||
QMLDOM_FIELD(annotations);
|
||||
QMLDOM_FIELD(astComments);
|
||||
|
@ -482,6 +483,7 @@ QMLDOM_FIELD(attachedType);
|
|||
QMLDOM_FIELD(attachedTypeName);
|
||||
QMLDOM_FIELD(autoExports);
|
||||
QMLDOM_FIELD(base);
|
||||
QMLDOM_FIELD(bindable);
|
||||
QMLDOM_FIELD(bindingType);
|
||||
QMLDOM_FIELD(bindings);
|
||||
QMLDOM_FIELD(body);
|
||||
|
@ -503,14 +505,15 @@ QMLDOM_FIELD(currentRevision);
|
|||
QMLDOM_FIELD(defaultPropertyName);
|
||||
QMLDOM_FIELD(defaultValue);
|
||||
QMLDOM_FIELD(designerSupported);
|
||||
QMLDOM_FIELD(elementCanonicalPath);
|
||||
QMLDOM_FIELD(elLocation);
|
||||
QMLDOM_FIELD(elementCanonicalPath);
|
||||
QMLDOM_FIELD(enumerations);
|
||||
QMLDOM_FIELD(errors);
|
||||
QMLDOM_FIELD(exportSource);
|
||||
QMLDOM_FIELD(exports);
|
||||
QMLDOM_FIELD(expr);
|
||||
QMLDOM_FIELD(expressionType);
|
||||
QMLDOM_FIELD(extensionTypeName);
|
||||
QMLDOM_FIELD(fileLocationsTree);
|
||||
QMLDOM_FIELD(fileName);
|
||||
QMLDOM_FIELD(fullRegion);
|
||||
|
@ -518,6 +521,7 @@ QMLDOM_FIELD(get);
|
|||
QMLDOM_FIELD(globalScopeName);
|
||||
QMLDOM_FIELD(globalScopeWithName);
|
||||
QMLDOM_FIELD(hasCallback);
|
||||
QMLDOM_FIELD(hasCustomParser);
|
||||
QMLDOM_FIELD(idStr);
|
||||
QMLDOM_FIELD(ids);
|
||||
QMLDOM_FIELD(implicit);
|
||||
|
@ -530,10 +534,13 @@ QMLDOM_FIELD(imports);
|
|||
QMLDOM_FIELD(inProgress);
|
||||
QMLDOM_FIELD(infoItem);
|
||||
QMLDOM_FIELD(inheritVersion);
|
||||
QMLDOM_FIELD(interfaceNames);
|
||||
QMLDOM_FIELD(isAlias);
|
||||
QMLDOM_FIELD(isComposite);
|
||||
QMLDOM_FIELD(isConstructor);
|
||||
QMLDOM_FIELD(isCreatable);
|
||||
QMLDOM_FIELD(isDefaultMember);
|
||||
QMLDOM_FIELD(isFinal);
|
||||
QMLDOM_FIELD(isInternal);
|
||||
QMLDOM_FIELD(isLatest);
|
||||
QMLDOM_FIELD(isList);
|
||||
|
@ -567,9 +574,10 @@ QMLDOM_FIELD(nCallbacks);
|
|||
QMLDOM_FIELD(nLoaded);
|
||||
QMLDOM_FIELD(nNotdone);
|
||||
QMLDOM_FIELD(name);
|
||||
QMLDOM_FIELD(newlinesBefore);
|
||||
QMLDOM_FIELD(nextComponent);
|
||||
QMLDOM_FIELD(nextScope);
|
||||
QMLDOM_FIELD(newlinesBefore);
|
||||
QMLDOM_FIELD(notify);
|
||||
QMLDOM_FIELD(objects);
|
||||
QMLDOM_FIELD(onAttachedObject);
|
||||
QMLDOM_FIELD(options);
|
||||
|
@ -579,13 +587,13 @@ QMLDOM_FIELD(parentObject);
|
|||
QMLDOM_FIELD(path);
|
||||
QMLDOM_FIELD(plugins);
|
||||
QMLDOM_FIELD(postCode);
|
||||
QMLDOM_FIELD(postComments);
|
||||
QMLDOM_FIELD(postCommentLocations);
|
||||
QMLDOM_FIELD(postComments);
|
||||
QMLDOM_FIELD(pragma);
|
||||
QMLDOM_FIELD(pragmas);
|
||||
QMLDOM_FIELD(preCode);
|
||||
QMLDOM_FIELD(preComments);
|
||||
QMLDOM_FIELD(preCommentLocations);
|
||||
QMLDOM_FIELD(preComments);
|
||||
QMLDOM_FIELD(propertyDef);
|
||||
QMLDOM_FIELD(propertyDefRef);
|
||||
QMLDOM_FIELD(propertyDefs);
|
||||
|
@ -602,6 +610,7 @@ QMLDOM_FIELD(qmltypesFiles);
|
|||
QMLDOM_FIELD(qualifiedImports);
|
||||
QMLDOM_FIELD(queue);
|
||||
QMLDOM_FIELD(rawComment);
|
||||
QMLDOM_FIELD(read);
|
||||
QMLDOM_FIELD(referredObject);
|
||||
QMLDOM_FIELD(referredObjectPath);
|
||||
QMLDOM_FIELD(regionComments);
|
||||
|
@ -632,9 +641,11 @@ QMLDOM_FIELD(uris);
|
|||
QMLDOM_FIELD(validExposedAt);
|
||||
QMLDOM_FIELD(validItem);
|
||||
QMLDOM_FIELD(value);
|
||||
QMLDOM_FIELD(valueTypeName);
|
||||
QMLDOM_FIELD(values);
|
||||
QMLDOM_FIELD(version);
|
||||
QMLDOM_FIELD(when);
|
||||
QMLDOM_FIELD(write);
|
||||
}
|
||||
|
||||
class Source;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "qqmldomelements_p.h"
|
||||
#include "qqmldomastcreator_p.h"
|
||||
#include "qqmldommoduleindex_p.h"
|
||||
#include "qqmldomtypesreader_p.h"
|
||||
|
||||
#include <QtQml/private/qqmljslexer_p.h>
|
||||
#include <QtQml/private/qqmljsparser_p.h>
|
||||
|
@ -456,6 +457,8 @@ void DomUniverse::execQueue()
|
|||
} else if (t.kind == DomType::QmltypesFile) {
|
||||
shared_ptr<QmltypesFile> qmltypesFile(
|
||||
new QmltypesFile(canonicalPath, code, contentDate));
|
||||
QmltypesReader reader(univ.copy(qmltypesFile));
|
||||
reader.parse();
|
||||
auto change = updateEntry<QmltypesFile>(univ, qmltypesFile, m_qmltypesFileWithPath,
|
||||
mutex());
|
||||
oldValue = univ.copy(change.first);
|
||||
|
@ -2267,6 +2270,8 @@ RefCacheEntry RefCacheEntry::forPath(DomItem &el, Path canonicalPath)
|
|||
QMutexLocker l(envPtr->mutex());
|
||||
cached = envPtr->m_referenceCache.value(canonicalPath, {});
|
||||
} else {
|
||||
qCWarning(domLog) << "No Env for reference" << canonicalPath << "from"
|
||||
<< el.internalKindStr() << el.canonicalPath();
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return cached;
|
||||
|
|
|
@ -0,0 +1,287 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qqmldomtypesreader_p.h"
|
||||
#include "qqmldomelements_p.h"
|
||||
#include "qqmldomcompare_p.h"
|
||||
#include "qqmldomfieldfilter_p.h"
|
||||
|
||||
#include <QtQml/private/qqmljsparser_p.h>
|
||||
#include <QtQml/private/qqmljslexer_p.h>
|
||||
#include <QtQml/private/qqmljsengine_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljsscope_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljstypedescriptionreader_p.h>
|
||||
#include <private/qqmljstypedescriptionreader_p.h>
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QQmlJS {
|
||||
namespace Dom {
|
||||
|
||||
using namespace QQmlJS::AST;
|
||||
|
||||
static ErrorGroups myParseErrors()
|
||||
{
|
||||
static ErrorGroups errs = { { NewErrorGroup("Dom"), NewErrorGroup("QmltypesFile"),
|
||||
NewErrorGroup("Parsing") } };
|
||||
return errs;
|
||||
}
|
||||
|
||||
void QmltypesReader::insertProperty(QQmlJSScope::Ptr jsScope, const QQmlJSMetaProperty &property,
|
||||
QMap<int, QmlObject> &objs)
|
||||
{
|
||||
PropertyDefinition prop;
|
||||
prop.name = property.propertyName();
|
||||
prop.typeName = property.typeName();
|
||||
prop.isPointer = property.isPointer();
|
||||
prop.isReadonly = !property.isWritable();
|
||||
prop.isRequired = jsScope->isPropertyLocallyRequired(prop.name);
|
||||
prop.isList = property.isList();
|
||||
int revision = property.revision();
|
||||
prop.isFinal = property.isFinal();
|
||||
prop.bindable = property.bindable();
|
||||
prop.read = property.read();
|
||||
prop.write = property.write();
|
||||
prop.notify = property.notify();
|
||||
|
||||
if (prop.name.isEmpty() || prop.typeName.isEmpty()) {
|
||||
addError(myParseErrors()
|
||||
.warning(tr("Property object is missing a name or type script binding."))
|
||||
.handle());
|
||||
return;
|
||||
}
|
||||
objs[revision].addPropertyDef(prop, AddOption::KeepExisting);
|
||||
}
|
||||
|
||||
void QmltypesReader::insertSignalOrMethod(const QQmlJSMetaMethod &metaMethod,
|
||||
QMap<int, QmlObject> &objs)
|
||||
{
|
||||
MethodInfo methodInfo;
|
||||
// ### confusion between Method and Slot. Method should be removed.
|
||||
switch (metaMethod.methodType()) {
|
||||
case QQmlJSMetaMethod::Method:
|
||||
case QQmlJSMetaMethod::Slot:
|
||||
methodInfo.methodType = MethodInfo::MethodType::Method;
|
||||
break;
|
||||
case QQmlJSMetaMethod::Signal:
|
||||
methodInfo.methodType = MethodInfo::MethodType::Signal;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
QStringList pNames = metaMethod.parameterNames();
|
||||
QStringList pTypes = metaMethod.parameterTypeNames();
|
||||
qsizetype nParam = qMax(pNames.size(), pTypes.size());
|
||||
for (int i = 0; i < nParam; ++i) {
|
||||
MethodParameter param;
|
||||
param.name = ((i < pNames.size()) ? pNames.at(i) : QString());
|
||||
param.typeName = ((i < pTypes.size()) ? pTypes.at(i) : QString());
|
||||
methodInfo.parameters.append(param);
|
||||
}
|
||||
methodInfo.name = metaMethod.methodName();
|
||||
methodInfo.typeName = metaMethod.returnTypeName();
|
||||
int revision = metaMethod.revision();
|
||||
methodInfo.isConstructor = metaMethod.isConstructor();
|
||||
if (methodInfo.name.isEmpty()) {
|
||||
addError(myParseErrors().error(tr("Method or signal is missing a name.")).handle());
|
||||
return;
|
||||
}
|
||||
|
||||
objs[revision].addMethod(methodInfo, AddOption::KeepExisting);
|
||||
}
|
||||
|
||||
EnumDecl QmltypesReader::enumFromMetaEnum(const QQmlJSMetaEnum &metaEnum)
|
||||
{
|
||||
EnumDecl res;
|
||||
res.setName(metaEnum.name());
|
||||
res.setAlias(metaEnum.alias());
|
||||
res.setIsFlag(metaEnum.isFlag());
|
||||
QList<EnumItem> values;
|
||||
int lastValue = -1;
|
||||
for (const auto &k : metaEnum.keys()) {
|
||||
if (metaEnum.hasValues())
|
||||
lastValue = metaEnum.value(k);
|
||||
else
|
||||
++lastValue;
|
||||
values.append(EnumItem(k, lastValue));
|
||||
}
|
||||
res.setValues(values);
|
||||
return res;
|
||||
}
|
||||
|
||||
void QmltypesReader::insertComponent(QQmlJSScope::Ptr jsScope)
|
||||
{
|
||||
QmltypesComponent comp;
|
||||
QMap<int, QmlObject> objects;
|
||||
objects.insert(0, QmlObject());
|
||||
bool incrementedPath = false;
|
||||
QString prototype;
|
||||
QString defaultPropertyName;
|
||||
QList<QQmlJSScope::Export> exportsList;
|
||||
{
|
||||
QHash<QString, QQmlJSMetaProperty> els = jsScope->ownProperties();
|
||||
auto it = els.cbegin();
|
||||
auto end = els.cend();
|
||||
while (it != end) {
|
||||
insertProperty(jsScope, it.value(), objects);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
{
|
||||
QMultiHash<QString, QQmlJSMetaMethod> els = jsScope->ownMethods();
|
||||
auto it = els.cbegin();
|
||||
auto end = els.cend();
|
||||
while (it != end) {
|
||||
insertSignalOrMethod(it.value(), objects);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
{
|
||||
QHash<QString, QQmlJSMetaEnum> els = jsScope->ownEnumerations();
|
||||
auto it = els.cbegin();
|
||||
auto end = els.cend();
|
||||
while (it != end) {
|
||||
comp.addEnumeration(enumFromMetaEnum(it.value()));
|
||||
++it;
|
||||
}
|
||||
}
|
||||
comp.setFileName(jsScope->fileName());
|
||||
comp.setName(jsScope->internalName());
|
||||
m_currentPath = m_currentPath.key(comp.name())
|
||||
.index(qmltypesFilePtr()->components().values(comp.name()).length());
|
||||
incrementedPath = true;
|
||||
prototype = jsScope->baseTypeName();
|
||||
#if QT_VERSION <= 0x060200
|
||||
defaultPropertyName = jsScope->defaultPropertyName();
|
||||
#else
|
||||
defaultPropertyName = jsScope->ownDefaultPropertyName();
|
||||
#endif // QT_VERSION <= 0x060200
|
||||
exportsList = jsScope->exports();
|
||||
comp.setInterfaceNames(jsScope->interfaceNames());
|
||||
QString typeName = jsScope->ownAttachedTypeName();
|
||||
comp.setAttachedTypeName(typeName);
|
||||
if (!typeName.isEmpty())
|
||||
comp.setAttachedTypePath(Paths::lookupCppTypePath(typeName));
|
||||
comp.setIsSingleton(jsScope->isSingleton());
|
||||
comp.setIsCreatable(jsScope->isCreatable());
|
||||
comp.setIsComposite(jsScope->isComposite());
|
||||
comp.setHasCustomParser(jsScope->hasCustomParser());
|
||||
comp.setValueTypeName(jsScope->valueTypeName());
|
||||
comp.setAccessSemantics(jsScope->accessSemantics());
|
||||
comp.setExtensionTypeName(jsScope->extensionTypeName());
|
||||
Path exportSourcePath = qmltypesFile().canonicalPath();
|
||||
QMap<int, Path> revToPath;
|
||||
auto it = objects.end();
|
||||
auto begin = objects.begin();
|
||||
int objectIndex = 0;
|
||||
QList<int> metaRevs;
|
||||
Path compPath = qmltypesFile()
|
||||
.canonicalPath()
|
||||
.field(Fields::components)
|
||||
.key(comp.name())
|
||||
.index(qmltypesFilePtr()->components().values(comp.name()).length());
|
||||
// emit & map objs
|
||||
|
||||
// exports:
|
||||
QList<Export> exports;
|
||||
int iExport = 0;
|
||||
for (const QQmlJSScope::Export &jsE : exportsList) {
|
||||
int metaRev = jsE.version().toEncodedVersion<int>();
|
||||
++iExport;
|
||||
Export e;
|
||||
e.uri = jsE.package();
|
||||
e.typeName = jsE.type();
|
||||
auto v = jsE.version();
|
||||
e.version = Version((v.hasMajorVersion() ? v.majorVersion() : Version::Latest),
|
||||
(v.hasMinorVersion() ? v.minorVersion() : Version::Latest));
|
||||
e.typePath = revToPath.value(metaRev);
|
||||
objects[metaRev];
|
||||
e.exportSourcePath = exportSourcePath;
|
||||
comp.addExport(e);
|
||||
}
|
||||
|
||||
while (it != begin) {
|
||||
--it;
|
||||
if (it.key() < 0) {
|
||||
addError(myParseErrors().error(
|
||||
tr("negative meta revision %1 not supported").arg(it.key())));
|
||||
}
|
||||
revToPath.insert(it.key(), compPath.field(Fields::objects).index(objectIndex));
|
||||
Path nextObjectPath = compPath.field(Fields::objects).index(++objectIndex);
|
||||
if (it == begin) {
|
||||
if (!prototype.isEmpty())
|
||||
it->addPrototypePath(Paths::lookupCppTypePath(prototype));
|
||||
it->setName(prototype);
|
||||
} else {
|
||||
it->addPrototypePath(nextObjectPath);
|
||||
it->setName(comp.name() + QLatin1String("-") + QString::number(it.key()));
|
||||
}
|
||||
comp.addObject(*it);
|
||||
metaRevs.append(it.key());
|
||||
}
|
||||
comp.setMetaRevisions(metaRevs);
|
||||
|
||||
if (comp.name().isEmpty()) {
|
||||
addError(myParseErrors()
|
||||
.error(tr("Component definition is missing a name binding."))
|
||||
.handle());
|
||||
return;
|
||||
}
|
||||
qmltypesFilePtr()->addComponent(comp, AddOption::KeepExisting);
|
||||
if (incrementedPath)
|
||||
m_currentPath = m_currentPath.dropTail().dropTail();
|
||||
}
|
||||
|
||||
bool QmltypesReader::parse()
|
||||
{
|
||||
QQmlJSTypeDescriptionReader reader(qmltypesFilePtr()->canonicalFilePath(),
|
||||
qmltypesFilePtr()->code());
|
||||
QHash<QString, QQmlJSScope::Ptr> objects;
|
||||
QStringList dependencies;
|
||||
m_isValid = reader(&objects, &dependencies);
|
||||
qmltypesFilePtr()->setIsValid(m_isValid);
|
||||
for (const auto &obj : objects) {
|
||||
insertComponent(obj);
|
||||
}
|
||||
return m_isValid;
|
||||
}
|
||||
|
||||
void QmltypesReader::addError(ErrorMessage message)
|
||||
{
|
||||
if (message.file.isEmpty())
|
||||
message.file = qmltypesFile().canonicalFilePath();
|
||||
if (!message.path)
|
||||
message.path = m_currentPath;
|
||||
qmltypesFilePtr()->addErrorLocal(message.handle());
|
||||
}
|
||||
|
||||
} // end namespace Dom
|
||||
} // end namespace QQmlJS
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,96 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the tools applications of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QQMLDOMTYPESREADER_H
|
||||
#define QQMLDOMTYPESREADER_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include "qqmldomexternalitems_p.h"
|
||||
|
||||
#include <QtQml/private/qqmljsastfwd_p.h>
|
||||
|
||||
// for Q_DECLARE_TR_FUNCTIONS
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#ifdef QMLDOM_STANDALONE
|
||||
# include "qqmljsmetatypes_p.h"
|
||||
#else
|
||||
# include <private/qqmljsmetatypes_p.h>
|
||||
# include <private/qqmljsscope_p.h>
|
||||
#endif
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QQmlJS {
|
||||
namespace Dom {
|
||||
|
||||
class QmltypesReader
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(TypeDescriptionReader)
|
||||
public:
|
||||
explicit QmltypesReader(DomItem qmltypesFile)
|
||||
: m_qmltypesFilePtr(qmltypesFile.ownerAs<QmltypesFile>()), m_qmltypesFile(qmltypesFile)
|
||||
{
|
||||
}
|
||||
|
||||
bool parse();
|
||||
// static void read
|
||||
private:
|
||||
void addError(ErrorMessage message);
|
||||
|
||||
void insertProperty(QQmlJSScope::Ptr jsScope, const QQmlJSMetaProperty &property,
|
||||
QMap<int, QmlObject> &objs);
|
||||
void insertSignalOrMethod(const QQmlJSMetaMethod &metaMethod, QMap<int, QmlObject> &objs);
|
||||
void insertComponent(QQmlJSScope::Ptr jsScope);
|
||||
EnumDecl enumFromMetaEnum(const QQmlJSMetaEnum &metaEnum);
|
||||
|
||||
std::shared_ptr<QmltypesFile> qmltypesFilePtr() { return m_qmltypesFilePtr; }
|
||||
DomItem &qmltypesFile() { return m_qmltypesFile; }
|
||||
ErrorHandler handler()
|
||||
{
|
||||
return [this](ErrorMessage m) { this->addError(m); };
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_isValid;
|
||||
std::shared_ptr<QmltypesFile> m_qmltypesFilePtr;
|
||||
DomItem m_qmltypesFile;
|
||||
Path m_currentPath;
|
||||
};
|
||||
|
||||
} // end namespace Dom
|
||||
} // end namespace QQmlJS
|
||||
QT_END_NAMESPACE
|
||||
#endif // QQMLDOMTYPESREADER_H
|
|
@ -111,6 +111,13 @@ int main(int argc, char *argv[])
|
|||
QLatin1String("pathToDump"));
|
||||
parser.addOption(pathToDumpOption);
|
||||
|
||||
QCommandLineOption dependenciesOption(
|
||||
QStringList() << "D"
|
||||
<< "dependencies",
|
||||
QLatin1String("Dependencies to load: none, required, reachable"),
|
||||
QLatin1String("dependenciesToLoad"), QLatin1String("required"));
|
||||
parser.addOption(dependenciesOption);
|
||||
|
||||
QCommandLineOption reformatDirOption(
|
||||
QStringList() << "reformat-dir",
|
||||
QLatin1String(
|
||||
|
@ -146,6 +153,24 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
Dependencies dep = Dependencies::None;
|
||||
for (QString depName : parser.values(dependenciesOption)) {
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Dependencies>();
|
||||
bool found = false;
|
||||
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
||||
if (QLatin1String(metaEnum.key(i)).compare(depName, Qt::CaseInsensitive) == 0) {
|
||||
found = true;
|
||||
dep = Dependencies(metaEnum.value(i));
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
QStringList values;
|
||||
for (int i = 0; i < metaEnum.keyCount(); ++i)
|
||||
values.append(QString::fromUtf8(metaEnum.key(i)).toLower());
|
||||
qDebug().noquote() << "Invalid dependencies argument, expected one of "
|
||||
<< values.join(QLatin1Char(','));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int nBackups = 2;
|
||||
if (parser.isSet(nBackupsOption)) {
|
||||
|
|
Loading…
Reference in New Issue