aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsimportvisitor.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-11-24 14:14:46 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-11-25 12:51:34 +0100
commit140a34afdd9ecbb7bc5f9db3f68dcd43a6c534e3 (patch)
treeb235dbaabac9e900992c76baf6b7f919b9a7195a /src/qmlcompiler/qqmljsimportvisitor.cpp
parent927dd69db9bbffcc423b735a7f89e950e052892a (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.cpp95
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 &parameter : 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 &parameter : 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