46 QQmlJSImportVisitor(
const QQmlJSScope::Ptr &target,
47 QQmlJSImporter *importer, QQmlJSLogger *logger,
48 const QString &implicitImportDirectory,
49 const QStringList &qmldirFiles = QStringList());
50 QQmlJSImportVisitor(QQmlJSImporter *importer, QQmlJSLogger *logger,
51 const QString &implicitImportDirectory,
52 const QStringList &qmldirFiles = QStringList())
53 : QQmlJSImportVisitor(QQmlJSScope::create(), importer, logger,
54 implicitImportDirectory, qmldirFiles)
56 ~QQmlJSImportVisitor();
58 using QQmlJS::AST::Visitor::endVisit;
59 using QQmlJS::AST::Visitor::postVisit;
60 using QQmlJS::AST::Visitor::preVisit;
61 using QQmlJS::AST::Visitor::visit;
63 QQmlJSScope::Ptr result()
const {
return m_exportedRootScope; }
65 const QQmlJSLogger *logger()
const {
return m_logger; }
66 QQmlJSLogger *logger() {
return m_logger; }
68 QQmlJSImporter::ImportedTypes imports()
const {
return m_rootScopeImports; }
69 QQmlJSScopesById addressableScopes()
const {
return m_scopesById; }
70 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> signalHandlers()
const
72 return m_signalHandlers;
74 QList<QQmlJSScope::ConstPtr> qmlTypes()
const {
return m_qmlTypes; }
75 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> scopesBylocation()
const
77 return m_scopesByIrLocation;
80 static QString implicitImportDirectory(
81 const QString &localFile, QQmlJSResourceFileMapper *mapper);
84 QQmlJSImporter *importer() {
return m_importer; }
85 const QQmlJSImporter *importer()
const {
return m_importer; }
87 struct UnfinishedBinding
89 QQmlJSScope::Ptr owner;
90 std::function<QQmlJSMetaPropertyBinding()> create;
91 QQmlJSScope::BindingTargetSpecifier specifier = QQmlJSScope::SimplePropertyTarget;
94 QStringList seenModuleQualifiers()
const {
return m_seenModuleQualifiers; }
97 bool visit(QQmlJS::AST::ExpressionStatement *ast) override;
98 void endVisit(QQmlJS::AST::ExpressionStatement *ast) override;
100 bool visit(QQmlJS::AST::UiProgram *) override;
101 void endVisit(QQmlJS::AST::UiProgram *) override;
102 bool visit(QQmlJS::AST::UiObjectDefinition *) override;
103 void endVisit(QQmlJS::AST::UiObjectDefinition *) override;
104 bool visit(QQmlJS::AST::UiInlineComponent *) override;
105 void endVisit(QQmlJS::AST::UiInlineComponent *) override;
106 bool visit(QQmlJS::AST::UiPublicMember *) override;
107 void endVisit(QQmlJS::AST::UiPublicMember *) override;
108 bool visit(QQmlJS::AST::UiRequired *required) override;
109 bool visit(QQmlJS::AST::UiScriptBinding *) override;
110 void endVisit(QQmlJS::AST::UiScriptBinding *) override;
111 bool visit(QQmlJS::AST::UiArrayBinding *) override;
112 void endVisit(QQmlJS::AST::UiArrayBinding *) override;
113 bool visit(QQmlJS::AST::UiEnumDeclaration *uied) override;
114 bool visit(QQmlJS::AST::FunctionExpression *fexpr) override;
115 void endVisit(QQmlJS::AST::FunctionExpression *) override;
116 bool visit(QQmlJS::AST::UiSourceElement *) override;
117 bool visit(QQmlJS::AST::FunctionDeclaration *fdecl) override;
118 void endVisit(QQmlJS::AST::FunctionDeclaration *) override;
119 bool visit(QQmlJS::AST::ClassExpression *ast) override;
120 void endVisit(QQmlJS::AST::ClassExpression *) override;
121 bool visit(QQmlJS::AST::UiImport *import) override;
122 bool visit(QQmlJS::AST::UiPragma *pragma) override;
123 bool visit(QQmlJS::AST::ClassDeclaration *ast) override;
124 void endVisit(QQmlJS::AST::ClassDeclaration *ast) override;
125 bool visit(QQmlJS::AST::ForStatement *ast) override;
126 void endVisit(QQmlJS::AST::ForStatement *ast) override;
127 bool visit(QQmlJS::AST::ForEachStatement *ast) override;
128 void endVisit(QQmlJS::AST::ForEachStatement *ast) override;
129 bool visit(QQmlJS::AST::Block *ast) override;
130 void endVisit(QQmlJS::AST::Block *ast) override;
131 bool visit(QQmlJS::AST::CaseBlock *ast) override;
132 void endVisit(QQmlJS::AST::CaseBlock *ast) override;
133 bool visit(QQmlJS::AST::Catch *ast) override;
134 void endVisit(QQmlJS::AST::Catch *ast) override;
135 bool visit(QQmlJS::AST::WithStatement *withStatement) override;
136 void endVisit(QQmlJS::AST::WithStatement *ast) override;
138 bool visit(QQmlJS::AST::VariableDeclarationList *vdl) override;
139 bool visit(QQmlJS::AST::FormalParameterList *fpl) override;
141 bool visit(QQmlJS::AST::UiObjectBinding *uiob) override;
142 void endVisit(QQmlJS::AST::UiObjectBinding *uiob) override;
144 bool visit(QQmlJS::AST::ExportDeclaration *exp) override;
145 void endVisit(QQmlJS::AST::ExportDeclaration *exp) override;
147 bool visit(QQmlJS::AST::ESModule *module) override;
148 void endVisit(QQmlJS::AST::ESModule *module) override;
150 bool visit(QQmlJS::AST::Program *program) override;
151 void endVisit(QQmlJS::AST::Program *program) override;
153 void endVisit(QQmlJS::AST::FieldMemberExpression *) override;
154 bool visit(QQmlJS::AST::IdentifierExpression *idexp) override;
156 bool visit(QQmlJS::AST::PatternElement *) override;
158 bool visit(QQmlJS::AST::IfStatement *) override;
160 void throwRecursionDepthError() override;
162 virtual bool checkCustomParser(
const QQmlJSScope::ConstPtr &scope);
164 void setScopeName(QQmlJSScope::Ptr &scope, QQmlJSScope::ScopeType type,
const QString &name);
166 QString m_implicitImportDirectory;
167 QStringList m_qmldirFiles;
168 QQmlJSScope::Ptr m_currentScope;
169 const QQmlJSScope::Ptr m_exportedRootScope;
170 QQmlJSImporter *m_importer =
nullptr;
171 QQmlJSLogger *m_logger =
nullptr;
173 using RootDocumentNameType = QQmlJSScope::RootDocumentNameType;
174 using InlineComponentNameType = QQmlJSScope::InlineComponentNameType;
175 using InlineComponentOrDocumentRootName = QQmlJSScope::RootDocumentNameType;
176 QQmlJSScope::InlineComponentOrDocumentRootName m_currentRootName =
177 QQmlJSScope::RootDocumentNameType();
178 bool m_nextIsInlineComponent =
false;
179 bool m_rootIsSingleton =
false;
180 QQmlJSScope::Ptr m_savedBindingOuterScope;
181 QQmlJSScope::ConstPtr m_globalScope;
182 QQmlJSScopesById m_scopesById;
183 QQmlJSImporter::ImportedTypes m_rootScopeImports;
184 QList<QQmlJSScope::ConstPtr> m_qmlTypes;
188 QHash<QV4::CompiledData::Location, QQmlJSScope::ConstPtr> m_scopesByIrLocation;
191 QMultiHash<QString, QQmlJS::SourceLocation> m_importTypeLocationMap;
193 QMultiHash<QString, QQmlJS::SourceLocation> m_importStaticModuleLocationMap;
195 QSet<QQmlJS::SourceLocation> m_importLocations;
197 QSet<QString> m_usedTypes;
199 QList<UnfinishedBinding> m_bindings;
200 QSet<std::pair<
const QQmlJSScope *, QString>> misplacedJSIdentifiers;
204 QHash<QQmlJSScope::ConstPtr, QList<QString>> m_functionsAndExpressions;
206 template <
bool scopeIsConst =
true>
209 using Scope = std::conditional_t<scopeIsConst, QQmlJSScope::ConstPtr, QQmlJSScope::Ptr>;
211 ScopeAndNameT() =
default;
212 ScopeAndNameT(
const Scope &scope,
const QString &name) : scope(scope), name(name) { }
213 ScopeAndNameT(
const ScopeAndNameT &) =
default;
214 ScopeAndNameT(ScopeAndNameT &&) =
default;
215 ScopeAndNameT &operator=(
const ScopeAndNameT &) =
default;
216 ScopeAndNameT &operator=(ScopeAndNameT &&) =
default;
217 ~ScopeAndNameT() =
default;
220 ScopeAndNameT(
typename std::enable_if<scopeIsConst, ScopeAndNameT<
false>>::type &nonConst)
221 : scope(nonConst.scope), name(nonConst.name)
225 friend bool operator==(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
227 return lhs.scope == rhs.scope && lhs.name == rhs.name;
229 friend bool operator!=(
const ScopeAndNameT &lhs,
const ScopeAndNameT &rhs)
231 return !(lhs == rhs);
233 friend size_t qHash(
const ScopeAndNameT &san, size_t seed = 0)
235 return qHashMulti(seed, san.scope, san.name);
241 using ConstScopeAndName = ScopeAndNameT<
true>;
242 using ScopeAndName = ScopeAndNameT<
false>;
244 using FunctionOrExpressionIdentifier = ConstScopeAndName;
245 using Property = ConstScopeAndName;
246 using Alias = ConstScopeAndName;
249 bool m_thisScriptBindingIsJavaScript =
false;
250 QStack<FunctionOrExpressionIdentifier> m_functionStack;
252 QHash<FunctionOrExpressionIdentifier,
int> m_innerFunctions;
253 QQmlJSMetaMethod::RelativeFunctionIndex
254 addFunctionOrExpression(
const QQmlJSScope::ConstPtr &scope,
const QString &name);
255 void forgetFunctionExpression(
const QString &name);
256 int synthesizeCompilationUnitRuntimeFunctionIndices(
const QQmlJSScope::Ptr &scope,
258 void populateRuntimeFunctionIndicesForDocument()
const;
260 void enterEnvironment(QQmlJSScope::ScopeType type,
const QString &name,
261 const QQmlJS::SourceLocation &location);
264 bool enterEnvironmentNonUnique(QQmlJSScope::ScopeType type,
const QString &name,
265 const QQmlJS::SourceLocation &location);
266 virtual void leaveEnvironment();
270 QDuplicateTracker<QQmlJSScope::ConstPtr> m_unresolvedTypes;
271 template<
typename ErrorHandler>
272 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type, ErrorHandler handle)
274 if (type->isFullyResolved() || checkCustomParser(type))
279 if (!m_unresolvedTypes.hasSeen(type))
285 bool checkTypeResolved(
const QQmlJSScope::ConstPtr &type)
287 return checkTypeResolved(type, [&](
const QQmlJSScope::ConstPtr &type) {
288 warnUnresolvedType(type);
292 void warnUnresolvedType(
const QQmlJSScope::ConstPtr &type)
const;
293 void warnMissingPropertyForBinding(
294 const QString &property,
const QQmlJS::SourceLocation &location,
295 const std::optional<QQmlJSFixSuggestion> &fixSuggestion = {});
297 QVector<QQmlJSAnnotation> parseAnnotations(QQmlJS::AST::UiAnnotationList *list);
298 void setAllBindings();
299 void addDefaultProperties();
300 void processDefaultProperties();
301 void processPropertyBindings();
302 void checkRequiredProperties();
303 void processPropertyTypes();
304 void processMethodTypes();
305 void processPropertyBindingObjects();
306 void flushPendingSignalParameters();
308 void breakInheritanceCycles(
const QQmlJSScope::Ptr &scope);
309 void checkDeprecation(
const QQmlJSScope::ConstPtr &scope);
310 void checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr scope);
311 bool rootScopeIsValid()
const {
return m_exportedRootScope->sourceLocation().isValid(); }
313 enum class BindingExpressionParseResult { Invalid, Script, Literal, Translation };
314 enum class BindingForPropertyDefintion { Yes, No };
315 virtual BindingExpressionParseResult parseBindingExpression(
316 const QString &name,
const QQmlJS::AST::Statement *statement,
317 const QQmlJS::AST::UiPublicMember *associatedPropertyDefinition =
nullptr);
318 bool isImportPrefix(QString prefix)
const;
321 QVector<QQmlJSAnnotation> m_pendingMethodAnnotations;
323 struct PendingPropertyType
325 QQmlJSScope::Ptr scope;
327 QQmlJS::SourceLocation location;
330 struct PendingMethodTypeAnnotations
332 QQmlJSScope::Ptr scope;
336 QVarLengthArray<QQmlJS::SourceLocation, 3> locations;
339 struct PendingPropertyObjectBinding
341 QQmlJSScope::Ptr scope;
342 QQmlJSScope::Ptr childScope;
344 QQmlJS::SourceLocation location;
348 struct RequiredProperty
350 QQmlJSScope::Ptr scope;
352 QQmlJS::SourceLocation location;
356
357
358
359
360
361
362
363
364
365
367 struct WithVisibilityScope
369 QQmlJSScope::Ptr visibilityScope;
370 QQmlJS::SourceLocation dataLocation;
374 QHash<QQmlJSScope::Ptr, QVector<QQmlJSScope::Ptr>> m_pendingDefaultProperties;
375 QVector<PendingPropertyType> m_pendingPropertyTypes;
376 QVector<PendingMethodTypeAnnotations> m_pendingMethodTypeAnnotations;
377 QVector<PendingPropertyObjectBinding> m_pendingPropertyObjectBindings;
378 QVector<RequiredProperty> m_requiredProperties;
379 QVector<QQmlJSScope::Ptr> m_objectBindingScopes;
380 QVector<QQmlJSScope::Ptr> m_objectDefinitionScopes;
382 QHash<QQmlJSScope::Ptr, QVector<WithVisibilityScope<QString>>> m_propertyBindings;
383 QVector<Alias> m_aliasDefinitions;
384 QHash<Property, QList<Alias>> m_propertyAliases;
386 QHash<QQmlJS::SourceLocation, QQmlJSMetaSignalHandler> m_signalHandlers;
387 QQmlJS::SourceLocation m_pendingSignalHandler;
388 QStringList m_seenModuleQualifiers;
389 QHash<QStringView, QQmlJS::SourceLocation> m_seenInlineComponents;
392 void registerTargetIntoImporter(
const QQmlJSScope::Ptr &target);
394 const QQmlJSScope::ConstPtr &signalScope,
const QQmlJS::SourceLocation &location,
395 const QString &handlerName,
const QStringList &handlerParameters);
396 void importBaseModules();
397 void resolveAliases();
398 void populatePropertyAliases();
399 void resolveGroupProperties();
400 void handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scriptBinding);
401 virtual void handleLiteralBinding(
const QQmlJSMetaPropertyBinding &,
402 const QQmlJS::AST::UiPublicMember *);
404 void visitFunctionExpressionHelper(QQmlJS::AST::FunctionExpression *fexpr);
405 void processImportWarnings(
406 const QString &what,
const QList<QQmlJS::DiagnosticMessage> &warnings,
407 const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation());
408 void addImportWithLocation(
409 const QString &name,
const QQmlJS::SourceLocation &loc,
bool hadWarnings);
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 bool safeInsertJSIdentifier(QQmlJSScope::Ptr &scope,
const QString &name,
416 const QQmlJSScope::JavaScriptIdentifier &identifier);
418 QList<QQmlJS::DiagnosticMessage> importFromHost(
419 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
420 QList<QQmlJS::DiagnosticMessage> importFromQrc(
421 const QString &path,
const QString &prefix,
const QQmlJS::SourceLocation &location);
424 friend class QQmlJS::Dom::QQmlDomAstCreatorWithQQmlJSScope;