diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-22 11:27:54 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-22 13:11:49 +0200 |
commit | 328759cdeb7b45eba5569b54ded35e38152ee0d0 (patch) | |
tree | feac5f52693441217836ff42d379aa6b7c3869bb /src | |
parent | c0063f73e5472f770133602ea2a7c6fe77f5a1b3 (diff) |
QmlCompiler: Properly discern between inherited and own names
Previously, we would mix them up on importExportedNames(), which was
also misnamed. Now we keep them in their proper place in the scope
hierarchy, so that we can identify which scope a property came from.
Exceptions are the qmllint-specific treatment of parent properties and
Connections elements.
Change-Id: I7c012388b16c83439d6f2de2e83fac0da4940d30
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor.cpp | 42 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor_p.h | 1 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope.cpp | 42 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsscope_p.h | 23 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypedescriptionreader.cpp | 4 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljstypereader.cpp | 2 |
6 files changed, 64 insertions, 50 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 6595b1d8d7..04bb27dc84 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -68,14 +68,14 @@ void QQmlJSImportVisitor::resolveAliases() while (!objects.isEmpty()) { const QQmlJSScope::Ptr object = objects.dequeue(); - const auto properties = object->properties(); + const auto properties = object->ownProperties(); for (auto property : properties) { if (!property.isAlias()) continue; const auto it = m_scopesById.find(property.typeName()); if (it != m_scopesById.end()) { property.setType(QQmlJSScope::ConstPtr(*it)); - object->addProperty(property); + object->addOwnProperty(property); } } @@ -90,31 +90,6 @@ QQmlJSScope::Ptr QQmlJSImportVisitor::result() const return m_qmlRootScope; } -void QQmlJSImportVisitor::importExportedNames(QQmlJSScope::ConstPtr scope) -{ - QList<QQmlJSScope::ConstPtr> scopes; - while (!scope.isNull()) { - if (scopes.contains(scope)) - break; - - scopes.append(scope); - - const auto properties = scope->properties(); - for (auto property : properties) - m_currentScope->insertPropertyIdentifier(property); - - m_currentScope->addMethods(scope->methods()); - - if (scope->baseTypeName().isEmpty()) - break; - - if (auto newScope = scope->baseType()) - scope = newScope; - else - break; - } -} - bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiProgram *) { m_rootScopeImports = m_importer->importBuiltins(); @@ -146,8 +121,6 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition) m_qmlRootScope = m_currentScope; m_currentScope->resolveTypes(m_rootScopeImports); - importExportedNames(m_currentScope); - return true; } @@ -168,7 +141,7 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember) method.addParameter(param->name.toString(), param->type->name.toString()); param = param->next; } - m_currentScope->addMethod(method); + m_currentScope->addOwnMethod(method); break; } case UiPublicMember::Property: { @@ -208,7 +181,7 @@ void QQmlJSImportVisitor::visitFunctionExpressionHelper(QQmlJS::AST::FunctionExp method.addParameter(parameters->element->bindingIdentifier.toString(), QString()); parameters = parameters->next; } - m_currentScope->addMethod(method); + m_currentScope->addOwnMethod(method); } else { m_currentScope->insertJSIdentifier( name, { @@ -249,7 +222,7 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::ClassExpression *ast) { QQmlJSMetaProperty prop; prop.setPropertyName(ast->name.toString()); - m_currentScope->addProperty(prop); + m_currentScope->addOwnProperty(prop); enterEnvironment(QQmlJSScope::JSFunctionScope, ast->name.toString(), ast->firstSourceLocation()); return true; @@ -466,11 +439,10 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob) prop.setIsPointer(true); prop.setIsAlias(name == QLatin1String("alias")); prop.setType(m_rootScopeImports.value(uiob->qualifiedTypeNameId->name.toString())); - m_currentScope->addProperty(prop); + m_currentScope->addOwnProperty(prop); enterEnvironment(QQmlJSScope::QMLScope, name, uiob->firstSourceLocation()); m_currentScope->resolveTypes(m_rootScopeImports); - importExportedNames(m_currentScope); return true; } @@ -481,7 +453,7 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob) QQmlJSMetaProperty property = m_currentScope->property(uiob->qualifiedId->name.toString()); property.setType(childScope); - m_currentScope->addProperty(property); + m_currentScope->addOwnProperty(property); } QT_END_NAMESPACE diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h index eef5889263..1f26536923 100644 --- a/src/qmlcompiler/qqmljsimportvisitor_p.h +++ b/src/qmlcompiler/qqmljsimportvisitor_p.h @@ -113,7 +113,6 @@ protected: private: void resolveAliases(); void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr); - void importExportedNames(QQmlJSScope::ConstPtr scope); }; QT_END_NAMESPACE diff --git a/src/qmlcompiler/qqmljsscope.cpp b/src/qmlcompiler/qqmljsscope.cpp index ba74280ae2..bea6c29932 100644 --- a/src/qmlcompiler/qqmljsscope.cpp +++ b/src/qmlcompiler/qqmljsscope.cpp @@ -66,9 +66,9 @@ void QQmlJSScope::insertJSIdentifier(const QString &name, const JavaScriptIdenti void QQmlJSScope::insertPropertyIdentifier(const QQmlJSMetaProperty &property) { - addProperty(property); + addOwnProperty(property); QQmlJSMetaMethod method(property.propertyName() + QLatin1String("Changed"), QLatin1String("void")); - addMethod(method); + addOwnMethod(method); } bool QQmlJSScope::isIdInCurrentScope(const QString &id) const @@ -76,6 +76,25 @@ bool QQmlJSScope::isIdInCurrentScope(const QString &id) const return isIdInCurrentQMlScopes(id) || isIdInCurrentJSScopes(id); } +bool QQmlJSScope::hasMethod(const QString &name) const +{ + for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { + if (scope->m_methods.contains(name)) + return true; + } + return false; +} + +QQmlJSMetaMethod QQmlJSScope::method(const QString &name) const +{ + for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { + const auto it = scope->m_methods.find(name); + if (it != scope->m_methods.end()) + return *it; + } + return {}; +} + bool QQmlJSScope::isIdInCurrentQMlScopes(const QString &id) const { if (m_scopeType == QQmlJSScope::QMLScope) @@ -163,6 +182,25 @@ void QQmlJSScope::addExport(const QString &name, const QString &package, m_exports.append(Export(package, name, version)); } +bool QQmlJSScope::hasProperty(const QString &name) const +{ + for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { + if (scope->m_properties.contains(name)) + return true; + } + return false; +} + +QQmlJSMetaProperty QQmlJSScope::property(const QString &name) const +{ + for (const QQmlJSScope *scope = this; scope; scope = scope->baseType().data()) { + const auto it = scope->m_properties.find(name); + if (it != scope->m_properties.end()) + return *it; + } + return {}; +} + QQmlJSScope::Export::Export(QString package, QString type, const QTypeRevision &version) : m_package(std::move(package)), m_type(std::move(type)), diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h index d656b2f5b4..175b2ecda1 100644 --- a/src/qmlcompiler/qqmljsscope_p.h +++ b/src/qmlcompiler/qqmljsscope_p.h @@ -156,11 +156,13 @@ public: ScopeType scopeType() const { return m_scopeType; } - void addMethods(const QMultiHash<QString, QQmlJSMetaMethod> &methods) { m_methods.unite(methods); } - void addMethod(const QQmlJSMetaMethod &method) { m_methods.insert(method.methodName(), method); } - QMultiHash<QString, QQmlJSMetaMethod> methods() const { return m_methods; } - QQmlJSMetaMethod method(const QString &name) const { return m_methods.value(name); } - bool hasMethod(const QString &name) const { return m_methods.contains(name); } + void addOwnMethod(const QQmlJSMetaMethod &method) { m_methods.insert(method.methodName(), method); } + QMultiHash<QString, QQmlJSMetaMethod> ownMethods() const { return m_methods; } + QQmlJSMetaMethod ownMethod(const QString &name) const { return m_methods.value(name); } + bool hasOwnMethod(const QString &name) const { return m_methods.contains(name); } + + bool hasMethod(const QString &name) const; + QQmlJSMetaMethod method(const QString &name) const; void addEnum(const QQmlJSMetaEnum &fakeEnum) { m_enums.insert(fakeEnum.name(), fakeEnum); } QHash<QString, QQmlJSMetaEnum> enums() const { return m_enums; } @@ -182,10 +184,13 @@ public: QString baseTypeName() const { return m_baseTypeName; } QQmlJSScope::ConstPtr baseType() const { return m_baseType; } - void addProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); } - QHash<QString, QQmlJSMetaProperty> properties() const { return m_properties; } - QQmlJSMetaProperty property(const QString &name) const { return m_properties.value(name); } - bool hasProperty(const QString &name) const { return m_properties.contains(name); } + void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); } + QHash<QString, QQmlJSMetaProperty> ownProperties() const { return m_properties; } + QQmlJSMetaProperty ownProperty(const QString &name) const { return m_properties.value(name); } + bool hasOwnProperty(const QString &name) const { return m_properties.contains(name); } + + bool hasProperty(const QString &name) const; + QQmlJSMetaProperty property(const QString &name) const; QString defaultPropertyName() const { return m_defaultPropertyName; } void setDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; } diff --git a/src/qmlcompiler/qqmljstypedescriptionreader.cpp b/src/qmlcompiler/qqmljstypedescriptionreader.cpp index 4b7dcead31..17e3d2e707 100644 --- a/src/qmlcompiler/qqmljstypedescriptionreader.cpp +++ b/src/qmlcompiler/qqmljstypedescriptionreader.cpp @@ -308,7 +308,7 @@ void QQmlJSTypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bo return; } - scope->addMethod(metaMethod); + scope->addOwnMethod(metaMethod); } void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQmlJSScope::Ptr &scope) @@ -351,7 +351,7 @@ void QQmlJSTypeDescriptionReader::readProperty(UiObjectDefinition *ast, const QQ return; } - scope->addProperty(property); + scope->addOwnProperty(property); } void QQmlJSTypeDescriptionReader::readEnum(UiObjectDefinition *ast, const QQmlJSScope::Ptr &scope) diff --git a/src/qmlcompiler/qqmljstypereader.cpp b/src/qmlcompiler/qqmljstypereader.cpp index 578b0378c3..2c45bb01d6 100644 --- a/src/qmlcompiler/qqmljstypereader.cpp +++ b/src/qmlcompiler/qqmljstypereader.cpp @@ -51,7 +51,7 @@ static QQmlJSScope::Ptr parseProgram(QQmlJS::AST::Program *program, const QStrin method.setMethodType(QQmlJSMetaMethod::Method); for (auto *parameters = function->formals; parameters; parameters = parameters->next) method.addParameter(parameters->element->bindingIdentifier.toString(), QString()); - result->addMethod(method); + result->addOwnMethod(method); } } return result; |