38 Q_DECLARE_TR_FUNCTIONS(QQmlDomAstCreator)
44 static constexpr const auto className =
"QmlDomAstCreator";
50 DomValue(
const T &obj) : kind(T::kindValue), value(obj)
68
69
70
71
72
73
74
75
76
77
78
79
80 class ScriptStackElement
84 static ScriptStackElement from(
const T &obj)
87 ScriptStackElement s{ ScriptElements::ScriptList::kindValue, obj };
102 Q_ASSERT_X(std::holds_alternative<ScriptElementVariant>(value),
"takeVariant",
103 "Should be a variant, did the parser change?");
104 return std::get<ScriptElementVariant>(std::move(value));
107 bool isList()
const {
return std::holds_alternative<ScriptElements::ScriptList>(value); };
111 Q_ASSERT_X(std::holds_alternative<ScriptElements::ScriptList>(value),
"takeList",
112 "Should be a List, did the parser change?");
113 return std::get<ScriptElements::ScriptList>(std::move(value));
116 void setSemanticScope(
const QQmlJSScope::ConstPtr &scope)
118 if (
auto x = std::get_if<ScriptElementVariant>(&value)) {
119 x->base()->setSemanticScope(scope);
121 }
else if (
auto x = std::get_if<ScriptElements::ScriptList>(&value)) {
122 x->setSemanticScope(scope);
136 std::shared_ptr<QmlFile> qmlFilePtr;
137 QVector<QmlStackElement> nodeStack;
138 QList<ScriptStackElement> scriptNodeStack;
139 QVector<
int> arrayBindingLevels;
141 int m_nestedFunctionDepth = 0;
142 bool m_enableScriptExpressions =
false;
143 bool m_loadFileLazily =
false;
148 bool m_skipBindingIdentifiers =
false;
150 void setBindingIdentifiers(
const Path &pathFromOwner,
const AST::UiQualifiedId *identifiers,
153 QmlStackElement ¤tEl(
int idx = 0)
155 Q_ASSERT_X(idx < nodeStack.size() && idx >= 0,
"currentQmlObjectOrComponentEl",
156 "Stack does not contain enough elements!");
157 int i = nodeStack.size() - idx;
159 DomType k = nodeStack.at(i).item.kind;
160 if (k == T::kindValue)
163 Q_ASSERT_X(
false,
"currentEl",
"Stack does not contan object of type ");
164 return nodeStack.last();
168 ScriptStackElement ¤tScriptEl(
int idx = 0)
170 Q_ASSERT_X(m_enableScriptExpressions,
"currentScriptEl",
171 "Cannot access script elements when they are disabled!");
173 Q_ASSERT_X(idx < scriptNodeStack.size() && idx >= 0,
"currentQmlObjectOrComponentEl",
174 "Stack does not contain enough elements!");
175 int i = scriptNodeStack.size() - idx;
177 DomType k = scriptNodeStack.at(i).kind;
178 if (k == T::element_type::kindValue)
179 return scriptNodeStack[i];
181 Q_ASSERT_X(
false,
"currentEl",
"Stack does not contain object of type ");
182 return scriptNodeStack.last();
186 T ¤t(
int idx = 0)
188 return std::get<T>(currentEl<T>(idx).item.value);
191 index_type currentIndex() {
return currentNodeEl().path.last().headIndex(); }
193 QmlStackElement ¤tQmlObjectOrComponentEl(
int idx = 0);
195 QmlStackElement ¤tNodeEl(
int i = 0);
196 ScriptStackElement ¤tScriptNodeEl(
int i = 0);
198 DomValue ¤tNode(
int i = 0);
200 void removeCurrentNode(
std::optional<
DomType> expectedType);
201 void removeCurrentScriptNode(
std::optional<
DomType> expectedType);
203 void pushEl(
const Path &p,
const DomValue &it, AST::Node *n)
205 nodeStack.append({ p, it, createMap(it.kind, p, n) });
218 Path pathOfLastScriptNode()
const;
221
222
223
224 template<
typename AstNodeT>
229 ast->lastSourceLocation());
230 myExp->setLiteralValue(value.toString());
235 QQmlJS::SourceLocation loc)
238 myExp->setLiteralValue(value.toString());
243
244
245
246
247
248 template<
typename ScriptElementT,
typename AstNodeT,
250 std::enable_if_t<!std::is_same_v<ScriptElementT, ScriptElements::ScriptList>>>
251 static decltype(
auto) makeScriptElement(AstNodeT *ast)
253 auto myExp =
std::make_shared<ScriptElementT>(ast->firstSourceLocation(),
254 ast->lastSourceLocation());
259
260
261
262
263 template<
typename AstNodeT>
265 makeGenericScriptElement(AstNodeT *ast,
DomType kind)
268 ast->firstSourceLocation(), ast->lastSourceLocation());
269 myExp->setKind(kind);
273 enum UnaryExpressionKind { Prefix, Postfix };
275 makeUnaryExpression(AST::Node *expression, QQmlJS::SourceLocation operatorToken,
276 bool hasExpression, UnaryExpressionKind type);
279 makeGenericScriptElement(SourceLocation location,
DomType kind)
282 myExp->setKind(kind);
287
288
289
290
291 template<
typename AstNodeT>
292 static decltype(
auto) makeScriptList(AstNodeT *ast)
299 template<
typename ScriptElementT>
300 void pushScriptElement(
const ScriptElementT &element)
302 Q_ASSERT_X(m_enableScriptExpressions,
"pushScriptElement",
303 "Cannot create script elements when they are disabled!");
304 scriptNodeStack.append(ScriptStackElement::from(element));
307 void disableScriptElements()
309 m_enableScriptExpressions =
false;
310 scriptNodeStack.clear();
318 bool visit(AST::UiProgram *program)
override;
321 bool visit(AST::UiPragma *el)
override;
323 bool visit(AST::UiImport *el)
override;
325 bool visit(AST::UiPublicMember *el)
override;
332 bool visit(AST::FunctionExpression *el)
override;
335 bool visit(AST::FunctionDeclaration *el)
override;
336 void endVisit(AST::FunctionDeclaration *)
override;
338 bool visit(AST::UiSourceElement *el)
override;
341 void loadAnnotations(AST::UiObjectMember *el) { AST::Node::accept(el->annotations,
this); }
343 bool visit(AST::UiObjectDefinition *el)
override;
346 bool visit(AST::UiObjectBinding *el)
override;
349 bool visit(AST::UiScriptBinding *el)
override;
352 bool visit(AST::UiArrayBinding *el)
override;
355 bool visit(AST::UiQualifiedId *)
override;
357 bool visit(AST::UiEnumDeclaration *el)
override;
360 bool visit(AST::UiEnumMemberList *el)
override;
363 bool visit(AST::UiInlineComponent *el)
override;
366 bool visit(AST::UiRequired *el)
override;
368 bool visit(AST::UiAnnotation *el)
override;
372 bool visit(AST::BinaryExpression *exp)
override;
373 void endVisit(AST::BinaryExpression *exp)
override;
375 bool visit(AST::Block *block)
override;
378 bool visit(AST::YieldExpression *block)
override;
381 bool visit(AST::ReturnStatement *block)
override;
384 bool visit(AST::ForStatement *forStatement)
override;
385 void endVisit(AST::ForStatement *forStatement)
override;
387 bool visit(AST::PatternElement *pe)
override;
392 bool visit(AST::IfStatement *)
override;
395 bool visit(AST::FieldMemberExpression *)
override;
396 void endVisit(AST::FieldMemberExpression *)
override;
398 bool visit(AST::ArrayMemberExpression *)
override;
399 void endVisit(AST::ArrayMemberExpression *)
override;
401 bool visit(AST::CallExpression *)
override;
404 bool visit(AST::ArrayPattern *)
override;
407 bool visit(AST::ObjectPattern *)
override;
410 bool visit(AST::PatternProperty *)
override;
413 bool visit(AST::VariableStatement *)
override;
416 bool visit(AST::Type *expression)
override;
419 bool visit(AST::DefaultClause *)
override;
422 bool visit(AST::CaseClause *)
override;
425 bool visit(AST::CaseClauses *)
override;
428 bool visit(AST::CaseBlock *)
override;
431 bool visit(AST::SwitchStatement *)
override;
434 bool visit(AST::WhileStatement *)
override;
437 bool visit(AST::DoWhileStatement *)
override;
440 bool visit(AST::ForEachStatement *)
override;
443 bool visit(AST::ClassExpression *)
override;
446 bool visit(AST::TryStatement *)
override;
452 bool visit(AST::Finally *)
override;
455 bool visit(AST::ThrowStatement *)
override;
458 bool visit(AST::LabelledStatement *)
override;
461 bool visit(AST::ContinueStatement *)
override;
464 bool visit(AST::BreakStatement *)
override;
467 bool visit(AST::CommaExpression *)
override;
470 bool visit(AST::ConditionalExpression *)
override;
471 void endVisit(AST::ConditionalExpression *)
override;
473 bool visit(AST::UnaryMinusExpression *)
override;
474 void endVisit(AST::UnaryMinusExpression *)
override;
476 bool visit(AST::UnaryPlusExpression *)
override;
477 void endVisit(AST::UnaryPlusExpression *)
override;
479 bool visit(AST::TildeExpression *)
override;
482 bool visit(AST::NotExpression *)
override;
485 bool visit(AST::TypeOfExpression *)
override;
488 bool visit(AST::DeleteExpression *)
override;
491 bool visit(AST::VoidExpression *)
override;
494 bool visit(AST::PostDecrementExpression *)
override;
495 void endVisit(AST::PostDecrementExpression *)
override;
497 bool visit(AST::PostIncrementExpression *)
override;
498 void endVisit(AST::PostIncrementExpression *)
override;
500 bool visit(AST::PreDecrementExpression *)
override;
501 void endVisit(AST::PreDecrementExpression *)
override;
503 bool visit(AST::PreIncrementExpression *)
override;
504 void endVisit(AST::PreIncrementExpression *)
override;
506 bool visit(AST::EmptyStatement *)
override;
509 bool visit(AST::NestedExpression *)
override;
512 bool visit(AST::NewExpression *)
override;
515 bool visit(AST::NewMemberExpression *)
override;
516 void endVisit(AST::NewMemberExpression *)
override;
521 bool visit(AST::UiParameterList *)
override;
522 bool visit(AST::Elision *elision)
override;
527 void endVisit(AST::VariableDeclarationList *vdl)
override;
530 void endVisit(AST::PatternPropertyList *)
override;
531 void endVisit(AST::FormalParameterList *el)
override;
537 bool visit(AST::IdentifierExpression *expression)
override;
538 bool visit(AST::NumericLiteral *expression)
override;
539 bool visit(AST::StringLiteral *expression)
override;
540 bool visit(AST::NullExpression *expression)
override;
541 bool visit(AST::TrueLiteral *expression)
override;
542 bool visit(AST::FalseLiteral *expression)
override;
543 bool visit(AST::ComputedPropertyName *expression)
override;
544 bool visit(AST::IdentifierPropertyName *expression)
override;
545 bool visit(AST::NumericLiteralPropertyName *expression)
override;
546 bool visit(AST::StringLiteralPropertyName *expression)
override;
547 bool visit(AST::TypeAnnotation *expression)
override;
548 bool visit(AST::RegExpLiteral *)
override;
549 bool visit(AST::ThisExpression *)
override;
550 bool visit(AST::SuperLiteral *)
override;
556 return !scriptNodeStack.isEmpty() && !scriptNodeStack.last().isList();
560 return !scriptNodeStack.isEmpty() && scriptNodeStack.last().isList();
565 void endVisitForLists(T *list,
const std::function<
int(T *)> &scriptElementsPerEntry = {});
581 for (T *it = t; it; it = it->next) {
582 if constexpr (std::is_same_v<T, AST::PatternElementList>) {
583 AST::Node::accept(it->elision, visitor);
584 AST::Node::accept(it->element, visitor);
585 }
else if constexpr (std::is_same_v<T, AST::PatternPropertyList>) {
586 AST::Node::accept(it->property, visitor);
587 }
else if constexpr (std::is_same_v<T, AST::FormalParameterList>) {
588 AST::Node::accept(it->element, visitor);
589 }
else if constexpr (std::is_same_v<T, AST::VariableDeclarationList>) {
590 AST::Node::accept(it->declaration, visitor);
591 }
else if constexpr (std::is_same_v<T, AST::ArgumentList>) {
592 AST::Node::accept(it->expression, visitor);
593 }
else if constexpr (std::is_same_v<T, AST::PatternElementList>) {
594 AST::Node::accept(it->elision, visitor);
595 AST::Node::accept(it->element, visitor);
596 }
else if constexpr (std::is_same_v<T, AST::TemplateLiteral>) {
597 AST::Node::accept(it->expression, visitor);
626 QQmlJSLogger *logger, QQmlJSImporter *importer);
629 bool visit(AST::name *) override;
630 void endVisit(AST::name *) override;
636
637
638
639
642 m_enableScriptExpressions = enable;
643 m_domCreator.enableScriptExpressions(enable);
648 m_loadFileLazily = enable;
649 m_domCreator.enableLoadFileLazily(enable);
655 void setScopeInDomAfterEndvisit();
656 void setScopeInDomBeforeEndvisit();
658 enum VisitorKind :
bool { DomCreator, ScopeCreator };
660
661
662
663
664 struct InactiveVisitorMarker
667 AST::Node::Kind nodeKind;
668 VisitorKind inactiveVisitorKind;
670 VisitorKind stillActiveVisitorKind()
const
672 return inactiveVisitorKind == DomCreator ? ScopeCreator : DomCreator;
676 static void initMarkerForActiveVisitor(
std::optional<InactiveVisitorMarker> &inactiveVisitorMarker,
677 AST::Node::Kind nodeKind,
bool continueForDom)
679 inactiveVisitorMarker.emplace();
680 inactiveVisitorMarker->inactiveVisitorKind = continueForDom ? ScopeCreator : DomCreator;
681 inactiveVisitorMarker->count = 1;
682 inactiveVisitorMarker->nodeKind = nodeKind;
688 const auto handleVisitResult = [
this, t](
const bool continueVisit) {
689 if (m_inactiveVisitorMarker && m_inactiveVisitorMarker->nodeKind == t->kind)
690 m_inactiveVisitorMarker->count += 1;
693 return visitWithCustomListIteration(t,
this);
694 return continueVisit;
698 if (!m_inactiveVisitorMarker) {
699 bool continueForDom = m_domCreator.visit(t);
700 bool continueForScope = m_scopeCreator.visit(t);
701 if (!continueForDom && !continueForScope)
703 else if (continueForDom ^ continueForScope) {
704 initMarkerForActiveVisitor(m_inactiveVisitorMarker, AST::Node::Kind(t->kind),
706 return visitWithCustomListIteration(t,
this);
708 Q_ASSERT(continueForDom && continueForScope);
709 return visitWithCustomListIteration(t,
this);
715 switch (m_inactiveVisitorMarker->stillActiveVisitorKind()) {
717 return handleVisitResult(m_domCreator.visit(t));
719 return handleVisitResult(m_scopeCreator.visit(t));
727 if (m_inactiveVisitorMarker && m_inactiveVisitorMarker->nodeKind == t->kind) {
728 m_inactiveVisitorMarker->count -= 1;
729 if (m_inactiveVisitorMarker->count == 0)
730 m_inactiveVisitorMarker.reset();
732 if (m_inactiveVisitorMarker) {
733 switch (m_inactiveVisitorMarker->stillActiveVisitorKind()) {
735 m_domCreator.endVisit(t);
738 m_scopeCreator.endVisit(t);
744 setScopeInDomBeforeEndvisit();
745 m_domCreator.endVisit(t);
746 setScopeInDomAfterEndvisit();
747 m_scopeCreator.endVisit(t);
750 QQmlJSScope::Ptr m_root;
751 QQmlJSLogger *m_logger =
nullptr;
752 QQmlJSImporter *m_importer =
nullptr;
753 QString m_implicitImportDirectory;
754 QQmlJSImportVisitor m_scopeCreator;
757 std::optional<InactiveVisitorMarker> m_inactiveVisitorMarker;
758 bool m_enableScriptExpressions =
false;
759 bool m_loadFileLazily =
false;