aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-10-15 11:16:34 +0200
committerUlf Hermann <ulf.hermann@qt.io>2020-10-15 13:17:12 +0200
commitea7d11a3c73b6054852092ab268466f7639b8dbf (patch)
treea9137ca1a34466bb95224c9a37adf3e20b8b14ab /src
parentfa48382c492097d06d7ce066ac36dba04fd5e801 (diff)
Further unify findwarnings.cpp and qqmljsimportvisitor.cpp
Most of the logic in findwarnings.cpp applies also to imported files and should live in the base class. Change-Id: I65f326f50a8bfab0dff4b5b31f7bee7300b20704 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp183
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor_p.h22
2 files changed, 201 insertions, 4 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index ac21c7715e..c74f4cd396 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -85,6 +85,31 @@ QQmlJSScope::Ptr QQmlJSImportVisitor::result() const
return result;
}
+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();
@@ -110,6 +135,9 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition)
if (!m_qmlRootScope)
m_qmlRootScope = m_currentScope;
+ m_currentScope->resolveTypes(m_rootScopeImports);
+ importExportedNames(m_currentScope);
+
return true;
}
@@ -134,7 +162,9 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
break;
}
case UiPublicMember::Property: {
- auto typeName = publicMember->memberType->name;
+ auto typeName = publicMember->memberType
+ ? publicMember->memberType->name
+ : QStringView();
const bool isAlias = (typeName == QLatin1String("alias"));
if (isAlias) {
const auto expression = cast<ExpressionStatement *>(publicMember->statement);
@@ -144,13 +174,14 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
QQmlJSMetaProperty prop {
publicMember->name.toString(),
typeName.toString(),
- false,
- false,
+ publicMember->typeModifier == QLatin1String("list"),
+ !publicMember->isReadonlyMember,
false,
isAlias,
0
};
- m_currentScope->addProperty(prop);
+ prop.setType(m_rootScopeImports.value(prop.typeName()));
+ m_currentScope->insertPropertyIdentifier(prop);
break;
}
}
@@ -291,4 +322,148 @@ void QQmlJSImportVisitor::throwRecursionDepthError()
});
}
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::ClassDeclaration *ast)
+{
+ enterEnvironment(QQmlJSScope::JSFunctionScope, ast->name.toString());
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ClassDeclaration *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::ForStatement *)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("forloop"));
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ForStatement *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::ForEachStatement *)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("foreachloop"));
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::ForEachStatement *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::Block *)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("block"));
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::Block *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::CaseBlock *)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("case"));
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::CaseBlock *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::Catch *catchStatement)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("catch"));
+ m_currentScope->insertJSIdentifier(
+ catchStatement->patternElement->bindingIdentifier.toString(), {
+ QQmlJSScope::JavaScriptIdentifier::LexicalScoped,
+ catchStatement->patternElement->firstSourceLocation()
+ });
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::Catch *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::WithStatement *)
+{
+ enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("with"));
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::WithStatement *)
+{
+ leaveEnvironment();
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::VariableDeclarationList *vdl)
+{
+ while (vdl) {
+ m_currentScope->insertJSIdentifier(
+ vdl->declaration->bindingIdentifier.toString(),
+ {
+ (vdl->declaration->scope == QQmlJS::AST::VariableScope::Var)
+ ? QQmlJSScope::JavaScriptIdentifier::FunctionScoped
+ : QQmlJSScope::JavaScriptIdentifier::LexicalScoped,
+ vdl->declaration->firstSourceLocation()
+ });
+ vdl = vdl->next;
+ }
+ return true;
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::FormalParameterList *fpl)
+{
+ for (auto const &boundName : fpl->boundNames()) {
+ m_currentScope->insertJSIdentifier(
+ boundName.id, {
+ QQmlJSScope::JavaScriptIdentifier::Parameter,
+ fpl->firstSourceLocation()
+ });
+ }
+ return true;
+}
+
+bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiObjectBinding *uiob)
+{
+ // property QtObject __styleData: QtObject {...}
+
+ QString name;
+ for (auto id = uiob->qualifiedTypeNameId; id; id = id->next)
+ name += id->name.toString() + QLatin1Char('.');
+
+ name.chop(1);
+
+ QQmlJSMetaProperty prop(uiob->qualifiedId->name.toString(), name, false, true, true,
+ name == QLatin1String("alias"), 0);
+ prop.setType(m_rootScopeImports.value(uiob->qualifiedTypeNameId->name.toString()));
+ m_currentScope->addProperty(prop);
+
+ enterEnvironment(QQmlJSScope::QMLScope, name);
+ m_currentScope->resolveTypes(m_rootScopeImports);
+ importExportedNames(m_currentScope);
+ return true;
+}
+
+void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob)
+{
+ const QQmlJSScope::ConstPtr childScope = m_currentScope;
+ leaveEnvironment();
+ QQmlJSMetaProperty property(uiob->qualifiedId->name.toString(),
+ uiob->qualifiedTypeNameId->name.toString(),
+ false, true, true,
+ uiob->qualifiedTypeNameId->name == QLatin1String("alias"),
+ 0);
+ property.setType(childScope);
+ m_currentScope->addProperty(property);
+}
+
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljsimportvisitor_p.h b/src/qmlcompiler/qqmljsimportvisitor_p.h
index 1d50881441..33bb3aa90d 100644
--- a/src/qmlcompiler/qqmljsimportvisitor_p.h
+++ b/src/qmlcompiler/qqmljsimportvisitor_p.h
@@ -70,6 +70,27 @@ protected:
bool visit(QQmlJS::AST::ClassExpression *ast) override;
void endVisit(QQmlJS::AST::ClassExpression *) override;
bool visit(QQmlJS::AST::UiImport *import) override;
+ bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
+ void endVisit(QQmlJS::AST::ClassDeclaration *ast) override;
+ bool visit(QQmlJS::AST::ForStatement *ast) override;
+ void endVisit(QQmlJS::AST::ForStatement *ast) override;
+ bool visit(QQmlJS::AST::ForEachStatement *ast) override;
+ void endVisit(QQmlJS::AST::ForEachStatement *ast) override;
+ bool visit(QQmlJS::AST::Block *ast) override;
+ void endVisit(QQmlJS::AST::Block *ast) override;
+ bool visit(QQmlJS::AST::CaseBlock *ast) override;
+ void endVisit(QQmlJS::AST::CaseBlock *ast) override;
+ bool visit(QQmlJS::AST::Catch *ast) override;
+ void endVisit(QQmlJS::AST::Catch *ast) override;
+ bool visit(QQmlJS::AST::WithStatement *withStatement) override;
+ void endVisit(QQmlJS::AST::WithStatement *ast) override;
+
+ bool visit(QQmlJS::AST::VariableDeclarationList *vdl) override;
+ bool visit(QQmlJS::AST::FormalParameterList *fpl) override;
+
+ bool visit(QQmlJS::AST::UiObjectBinding *uiob) override;
+ void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override;
+
void throwRecursionDepthError() override;
QString m_implicitImportDirectory;
@@ -85,6 +106,7 @@ protected:
void enterEnvironment(QQmlJSScope::ScopeType type, const QString &name);
void leaveEnvironment();
+ void importExportedNames(QQmlJSScope::ConstPtr scope);
private:
void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);