aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/qmlcompiler')
-rw-r--r--src/qmlcompiler/qdeferredpointer_p.h23
-rw-r--r--src/qmlcompiler/qqmljscompiler.cpp3
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp96
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h12
-rw-r--r--src/qmlcompiler/qqmljslinter.cpp3
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp77
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h31
-rw-r--r--src/qmlcompiler/qqmljstypereader.cpp27
-rw-r--r--src/qmlcompiler/qqmljstypereader_p.h2
9 files changed, 169 insertions, 105 deletions
diff --git a/src/qmlcompiler/qdeferredpointer_p.h b/src/qmlcompiler/qdeferredpointer_p.h
index e19676d7ea..8a72c7a913 100644
--- a/src/qmlcompiler/qdeferredpointer_p.h
+++ b/src/qmlcompiler/qdeferredpointer_p.h
@@ -47,15 +47,24 @@
QT_BEGIN_NAMESPACE
template<typename T>
+class QDeferredSharedPointer;
+
+template<typename T>
+class QDeferredWeakPointer;
+
+template<typename T>
class QDeferredFactory
{
public:
- T create() const;
bool isValid() const;
-};
-template<typename T>
-class QDeferredWeakPointer;
+private:
+ friend class QDeferredSharedPointer<const T>;
+ friend class QDeferredWeakPointer<const T>;
+ friend class QDeferredSharedPointer<T>;
+ friend class QDeferredWeakPointer<T>;
+ void populate(const QSharedPointer<T> &) const;
+};
template<typename T>
class QDeferredSharedPointer
@@ -179,7 +188,7 @@ private:
if (Factory *f = factory()) {
Factory localFactory;
std::swap(localFactory, *f); // Swap before executing, to avoid recursion
- const_cast<std::remove_const_t<T> &>(*m_data) = localFactory.create();
+ localFactory.populate(m_data.template constCast<std::remove_const_t<T>>());
}
}
@@ -245,8 +254,8 @@ private:
if (factory->isValid()) {
Factory localFactory;
std::swap(localFactory, *factory); // Swap before executing, to avoid recursion
- const_cast<std::remove_const_t<T> &>(*(m_data.toStrongRef()))
- = localFactory.create();
+ localFactory.populate(
+ m_data.toStrongRef().template constCast<std::remove_const_t<T>>());
}
}
}
diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp
index c765a1c94e..14811c2aa2 100644
--- a/src/qmlcompiler/qqmljscompiler.cpp
+++ b/src/qmlcompiler/qqmljscompiler.cpp
@@ -645,7 +645,8 @@ void QQmlJSAotCompiler::setDocument(
m_logger->setCode(irDocument->code);
m_unitGenerator = &irDocument->jsGenerator;
m_entireSourceCodeLines = irDocument->code.split(u'\n');
- QQmlJSImportVisitor visitor(m_importer, m_logger,
+ QQmlJSScope::Ptr target = QQmlJSScope::create();
+ QQmlJSImportVisitor visitor(target, m_importer, m_logger,
resourcePathInfo.canonicalPath() + u'/',
m_qmldirFiles);
m_typeResolver.init(&visitor, irDocument->program);
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 4f8a916940..5e1318fca2 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -74,15 +74,17 @@ inline QString getScopeName(const QQmlJSScope::ConstPtr &scope, QQmlJSScope::Sco
return scope->baseTypeName();
}
-QQmlJSImportVisitor::QQmlJSImportVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger,
- const QString &implicitImportDirectory,
- const QStringList &qmldirFiles)
+QQmlJSImportVisitor::QQmlJSImportVisitor(
+ const QQmlJSScope::Ptr &target, QQmlJSImporter *importer, QQmlJSLogger *logger,
+ const QString &implicitImportDirectory, const QStringList &qmldirFiles)
: m_implicitImportDirectory(implicitImportDirectory),
m_qmldirFiles(qmldirFiles),
- m_currentScope(QQmlJSScope::create(QQmlJSScope::JSFunctionScope)),
+ m_currentScope(QQmlJSScope::create()),
+ m_exportedRootScope(target),
m_importer(importer),
m_logger(logger)
{
+ m_currentScope->setScopeType(QQmlJSScope::JSFunctionScope);
Q_ASSERT(logger); // must be valid
m_globalScope = m_currentScope;
@@ -116,10 +118,10 @@ QQmlJSImportVisitor::QQmlJSImportVisitor(QQmlJSImporter *importer, QQmlJSLogger
QQmlJSImportVisitor::~QQmlJSImportVisitor() = default;
-void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QString &name,
- const QQmlJS::SourceLocation &location)
+void QQmlJSImportVisitor::populateCurrentScope(
+ QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location)
{
- m_currentScope = QQmlJSScope::create(type, m_currentScope);
+ m_currentScope->setScopeType(type);
setScopeName(m_currentScope, type, name);
m_currentScope->setIsComposite(true);
m_currentScope->setFilePath(QFileInfo(m_logger->fileName()).absoluteFilePath());
@@ -127,6 +129,22 @@ void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QS
m_scopesByIrLocation.insert({ location.startLine, location.startColumn }, m_currentScope);
}
+void QQmlJSImportVisitor::enterRootScope(QQmlJSScope::ScopeType type, const QString &name, const QQmlJS::SourceLocation &location)
+{
+ QQmlJSScope::reparent(m_currentScope, m_exportedRootScope);
+ m_currentScope = m_exportedRootScope;
+ populateCurrentScope(type, name, location);
+}
+
+void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QString &name,
+ const QQmlJS::SourceLocation &location)
+{
+ QQmlJSScope::Ptr newScope = QQmlJSScope::create();
+ QQmlJSScope::reparent(m_currentScope, newScope);
+ m_currentScope = std::move(newScope);
+ populateCurrentScope(type, name, location);
+}
+
bool QQmlJSImportVisitor::enterEnvironmentNonUnique(QQmlJSScope::ScopeType type,
const QString &name,
const QQmlJS::SourceLocation &location)
@@ -295,11 +313,6 @@ void QQmlJSImportVisitor::resolveAliasesAndIds()
}
}
-QQmlJSScope::Ptr QQmlJSImportVisitor::result() const
-{
- return m_exportedRootScope;
-}
-
QString QQmlJSImportVisitor::implicitImportDirectory(
const QString &localFile, QQmlJSResourceFileMapper *mapper)
{
@@ -1048,28 +1061,34 @@ void QQmlJSImportVisitor::breakInheritanceCycles(const QQmlJSScope::Ptr &origina
if (scopes.contains(scope)) {
QString inheritenceCycle;
for (const auto &seen : qAsConst(scopes)) {
- if (!inheritenceCycle.isEmpty())
- inheritenceCycle.append(QLatin1String(" -> "));
inheritenceCycle.append(seen->baseTypeName());
+ inheritenceCycle.append(QLatin1String(" -> "));
}
+ inheritenceCycle.append(scopes.first()->baseTypeName());
- m_logger->log(QStringLiteral("%1 is part of an inheritance cycle: %2")
- .arg(scope->internalName())
- .arg(inheritenceCycle),
- Log_InheritanceCycle, scope->sourceLocation());
+ const QString message = QStringLiteral("%1 is part of an inheritance cycle: %2")
+ .arg(scope->internalName(), inheritenceCycle);
+ m_logger->log(message, Log_InheritanceCycle, scope->sourceLocation());
originalScope->clearBaseType();
+ originalScope->setBaseTypeError(message);
break;
}
scopes.append(scope);
const auto newScope = scope->baseType();
- if (newScope.isNull() && !scope->baseTypeName().isEmpty()) {
- m_logger->log(scope->baseTypeName()
- + QStringLiteral(" was not found. Did you add all import paths?"),
- Log_Import, scope->sourceLocation(), true, true,
- QQmlJSUtils::didYouMean(scope->baseTypeName(), m_rootScopeImports.keys(),
- scope->sourceLocation()));
+ if (newScope.isNull()) {
+ const QString error = scope->baseTypeError();
+ const QString name = scope->baseTypeName();
+ if (!error.isEmpty()) {
+ m_logger->log(error, Log_Import, scope->sourceLocation(), true, true);
+ } else if (!name.isEmpty()) {
+ m_logger->log(
+ name + QStringLiteral(" was not found. Did you add all import paths?"),
+ Log_Import, scope->sourceLocation(), true, true,
+ QQmlJSUtils::didYouMean(scope->baseTypeName(), m_rootScopeImports.keys(),
+ scope->sourceLocation()));
+ }
}
scope = newScope;
@@ -1206,10 +1225,11 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition)
Q_ASSERT(!superType.isEmpty());
if (superType.front().isUpper()) {
- enterEnvironment(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation());
- if (!m_exportedRootScope) {
- m_exportedRootScope = m_currentScope;
- m_exportedRootScope->setIsSingleton(m_rootIsSingleton);
+ if (rootScopeIsValid()) {
+ enterEnvironment(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation());
+ } else {
+ enterRootScope(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation());
+ m_currentScope->setIsSingleton(m_rootIsSingleton);
}
const QTypeRevision revision = QQmlJSScope::resolveTypes(
@@ -1223,7 +1243,7 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition)
} else {
enterEnvironmentNonUnique(QQmlJSScope::GroupedPropertyScope, superType,
definition->firstSourceLocation());
- Q_ASSERT(m_exportedRootScope);
+ Q_ASSERT(rootScopeIsValid());
QQmlJSScope::resolveTypes(m_currentScope, m_rootScopeImports, &m_usedTypes);
}
@@ -2118,7 +2138,7 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob)
bool QQmlJSImportVisitor::visit(ExportDeclaration *)
{
- Q_ASSERT(!m_exportedRootScope.isNull());
+ Q_ASSERT(rootScopeIsValid());
Q_ASSERT(m_exportedRootScope != m_globalScope);
Q_ASSERT(m_currentScope == m_globalScope);
m_currentScope = m_exportedRootScope;
@@ -2127,18 +2147,17 @@ bool QQmlJSImportVisitor::visit(ExportDeclaration *)
void QQmlJSImportVisitor::endVisit(ExportDeclaration *)
{
- Q_ASSERT(!m_exportedRootScope.isNull());
+ Q_ASSERT(rootScopeIsValid());
m_currentScope = m_exportedRootScope->parentScope();
Q_ASSERT(m_currentScope == m_globalScope);
}
bool QQmlJSImportVisitor::visit(ESModule *module)
{
- enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("module"),
- module->firstSourceLocation());
- Q_ASSERT(m_exportedRootScope.isNull());
- m_exportedRootScope = m_currentScope;
- m_exportedRootScope->setIsScript(true);
+ Q_ASSERT(!rootScopeIsValid());
+ enterRootScope(
+ QQmlJSScope::JSLexicalScope, QStringLiteral("module"), module->firstSourceLocation());
+ m_currentScope->setIsScript(true);
importBaseModules();
leaveEnvironment();
return true;
@@ -2152,9 +2171,10 @@ void QQmlJSImportVisitor::endVisit(ESModule *)
bool QQmlJSImportVisitor::visit(Program *)
{
Q_ASSERT(m_globalScope == m_currentScope);
- Q_ASSERT(m_exportedRootScope.isNull());
- m_exportedRootScope = m_currentScope;
+ Q_ASSERT(!rootScopeIsValid());
+ *m_exportedRootScope = std::move(*QQmlJSScope::clone(m_currentScope));
m_exportedRootScope->setIsScript(true);
+ m_currentScope = m_exportedRootScope;
importBaseModules();
return true;
}
diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h
index 69714ced36..e9347a49f0 100644
--- a/src/qmlcompiler/qqmljsimportvisitor_p.h
+++ b/src/qmlcompiler/qqmljsimportvisitor_p.h
@@ -61,12 +61,13 @@ struct QQmlJSResourceFileMapper;
class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSImportVisitor : public QQmlJS::AST::Visitor
{
public:
- QQmlJSImportVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger,
+ QQmlJSImportVisitor(const QQmlJSScope::Ptr &target,
+ QQmlJSImporter *importer, QQmlJSLogger *logger,
const QString &implicitImportDirectory,
const QStringList &qmldirFiles = QStringList());
~QQmlJSImportVisitor();
- QQmlJSScope::Ptr result() const;
+ QQmlJSScope::Ptr result() const { return m_exportedRootScope; }
QQmlJSLogger *logger() { return m_logger; }
@@ -161,7 +162,7 @@ protected:
QStringList m_qmldirFiles;
QQmlJSScope::Ptr m_currentScope;
QQmlJSScope::Ptr m_savedBindingOuterScope;
- QQmlJSScope::Ptr m_exportedRootScope;
+ const QQmlJSScope::Ptr m_exportedRootScope;
QQmlJSScope::ConstPtr m_globalScope;
QQmlJSScopesById m_scopesById;
QQmlJSImporter::ImportedTypes m_rootScopeImports;
@@ -226,6 +227,7 @@ protected:
void breakInheritanceCycles(const QQmlJSScope::Ptr &scope);
void checkDeprecation(const QQmlJSScope::ConstPtr &scope);
void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
+ bool rootScopeIsValid() const { return m_exportedRootScope->sourceLocation().isValid(); }
QQmlJSLogger *m_logger;
enum class LiteralOrScriptParseResult { Invalid, Script, Literal };
@@ -300,6 +302,10 @@ private:
const QString &what,
const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
void addImportWithLocation(const QString &name, const QQmlJS::SourceLocation &loc);
+ void populateCurrentScope(QQmlJSScope::ScopeType type, const QString &name,
+ const QQmlJS::SourceLocation &location);
+ void enterRootScope(QQmlJSScope::ScopeType type, const QString &name,
+ const QQmlJS::SourceLocation &location);
};
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljslinter.cpp b/src/qmlcompiler/qqmljslinter.cpp
index 83145e8b3e..e8ca914b04 100644
--- a/src/qmlcompiler/qqmljslinter.cpp
+++ b/src/qmlcompiler/qqmljslinter.cpp
@@ -311,7 +311,8 @@ QQmlJSLinter::LintResult QQmlJSLinter::lintFile(const QString &filename,
m_logger->setFileName(m_useAbsolutePath ? info.absoluteFilePath() : filename);
m_logger->setCode(code);
m_logger->setSilent(silent || json);
- QQmlJSImportVisitor v { &m_importer, m_logger.get(),
+ QQmlJSScope::Ptr target = QQmlJSScope::create();
+ QQmlJSImportVisitor v { target, &m_importer, m_logger.get(),
QQmlJSImportVisitor::implicitImportDirectory(
m_logger->fileName(), m_importer.resourceFileMapper()),
qmldirFiles };
diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp
index a13fa32790..5b23b247b3 100644
--- a/src/qmlcompiler/qqmljsscope.cpp
+++ b/src/qmlcompiler/qqmljsscope.cpp
@@ -92,23 +92,23 @@ static bool searchBaseAndExtensionTypes(QQmlJSScopePtr type, const Action &check
return false;
}
-QQmlJSScope::QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope)
- : m_parentScope(parentScope), m_scopeType(type) {}
-
-QQmlJSScope::Ptr QQmlJSScope::create(ScopeType type, const QQmlJSScope::Ptr &parentScope)
+void QQmlJSScope::reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope)
{
- QSharedPointer<QQmlJSScope> childScope(new QQmlJSScope{type, parentScope});
+ if (const QQmlJSScope::Ptr parent = childScope->m_parentScope.toStrongRef())
+ parent->m_childScopes.removeOne(childScope);
if (parentScope)
- parentScope->m_childScopes.push_back(childScope);
- return childScope;
+ parentScope->m_childScopes.append(childScope);
+ childScope->m_parentScope = parentScope;
}
QQmlJSScope::Ptr QQmlJSScope::clone(const ConstPtr &origin)
{
if (origin.isNull())
return QQmlJSScope::Ptr();
- QQmlJSScope::Ptr cloned = create(origin->m_scopeType, origin->m_parentScope);
+ QQmlJSScope::Ptr cloned = create();
*cloned = *origin;
+ if (QQmlJSScope::Ptr parent = cloned->parentScope())
+ parent->m_childScopes.append(cloned);
return cloned;
}
@@ -382,8 +382,9 @@ QTypeRevision QQmlJSScope::resolveType(
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &context,
QSet<QString> *usedTypes)
{
- const auto baseType = findType(self->m_baseTypeName, context, usedTypes);
- if (!self->m_baseType.scope && !self->m_baseTypeName.isEmpty())
+ const QString baseTypeName = self->baseTypeName();
+ const auto baseType = findType(baseTypeName, context, usedTypes);
+ if (!self->m_baseType.scope && !baseTypeName.isEmpty())
self->m_baseType = { baseType.scope, baseType.revision };
if (!self->m_attachedType && !self->m_attachedTypeName.isEmpty())
@@ -447,7 +448,7 @@ void QQmlJSScope::updateChildScope(
const auto propertyIt = type->m_properties.find(childScope->internalName());
if (propertyIt != type->m_properties.end()) {
childScope->m_baseType.scope = QQmlJSScope::ConstPtr(propertyIt->type());
- childScope->m_baseTypeName = propertyIt->typeName();
+ childScope->setBaseTypeName(propertyIt->typeName());
return true;
}
return false;
@@ -457,7 +458,7 @@ void QQmlJSScope::updateChildScope(
if (const auto attachedBase = findType(
childScope->internalName(), contextualTypes, usedTypes).scope) {
childScope->m_baseType.scope = attachedBase->attachedType();
- childScope->m_baseTypeName = attachedBase->attachedTypeName();
+ childScope->setBaseTypeName(attachedBase->attachedTypeName());
}
break;
default:
@@ -508,8 +509,10 @@ void QQmlJSScope::resolveEnums(const QQmlJSScope::Ptr &self, const QQmlJSScope::
if (it->type())
continue;
Q_ASSERT(intType); // We need an "int" type to resolve enums
- auto enumScope = QQmlJSScope::create(EnumScope, self);
- enumScope->m_baseTypeName = QStringLiteral("int");
+ QQmlJSScope::Ptr enumScope = QQmlJSScope::create();
+ reparent(self, enumScope);
+ enumScope->m_scopeType = EnumScope;
+ enumScope->setBaseTypeName(QStringLiteral("int"));
enumScope->m_baseType.scope = intType;
enumScope->m_semantics = AccessSemantics::Value;
enumScope->m_internalName = self->internalName() + QStringLiteral("::") + it->name();
@@ -761,6 +764,28 @@ bool QQmlJSScope::isNameDeferred(const QString &name) const
return isDeferred;
}
+void QQmlJSScope::setBaseTypeName(const QString &baseTypeName)
+{
+ m_flags.setFlag(HasBaseTypeError, false);
+ m_baseTypeNameOrError = baseTypeName;
+}
+
+QString QQmlJSScope::baseTypeName() const
+{
+ return m_flags.testFlag(HasBaseTypeError) ? QString() : m_baseTypeNameOrError;
+}
+
+void QQmlJSScope::setBaseTypeError(const QString &baseTypeError)
+{
+ m_flags.setFlag(HasBaseTypeError);
+ m_baseTypeNameOrError = baseTypeError;
+}
+
+QString QQmlJSScope::baseTypeError() const
+{
+ return m_flags.testFlag(HasBaseTypeError) ? m_baseTypeNameOrError : QString();
+}
+
QString QQmlJSScope::attachedTypeName() const
{
QString name;
@@ -792,7 +817,7 @@ bool QQmlJSScope::isResolved() const
const bool nameIsEmpty = (m_scopeType == ScopeType::AttachedPropertyScope
|| m_scopeType == ScopeType::GroupedPropertyScope)
? m_internalName.isEmpty()
- : m_baseTypeName.isEmpty();
+ : m_baseTypeNameOrError.isEmpty();
if (nameIsEmpty)
return true;
if (m_baseType.scope.isNull())
@@ -865,31 +890,29 @@ bool QQmlJSScope::Export::isValid() const
return m_version.isValid() || !m_package.isEmpty() || !m_type.isEmpty();
}
-QQmlJSScope QDeferredFactory<QQmlJSScope>::create() const
+void QDeferredFactory<QQmlJSScope>::populate(const QSharedPointer<QQmlJSScope> &scope) const
{
QQmlJSTypeReader typeReader(m_importer, m_filePath);
- QQmlJSScope::Ptr result = typeReader();
+ typeReader(scope);
m_importer->m_globalWarnings.append(typeReader.errors());
- result->setInternalName(internalName());
- QQmlJSScope::resolveEnums(result, m_importer->builtinInternalNames().value(u"int"_qs).scope);
+ scope->setInternalName(internalName());
+ QQmlJSScope::resolveEnums(scope, m_importer->builtinInternalNames().value(u"int"_qs).scope);
- if (m_isSingleton && !result->isSingleton()) {
+ if (m_isSingleton && !scope->isSingleton()) {
m_importer->m_globalWarnings.append(
{ QStringLiteral(
"Type %1 declared as singleton in qmldir but missing pragma Singleton")
- .arg(result->internalName()),
+ .arg(scope->internalName()),
QtCriticalMsg, QQmlJS::SourceLocation() });
- result->setIsSingleton(true);
- } else if (!m_isSingleton && result->isSingleton()) {
+ scope->setIsSingleton(true);
+ } else if (!m_isSingleton && scope->isSingleton()) {
m_importer->m_globalWarnings.append(
{ QStringLiteral("Type %1 not declared as singleton in qmldir "
"but using pragma Singleton")
- .arg(result->internalName()),
+ .arg(scope->internalName()),
QtCriticalMsg, QQmlJS::SourceLocation() });
- result->setIsSingleton(false);
+ scope->setIsSingleton(false);
}
-
- return std::move(*result);
}
bool QQmlJSScope::canAssign(const QQmlJSScope::ConstPtr &derived) const
diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h
index da670f0c71..f68c5d0596 100644
--- a/src/qmlcompiler/qqmljsscope_p.h
+++ b/src/qmlcompiler/qqmljsscope_p.h
@@ -95,7 +95,8 @@ public:
CustomParser = 0x10,
Array = 0x20,
InlineComponent = 0x40,
- WrappedInImplicitComponent = 0x80
+ WrappedInImplicitComponent = 0x80,
+ HasBaseTypeError = 0x100
};
Q_DECLARE_FLAGS(Flags, Flag)
Q_FLAGS(Flags);
@@ -241,8 +242,7 @@ public:
UnnamedPropertyTarget // default property bindings, where property name is unspecified
};
- static QQmlJSScope::Ptr create(ScopeType type = QQmlJSScope::QMLScope,
- const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr());
+ static QQmlJSScope::Ptr create() { return QSharedPointer<QQmlJSScope>(new QQmlJSScope); }
static QQmlJSScope::Ptr clone(const QQmlJSScope::ConstPtr &origin);
static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope);
@@ -256,6 +256,8 @@ public:
return QQmlJSScope::WeakConstPtr(m_parentScope).toStrongRef();
}
+ static void reparent(const QQmlJSScope::Ptr &parentScope, const QQmlJSScope::Ptr &childScope);
+
void insertJSIdentifier(const QString &name, const JavaScriptIdentifier &identifier);
// inserts property as qml identifier as well as the corresponding
@@ -264,6 +266,7 @@ public:
bool isIdInCurrentScope(const QString &id) const;
ScopeType scopeType() const { return m_scopeType; }
+ void setScopeType(ScopeType type) { m_scopeType = type; }
void addOwnMethod(const QQmlJSMetaMethod &method) { m_methods.insert(method.methodName(), method); }
QMultiHash<QString, QQmlJSMetaMethod> ownMethods() const { return m_methods; }
@@ -322,11 +325,15 @@ public:
// If isComposite(), this is the QML/JS name of the prototype. Otherwise it's the
// relevant base class (in the hierarchy starting from QObject) of a C++ type.
- void setBaseTypeName(const QString &baseTypeName) { m_baseTypeName = baseTypeName; }
- QString baseTypeName() const { return m_baseTypeName; }
+ void setBaseTypeName(const QString &baseTypeName);
+ QString baseTypeName() const;
+
QQmlJSScope::ConstPtr baseType() const { return m_baseType.scope; }
QTypeRevision baseTypeRevision() const { return m_baseType.revision; }
+
void clearBaseType() { m_baseType = {}; }
+ void setBaseTypeError(const QString &baseTypeError);
+ QString baseTypeError() const;
void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); }
QHash<QString, QQmlJSMetaProperty> ownProperties() const { return m_properties; }
@@ -552,7 +559,7 @@ public:
};
private:
- QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr());
+ QQmlJSScope() = default;
QQmlJSScope(const QQmlJSScope &) = default;
QQmlJSScope &operator=(const QQmlJSScope &) = default;
@@ -587,7 +594,7 @@ private:
QString m_filePath;
QString m_internalName;
- QString m_baseTypeName;
+ QString m_baseTypeNameOrError;
// We only need the revision for the base type as inheritance is
// the only relation between two types where the revisions matter.
@@ -627,8 +634,6 @@ public:
m_filePath(filePath), m_importer(importer)
{}
- QQmlJSScope create() const;
-
bool isValid() const
{
return !m_filePath.isEmpty() && m_importer != nullptr;
@@ -645,6 +650,14 @@ public:
}
private:
+ friend class QDeferredSharedPointer<QQmlJSScope>;
+ friend class QDeferredSharedPointer<const QQmlJSScope>;
+ friend class QDeferredWeakPointer<QQmlJSScope>;
+ friend class QDeferredWeakPointer<const QQmlJSScope>;
+
+ // Should only be called when lazy-loading the type in a deferred pointer.
+ void populate(const QSharedPointer<QQmlJSScope> &scope) const;
+
QString m_filePath;
QQmlJSImporter *m_importer = nullptr;
bool m_isSingleton = false;
diff --git a/src/qmlcompiler/qqmljstypereader.cpp b/src/qmlcompiler/qqmljstypereader.cpp
index ae3c0becfe..753fbe12f8 100644
--- a/src/qmlcompiler/qqmljstypereader.cpp
+++ b/src/qmlcompiler/qqmljstypereader.cpp
@@ -40,13 +40,13 @@
QT_BEGIN_NAMESPACE
-QQmlJSScope::Ptr QQmlJSTypeReader::operator()()
+bool QQmlJSTypeReader::operator ()(const QSharedPointer<QQmlJSScope> &scope)
{
using namespace QQmlJS::AST;
const QFileInfo info { m_file };
- QString baseName = info.baseName();
- const QString scopeName = baseName.endsWith(QStringLiteral(".ui")) ? baseName.chopped(3)
- : baseName;
+ const QString baseName = info.baseName();
+ scope->setInternalName(baseName.endsWith(QStringLiteral(".ui")) ? baseName.chopped(3)
+ : baseName);
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
@@ -55,16 +55,10 @@ QQmlJSScope::Ptr QQmlJSTypeReader::operator()()
const bool isESModule = lowerSuffix == QLatin1String("mjs");
const bool isJavaScript = isESModule || lowerSuffix == QLatin1String("js");
- auto errorResult = [&](){
- QQmlJSScope::Ptr result = QQmlJSScope::create(
- isJavaScript ? QQmlJSScope::JSLexicalScope : QQmlJSScope::QMLScope);
- result->setInternalName(scopeName);
- return result;
- };
QFile file(m_file);
if (!file.open(QFile::ReadOnly))
- return errorResult();
+ return false;
QString code = QString::fromUtf8(file.readAll());
file.close();
@@ -76,11 +70,11 @@ QQmlJSScope::Ptr QQmlJSTypeReader::operator()()
: parser.parseProgram())
: parser.parse();
if (!success)
- return errorResult();
+ return false;
QQmlJS::AST::Node *rootNode = parser.rootNode();
if (!rootNode)
- return errorResult();
+ return false;
QQmlJSLogger logger;
logger.setFileName(m_file);
@@ -88,13 +82,10 @@ QQmlJSScope::Ptr QQmlJSTypeReader::operator()()
logger.setSilent(true);
QQmlJSImportVisitor membersVisitor(
- m_importer, &logger,
+ scope, m_importer, &logger,
QQmlJSImportVisitor::implicitImportDirectory(m_file, m_importer->resourceFileMapper()));
rootNode->accept(&membersVisitor);
- auto result = membersVisitor.result();
- Q_ASSERT(result);
- result->setInternalName(scopeName);
- return result;
+ return true;
}
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljstypereader_p.h b/src/qmlcompiler/qqmljstypereader_p.h
index 4dcdc3dc7f..f4dd8ceb15 100644
--- a/src/qmlcompiler/qqmljstypereader_p.h
+++ b/src/qmlcompiler/qqmljstypereader_p.h
@@ -59,7 +59,7 @@ public:
, m_file(file)
{}
- QQmlJSScope::Ptr operator()();
+ bool operator()(const QSharedPointer<QQmlJSScope> &scope);
QList<QQmlJS::DiagnosticMessage> errors() const { return m_errors; }
private: