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(
75 const QString &localFile, 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 void endVisit(QQmlJS::AST::FieldMemberExpression *) override;
147 bool visit(QQmlJS::AST::IdentifierExpression *idexp) override;
149 bool visit(QQmlJS::AST::PatternElement *) override;
151 bool visit(QQmlJS::AST::IfStatement *) override;
153 void throwRecursionDepthError() override;
155 virtual bool checkCustomParser(
const QQmlJSScope::ConstPtr &scope);
157 void setScopeName(QQmlJSScope::Ptr &scope, QQmlJSScope::ScopeType type,
const QString &name);
158 virtual bool safeInsertJSIdentifier(QQmlJSScope::Ptr &scope,
const QString &name,
159 const QQmlJSScope::JavaScriptIdentifier &identifier);
160 void createAttachedAndGroupedScopes(QQmlJS::AST::UiQualifiedId *propertyName);
161 int openAttachedAndGroupedScopes(QQmlJS::AST::UiQualifiedId *propertyName);
163 QString m_implicitImportDirectory;
164 QStringList m_qmldirFiles;
165 QQmlJSScope::Ptr m_currentScope;
166 const QQmlJSScope::Ptr m_exportedRootScope;
167 QQmlJSImporter *m_importer =
nullptr;
168 QQmlJSLogger *m_logger =
nullptr;
170 using RootDocumentNameType = QQmlJSScope::RootDocumentNameType;
171 using InlineComponentNameType = QQmlJSScope::InlineComponentNameType;
172 using InlineComponentOrDocumentRootName = QQmlJSScope::RootDocumentNameType;
173 QQmlJSScope::InlineComponentOrDocumentRootName m_currentRootName =
174 QQmlJSScope::RootDocumentNameType();
175 bool m_nextIsInlineComponent =
false;
176 bool m_rootIsSingleton =
false;
177 QQmlJSScope::Ptr m_savedBindingOuterScope;
178 QQmlJSScope::ConstPtr m_globalScope;
179 QQmlJSScopesById m_scopesById;
180 QQmlJSImporter::ImportedTypes m_rootScopeImports;
181 QList<QQmlJSScope::ConstPtr> m_qmlTypes;
185 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_scopesByIrLocation;
188 QMultiHash<QString, QQmlJS::SourceLocation> m_importTypeLocationMap;
190 QMultiHash<QString, QQmlJS::SourceLocation> m_importStaticModuleLocationMap;
192 QSet<QQmlJS::SourceLocation> m_importLocations;
194 QSet<QString> m_usedTypes;
196 QList<UnfinishedBinding> m_bindings;
200 QHash<QQmlJSScope::ConstPtr, QList<QString>> m_functionsAndExpressions;
202 template <
bool scopeIsConst =
true>
205 using Scope = std::conditional_t<scopeIsConst, QQmlJSScope::ConstPtr, QQmlJSScope::Ptr>;
207 ScopeAndNameT() =
default;
208 ScopeAndNameT(
const Scope &scope,
const QString &name) : scope(scope), name(name) { }
209 ScopeAndNameT(
const ScopeAndNameT &) =
default;
210 ScopeAndNameT(ScopeAndNameT &&) =
default;
211 ScopeAndNameT &operator=(
const ScopeAndNameT &) =
default;
212 ScopeAndNameT &operator=(ScopeAndNameT &&) =
default;
213 ~ScopeAndNameT() =
default;
216 ScopeAndNameT(
typename std::enable_if<scopeIsConst, ScopeAndNameT<
false>>::type &nonConst)
217 : scope(nonConst.scope), name(nonConst.name)
221 friend bool operator==(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
223 return lhs.scope == rhs.scope && lhs.name == rhs.name;
225 friend bool operator!=(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
227 return !(lhs == rhs);
229 friend size_t qHash(
const ScopeAndNameT &san, size_t seed = 0)
231 return qHashMulti(seed, san.scope, san.name);
237 using ConstScopeAndName = ScopeAndNameT<
true>;
238 using ScopeAndName = ScopeAndNameT<
false>;
240 using FunctionOrExpressionIdentifier = ConstScopeAndName;
241 using Property = ConstScopeAndName;
242 using Alias = ConstScopeAndName;
245 bool m_thisScriptBindingIsJavaScript =
false;
246 QStack<FunctionOrExpressionIdentifier> m_functionStack;
248 QHash<FunctionOrExpressionIdentifier,
int> m_innerFunctions;
249 QQmlJSMetaMethod::RelativeFunctionIndex
250 addFunctionOrExpression(
const QQmlJSScope::ConstPtr &scope,
const QString &name);
251 void forgetFunctionExpression(
const QString &name);
252 int synthesizeCompilationUnitRuntimeFunctionIndices(
const QQmlJSScope::Ptr &scope,
254 void populateRuntimeFunctionIndicesForDocument()
const;
256 void enterEnvironment(QQmlJSScope::ScopeType type,
const QString &name,
257 const QQmlJS::SourceLocation &location);
260 bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type,
const QString &name,
261 const QQmlJS::SourceLocation &location);
262 virtual void leaveEnvironment();
266 QDuplicateTracker<QQmlJSScope::ConstPtr> m_unresolvedTypes;
267 template<
typename ErrorHandler>
268 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type, ErrorHandler handle)
270 if (type->isFullyResolved() || checkCustomParser(type))
275 if (!m_unresolvedTypes.hasSeen(type))
281 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type)
283 return checkTypeResolved(type, [&](
const QQmlJSScope::ConstPtr &type) {
284 warnUnresolvedType(type);
288 void warnUnresolvedType(
const QQmlJSScope::ConstPtr &type)
const;
289 void warnMissingPropertyForBinding(
290 const QString &property,
const QQmlJS::SourceLocation &location,
291 const std::optional<QQmlJSFixSuggestion> &fixSuggestion = {});
293 QList<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
294 void setAllBindings();
295 void addDefaultProperties();
296 void processDefaultProperties();
297 void processPropertyBindings();
298 void checkRequiredProperties();
299 void processPropertyTypes();
300 void processMethodTypes();
301 void processPropertyBindingObjects();
302 void flushPendingSignalParameters();
304 void breakInheritanceCycles(
const QQmlJSScope::Ptr &scope);
305 void checkDeprecation(
const QQmlJSScope::ConstPtr &scope);
306 void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
307 void checkForComponentTypeWithProperties(
const QQmlJSScope::ConstPtr &scope);
308 bool rootScopeIsValid()
const {
return m_exportedRootScope->sourceLocation().isValid(); }
310 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
311 enum class BindingForPropertyDefintion { Yes, No };
312 virtual BindingExpressionParseResult parseBindingExpression(
313 const QString &name,
const QQmlJS::AST::Statement *statement,
314 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition =
nullptr);
315 bool isImportPrefix(QString prefix)
const;
318 QList<QQmlJSAnnotation> m_pendingMethodAnnotations;
320 struct PendingPropertyType
322 QQmlJSScope::Ptr scope;
324 QQmlJS::SourceLocation location;
327 struct PendingMethodTypeAnnotations
329 QQmlJSScope::Ptr scope;
333 QVarLengthArray<QQmlJS::SourceLocation, 3> locations;
336 struct PendingPropertyObjectBinding
338 QQmlJSScope::Ptr scope;
339 QQmlJSScope::Ptr childScope;
341 QQmlJS::SourceLocation location;
345 struct RequiredProperty
347 QQmlJSScope::Ptr scope;
349 QQmlJS::SourceLocation location;
353
354
355
356
357
358
359
360
361
362
364 struct WithVisibilityScope
366 QQmlJSScope::Ptr visibilityScope;
367 QQmlJS::SourceLocation dataLocation;
371 QHash<QQmlJSScope::Ptr, QList<QQmlJSScope::Ptr>> m_pendingDefaultProperties;
372 QList<PendingPropertyType> m_pendingPropertyTypes;
373 QList<PendingMethodTypeAnnotations> m_pendingMethodTypeAnnotations;
374 QList<PendingPropertyObjectBinding> m_pendingPropertyObjectBindings;
375 QList<RequiredProperty> m_requiredProperties;
376 QList<QQmlJSScope::Ptr> m_objectBindingScopes;
377 QList<QQmlJSScope::Ptr> m_objectDefinitionScopes;
379 QHash<QQmlJSScope::Ptr, QList<WithVisibilityScope<QString>>> m_propertyBindings;
380 QList<Alias> m_aliasDefinitions;
381 QHash<Property, QList<Alias>> m_propertyAliases;
383 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
384 QQmlJS::SourceLocation m_pendingSignalHandler;
385 QStringList m_seenModuleQualifiers;
386 QHash<QStringView, QQmlJS::SourceLocation> m_seenInlineComponents;
389 void registerTargetIntoImporter(
const QQmlJSScope::Ptr &target);
391 const QQmlJSScope::ConstPtr &signalScope,
const QQmlJS::SourceLocation &location,
392 const QString &handlerName,
const QStringList &handlerParameters);
393 void importBaseModules();
394 void resolveAliases();
395 void populatePropertyAliases();
396 void resolveGroupProperties();
397 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
398 virtual void handleLiteralBinding(
const QQmlJSMetaPropertyBinding &,
399 const QQmlJS::AST::UiPublicMember *);
401 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
402 void processImportWarnings(
403 const QString &what,
const QList<QQmlJS::DiagnosticMessage> &warnings,
404 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
405 void addImportWithLocation(
406 const QString &name,
const QQmlJS::SourceLocation &loc,
bool hadWarnings);
407 void populateCurrentScope(QQmlJSScope::ScopeType type,
const QString &name,
408 const QQmlJS::SourceLocation &location);
409 void enterRootScope(QQmlJSScope::ScopeType type,
const QString &name,
410 const QQmlJS::SourceLocation &location);
412 QList<QQmlJS::DiagnosticMessage> importFromHost(
413 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
414 QList<QQmlJS::DiagnosticMessage> importFromQrc(
415 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
418 friend class QQmlJS::Dom::QQmlDomAstCreatorWithQQmlJSScope;