Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmldomreformatter_p.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLDOMREFORMATTER_P
5#define QQMLDOMREFORMATTER_P
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qqmldom_global.h"
19
21#include "qqmldom_fwd_p.h"
24
25#include <QtQml/private/qqmljsast_p.h>
26
27QT_BEGIN_NAMESPACE
28namespace QQmlJS {
29namespace Dom {
30
31class ScriptFormatter final : protected AST::JSVisitor
32{
33public:
34 // TODO QTBUG-121988
35 ScriptFormatter(OutWriter &lw, const ScriptExpression *const script) : lw(lw), m_script(script)
36 {
37 if (m_script) {
38 comments = m_script->astComments();
39 accept(m_script->ast());
40 }
41 }
42
43protected:
44 // output functions
45 inline void out(const char *str)
46 {
47 ensureDeferredSpacesAndMarkWriteAsNotComment();
48 lw.write(QString::fromLatin1(str));
49 }
50 inline void out(QStringView str)
51 {
52 ensureDeferredSpacesAndMarkWriteAsNotComment();
53 lw.write(str);
54 }
55 inline void out(const SourceLocation &loc)
56 {
57 ensureDeferredSpacesAndMarkWriteAsNotComment();
58 if (loc.length != 0)
59 out(m_script->loc2Str(loc));
60 }
61 void writePreComment(const CommentedElement *c)
62 {
63 Q_ASSERT(c);
64
65 if (!c->preComments().empty())
66 deferredSpaces = 0;
67 else
68 ensureDeferredSpaces();
69 c->writePre(lw);
70 if (!c->preComments().empty())
71 lastWriteWasComment = true;
72 }
73
74 void writePostComment(const CommentedElement *c)
75 {
76 Q_ASSERT(c);
77 c->writePost(lw);
78
79 if (!c->postComments().empty())
80 lastWriteWasComment = true;
81 }
82
83 enum CommentOption { TokenAndComment, OnlyComments };
84 void outWithComments(const SourceLocation &loc, AST::Node *node,
85 CommentOption option = TokenAndComment)
86 {
87 if (!loc.isValid())
88 return;
89 const CommentedElement *c = comments->commentForNode(node, CommentAnchor::from(loc));
90 if (c)
91 writePreComment(c);
92
93 if (option != OnlyComments)
94 out(loc);
95
96 if (c)
97 writePostComment(c);
98 }
99
100 inline void ensureSpaceIfNoComment()
101 {
102 // Comments contain the spaces before and after them. And, in case the comment doesn't end
103 // with spaces, we still respect the user's formatting choice.
104 if (!lastWriteWasComment)
105 ++deferredSpaces;
106 lastWriteWasComment = false;
107 }
108 inline void ensureNewline(quint32 count = 1)
109 {
110 ensureDeferredSpacesAndMarkWriteAsNotComment();
111 lw.ensureNewline(count);
112 }
113
114 inline void ensureDeferredSpaces()
115 {
116 for (int i = 0; i < deferredSpaces; ++i)
117 lw.ensureSpace();
118 deferredSpaces = 0;
119 }
120 inline void ensureDeferredSpacesAndMarkWriteAsNotComment()
121 {
122 ensureDeferredSpaces();
123 lastWriteWasComment = false;
124 }
125
126 // visitor functions
127 inline void accept(AST::Node *node) { AST::Node::accept(node, this); }
128 void lnAcceptIndented(AST::Node *node);
129 bool acceptBlockOrIndented(AST::Node *ast, bool finishWithSpaceOrNewline = false);
130
131 bool preVisit(AST::Node *n) override;
132 void postVisit(AST::Node *n) override;
133
134 bool visit(AST::ThisExpression *ast) override;
135 bool visit(AST::NullExpression *ast) override;
136 bool visit(AST::TrueLiteral *ast) override;
137 bool visit(AST::FalseLiteral *ast) override;
138 bool visit(AST::IdentifierExpression *ast) override;
139 bool visit(AST::StringLiteral *ast) override;
140 bool visit(AST::NumericLiteral *ast) override;
141 bool visit(AST::RegExpLiteral *ast) override;
142
143 bool visit(AST::ArrayPattern *ast) override;
144
145 bool visit(AST::ObjectPattern *ast) override;
146
147 bool visit(AST::PatternElementList *ast) override;
148
149 bool visit(AST::PatternPropertyList *ast) override;
150 bool visit(AST::PatternProperty *property) override;
151
152 bool visit(AST::NestedExpression *ast) override;
153 bool visit(AST::IdentifierPropertyName *ast) override;
154 bool visit(AST::StringLiteralPropertyName *ast) override;
155 bool visit(AST::NumericLiteralPropertyName *ast) override;
156
157 bool visit(AST::TemplateLiteral *ast) override;
158 bool visit(AST::ArrayMemberExpression *ast) override;
159
160 bool visit(AST::FieldMemberExpression *ast) override;
161
162 bool visit(AST::NewMemberExpression *ast) override;
163
164 bool visit(AST::NewExpression *ast) override;
165
166 bool visit(AST::CallExpression *ast) override;
167
168 bool visit(AST::PostIncrementExpression *ast) override;
169
170 bool visit(AST::PostDecrementExpression *ast) override;
171 bool visit(AST::PreIncrementExpression *ast) override;
172
173 bool visit(AST::PreDecrementExpression *ast) override;
174
175 bool visit(AST::DeleteExpression *ast) override;
176
177 bool visit(AST::VoidExpression *ast) override;
178 bool visit(AST::TypeOfExpression *ast) override;
179
180 bool visit(AST::UnaryPlusExpression *ast) override;
181
182 bool visit(AST::UnaryMinusExpression *ast) override;
183
184 bool visit(AST::TildeExpression *ast) override;
185
186 bool visit(AST::NotExpression *ast) override;
187
188 bool visit(AST::BinaryExpression *ast) override;
189
190 bool visit(AST::ConditionalExpression *ast) override;
191
192 bool visit(AST::Block *ast) override;
193
194 bool visit(AST::VariableStatement *ast) override;
195
196 bool visit(AST::PatternElement *ast) override;
197 bool visit(AST::TypeAnnotation *ast) override;
198 bool visit(AST::Type *ast) override;
199 bool visit(AST::UiQualifiedId *ast) override;
200
201 bool visit(AST::EmptyStatement *ast) override;
202
203 bool visit(AST::IfStatement *ast) override;
204 bool visit(AST::DoWhileStatement *ast) override;
205
206 bool visit(AST::WhileStatement *ast) override;
207
208 bool visit(AST::ForStatement *ast) override;
209
210 bool visit(AST::ForEachStatement *ast) override;
211
212 bool visit(AST::ContinueStatement *ast) override;
213 bool visit(AST::BreakStatement *ast) override;
214
215 bool visit(AST::ReturnStatement *ast) override;
216 bool visit(AST::YieldExpression *ast) override;
217 bool visit(AST::ThrowStatement *ast) override;
218 bool visit(AST::WithStatement *ast) override;
219
220 bool visit(AST::SwitchStatement *ast) override;
221
222 bool visit(AST::CaseBlock *ast) override;
223
224 bool visit(AST::CaseClause *ast) override;
225
226 bool visit(AST::DefaultClause *ast) override;
227
228 bool visit(AST::LabelledStatement *ast) override;
229
230 bool visit(AST::TryStatement *ast) override;
231
232 bool visit(AST::Catch *ast) override;
233
234 bool visit(AST::Finally *ast) override;
235
236 bool visit(AST::FunctionDeclaration *ast) override;
237
238 bool visit(AST::FunctionExpression *ast) override;
239
240 bool visit(AST::Elision *ast) override;
241
242 bool visit(AST::ArgumentList *ast) override;
243
244 bool visit(AST::StatementList *ast) override;
245
246 bool visit(AST::VariableDeclarationList *ast) override;
247
248 bool visit(AST::CaseClauses *ast) override;
249
250 bool visit(AST::FormalParameterList *ast) override;
251
252 bool visit(AST::SuperLiteral *) override;
253 bool visit(AST::ComputedPropertyName *) override;
254 bool visit(AST::CommaExpression *el) override;
255 bool visit(AST::ExpressionStatement *el) override;
256
257 bool visit(AST::ClassDeclaration *ast) override;
258
259 bool visit(AST::ImportDeclaration *ast) override;
260 bool visit(AST::ImportSpecifier *ast) override;
261 bool visit(AST::NameSpaceImport *ast) override;
262 bool visit(AST::ImportsList *ast) override;
263 bool visit(AST::NamedImports *ast) override;
264 bool visit(AST::ImportClause *ast) override;
265
266 bool visit(AST::ExportDeclaration *ast) override;
267 bool visit(AST::ExportClause *ast) override;
268 bool visit(AST::ExportSpecifier *ast) override;
269 bool visit(AST::ExportsList *ast) override;
270
271 bool visit(AST::FromClause *ast) override;
272
273 void endVisit(AST::ComputedPropertyName *) override;
274
275 void endVisit(AST::ExportDeclaration *ast) override;
276 void endVisit(AST::ExportClause *ast) override;
277
278 void endVisit(AST::ImportDeclaration *ast) override;
279 void endVisit(AST::NamedImports *ast) override;
280
281 void throwRecursionDepthError() override;
282
283private:
284 bool addSemicolons() const { return expressionDepth > 0; }
285 bool canRemoveSemicolon(AST::Node *node);
286 OutWriter &writeOutSemicolon(AST::Node *);
287 OutWriter &lw;
288 std::shared_ptr<AstComments> comments;
289 const ScriptExpression *const m_script = nullptr; // outlives this
290 QHash<AST::Node *, QList<std::function<void()>>> postOps;
291 int expressionDepth = 0;
292 int deferredSpaces = 0;
293 bool lastWriteWasComment = false;
294};
295
296QMLDOM_EXPORT void reformatAst(OutWriter &lw, const QQmlJS::Dom::ScriptExpression *const script);
297
298} // namespace Dom
299} // namespace QQmlJS
300QT_END_NAMESPACE
301
302#endif // QQMLDOMREFORMATTER_P
std::pair< AST::Node *, CommentAnchor > CommentKey
void updatePathFromOwner(const Path &newPath)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &annotation, QmlObject **aPtr=nullptr)
BindingValue(const QList< QmlObject > &l)
void updatePathFromOwner(const Path &newPath)
BindingValue(const std::shared_ptr< ScriptExpression > &o)
BindingValue(const BindingValue &o)
DomItem value(const DomItem &binding) const
BindingValue & operator=(const BindingValue &o)
BindingValue(const QmlObject &o)
void setValue(std::unique_ptr< BindingValue > &&value)
std::shared_ptr< ScriptExpression > scriptExpressionValue() const
Binding & operator=(const Binding &)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &a, QmlObject **aPtr=nullptr)
void updatePathFromOwner(const Path &newPath)
QmlObject const * objectValue() const
DomItem valueItem(const DomItem &self) const
QList< QmlObject > * arrayValue()
Binding(const Binding &o)
QList< QmlObject > const * arrayValue() const
void writeOut(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name, const QString &scriptCode, BindingType bindingType=BindingType::Normal)
Binding(const QString &m_name, std::unique_ptr< BindingValue > &&value, BindingType bindingType=BindingType::Normal)
void writeOutValue(const DomItem &self, OutWriter &lw) const
Binding(const QString &m_name=QString())
Binding(const QString &m_name, const QmlObject &value, BindingType bindingType=BindingType::Normal)
std::shared_ptr< ScriptExpression > scriptExpressionValue()
BindingValueKind valueKind() const
Binding(const QString &m_name, const std::shared_ptr< ScriptExpression > &value, BindingType bindingType=BindingType::Normal)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
CommentableDomElement(const Path &pathFromOwner=Path())
void updatePathFromOwner(const Path &newPath) override
Component(const Path &pathFromOwner=Path())
Path addObject(const QmlObject &object, QmlObject **oPtr=nullptr)
Path attachedTypePath(const DomItem &) const
DomItem field(const DomItem &self, QStringView name) const override
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
Component(const QString &name)
virtual void updatePathFromOwner(const Path &newPath)
Path pathFromOwner() const override
A value type that references any element of the Dom.
DomItem top() const
void writeOutPost(OutWriter &lw) const
DomItem path(const Path &p, const ErrorHandler &h=&defaultErrorHandler) const
void writeOutPre(OutWriter &lw) const
DomItem environment() const
Path canonicalPath() const
DomItem containingObject() const
DomItem subMapItem(const Map &map) const
DomItem subReferenceItem(const PathEls::PathComponent &c, const Path &referencedObject) const
InternalKind internalKind() const
DomItem owner() const
The owner of an element, for an qmlObject this is the containing qml file.
void writeOut(OutWriter &lw) const
Path pathFromOwner() const
static ErrorGroup domErrorGroup
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
void setAnnotations(const QList< QmlObject > &annotations)
void writeOut(const DomItem &self, OutWriter &lw) const override
void updatePathFromOwner(const Path &newP) override
Path addAnnotation(const QmlObject &child, QmlObject **cPtr=nullptr)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &lw) const
Represents a set of tags grouping a set of related error messages.
ErrorMessage warning(const Dumper &message) const
ErrorMessage error(const Dumper &message) const
bool preVisit(AST::Node *n) override
FirstNodeVisitor(qsizetype minStart, qsizetype maxEnd)
Path addAnnotation(const Path &selfPathFromOwner, const QmlObject &ann, QmlObject **aPtr=nullptr)
Id(const QString &idName=QString(), const Path &referredObject=Path())
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void updatePathFromOwner(const Path &pathFromOwner)
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
QList< Path > allSources(const DomItem &self) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
void eof(bool ensureNewline=true)
void writeOut(const DomItem &self, OutWriter &ow, bool compact) const
std::function< index_type(const DomItem &)> Length
std::function< QSet< QString >(const DomItem &)> Keys
Path typePath(const DomItem &) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOut(const DomItem &self, OutWriter &ow) const
QString signature(const DomItem &self) const
void writeOut(const DomItem &self, OutWriter &ow) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
void writeOutSignal(const DomItem &self, OutWriter &ow) const
TypeAnnotationStyle typeAnnotationStyle
MockObject(const Path &pathFromOwner=Path(), QMap< QString, MockObject > subObjects={}, QMap< QString, QCborValue > subValues={})
QMap< QString, MockObject > subObjects
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
DomType kind() const override
MockObject copy() const
std::pair< QString, MockObject > asStringPair() const
static constexpr DomType kindValue
QMap< QString, QCborValue > subValues
QMap< QString, MockObject > subObjects
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
std::shared_ptr< OwningItem > doCopy(const DomItem &self) const override
std::shared_ptr< MockOwner > makeCopy(const DomItem &self) const
MockOwner(const MockOwner &o)
Path canonicalPath(const DomItem &self) const override
static constexpr DomType kindValue
QMap< QString, QMap< QString, MockObject > > subMaps
QMap< QString, QCborValue > subValues
DomType kind() const override
MockOwner(const Path &pathFromTop=Path(), int derivedFrom=0, QMap< QString, MockObject > subObjects={}, QMap< QString, QCborValue > subValues={}, QMap< QString, QMap< QString, MockObject > > subMaps={}, QMap< QString, QMultiMap< QString, MockObject > > subMultiMaps={}, QMap< QString, QList< MockObject > > subLists={})
MutableDomItem path(const Path &p)
A DomItem that owns other DomItems and is managed through a shared pointer.
void addErrorLocal(ErrorMessage &&msg)
OwningItem(int derivedFrom=0)
static Path fromRoot(PathRoot r)
Path operator[](int i) const
Path last() const
void writeOut(const DomItem &self, OutWriter &ow) const
void writeOut(const DomItem &self, OutWriter &lw) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
QList< DomItem > subComponents(const DomItem &self) const
void updatePathFromOwner(const Path &newPath) override
void writeOut(const DomItem &self, OutWriter &) const override
QList< QString > subComponentsNames(const DomItem &self) const
MutableDomItem addBinding(MutableDomItem &self, const Binding &binding, AddOption option)
void writeOut(const DomItem &self, OutWriter &ow, const QString &onTarget) const
QList< std::pair< SourceLocation, DomItem > > orderOfAttributes(const DomItem &self, const DomItem &component) const
bool iterateSubOwners(const DomItem &self, function_ref< bool(const DomItem &owner)> visitor) const
void updatePathFromOwner(const Path &newPath) override
Path addBinding(const Binding &binding, AddOption option, Binding **bPtr=nullptr)
static constexpr DomType kindValue
void writeOutSortedEnumerations(const DomItem &component, OutWriter &ow) const
LocallyResolvedAlias resolveAlias(const DomItem &self, std::shared_ptr< ScriptExpression > accessSequence) const
void writeOutId(const DomItem &self, OutWriter &ow) const
LocallyResolvedAlias resolveAlias(const DomItem &self, const QStringList &accessSequence) const
void writeOutSortedPropertyDefinition(const DomItem &self, OutWriter &ow, QSet< QString > &mergedDefBinding) const
Path addPropertyDef(const PropertyDefinition &propertyDef, AddOption option, PropertyDefinition **pDef=nullptr)
MutableDomItem addPropertyDef(MutableDomItem &self, const PropertyDefinition &propertyDef, AddOption option)
DomItem field(const DomItem &self, QStringView name) const override
QString localDefaultPropertyName() const
QString defaultPropertyName(const DomItem &self) const
QmlObject(const Path &pathFromOwner=Path())
void writeOutSortedAttributes(const DomItem &self, OutWriter &ow, const DomItem &component) const
MutableDomItem addMethod(MutableDomItem &self, const MethodInfo &functionDef, AddOption option)
void writeOutAttributes(const DomItem &self, OutWriter &ow, const DomItem &component, const QString &code) const
QList< QString > fields() const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const override
Path addMethod(const MethodInfo &functionDef, AddOption option, MethodInfo **mPtr=nullptr)
bool iterateBaseDirectSubpaths(const DomItem &self, DirectVisitor) const
QString absoluteLocalPath(const QString &basePath=QString()) const
QString directoryString() const
QString localPath() const
QString moduleUri() const
bool iterateDirectSubpaths(const DomItem &, DirectVisitor) const override
Use this to contain any script element.
QStringView loc2Str(const SourceLocation &) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor visitor) const override
ScriptExpression(const ScriptExpression &e)
void writeOut(const DomItem &self, OutWriter &lw) const override
SourceLocation globalLocation(const DomItem &self) const
ScriptExpression(QStringView code, const std::shared_ptr< QQmlJS::Engine > &engine, AST::Node *ast, const std::shared_ptr< AstComments > &comments, ExpressionType expressionType, const SourceLocation &localOffset=SourceLocation())
void setScriptElement(const ScriptElementVariant &p)
void astDumper(const Sink &s, AstDumperOptions options) const
bool iterateDirectSubpaths(const DomItem &self, DirectVisitor) const
Version(qint32 majorVersion=Undefined, qint32 minorVersion=Undefined)
QString stringValue() const
A vistor that visits all the AST:Node.
Provides entities to maintain mappings between elements and their location in a file.
Tree find(const Tree &self, const Path &p)
Path moduleIndexPath(const QString &uri, int majorVersion, const ErrorHandler &errorHandler=nullptr)
Path moduleScopePath(const QString &uri, const QString &version, const ErrorHandler &errorHandler=nullptr)
Path moduleScopePath(const QString &uri, Version version, const ErrorHandler &errorHandler=nullptr)
static ErrorGroups domParsingErrors()
static QStringList dotExpressionToList(const std::shared_ptr< ScriptExpression > &expr)
std::function< void(const ErrorMessage &)> ErrorHandler
AST::Node * firstNodeInRange(AST::Node *n, qsizetype minStart=0, qsizetype maxEnd=std::numeric_limits< qint32 >::max())
#define QMLDOM_EXPORT
#define NewErrorGroup(name)