4#ifndef QQMLDOMASTCREATOR_P_H
5#define QQMLDOMASTCREATOR_P_H
23#include <QtQmlCompiler/private/qqmljsimportvisitor_p.h>
25#include <QtQml/private/qqmljsastvisitor_p.h>
38 using AST::Visitor::endVisit;
39 using AST::Visitor::visit;
41 static constexpr const auto className =
"QmlDomAstCreator";
47 DomValue(
const T &
obj) : kind(T::kindValue),
value(
obj)
77 class ScriptStackElement
81 static ScriptStackElement from(
const T &
obj)
83 if constexpr (std::is_same_v<T, ScriptElements::ScriptList>) {
94 using Variant = std::variant<ScriptElementVariant, ScriptElements::ScriptList>;
99 Q_ASSERT_X(std::holds_alternative<ScriptElementVariant>(
value),
"takeVariant",
100 "Should be a variant, did the parser change?");
101 return std::get<ScriptElementVariant>(std::move(
value));
104 bool isList()
const {
return std::holds_alternative<ScriptElements::ScriptList>(
value); };
108 Q_ASSERT_X(std::holds_alternative<ScriptElements::ScriptList>(
value),
"takeList",
109 "Should be a List, did the parser change?");
110 return std::get<ScriptElements::ScriptList>(std::move(
value));
115 if (
auto x = std::get_if<ScriptElementVariant>(&
value)) {
116 x->base()->setSemanticScope(scope);
118 }
else if (
auto x = std::get_if<ScriptElements::ScriptList>(&
value)) {
119 x->setSemanticScope(scope);
132 std::shared_ptr<QmlFile> qmlFilePtr;
137 bool m_enableScriptExpressions;
140 QmlStackElement ¤tEl(
int idx = 0)
142 Q_ASSERT_X(idx < nodeStack.
size() && idx >= 0,
"currentQmlObjectOrComponentEl",
143 "Stack does not contain enough elements!");
144 int i = nodeStack.
size() - idx;
147 if (k == T::kindValue)
150 Q_ASSERT_X(
false,
"currentEl",
"Stack does not contan object of type ");
151 return nodeStack.
last();
155 ScriptStackElement ¤tScriptEl(
int idx = 0)
157 Q_ASSERT_X(m_enableScriptExpressions,
"currentScriptEl",
158 "Cannot access script elements when they are disabled!");
160 Q_ASSERT_X(idx < scriptNodeStack.
size() && idx >= 0,
"currentQmlObjectOrComponentEl",
161 "Stack does not contain enough elements!");
162 int i = scriptNodeStack.
size() - idx;
165 if (k == T::element_type::kindValue)
166 return scriptNodeStack[
i];
168 Q_ASSERT_X(
false,
"currentEl",
"Stack does not contain object of type ");
169 return scriptNodeStack.
last();
173 T ¤t(
int idx = 0)
175 return std::get<T>(currentEl<T>(idx).
item.value);
178 index_type currentIndex() {
return currentNodeEl().path.last().headIndex(); }
180 QmlStackElement ¤tQmlObjectOrComponentEl(
int idx = 0);
182 QmlStackElement ¤tNodeEl(
int i = 0);
183 ScriptStackElement ¤tScriptNodeEl(
int i = 0);
185 DomValue ¤tNode(
int i = 0);
187 void removeCurrentNode(std::optional<DomType> expectedType);
188 void removeCurrentScriptNode(std::optional<DomType> expectedType);
190 void pushEl(Path
p, DomValue
it, AST::Node *
n)
199 const ScriptElementVariant &finalizeScriptExpression(
const ScriptElementVariant &element,
204 void setScriptExpression (
const std::shared_ptr<ScriptExpression>&
value);
206 Path pathOfLastScriptNode()
const;
212 template<
typename AstNodeT>
213 static std::shared_ptr<ScriptElements::Literal> makeStringLiteral(
QStringView value,
216 auto myExp = std::make_shared<ScriptElements::Literal>(ast->firstSourceLocation(),
217 ast->lastSourceLocation());
218 myExp->setLiteralValue(
value.toString());
222 static std::shared_ptr<ScriptElements::Literal> makeStringLiteral(
QStringView value,
225 auto myExp = std::make_shared<ScriptElements::Literal>(loc);
226 myExp->setLiteralValue(
value.toString());
236 template<
typename ScriptElementT,
typename AstNodeT,
238 std::enable_if_t<!std::is_same_v<ScriptElementT, ScriptElements::ScriptList>>>
239 static decltype(
auto) makeScriptElement(AstNodeT *ast)
241 auto myExp = std::make_shared<ScriptElementT>(ast->firstSourceLocation(),
242 ast->lastSourceLocation());
251 template<
typename AstNodeT>
252 static std::shared_ptr<ScriptElements::GenericScriptElement>
253 makeGenericScriptElement(AstNodeT *ast,
DomType kind)
255 auto myExp = std::make_shared<ScriptElements::GenericScriptElement>(
256 ast->firstSourceLocation(), ast->lastSourceLocation());
257 myExp->setKind(kind);
261 static std::shared_ptr<ScriptElements::GenericScriptElement>
264 auto myExp = std::make_shared<ScriptElements::GenericScriptElement>(
location);
265 myExp->setKind(kind);
274 template<
typename AstNodeT>
275 static decltype(
auto) makeScriptList(AstNodeT *ast)
278 ScriptElements::ScriptList(ast->firstSourceLocation(), ast->lastSourceLocation());
282 template<
typename ScriptElementT>
283 void pushScriptElement(ScriptElementT element)
285 Q_ASSERT_X(m_enableScriptExpressions,
"pushScriptElement",
286 "Cannot create script elements when they are disabled!");
287 scriptNodeStack.
append(ScriptStackElement::from(element));
290 void disableScriptElements()
292 m_enableScriptExpressions =
false;
293 scriptNodeStack.
clear();
296 ScriptElementVariant scriptElementForQualifiedId(AST::UiQualifiedId *expression);
302 void endVisit(AST::UiProgram *)
override;
304 bool visit(AST::UiPragma *
el)
override;
306 bool visit(AST::UiImport *
el)
override;
308 bool visit(AST::UiPublicMember *
el)
override;
309 void endVisit(AST::UiPublicMember *
el)
override;
311 bool visit(AST::UiSourceElement *
el)
override;
312 void endVisit(AST::UiSourceElement *)
override;
360 const std::shared_ptr<ScriptElements::GenericScriptElement> &element);
450 bool visit(AST::name *) override; \
451 void endVisit(AST::name *) override;
463 m_enableScriptExpressions =
enable;
471 void setScopeInDomAfterEndvisit();
472 void setScopeInDomBeforeEndvisit();
474 template<
typename U,
typename... V>
475 using IsInList = std::disjunction<std::is_same<U, V>...>;
481 void customListIteration(T *
t)
483 static_assert(RequiresCustomIteration<T>::value);
485 if constexpr (std::is_same_v<T, AST::PatternElementList>) {
488 }
else if constexpr (std::is_same_v<T, AST::PatternPropertyList>) {
490 }
else if constexpr (std::is_same_v<T, AST::FormalParameterList>) {
501 if (m_marker && m_marker->nodeKind ==
t->kind) {
502 m_marker->count += 1;
507 bool continueForDom = m_domCreator.
visit(
t);
508 bool continueForScope = m_scopeCreator.
visit(
t);
509 if (!continueForDom && !continueForScope)
511 else if (continueForDom ^ continueForScope) {
513 m_marker->inactiveVisitor = continueForDom ? ScopeCreator : DomCreator;
517 if constexpr (RequiresCustomIteration<T>::value) {
518 customListIteration(
t);
524 Q_ASSERT(continueForDom && continueForScope);
526 if constexpr (RequiresCustomIteration<T>::value) {
527 customListIteration(
t);
537 switch (m_marker->inactiveVisitor) {
539 const bool continueForScope = m_scopeCreator.
visit(
t);
540 if (continueForScope) {
541 if constexpr (RequiresCustomIteration<T>::value) {
542 customListIteration(
t);
546 return continueForScope;
549 const bool continueForDom = m_domCreator.
visit(
t);
550 if (continueForDom) {
551 if constexpr (RequiresCustomIteration<T>::value) {
552 customListIteration(
t);
556 return continueForDom;
565 if (m_marker && m_marker->nodeKind ==
t->kind) {
566 m_marker->count -= 1;
567 if (m_marker->count == 0)
572 switch (m_marker->inactiveVisitor) {
585 setScopeInDomBeforeEndvisit();
587 setScopeInDomAfterEndvisit();
594 QString m_implicitImportDirectory;
596 QQmlDomAstCreator m_domCreator;
598 enum InactiveVisitor :
bool { DomCreator, ScopeCreator };
603 InactiveVisitor inactiveVisitor;
605 std::optional<Marker> m_marker;
606 bool m_enableScriptExpressions;
qsizetype size() const noexcept
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
void endVisit(QQmlJS::AST::ExpressionStatement *ast) override
bool visit(QQmlJS::AST::StringLiteral *) override
void accept(BaseVisitor *visitor)
std::shared_ptr< AttachedInfoT< FileLocations > > Tree
virtual QQmlJSASTClassListToVisit void throwRecursionDepthError() override
QQmlJSImportVisitor & scopeCreator()
QQmlJSImporter & importer()
void enableScriptExpressions(bool enable=true)
void endVisit(AST::UiProgram *) override
void endVisitHelper(AST::PatternElement *pe, const std::shared_ptr< ScriptElements::GenericScriptElement > &element)
QQmlDomAstCreator(MutableDomItem qmlFile)
void enableScriptExpressions(bool enable=true)
bool visit(AST::UiProgram *program) override
void throwRecursionDepthError() override
void loadAnnotations(AST::UiObjectMember *el)
Use this to contain any script element.
static ScriptElementVariant fromElement(T element)
static constexpr DomType kindValue
\macro QT_RESTRICTED_CAST_FROM_ASCII
QSet< QString >::iterator it
Combined button and popup list for selecting options.
#define Q_DECLARE_TR_FUNCTIONS(context)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLint GLint GLint GLint GLint x
[0]
GLenum GLenum GLsizei count
GLsizei const GLchar *const * path
#define QQmlJSASTClassListToVisit
#define Q_ASSERT_X(cond, x, msg)