diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-21 16:06:20 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-27 09:23:30 +0100 |
commit | ed8127cf41951a9ff1d6032c2158e49fdebe51c3 (patch) | |
tree | 12e74c92f9c9a9ee940e4bde91ba4132454c1dd8 /src/qmlcompiler | |
parent | 23813a319898e8951645a9f9bec5813090fd3a85 (diff) |
QmlCompiler: Introduce grouped scopes
This way we can analyze the left hand part of things like
"anchors.fill: parent" in qmllint.
Change-Id: I0f58312566c3d5062e0fb301c2bad908ab8b8cbb
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler')
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor.cpp | 25 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 21 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope_p.h | 4 |
3 files changed, 47 insertions, 3 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 04bb27dc84..bb789a1c66 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -51,7 +51,10 @@ void QQmlJSImportVisitor::enterEnvironment(QQmlJSScope::ScopeType type, const QS const QQmlJS::SourceLocation &location) { m_currentScope = QQmlJSScope::create(type, m_currentScope); - m_currentScope->setBaseTypeName(name); + if (type == QQmlJSScope::GroupedPropertyScope) + m_currentScope->setInternalName(name); + else + m_currentScope->setBaseTypeName(name); m_currentScope->setIsComposite(true); m_currentScope->setSourceLocation(location); } @@ -126,6 +129,7 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition) void QQmlJSImportVisitor::endVisit(UiObjectDefinition *) { + m_currentScope->resolveGroupedScopes(); leaveEnvironment(); } @@ -235,11 +239,27 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ClassExpression *) bool QQmlJSImportVisitor::visit(UiScriptBinding *scriptBinding) { - if (scriptBinding->qualifiedId->name == QLatin1String("id")) { + const auto id = scriptBinding->qualifiedId; + if (!id->next && id->name == QLatin1String("id")) { const auto *statement = cast<ExpressionStatement *>(scriptBinding->statement); const auto *idExprension = cast<IdentifierExpression *>(statement->expression); m_scopesById.insert(idExprension->name.toString(), m_currentScope); + } else { + for (auto group = id; group->next; group = group->next) { + const QString name = group->name.toString(); + + if (name.isEmpty() || name.front().isUpper()) + break; // TODO: uppercase grouped scopes are attached properties. Handle them. + + enterEnvironment(QQmlJSScope::GroupedPropertyScope, name, group->firstSourceLocation()); + } + + // TODO: remember the actual binding, once we can process it. + + while (m_currentScope->scopeType() == QQmlJSScope::GroupedPropertyScope) + leaveEnvironment(); } + return true; } @@ -448,6 +468,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob) { + m_currentScope->resolveGroupedScopes(); const QQmlJSScope::ConstPtr childScope = m_currentScope; leaveEnvironment(); diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index bea6c29932..0787e1062e 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -168,6 +168,27 @@ void QQmlJSScope::resolveTypes(const QHash<QString, QQmlJSScope::ConstPtr> &cont } } +void QQmlJSScope::resolveGroupedScopes() +{ + for (auto it = m_childScopes.begin(), end = m_childScopes.end(); it != end; ++it) { + QQmlJSScope::Ptr childScope = *it; + if (childScope->scopeType() != QQmlJSScope::GroupedPropertyScope) + continue; + + const QString propertyName = childScope->internalName(); + for (const QQmlJSScope *type = this; type; type = type->baseType().data()) { + auto propertyIt = type->m_properties.find(propertyName); + if (propertyIt != type->m_properties.end()) { + childScope->m_baseType = QQmlJSScope::ConstPtr(propertyIt->type()); + childScope->m_baseTypeName = propertyIt->typeName(); + break; + } + } + + childScope->resolveGroupedScopes(); + } +} + QQmlJSScope::ConstPtr QQmlJSScope::findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope) { auto qmlScope = scope; diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index 175b2ecda1..99645a8071 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -94,7 +94,8 @@ public: { JSFunctionScope, JSLexicalScope, - QMLScope + QMLScope, + GroupedPropertyScope }; enum class AccessSemantics { @@ -221,6 +222,7 @@ public: } void resolveTypes(const QHash<QString, ConstPtr> &contextualTypes); + void resolveGroupedScopes(); void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation) { |