diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-15 11:16:34 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-10-15 13:17:12 +0200 |
commit | ea7d11a3c73b6054852092ab268466f7639b8dbf (patch) | |
tree | a9137ca1a34466bb95224c9a37adf3e20b8b14ab /src | |
parent | fa48382c492097d06d7ce066ac36dba04fd5e801 (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.cpp | 183 | ||||
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor_p.h | 22 |
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); |