aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-10-22 11:27:54 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-10-22 13:11:49 +0200
commit328759cdeb7b45eba5569b54ded35e38152ee0d0 (patch)
treefeac5f52693441217836ff42d379aa6b7c3869bb /src
parentc0063f73e5472f770133602ea2a7c6fe77f5a1b3 (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.cpp42
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h1
-rw-r--r--src/qmlcompiler/qqmljsscope.cpp42
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h23
-rw-r--r--src/qmlcompiler/qqmljstypedescriptionreader.cpp4
-rw-r--r--src/qmlcompiler/qqmljstypereader.cpp2
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;