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 (!m_unresolvedTypes.hasSeen(type))
271 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type)
273 return checkTypeResolved(type, [&](
const QQmlJSScope::ConstPtr &type) {
274 warnUnresolvedType(type);
278 void warnUnresolvedType(
const QQmlJSScope::ConstPtr &type)
const;
279 void warnMissingPropertyForBinding(
280 const QString &property,
const QQmlJS::SourceLocation &location,
281 const std::optional<QQmlJSFixSuggestion> &fixSuggestion = {});
283 QList<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
284 void setAllBindings();
285 void addDefaultProperties();
286 void processDefaultProperties();
287 void processPropertyBindings();
288 void checkRequiredProperties();
289 void processPropertyTypes();
290 void processMethodTypes();
291 void processPropertyBindingObjects();
292 void flushPendingSignalParameters();
294 void breakInheritanceCycles(
const QQmlJSScope::Ptr &scope);
295 void checkDeprecation(
const QQmlJSScope::ConstPtr &scope);
296 void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
297 void checkForComponentTypeWithProperties(
const QQmlJSScope::ConstPtr &scope);
298 bool rootScopeIsValid()
const {
return m_exportedRootScope->sourceLocation().isValid(); }
300 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
301 enum class BindingForPropertyDefintion { Yes, No };
302 virtual BindingExpressionParseResult parseBindingExpression(
303 const QString &name,
const QQmlJS::AST::Statement *statement,
304 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition =
nullptr);
305 bool isImportPrefix(QString prefix)
const;
308 QList<QQmlJSAnnotation> m_pendingMethodAnnotations;
310 struct PendingPropertyType
312 QQmlJSScope::Ptr scope;
314 QQmlJS::SourceLocation location;
317 struct PendingMethodTypeAnnotations
319 QQmlJSScope::Ptr scope;
323 QVarLengthArray<QQmlJS::SourceLocation, 3> locations;
326 struct PendingPropertyObjectBinding
328 QQmlJSScope::Ptr scope;
329 QQmlJSScope::Ptr childScope;
331 QQmlJS::SourceLocation location;
335 struct RequiredProperty
337 QQmlJSScope::Ptr scope;
339 QQmlJS::SourceLocation location;
343
344
345
346
347
348
349
350
351
352
354 struct WithVisibilityScope
356 QQmlJSScope::Ptr visibilityScope;
357 QQmlJS::SourceLocation dataLocation;
361 QHash<QQmlJSScope::Ptr, QList<QQmlJSScope::Ptr>> m_pendingDefaultProperties;
362 QList<PendingPropertyType> m_pendingPropertyTypes;
363 QList<PendingMethodTypeAnnotations> m_pendingMethodTypeAnnotations;
364 QList<PendingPropertyObjectBinding> m_pendingPropertyObjectBindings;
365 QList<RequiredProperty> m_requiredProperties;
366 QList<QQmlJSScope::Ptr> m_objectBindingScopes;
367 QList<QQmlJSScope::Ptr> m_objectDefinitionScopes;
369 QHash<QQmlJSScope::Ptr, QList<WithVisibilityScope<QString>>> m_propertyBindings;
370 QList<Alias> m_aliasDefinitions;
371 QHash<Property, QList<Alias>> m_propertyAliases;
373 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
374 QQmlJS::SourceLocation m_pendingSignalHandler;
375 QStringList m_seenModuleQualifiers;
376 QHash<QStringView, QQmlJS::SourceLocation> m_seenInlineComponents;
379 void registerTargetIntoImporter(
const QQmlJSScope::Ptr &target);
381 const QQmlJSScope::ConstPtr &signalScope,
const QQmlJS::SourceLocation &location,
382 const QString &handlerName,
const QStringList &handlerParameters);
383 void importBaseModules();
384 void resolveAliases();
385 bool resolveAliasProperty(
const QQmlJSScope::Ptr &object,
const QQmlJSMetaProperty &property);
386 void populatePropertyAliases();
387 void resolveGroupProperties();
388 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
389 virtual void handleLiteralBinding(
const QQmlJSMetaPropertyBinding &,
390 const QQmlJS::AST::UiPublicMember *);
392 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
393 void processImportWarnings(
394 const QString &what,
const QList<QQmlJS::DiagnosticMessage> &warnings,
395 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
397 virtual void addImportWithLocation(
const QString &,
const QQmlJS::SourceLocation &,
bool) { }
398 virtual void addStaticImportWithLocation(
const QString &,
const QQmlJS::SourceLocation &,
bool)
403 void populateCurrentScope(QQmlJSScope::ScopeType type,
const QString &name,
404 const QQmlJS::SourceLocation &location);
405 void enterRootScope(QQmlJSScope::ScopeType type,
const QString &name,
406 const QQmlJS::SourceLocation &location);
408 QList<QQmlJS::DiagnosticMessage> importFromHost(
409 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
410 QList<QQmlJS::DiagnosticMessage> importFromQrc(
411 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
414 friend class QQmlJS::Dom::QQmlDomAstCreatorWithQQmlJSScope;