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
qmlcodeparser.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
6#include "node.h"
7#include "qmlvisitor.h"
8#include "utilities.h"
9
10#include <private/qqmljsast_p.h>
11
12#include <qdebug.h>
13
15
16/*!
17 Returns "QML".
18 */
20{
21 return "QML";
22}
23
24/*!
25 Returns a string list containing "*.qml". This is the only
26 file type parsed by the QMLN parser.
27 */
29{
30 return QStringList() << "*.qml";
31}
32
33/*!
34 Parses the source file at \a filePath and inserts the contents
35 into the database. The \a location is used for error reporting.
36
37 If it can't open the file at \a filePath, it reports an error
38 and returns without doing anything.
39 */
40void QmlCodeParser::parseSourceFile(const Location &location, const QString &filePath, CppCodeParser&)
41{
42 static const QSet<QString> topic_commands{
47 };
48
49 QFile in(filePath);
50 if (!in.open(QIODevice::ReadOnly)) {
51 location.error(QStringLiteral("Cannot open QML file '%1'").arg(filePath));
52 return;
53 }
54
55 QString document = in.readAll();
56 in.close();
57
58 QString newCode = document;
59 extractPragmas(newCode);
60
61 QQmlJS::Engine engine{};
62 QQmlJS::Lexer lexer{&engine};
63 lexer.setCode(newCode, 1);
64
65 QQmlJS::Parser parser{&engine};
66
67 if (parser.parse()) {
68 QQmlJS::AST::UiProgram *ast = parser.ast();
69 QmlDocVisitor visitor(filePath, newCode, &engine, topic_commands + CodeParser::common_meta_commands,
70 topic_commands);
71 QQmlJS::AST::Node::accept(ast, &visitor);
72 if (visitor.hasError())
73 Location(filePath).warning("Could not analyze QML file, output is incomplete.");
74 }
75 const auto &messages = parser.diagnosticMessages();
76 for (const auto &msg : messages) {
77 qCDebug(lcQdoc, "%s: %d: %d: QML syntax error: %s", qUtf8Printable(filePath),
78 msg.loc.startLine, msg.loc.startColumn, qUtf8Printable(msg.message));
79 }
80}
81
82/*!
83 Copy and paste from src/declarative/qml/qdeclarativescriptparser.cpp.
84 This function blanks out the section of the \a str beginning at \a idx
85 and running for \a n characters.
86*/
87void replaceWithSpace(QString &str, int idx, int n) // Also used in qmlcodemarker.cpp.
88{
89 QChar *data = str.data() + idx;
90 const QChar space(QLatin1Char(' '));
91 for (int ii = 0; ii < n; ++ii)
92 *data++ = space;
93}
94
95/*!
96 Copy & paste from src/declarative/qml/qdeclarativescriptparser.cpp,
97 then modified to return no values.
98
99 Searches for ".pragma <value>" declarations within \a script.
100 Currently supported pragmas are: library
101*/
102void QmlCodeParser::extractPragmas(QString &script)
103{
104 const QString pragma(QLatin1String("pragma"));
105
106 QQmlJS::Lexer l(nullptr);
107 l.setCode(script, 0);
108
109 int token = l.lex();
110
111 while (true) {
112 if (token != QQmlJSGrammar::T_DOT)
113 return;
114
115 int startOffset = l.tokenOffset();
116 int startLine = l.tokenStartLine();
117
118 token = l.lex();
119
120 if (token != QQmlJSGrammar::T_IDENTIFIER || l.tokenStartLine() != startLine
121 || script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
122 return;
123
124 token = l.lex();
125
126 if (token != QQmlJSGrammar::T_IDENTIFIER || l.tokenStartLine() != startLine)
127 return;
128
129 QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
130 int endOffset = l.tokenLength() + l.tokenOffset();
131
132 token = l.lex();
133 if (l.tokenStartLine() == startLine)
134 return;
135
136 if (pragmaValue == QLatin1String("library"))
137 replaceWithSpace(script, startOffset, endOffset - startOffset);
138 else
139 return;
140 }
141}
142
143QT_END_NAMESPACE
The Location class provides a way to mark a location in a file.
Definition location.h:15
QString language() override
Returns "QML".
QStringList sourceFileNameFilter() override
Returns a string list containing "*.qml".
void parseSourceFile(const Location &location, const QString &filePath, CppCodeParser &) override
Parses the source file at filePath and inserts the contents into the database.
void extractPragmas(QString &script)
Copy & paste from src/declarative/qml/qdeclarativescriptparser.cpp, then modified to return no values...
bool hasError() const
#define COMMAND_QMLSIGNAL
Definition codeparser.h:65
#define COMMAND_QMLPROPERTYGROUP
Definition codeparser.h:62
#define COMMAND_QMLPROPERTY
Definition codeparser.h:61
#define COMMAND_QMLATTACHEDPROPERTY
Definition codeparser.h:50
#define COMMAND_VARIABLE
Definition codeparser.h:81
#define COMMAND_QMLBASICTYPE
Definition codeparser.h:88
#define COMMAND_QMLMETHOD
Definition codeparser.h:58
#define COMMAND_QMLCLASS
Definition codeparser.h:53
#define COMMAND_QMLVALUETYPE
Definition codeparser.h:52
#define COMMAND_QMLTYPE
Definition codeparser.h:66
#define COMMAND_QMLATTACHEDMETHOD
Definition codeparser.h:49
#define COMMAND_QMLATTACHEDSIGNAL
Definition codeparser.h:51
Combined button and popup list for selecting options.
void replaceWithSpace(QString &str, int idx, int n)
Copy and paste from src/declarative/qml/qdeclarativescriptparser.cpp.