46 QQmlJSImportVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger,
47 const QString &implicitImportDirectory,
48 const QStringList &qmldirFiles = QStringList());
49 ~QQmlJSImportVisitor();
51 using QQmlJS::AST::Visitor::endVisit;
52 using QQmlJS::AST::Visitor::postVisit;
53 using QQmlJS::AST::Visitor::preVisit;
54 using QQmlJS::AST::Visitor::visit;
56 QQmlJSScope::Ptr result()
const {
return m_exportedRootScope; }
58 const QQmlJSLogger *logger()
const {
return m_logger; }
59 QQmlJSLogger *logger() {
return m_logger; }
61 QQmlJSImporter::ImportedTypes imports()
const {
return m_rootScopeImports; }
62 QQmlJSScopesById addressableScopes()
const {
return m_scopesById; }
63 QDuplicateTracker<QQmlJSScope::ConstPtr> *knownUnresolvedTypes() {
return &m_unresolvedTypes; }
64 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> signalHandlers()
const
66 return m_signalHandlers;
68 QList<QQmlJSScope::ConstPtr> qmlTypes()
const {
return m_qmlTypes; }
69 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> scopesBylocation()
const
71 return m_scopesByIrLocation;
74 static QString implicitImportDirectory(
const QString &localFile,
75 const QQmlJSResourceFileMapper *mapper);
78 QQmlJSImporter *importer() {
return m_importer; }
79 const QQmlJSImporter *importer()
const {
return m_importer; }
81 struct UnfinishedBinding
83 QQmlJSScope::Ptr owner;
84 std::function<QQmlJSMetaPropertyBinding()> create;
85 QQmlJSScope::BindingTargetSpecifier specifier = QQmlJSScope::SimplePropertyTarget;
88 QStringList seenModuleQualifiers()
const {
return m_seenModuleQualifiers; }
91 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
92 void endVisit(QQmlJS::AST::ExpressionStatement *ast) override;
94 bool visit(QQmlJS::AST::UiProgram *) override;
95 void endVisit(QQmlJS::AST::UiProgram *) override;
96 bool visit(QQmlJS::AST::UiObjectDefinition *) override;
97 void endVisit(QQmlJS::AST::UiObjectDefinition *) override;
98 bool visit(QQmlJS::AST::UiInlineComponent *) override;
99 void endVisit(QQmlJS::AST::UiInlineComponent *) override;
100 bool visit(QQmlJS::AST::UiPublicMember *) override;
101 void endVisit(QQmlJS::AST::UiPublicMember *) override;
102 bool visit(QQmlJS::AST::UiRequired *required) override;
103 bool visit(QQmlJS::AST::UiScriptBinding *) override;
104 void endVisit(QQmlJS::AST::UiScriptBinding *) override;
105 bool visit(QQmlJS::AST::UiArrayBinding *) override;
106 void endVisit(QQmlJS::AST::UiArrayBinding *) override;
107 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
108 bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
109 void endVisit(QQmlJS::AST::FunctionExpression *) override;
110 bool visit(QQmlJS::AST::UiSourceElement *) override;
111 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override;
112 void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
113 bool visit(QQmlJS::AST::ClassExpression *ast) override;
114 void endVisit(QQmlJS::AST::ClassExpression *) override;
115 bool visit(QQmlJS::AST::UiImport *import) override;
116 bool visit(QQmlJS::AST::UiPragma *pragma) override;
117 bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
118 void endVisit(QQmlJS::AST::ClassDeclaration *ast) override;
119 bool visit(QQmlJS::AST::ForStatement *ast) override;
120 void endVisit(QQmlJS::AST::ForStatement *ast) override;
121 bool visit(QQmlJS::AST::ForEachStatement *ast) override;
122 void endVisit(QQmlJS::AST::ForEachStatement *ast) override;
123 bool visit(QQmlJS::AST::Block *ast) override;
124 void endVisit(QQmlJS::AST::Block *ast) override;
125 bool visit(QQmlJS::AST::CaseBlock *ast) override;
126 void endVisit(QQmlJS::AST::CaseBlock *ast) override;
127 bool visit(QQmlJS::AST::Catch *ast) override;
128 void endVisit(QQmlJS::AST::Catch *ast) override;
129 bool visit(QQmlJS::AST::WithStatement *withStatement) override;
130 void endVisit(QQmlJS::AST::WithStatement *ast) override;
132 bool visit(QQmlJS::AST::FormalParameterList *fpl) override;
134 bool visit(QQmlJS::AST::UiObjectBinding *uiob) override;
135 void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override;
137 bool visit(QQmlJS::AST::ExportDeclaration *exp) override;
138 void endVisit(QQmlJS::AST::ExportDeclaration *exp) override;
140 bool visit(QQmlJS::AST::ESModule *module) override;
141 void endVisit(QQmlJS::AST::ESModule *module) override;
143 bool visit(QQmlJS::AST::Program *program) override;
144 void endVisit(QQmlJS::AST::Program *program) override;
146 bool visit(QQmlJS::AST::PatternElement *) override;
148 bool visit(QQmlJS::AST::IfStatement *) override;
150 void throwRecursionDepthError() override;
152 virtual bool checkCustomParser(
const QQmlJSScope::ConstPtr &scope);
154 void setScopeName(QQmlJSScope::Ptr &scope, QQmlJSScope::ScopeType type,
const QString &name);
155 virtual bool safeInsertJSIdentifier(QQmlJSScope::Ptr &scope,
const QString &name,
156 const QQmlJSScope::JavaScriptIdentifier &identifier);
157 void createAttachedAndGroupedScopes(QQmlJS::AST::UiQualifiedId *propertyName);
158 int openAttachedAndGroupedScopes(QQmlJS::AST::UiQualifiedId *propertyName);
160 QString m_implicitImportDirectory;
161 QStringList m_qmldirFiles;
162 QQmlJSScope::Ptr m_currentScope;
163 const QQmlJSScope::Ptr m_exportedRootScope;
164 QQmlJSImporter *m_importer =
nullptr;
165 QQmlJSLogger *m_logger =
nullptr;
167 using RootDocumentNameType = QQmlJSScope::RootDocumentNameType;
168 using InlineComponentNameType = QQmlJSScope::InlineComponentNameType;
169 using InlineComponentOrDocumentRootName = QQmlJSScope::RootDocumentNameType;
170 QQmlJSScope::InlineComponentOrDocumentRootName m_currentRootName =
171 QQmlJSScope::RootDocumentNameType();
172 bool m_nextIsInlineComponent =
false;
173 bool m_rootIsSingleton =
false;
174 QQmlJSScope::Ptr m_savedBindingOuterScope;
175 QQmlJSScope::ConstPtr m_globalScope;
176 QQmlJSScopesById m_scopesById;
177 QQmlJSImporter::ImportedTypes m_rootScopeImports;
178 QList<QQmlJSScope::ConstPtr> m_qmlTypes;
182 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_scopesByIrLocation;
184 virtual QSet<QString> *usedTypes() {
return nullptr; };
186 QList<UnfinishedBinding> m_bindings;
190 QHash<QQmlJSScope::ConstPtr, QList<QString>> m_functionsAndExpressions;
192 template <
bool scopeIsConst =
true>
195 using Scope = std::conditional_t<scopeIsConst, QQmlJSScope::ConstPtr, QQmlJSScope::Ptr>;
197 ScopeAndNameT() =
default;
198 ScopeAndNameT(
const Scope &scope,
const QString &name) : scope(scope), name(name) { }
199 ScopeAndNameT(
const ScopeAndNameT &) =
default;
200 ScopeAndNameT(ScopeAndNameT &&) =
default;
201 ScopeAndNameT &operator=(
const ScopeAndNameT &) =
default;
202 ScopeAndNameT &operator=(ScopeAndNameT &&) =
default;
203 ~ScopeAndNameT() =
default;
206 ScopeAndNameT(
typename std::enable_if<scopeIsConst, ScopeAndNameT<
false>>::type &nonConst)
207 : scope(nonConst.scope), name(nonConst.name)
211 friend bool operator==(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
213 return lhs.scope == rhs.scope && lhs.name == rhs.name;
215 friend bool operator!=(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
217 return !(lhs == rhs);
219 friend size_t qHash(
const ScopeAndNameT &san, size_t seed = 0)
221 return qHashMulti(seed, san.scope, san.name);
227 using ConstScopeAndName = ScopeAndNameT<
true>;
228 using ScopeAndName = ScopeAndNameT<
false>;
230 using FunctionOrExpressionIdentifier = ConstScopeAndName;
231 using Property = ConstScopeAndName;
232 using Alias = ConstScopeAndName;
235 bool m_thisScriptBindingIsJavaScript =
false;
236 QStack<FunctionOrExpressionIdentifier> m_functionStack;
238 QHash<FunctionOrExpressionIdentifier,
int> m_innerFunctions;
239 QQmlJSMetaMethod::RelativeFunctionIndex
240 addFunctionOrExpression(
const QQmlJSScope::ConstPtr &scope,
const QString &name);
241 void forgetFunctionExpression(
const QString &name);
242 int synthesizeCompilationUnitRuntimeFunctionIndices(
const QQmlJSScope::Ptr &scope,
244 void populateRuntimeFunctionIndicesForDocument()
const;
246 void enterEnvironment(QQmlJSScope::ScopeType type,
const QString &name,
247 const QQmlJS::SourceLocation &location);
250 bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type,
const QString &name,
251 const QQmlJS::SourceLocation &location);
252 virtual void leaveEnvironment();
256 QDuplicateTracker<QQmlJSScope::ConstPtr> m_unresolvedTypes;
257 template<
typename ErrorHandler>
258 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type, ErrorHandler handle)
260 if (type->isFullyResolved() || checkCustomParser(type))
265 if (type->scopeType() == QQmlSA::ScopeType::GroupedPropertyScope && type->parentScope()
266 && !checkTypeResolved(type->parentScope(), handle)) {
272 if (!m_unresolvedTypes.hasSeen(type))
278 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type)
280 return checkTypeResolved(type, [&](
const QQmlJSScope::ConstPtr &type) {
281 warnUnresolvedType(type);
285 void warnUnresolvedType(
const QQmlJSScope::ConstPtr &type)
const;
286 void warnMissingPropertyForBinding(
287 const QString &property,
const QQmlJS::SourceLocation &location,
288 const std::optional<QQmlJSFixSuggestion> &fixSuggestion = {});
290 QList<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
291 void setAllBindings();
292 void addDefaultProperties();
293 void processDefaultProperties();
294 void processPropertyBindings();
295 void checkRequiredProperties();
296 void processPropertyTypes();
297 void processMethodTypes();
298 void processPropertyBindingObjects();
299 void flushPendingSignalParameters();
301 void breakInheritanceCycles(
const QQmlJSScope::Ptr &scope);
302 void checkDeprecation(
const QQmlJSScope::ConstPtr &scope);
303 virtual void checkGroupedAndAttachedScopes() { }
304 void checkForComponentTypeWithProperties(
const QQmlJSScope::ConstPtr &scope);
305 bool rootScopeIsValid()
const {
return m_exportedRootScope->sourceLocation().isValid(); }
307 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
308 enum class BindingForPropertyDefintion { Yes, No };
309 virtual BindingExpressionParseResult parseBindingExpression(
310 const QString &name,
const QQmlJS::AST::Statement *statement,
311 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition =
nullptr);
312 bool isImportPrefix(QString prefix)
const;
315 QList<QQmlJSAnnotation> m_pendingMethodAnnotations;
317 struct PendingPropertyType
319 QQmlJSScope::Ptr scope;
321 QQmlJS::SourceLocation location;
324 struct PendingMethodTypeAnnotations
326 QQmlJSScope::Ptr scope;
330 QVarLengthArray<QQmlJS::SourceLocation, 3> locations;
333 struct PendingPropertyObjectBinding
335 QQmlJSScope::Ptr scope;
336 QQmlJSScope::Ptr childScope;
338 QQmlJS::SourceLocation location;
342 struct RequiredProperty
344 QQmlJSScope::Ptr scope;
346 QQmlJS::SourceLocation location;
350
351
352
353
354
355
356
357
358
359
361 struct WithVisibilityScope
363 QQmlJSScope::Ptr visibilityScope;
364 QQmlJS::SourceLocation dataLocation;
368 QHash<QQmlJSScope::Ptr, QList<QQmlJSScope::Ptr>> m_pendingDefaultProperties;
369 QList<PendingPropertyType> m_pendingPropertyTypes;
370 QList<PendingMethodTypeAnnotations> m_pendingMethodTypeAnnotations;
371 QList<PendingPropertyObjectBinding> m_pendingPropertyObjectBindings;
372 QList<RequiredProperty> m_requiredProperties;
373 QList<QQmlJSScope::Ptr> m_objectBindingScopes;
374 QList<QQmlJSScope::Ptr> m_objectDefinitionScopes;
376 QHash<QQmlJSScope::Ptr, QList<WithVisibilityScope<QString>>> m_propertyBindings;
377 QList<Alias> m_aliasDefinitions;
378 QHash<Property, QList<Alias>> m_propertyAliases;
380 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
381 QQmlJS::SourceLocation m_pendingSignalHandler;
382 QStringList m_seenModuleQualifiers;
383 QHash<QStringView, QQmlJS::SourceLocation> m_seenInlineComponents;
386 void registerTargetIntoImporter(
const QQmlJSScope::Ptr &target);
388 const QQmlJSScope::ConstPtr &signalScope,
const QQmlJS::SourceLocation &location,
389 const QString &handlerName,
const QStringList &handlerParameters);
390 void importBaseModules();
391 void resolveAliases();
392 bool resolveAliasProperty(
const QQmlJSScope::Ptr &object,
const QQmlJSMetaProperty &property);
393 void populatePropertyAliases();
394 void resolveGroupProperties();
395 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
396 virtual void handleLiteralBinding(
const QQmlJSMetaPropertyBinding &,
397 const QQmlJS::AST::UiPublicMember *);
399 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
400 void processImportWarnings(
401 const QString &what,
const QList<QQmlJS::DiagnosticMessage> &warnings,
402 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
404 virtual void addImportWithLocation(
const QString &,
const QQmlJS::SourceLocation &,
bool) { }
405 virtual void addStaticImportWithLocation(
const QString &,
const QQmlJS::SourceLocation &,
bool)
410 void populateCurrentScope(QQmlJSScope::ScopeType type,
const QString &name,
411 const QQmlJS::SourceLocation &location);
412 void enterRootScope(QQmlJSScope::ScopeType type,
const QString &name,
413 const QQmlJS::SourceLocation &location);
415 QList<QQmlJS::DiagnosticMessage> importFromHost(
416 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
417 QList<QQmlJS::DiagnosticMessage> importFromQrc(
418 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
421 friend class QQmlJS::Dom::QQmlDomAstCreatorWithQQmlJSScope;