diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-24 14:14:46 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-11-25 12:51:34 +0100 |
commit | 140a34afdd9ecbb7bc5f9db3f68dcd43a6c534e3 (patch) | |
tree | b235dbaabac9e900992c76baf6b7f919b9a7195a /src/qmlcompiler/qqmljsimportvisitor.cpp | |
parent | 927dd69db9bbffcc423b735a7f89e950e052892a (diff) |
QmlCompiler: Unify parsing of QML components, JS programs, ES modules
There is no reason to duplicate the code for retrieving method
signatures 3 times over. As an added benefit, the types on those methods
are resolved now.
Change-Id: I2f9681911b938c4a260b6593ab49e9cc5098c546
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljsimportvisitor.cpp')
-rw-r--r-- | src/qmlcompiler/qqmljsimportvisitor.cpp | 95 |
1 files changed, 74 insertions, 21 deletions
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp index 0e16b02846..c4f99f48b2 100644 --- a/src/qmlcompiler/qqmljsimportvisitor.cpp +++ b/src/qmlcompiler/qqmljsimportvisitor.cpp @@ -67,7 +67,7 @@ void QQmlJSImportVisitor::leaveEnvironment() void QQmlJSImportVisitor::resolveAliases() { QQueue<QQmlJSScope::Ptr> objects; - objects.enqueue(m_qmlRootScope); + objects.enqueue(m_exportedRootScope); while (!objects.isEmpty()) { const QQmlJSScope::Ptr object = objects.dequeue(); @@ -90,19 +90,24 @@ void QQmlJSImportVisitor::resolveAliases() QQmlJSScope::Ptr QQmlJSImportVisitor::result() const { - return m_qmlRootScope; + return m_exportedRootScope; } -bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiProgram *) +void QQmlJSImportVisitor::importBaseModules() { + Q_ASSERT(m_rootScopeImports.isEmpty()); m_rootScopeImports = m_importer->importBuiltins(); if (!m_qmltypesFiles.isEmpty()) m_rootScopeImports.insert(m_importer->importQmltypes(m_qmltypesFiles)); m_rootScopeImports.insert(m_importer->importDirectory(m_implicitImportDirectory)); - m_errors.append(m_importer->takeWarnings()); +} + +bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiProgram *) +{ + importBaseModules(); return true; } @@ -120,8 +125,8 @@ bool QQmlJSImportVisitor::visit(UiObjectDefinition *definition) superType.append(segment->name.toString()); } enterEnvironment(QQmlJSScope::QMLScope, superType, definition->firstSourceLocation()); - if (!m_qmlRootScope) - m_qmlRootScope = m_currentScope; + if (!m_exportedRootScope) + m_exportedRootScope = m_currentScope; m_currentScope->resolveTypes(m_rootScopeImports); return true; @@ -178,22 +183,22 @@ void QQmlJSImportVisitor::visitFunctionExpressionHelper(QQmlJS::AST::FunctionExp using namespace QQmlJS::AST; auto name = fexpr->name.toString(); if (!name.isEmpty()) { - if (m_currentScope->scopeType() == QQmlJSScope::QMLScope) { - QQmlJSMetaMethod method(name); - method.setMethodType(QQmlJSMetaMethod::Method); - if (const auto *formals = fexpr->formals) { - const auto parameters = formals->formals(); - for (const auto ¶meter : parameters) { - const QString type = parameter.typeName(); - method.addParameter(parameter.id, - type.isEmpty() ? QStringLiteral("var") : type); - } + QQmlJSMetaMethod method(name); + method.setMethodType(QQmlJSMetaMethod::Method); + if (const auto *formals = fexpr->formals) { + const auto parameters = formals->formals(); + for (const auto ¶meter : parameters) { + const QString type = parameter.typeName(); + method.addParameter(parameter.id, + type.isEmpty() ? QStringLiteral("var") : type); } - method.setReturnTypeName(fexpr->typeAnnotation - ? fexpr->typeAnnotation->type->toString() - : QStringLiteral("var")); - m_currentScope->addOwnMethod(method); - } else { + } + method.setReturnTypeName(fexpr->typeAnnotation + ? fexpr->typeAnnotation->type->toString() + : QStringLiteral("var")); + m_currentScope->addOwnMethod(method); + + if (m_currentScope->scopeType() != QQmlJSScope::QMLScope) { m_currentScope->insertJSIdentifier( name, { QQmlJSScope::JavaScriptIdentifier::LexicalScoped, @@ -504,4 +509,52 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob) m_currentScope->addOwnProperty(property); } +bool QQmlJSImportVisitor::visit(ExportDeclaration *) +{ + Q_ASSERT(!m_exportedRootScope.isNull()); + Q_ASSERT(m_exportedRootScope != m_globalScope); + Q_ASSERT(m_currentScope == m_globalScope); + m_currentScope = m_exportedRootScope; + return true; +} + +void QQmlJSImportVisitor::endVisit(ExportDeclaration *) +{ + Q_ASSERT(!m_exportedRootScope.isNull()); + m_currentScope = m_exportedRootScope->parentScope(); + Q_ASSERT(m_currentScope == m_globalScope); +} + +bool QQmlJSImportVisitor::visit(ESModule *module) +{ + enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("module"), + module->firstSourceLocation()); + Q_ASSERT(m_exportedRootScope.isNull()); + m_exportedRootScope = m_currentScope; + m_exportedRootScope->setIsScript(true); + importBaseModules(); + leaveEnvironment(); + return true; +} + +void QQmlJSImportVisitor::endVisit(ESModule *) +{ + m_exportedRootScope->resolveTypes(m_rootScopeImports); +} + +bool QQmlJSImportVisitor::visit(Program *) +{ + Q_ASSERT(m_globalScope == m_currentScope); + Q_ASSERT(m_exportedRootScope.isNull()); + m_exportedRootScope = m_currentScope; + m_exportedRootScope->setIsScript(true); + importBaseModules(); + return true; +} + +void QQmlJSImportVisitor::endVisit(Program *) +{ + m_exportedRootScope->resolveTypes(m_rootScopeImports); +} + QT_END_NAMESPACE |