Update qmljs parser to Qt 5.15 parser

* parser side support for annotations, inline components, new UiVersion
  and all the things included in QT 5.15 parser
* SourceLocation moved from QmlJS:AST to QmlJS
* Visitors now need to handle throwRecursionDepthError
* BaseVisitor for visitors that want to override all visit

Task-number: QTCREATORBUG-23591
Change-Id: I682a30d0b08b6c929739fd0e339ef6fbde3eb630
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Fawzi Mohamed
2020-02-28 17:51:32 +01:00
parent a24dead5f6
commit b09a48599e
88 changed files with 5290 additions and 4350 deletions

View File

@@ -669,10 +669,18 @@
\l{http://linterrors.com/js/the-array-literal-notation-is-preferrable} \l{http://linterrors.com/js/the-array-literal-notation-is-preferrable}
{The array literal notation [] is preferable}. {The array literal notation [] is preferable}.
\row
\li M324
\li Error
\li Hit maximum recursion limit visiting AST, the code model will be unreliable
and most likely invalid
\li
\row \row
\li M400 \li M400
\li Warning \li Warning
\li Duplicate import \li Duplicate import
\li
\endtable \endtable

View File

@@ -4,7 +4,6 @@ add_qtc_library(QmlJS
SOURCES SOURCES
jsoncheck.cpp jsoncheck.h jsoncheck.cpp jsoncheck.h
parser/qmldirparser.cpp parser/qmldirparser_p.h parser/qmldirparser.cpp parser/qmldirparser_p.h
parser/qmlerror.cpp parser/qmlerror.h
parser/qmljsast.cpp parser/qmljsast_p.h parser/qmljsast.cpp parser/qmljsast_p.h
parser/qmljsastfwd_p.h parser/qmljsastfwd_p.h
parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h
@@ -15,6 +14,7 @@ add_qtc_library(QmlJS
parser/qmljslexer.cpp parser/qmljslexer_p.h parser/qmljslexer.cpp parser/qmljslexer_p.h
parser/qmljsmemorypool_p.h parser/qmljsmemorypool_p.h
parser/qmljsparser.cpp parser/qmljsparser_p.h parser/qmljsparser.cpp parser/qmljsparser_p.h
parser/qmljssourcelocation.cpp parser/qmljssourcelocation_p.h
persistenttrie.cpp persistenttrie.h persistenttrie.cpp persistenttrie.h
qmljs_global.h qmljs_global.h
qmljsbind.cpp qmljsbind.h qmljsbind.cpp qmljsbind.h

View File

@@ -310,6 +310,14 @@ bool JsonCheck::visit(StringLiteral *ast)
return false; return false;
} }
void JsonCheck::throwRecursionDepthError()
{
analysis()->m_messages.append(Message(ErrHitMaximumRecursion,
SourceLocation(),
QString(), QString(), false));
}
static QString formatExpectedTypes(QStringList all) static QString formatExpectedTypes(QStringList all)
{ {
all.removeDuplicates(); all.removeDuplicates();

View File

@@ -59,6 +59,8 @@ private:
bool visit(AST::NumericLiteral *ast) override; bool visit(AST::NumericLiteral *ast) override;
bool visit(AST::StringLiteral *ast) override; bool visit(AST::StringLiteral *ast) override;
void throwRecursionDepthError() override;
struct AnalysisData struct AnalysisData
{ {
AnalysisData() : m_ranking(0), m_hasMatch(false) {} AnalysisData() : m_ranking(0), m_hasMatch(false) {}
@@ -71,12 +73,12 @@ private:
}; };
void processSchema(AST::Node *ast); void processSchema(AST::Node *ast);
bool proceedCheck(Utils::JsonValue::Kind kind, const AST::SourceLocation &location); bool proceedCheck(Utils::JsonValue::Kind kind, const SourceLocation &location);
AnalysisData *analysis(); AnalysisData *analysis();
Document::Ptr m_doc; Document::Ptr m_doc;
AST::SourceLocation m_firstLoc; SourceLocation m_firstLoc;
Utils::JsonSchema *m_schema; Utils::JsonSchema *m_schema;
QStack<AnalysisData> m_analysis; QStack<AnalysisData> m_analysis;
}; };

View File

@@ -1,16 +1,25 @@
s/private\/qdeclarative/qml/g s/include *<private\/\([a-zA-Z_.]*\)>/include "qmljs\/parser\/\1"/g
s/qtqmlcompilerglobal_p.h/qmljsglobal_p.h/g
s/<QtCore\/qglobal.h>/"qmljsglobal_p.h"/g
s/Q_QMLCOMPILER_PRIVATE_EXPORT/QML_PARSER_EXPORT/g
s/qqml/qml/g s/qqml/qml/g
s/QDECLARATIVE/QML/g s/QDECLARATIVE/QML/g
s/QQml/Qml/g s/QQml/Qml/g
s/QQMLJS/QMLJS/g s/QQMLJS/QMLJS/g
s/Q_QML_EXPORT //g s/Q_QML_EXPORT //g
s/Q_QML_PRIVATE_EXPORT/QML_PARSER_EXPORT/ s/Q_QML_PRIVATE_EXPORT/QML_PARSER_EXPORT/g
s/QT_BEGIN_NAMESPACE/QT_QML_BEGIN_NAMESPACE/g
s/QT_END_NAMESPACE/QT_QML_END_NAMESPACE/g
# adjust pri file # adjust pri file
s/ \$\$PWD\/qmljsglobal_p.h/ $$PWD\/qmljsglobal_p.h \\\ s/ \$\$PWD\/qmljsglobal_p.h/ $$PWD\/qmljsglobal_p.h \\\
$$PWD\/qmljssourcelocation_p.h \\\
$$PWD\/qmljsmemorypool_p.h \\\
$$PWD\/qmldirparser_p.h \\\ $$PWD\/qmldirparser_p.h \\\
$$PWD\/qmlerror.h/ $$PWD\/qmljsgrammar_p.h \\\
s/ \$\$PWD\/qmljsparser.cpp/ $$PWD\/qmljsparser.cpp \\\ $$PWD\/qmljsparser_p.h/
s/ \$\$PWD\/qmljslexer.cpp/ $$PWD\/qmljslexer.cpp \\\
$$PWD\/qmldirparser.cpp \\\ $$PWD\/qmldirparser.cpp \\\
$$PWD\/qmlerror.cpp/ $$PWD\/qmljsgrammar.cpp \\\
s/OTHER_FILES/DISTFILES/ $$PWD\/qmljsparser.cpp/

View File

@@ -10,11 +10,12 @@
# cd src/libs/qmljs/parser # cd src/libs/qmljs/parser
# QTDIR=~/path/to/qtdeclarative-checkout ./gen-parser.sh # QTDIR=~/path/to/qtdeclarative-checkout ./gen-parser.sh
if [ -z "$QTDIR" ]; then if [ -z "$QTDIR" -o -z "$QLALR" ]; then
echo "Usage: QTDIR=~/path/to/qtdeclarative-checkout $0" 1>&2 echo "Usage: QTDIR=~/path/to/qtdeclarative-checkout QLALR=~/path/to/qlalr $0" 1>&2
exit 1 exit 1
fi fi
me=$(dirname $0) me=$(dirname $0)
for i in $QTDIR/src/qml/parser/*.{g,h,cpp,pri}; do for i in $QTDIR/src/qml/parser/*.{g,h,cpp,pri}; do
@@ -23,22 +24,23 @@ for i in $QTDIR/src/qml/parser/*.{g,h,cpp,pri}; do
fi fi
done done
for i in $QTDIR/src/qml/qml/qqml{error.{h,cpp},dirparser{_p.h,.cpp}}; do for i in $QTDIR/src/qml/qmldirparser/*.{h,cpp}; do
if ! echo $i | grep -q qmljsglobal; then
sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqml/qml/) sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqml/qml/)
fi
done done
# export QmlDirParser for i in $QTDIR/src/qml/common/qqmljs{sourcelocation,memorypool}_p.h; do
perl -p -0777 -i -e 's/QT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QmlEngine;\nclass Q_AUTOTEST_EXPORT QmlDirParser/#include "qmljsglobal_p.h"\n\nQT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QmlEngine;\nclass QML_PARSER_EXPORT QmlDirParser/' qmldirparser_p.h sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqmljs/qmljs/)
# export QmlJSGrammar done
perl -p -0777 -i -e 's/#include <QtCore\/qglobal.h>\n\nQT_BEGIN_NAMESPACE\n\nclass QmlJSGrammar\n/#include "qmljsglobal_p.h"\n#include <QtCore\/qglobal.h>\n\nQT_BEGIN_NAMESPACE\n\nclass QML_PARSER_EXPORT QmlJSGrammar\n/' qmljsgrammar_p.h
# remove qmlapiversion_p.h include
#include "qmlapiversion_p.h"
perl -p -0777 -i -e 's/#include \"qmlapiversion_p.h\"//' qmljsdiagnosticmessage_p.h
# remove qmlglobal_p.h include # remove qmlglobal_p.h include
perl -p -0777 -i -e 's/#include \"qmlglobal_p.h\"//' qmldirparser.cpp perl -p -0777 -i -e 's/#include \"qmlglobal_p.h\"//' qmldirparser.cpp
# remove qmlglobal_p.h include # remove qmlglobal_p.h include
perl -p -0777 -i -e 's/#include \"qmlglobal_p.h\"//' qmlerror.cpp
# remove qmlglobal_p.h include
perl -p -0777 -i -e 's/#include \<QtQml\/qmlfile.h\>//' qmldirparser.cpp perl -p -0777 -i -e 's/#include \<QtQml\/qmlfile.h\>//' qmldirparser.cpp
# remove QtQml/qtqmlglobal.h include
perl -p -0777 -i -e 's/#include \<QtQml\/qtqmlglobal.h\>//' qmlerror.h
# replace private/qhashedstring_p.h include and QHashedStringRef # replace private/qhashedstring_p.h include and QHashedStringRef
perl -p -0777 -i -e 's/#include \<private\/qhashedstring_p.h\>//' qmldirparser_p.h perl -p -0777 -i -e 's/#include \<private\/qhashedstring_p.h\>//' qmldirparser_p.h
perl -p -0777 -i -e 's/QHashedStringRef/QString/g' qmldirparser_p.h qmldirparser.cpp perl -p -0777 -i -e 's/QHashedStringRef/QString/g' qmldirparser_p.h qmldirparser.cpp
@@ -51,11 +53,15 @@ sed -i -e 's/chars.length()/chars.size()/' $me/qmljslexer.cpp
sed -i -e 's/DiagnosticMessage::Error/Severity::Error/g' $me/qmljsparser.cpp sed -i -e 's/DiagnosticMessage::Error/Severity::Error/g' $me/qmljsparser.cpp
sed -i -e 's/DiagnosticMessage::Warning/Severity::Warning/g' $me/qmljsparser.cpp sed -i -e 's/DiagnosticMessage::Warning/Severity::Warning/g' $me/qmljsparser.cpp
sed -i -e 's/DiagnosticMessage::Warning/Severity::Warning/g' $me/qmljsparser_p.h sed -i -e 's/DiagnosticMessage::Warning/Severity::Warning/g' $me/qmljsparser_p.h
sed -i -e 's|#include <private/qv4errorobject_p.h>||g' $me/qmlerror.cpp
sed -i -e 's|#include <QtCore/qstring.h>|#include <QString>|g' $me/qmljsengine_p.h sed -i -e 's|#include <QtCore/qstring.h>|#include <QString>|g' $me/qmljsengine_p.h
sed -i -e 's|#include <QtCore/qset.h>|#include <QSet>|g' $me/qmljsengine_p.h sed -i -e 's|#include <QtCore/qset.h>|#include <QSet>|g' $me/qmljsengine_p.h
sed -i -e 's/qt_qnan/qQNaN/' $me/qmljsengine_p.cpp sed -i -e 's/qt_qnan/qQNaN/' $me/qmljsengine_p.cpp
sed -i -e 's|#include <QtCore/private/qnumeric_p.h>|#include <QtCore/qnumeric.h>|' $me/qmljsengine_p.cpp sed -i -e 's|#include <QtCore/private/qnumeric_p.h>|#include <QtCore/qnumeric.h>|' $me/qmljsengine_p.cpp
perl -p -0777 -i -e 's/QT_QML_BEGIN_NAMESPACE/#include <qmljs\/qmljsconstants.h>\nQT_QML_BEGIN_NAMESPACE/' qmljsengine_p.h perl -p -0777 -i -e 's/QT_QML_BEGIN_NAMESPACE/#include <qmljs\/qmljsconstants.h>\nQT_QML_BEGIN_NAMESPACE/' qmljsengine_p.h
patch -p1 < grammar.patch
$QLALR qmljs.g
./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h} ./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h}
patch -p1 < parser.patch

View File

@@ -0,0 +1,21 @@
diff -u parser-genOut/qmljs.g parser/qmljs.g
--- parser-genOut/qmljs.g 2020-03-02 13:53:50.000000000 +0100
+++ parser/qmljs.g 2020-03-02 13:55:50.000000000 +0100
@@ -379,7 +379,7 @@
inline DiagnosticMessage diagnosticMessage() const
{
for (const DiagnosticMessage &d : diagnostic_messages) {
- if (d.type != QtWarningMsg)
+ if (d.kind != Severity::Warning)
return d;
}
@@ -423,7 +423,7 @@
DiagnosticMessage error;
error.loc = location;
error.message = message;
- error.type = kind;
+ error.kind = DiagnosticMessage::qtMsgTypeToKind(kind);
return error;
}

View File

@@ -1,157 +1,83 @@
diff --git a/src/libs/qmljs/parser/qmlerror.cpp b/src/libs/qmljs/parser/qmlerror.cpp diff -u parser-genOut/qmljsgrammar.cpp parser/qmljsgrammar.cpp
index d090a19..5ec311d 100644 --- parser-genOut/qmljsgrammar.cpp 2020-03-02 13:53:50.000000000 +0100
--- a/src/libs/qmljs/parser/qmlerror.cpp +++ parser/qmljsgrammar.cpp 2020-03-02 14:16:26.000000000 +0100
+++ b/src/libs/qmljs/parser/qmlerror.cpp @@ -21,7 +21,8 @@
@@ -65,6 +65,12 @@ QT_BEGIN_NAMESPACE ** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
-***************************************************************************// This file was generated by qlalr - DO NOT EDIT!
+***************************************************************************/
+// This file was generated by qlalr - DO NOT EDIT!
#include "qmljsgrammar_p.h"
\sa QQuickView::errors(), QmlComponent::errors() const char *const QmlJSGrammar::spell [] = {
*/ diff -u parser-genOut/qmljsgrammar_p.h parser/qmljsgrammar_p.h
+ --- parser/qmljsgrammar_p.h 2020-03-03 13:51:43.000000000 +0100
+static quint16 qmlSourceCoordinate(int n) +++ parser-fixed2/qmljsgrammar_p.h 2020-03-02 17:20:56.000000000 +0100
+{ @@ -21,11 +21,13 @@
+ return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0; ** information to ensure the GNU General Public License requirements will
+} ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+ **
class QmlErrorPrivate -***************************************************************************// This file was generated by qlalr - DO NOT EDIT!
+***************************************************************************/
+// This file was generated by qlalr - DO NOT EDIT!
#ifndef QMLJSGRAMMAR_P_H
#define QMLJSGRAMMAR_P_H
+#include "qmljsglobal_p.h"
-class QmlJSGrammar
+class QML_PARSER_EXPORT QmlJSGrammar
{ {
public: public:
diff --git a/src/libs/qmljs/parser/qmljsengine_p.cpp b/src/libs/qmljs/parser/qmljsengine_p.cpp enum VariousConstants {
index 1e22fa5..10fc3d1 100644 diff -u parser-genOut/qmljslexer_p.h parser/qmljslexer_p.h
--- a/src/libs/qmljs/parser/qmljsengine_p.cpp --- parser-genOut/qmljslexer_p.h 2020-03-02 13:53:50.000000000 +0100
+++ b/src/libs/qmljs/parser/qmljsengine_p.cpp +++ parser/qmljslexer_p.h 2020-03-02 13:55:13.000000000 +0100
@@ -110,7 +110,7 @@ double integerFromString(const QString &str, int radix) @@ -47,7 +47,7 @@
Engine::Engine()
- : _lexer(0)
+ : _lexer(0), _directives(0)
{ }
Engine::~Engine()
@@ -131,6 +131,12 @@ Lexer *Engine::lexer() const
void Engine::setLexer(Lexer *lexer)
{ _lexer = lexer; }
+void Engine::setDirectives(Directives *directives)
+{ _directives = directives; }
+
+Directives *Engine::directives() const
+{ return _directives; }
+
MemoryPool *Engine::pool()
{ return &_pool; }
diff --git a/src/libs/qmljs/parser/qmljsengine_p.h b/src/libs/qmljs/parser/qmljsengine_p.h
index b1f7e1a..29b69d1 100644
--- a/src/libs/qmljs/parser/qmljsengine_p.h
+++ b/src/libs/qmljs/parser/qmljsengine_p.h
@@ -44,36 +44,35 @@
#include "qmljsglobal_p.h"
#include "qmljsastfwd_p.h"
#include "qmljsmemorypool_p.h"
+#include <qmljs/qmljsconstants.h>
#include <QString>
#include <QSet>
-#include <qmljs/qmljsconstants.h>
QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace QmlJS {
class Lexer; class Engine;
+class Directives; -struct DiagnosticMessage;
class MemoryPool; +class DiagnosticMessage;
class Directives;
class QML_PARSER_EXPORT DiagnosticMessage class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
{ diff -u parser-genOut/qmljsparser.cpp parser/qmljsparser.cpp
public: --- parser-genOut/qmljsparser.cpp 2020-03-02 13:53:50.000000000 +0100
- enum Kind { Warning, Error }; +++ parser/qmljsparser.cpp 2020-03-02 14:16:01.000000000 +0100
- @@ -22,5 +22,6 @@
DiagnosticMessage() ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
- : kind(Error) {} **
+ : kind(Severity::Error) {} ****************************************************************************/
+#line 172 "qmljs.g"
- DiagnosticMessage(Kind kind, const AST::SourceLocation &loc, const QString &message) #include "qmljs/parser/qmljsengine_p.h"
+ DiagnosticMessage(Severity::Enum kind, const AST::SourceLocation &loc, const QString &message) diff -u parser-genOut/qmljsparser_p.h parser/qmljsparser_p.h
: kind(kind), loc(loc), message(message) {} --- parser-genOut/qmljsparser_p.h 2020-03-02 13:53:50.000000000 +0100
+++ parser/qmljsparser_p.h 2020-03-02 14:13:25.000000000 +0100
@@ -22,6 +22,7 @@
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
+#line 223 "qmljs.g"
bool isWarning() const
- { return kind == Warning; }
+ { return kind == Severity::Warning; }
bool isError() const //
- { return kind == Error; }
+ { return kind == Severity::Error; }
- Kind kind; diff -u parser-genOut/parser.pri parser/parser.pri
+ Severity::Enum kind; --- parser-genOut/parser.pri 2020-03-02 15:40:09.000000000 +0100
AST::SourceLocation loc; +++ parser/parser.pri 2020-03-02 15:41:11.000000000 +0100
QString message; @@ -22,10 +22,10 @@
}; $$PWD/qmljsparser.cpp \
@@ -81,6 +80,7 @@ public:
class QML_PARSER_EXPORT Engine
{
Lexer *_lexer;
+ Directives *_directives;
MemoryPool _pool;
QList<AST::SourceLocation> _comments;
QString _extraCode;
@@ -99,6 +99,9 @@ public:
Lexer *lexer() const;
void setLexer(Lexer *lexer);
+ void setDirectives(Directives *directives); -CONFIG += qlalr
+ Directives *directives() const; +#CONFIG += qlalr
+ QLALRSOURCES = $$PWD/qmljs.g
MemoryPool *pool(); -QMAKE_QLALRFLAGS = --no-debug --qt
+#QMAKE_QLALRFLAGS = --no-debug --qt
inline QStringRef midRef(int position, int size) { return _code.midRef(position, size); } OTHER_FILES += $$QLALRSOURCES
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
index 9698e9d..036be75 100644
--- a/src/libs/qmljs/parser/qmljslexer.cpp
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
@@ -345,7 +345,7 @@ static inline bool isIdentifierStart(QChar ch)
// fast path for ascii
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
- ch == '$' || ch == '_')
+ ch == QLatin1Char('$') || ch == QLatin1Char('_'))
return true;
switch (ch.category()) { # make sure we install the headers generated by qlalr
@@ -368,7 +368,7 @@ static bool isIdentifierPart(QChar ch) -private_headers.CONFIG += no_check_exist
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || +#private_headers.CONFIG += no_check_exist
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
(ch.unicode() >= '0' && ch.unicode() <= '9') ||
- ch == '$' || ch == '_' ||
+ ch == QLatin1Char('$') || ch == QLatin1Char('_') ||
ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
return true;
diff --git a/src/libs/qmljs/parser/qmljsparser.cpp b/src/libs/qmljs/parser/qmljsparser.cpp
index 6e61637..e016b91 100644
--- a/src/libs/qmljs/parser/qmljsparser.cpp
+++ b/src/libs/qmljs/parser/qmljsparser.cpp
@@ -157,7 +157,20 @@ bool Parser::parse(int startToken)
token_buffer[0].token = startToken;
first_token = &token_buffer[0];
- last_token = &token_buffer[1];
+ if (startToken == T_FEED_JS_PROGRAM) {
+ Directives ignoreDirectives;
+ Directives *directives = driver->directives();
+ if (!directives)
+ directives = &ignoreDirectives;
+ lexer->scanDirectives(directives);
+ token_buffer[1].token = lexer->tokenKind();
+ token_buffer[1].dval = lexer->tokenValue();
+ token_buffer[1].loc = location(lexer);
+ token_buffer[1].spell = lexer->tokenSpell();
+ last_token = &token_buffer[2];
+ } else {
+ last_token = &token_buffer[1];
+ }
tos = -1;
program = 0;

View File

@@ -3,30 +3,29 @@ HEADERS += \
$$PWD/qmljsastfwd_p.h \ $$PWD/qmljsastfwd_p.h \
$$PWD/qmljsastvisitor_p.h \ $$PWD/qmljsastvisitor_p.h \
$$PWD/qmljsengine_p.h \ $$PWD/qmljsengine_p.h \
$$PWD/qmljsgrammar_p.h \
$$PWD/qmljslexer_p.h \ $$PWD/qmljslexer_p.h \
$$PWD/qmljsmemorypool_p.h \
$$PWD/qmljsparser_p.h \
$$PWD/qmljsglobal_p.h \ $$PWD/qmljsglobal_p.h \
$$PWD/qmljssourcelocation_p.h \
$$PWD/qmljsmemorypool_p.h \
$$PWD/qmldirparser_p.h \ $$PWD/qmldirparser_p.h \
$$PWD/qmlerror.h \ $$PWD/qmljsgrammar_p.h \
$$PWD/qmljsparser_p.h \
$$PWD/qmljskeywords_p.h $$PWD/qmljskeywords_p.h
SOURCES += \ SOURCES += \
$$PWD/qmljsast.cpp \ $$PWD/qmljsast.cpp \
$$PWD/qmljsastvisitor.cpp \ $$PWD/qmljsastvisitor.cpp \
$$PWD/qmljsengine_p.cpp \ $$PWD/qmljsengine_p.cpp \
$$PWD/qmljsgrammar.cpp \
$$PWD/qmljslexer.cpp \ $$PWD/qmljslexer.cpp \
$$PWD/qmljsparser.cpp \
$$PWD/qmldirparser.cpp \ $$PWD/qmldirparser.cpp \
$$PWD/qmlerror.cpp $$PWD/qmljsgrammar.cpp \
$$PWD/qmljsparser.cpp \
#CONFIG += qlalr #CONFIG += qlalr
QLALRSOURCES = $$PWD/qmljs.g QLALRSOURCES = $$PWD/qmljs.g
#QMAKE_QLALRFLAGS = --no-debug --qt #QMAKE_QLALRFLAGS = --no-debug --qt
DISTFILES += $$QLALRSOURCES OTHER_FILES += $$QLALRSOURCES
# make sure we install the headers generated by qlalr # make sure we install the headers generated by qlalr
#private_headers.CONFIG += no_check_exist #private_headers.CONFIG += no_check_exist

View File

@@ -24,11 +24,10 @@
****************************************************************************/ ****************************************************************************/
#include "qmldirparser_p.h" #include "qmldirparser_p.h"
#include "qmlerror.h"
#include <QtCore/QtDebug> #include <QtCore/QtDebug>
QT_BEGIN_NAMESPACE QT_QML_BEGIN_NAMESPACE
static int parseInt(const QStringRef &str, bool *ok) static int parseInt(const QStringRef &str, bool *ok)
{ {
@@ -60,12 +59,18 @@ static bool parseVersion(const QString &str, int *major, int *minor)
return false; return false;
} }
QmlDirParser::QmlDirParser() : _designerSupported(false) void QmlDirParser::clear()
{
}
QmlDirParser::~QmlDirParser()
{ {
_errors.clear();
_typeNamespace.clear();
_components.clear();
_dependencies.clear();
_imports.clear();
_scripts.clear();
_plugins.clear();
_designerSupported = false;
_typeInfos.clear();
_className.clear();
} }
inline static void scanSpace(const QChar *&ch) { inline static void scanSpace(const QChar *&ch) {
@@ -88,13 +93,6 @@ inline static void scanWord(const QChar *&ch) {
*/ */
bool QmlDirParser::parse(const QString &source) bool QmlDirParser::parse(const QString &source)
{ {
_errors.clear();
_plugins.clear();
_components.clear();
_scripts.clear();
_designerSupported = false;
_className.clear();
quint16 lineNumber = 0; quint16 lineNumber = 0;
bool firstLine = true; bool firstLine = true;
@@ -193,7 +191,7 @@ bool QmlDirParser::parse(const QString &source)
} }
Component entry(sections[1], sections[2], -1, -1); Component entry(sections[1], sections[2], -1, -1);
entry.internal = true; entry.internal = true;
_components.insertMulti(entry.typeName, entry); _components.insert(entry.typeName, entry);
} else if (sections[0] == QLatin1String("singleton")) { } else if (sections[0] == QLatin1String("singleton")) {
if (sectionCount < 3 || sectionCount > 4) { if (sectionCount < 3 || sectionCount > 4) {
reportError(lineNumber, 0, reportError(lineNumber, 0,
@@ -204,7 +202,7 @@ bool QmlDirParser::parse(const QString &source)
// singleton TestSingletonType TestSingletonType.qml // singleton TestSingletonType TestSingletonType.qml
Component entry(sections[1], sections[2], -1, -1); Component entry(sections[1], sections[2], -1, -1);
entry.singleton = true; entry.singleton = true;
_components.insertMulti(entry.typeName, entry); _components.insert(entry.typeName, entry);
} else { } else {
// handle qmldir module listing case where singleton is defined in the following pattern: // handle qmldir module listing case where singleton is defined in the following pattern:
// singleton TestSingletonType 2.0 TestSingletonType20.qml // singleton TestSingletonType 2.0 TestSingletonType20.qml
@@ -213,7 +211,7 @@ bool QmlDirParser::parse(const QString &source)
const QString &fileName = sections[3]; const QString &fileName = sections[3];
Component entry(sections[1], fileName, major, minor); Component entry(sections[1], fileName, major, minor);
entry.singleton = true; entry.singleton = true;
_components.insertMulti(entry.typeName, entry); _components.insert(entry.typeName, entry);
} else { } else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2])); reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2]));
} }
@@ -249,10 +247,17 @@ bool QmlDirParser::parse(const QString &source)
} else { } else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2])); reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[2]));
} }
} else if (sections[0] == QLatin1String("import")) {
if (sectionCount != 2) {
reportError(lineNumber, 0,
QStringLiteral("import requires 2 arguments, but %1 were provided").arg(sectionCount - 1));
continue;
}
_imports << sections[1];
} else if (sectionCount == 2) { } else if (sectionCount == 2) {
// No version specified (should only be used for relative qmldir files) // No version specified (should only be used for relative qmldir files)
const Component entry(sections[0], sections[1], -1, -1); const Component entry(sections[0], sections[1], -1, -1);
_components.insertMulti(entry.typeName, entry); _components.insert(entry.typeName, entry);
} else if (sectionCount == 3) { } else if (sectionCount == 3) {
int major, minor; int major, minor;
if (parseVersion(sections[1], &major, &minor)) { if (parseVersion(sections[1], &major, &minor)) {
@@ -264,7 +269,7 @@ bool QmlDirParser::parse(const QString &source)
_scripts.append(entry); _scripts.append(entry);
} else { } else {
const Component entry(sections[0], fileName, major, minor); const Component entry(sections[0], fileName, major, minor);
_components.insertMulti(entry.typeName, entry); _components.insert(entry.typeName, entry);
} }
} else { } else {
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[1])); reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").arg(sections[1]));
@@ -297,27 +302,20 @@ bool QmlDirParser::hasError() const
return false; return false;
} }
void QmlDirParser::setError(const QmlError &e) void QmlDirParser::setError(const QmlJS::DiagnosticMessage &e)
{ {
_errors.clear(); _errors.clear();
reportError(e.line(), e.column(), e.description()); reportError(e.loc.startLine, e.loc.startColumn, e.message);
} }
QList<QmlError> QmlDirParser::errors(const QString &uri) const QList<QmlJS::DiagnosticMessage> QmlDirParser::errors(const QString &uri) const
{ {
QUrl url(uri); QList<QmlJS::DiagnosticMessage> errors;
QList<QmlError> errors;
const int numErrors = _errors.size(); const int numErrors = _errors.size();
errors.reserve(numErrors); errors.reserve(numErrors);
for (int i = 0; i < numErrors; ++i) { for (int i = 0; i < numErrors; ++i) {
const QmlJS::DiagnosticMessage &msg = _errors.at(i); QmlJS::DiagnosticMessage e = _errors.at(i);
QmlError e; e.message.replace(QLatin1String("$$URI$$"), uri);
QString description = msg.message;
description.replace(QLatin1String("$$URI$$"), uri);
e.setDescription(description);
e.setUrl(url);
e.setLine(msg.loc.startLine);
e.setColumn(msg.loc.startColumn);
errors << e; errors << e;
} }
return errors; return errors;
@@ -338,7 +336,7 @@ QList<QmlDirParser::Plugin> QmlDirParser::plugins() const
return _plugins; return _plugins;
} }
QHash<QString, QmlDirParser::Component> QmlDirParser::components() const QMultiHash<QString, QmlDirParser::Component> QmlDirParser::components() const
{ {
return _components; return _components;
} }
@@ -348,17 +346,20 @@ QHash<QString, QmlDirParser::Component> QmlDirParser::dependencies() const
return _dependencies; return _dependencies;
} }
QStringList QmlDirParser::imports() const
{
return _imports;
}
QList<QmlDirParser::Script> QmlDirParser::scripts() const QList<QmlDirParser::Script> QmlDirParser::scripts() const
{ {
return _scripts; return _scripts;
} }
#ifdef QT_CREATOR
QList<QmlDirParser::TypeInfo> QmlDirParser::typeInfos() const QList<QmlDirParser::TypeInfo> QmlDirParser::typeInfos() const
{ {
return _typeInfos; return _typeInfos;
} }
#endif
bool QmlDirParser::designerSupported() const bool QmlDirParser::designerSupported() const
{ {
@@ -384,4 +385,4 @@ QDebug &operator<< (QDebug &debug, const QmlDirParser::Script &script)
return debug << qPrintable(output); return debug << qPrintable(output);
} }
QT_END_NAMESPACE QT_QML_END_NAMESPACE

View File

@@ -39,34 +39,44 @@
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtCore/QHash> #include <QtCore/QHash>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include "qmljsengine_p.h" #include "qmljs/parser/qmljsglobal_p.h"
#include "qmljsglobal_p.h" #include "qmljs/parser/qmljsengine_p.h"
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
QT_BEGIN_NAMESPACE QT_QML_BEGIN_NAMESPACE
class QmlError;
class QmlEngine; class QmlEngine;
class QML_PARSER_EXPORT QmlDirParser class QML_PARSER_EXPORT QmlDirParser
{ {
public: public:
QmlDirParser(); void clear();
~QmlDirParser();
bool parse(const QString &source); bool parse(const QString &source);
bool hasError() const; bool hasError() const;
void setError(const QmlError &); void setError(const QmlJS::DiagnosticMessage &);
QList<QmlError> errors(const QString &uri) const; QList<QmlJS::DiagnosticMessage> errors(const QString &uri) const;
QString typeNamespace() const; QString typeNamespace() const;
void setTypeNamespace(const QString &s); void setTypeNamespace(const QString &s);
static void checkNonRelative(const char *item, const QString &typeName, const QString &fileName)
{
if (fileName.startsWith(QLatin1Char('/'))) {
qWarning() << item << typeName
<< "is specified with non-relative URL" << fileName << "in a qmldir file."
<< "URLs in qmldir files should be relative to the qmldir file's directory.";
}
}
struct Plugin struct Plugin
{ {
Plugin() {} Plugin() = default;
Plugin(const QString &name, const QString &path) Plugin(const QString &name, const QString &path)
: name(name), path(path) {} : name(name), path(path)
{
checkNonRelative("Plugin", name, path);
}
QString name; QString name;
QString path; QString path;
@@ -74,11 +84,14 @@ public:
struct Component struct Component
{ {
Component() {} Component() = default;
Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion) Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
: typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion), : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
internal(false), singleton(false) {} internal(false), singleton(false)
{
checkNonRelative("Component", typeName, fileName);
}
QString typeName; QString typeName;
QString fileName; QString fileName;
@@ -90,10 +103,13 @@ public:
struct Script struct Script
{ {
Script() {} Script() = default;
Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
: nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion)
{
checkNonRelative("Script", nameSpace, fileName);
}
QString nameSpace; QString nameSpace;
QString fileName; QString fileName;
@@ -101,16 +117,16 @@ public:
int minorVersion = 0; int minorVersion = 0;
}; };
QHash<QString,Component> components() const; QMultiHash<QString,Component> components() const;
QHash<QString,Component> dependencies() const; QHash<QString,Component> dependencies() const;
QStringList imports() const;
QList<Script> scripts() const; QList<Script> scripts() const;
QList<Plugin> plugins() const; QList<Plugin> plugins() const;
bool designerSupported() const; bool designerSupported() const;
#ifdef QT_CREATOR
struct TypeInfo struct TypeInfo
{ {
TypeInfo() {} TypeInfo() = default;
TypeInfo(const QString &fileName) TypeInfo(const QString &fileName)
: fileName(fileName) {} : fileName(fileName) {}
@@ -118,7 +134,6 @@ public:
}; };
QList<TypeInfo> typeInfos() const; QList<TypeInfo> typeInfos() const;
#endif
QString className() const; QString className() const;
@@ -129,23 +144,22 @@ private:
private: private:
QList<QmlJS::DiagnosticMessage> _errors; QList<QmlJS::DiagnosticMessage> _errors;
QString _typeNamespace; QString _typeNamespace;
QHash<QString,Component> _components; // multi hash QMultiHash<QString,Component> _components;
QHash<QString,Component> _dependencies; QHash<QString,Component> _dependencies;
QStringList _imports;
QList<Script> _scripts; QList<Script> _scripts;
QList<Plugin> _plugins; QList<Plugin> _plugins;
bool _designerSupported; bool _designerSupported = false;
#ifdef QT_CREATOR
QList<TypeInfo> _typeInfos; QList<TypeInfo> _typeInfos;
#endif
QString _className; QString _className;
}; };
typedef QHash<QString,QmlDirParser::Component> QmlDirComponents; using QmlDirComponents = QMultiHash<QString,QmlDirParser::Component>;
typedef QList<QmlDirParser::Script> QmlDirScripts; using QmlDirScripts = QList<QmlDirParser::Script>;
typedef QList<QmlDirParser::Plugin> QmlDirPlugins; using QmlDirPlugins = QList<QmlDirParser::Plugin>;
QDebug &operator<< (QDebug &, const QmlDirParser::Component &); QDebug &operator<< (QDebug &, const QmlDirParser::Component &);
QDebug &operator<< (QDebug &, const QmlDirParser::Script &); QDebug &operator<< (QDebug &, const QmlDirParser::Script &);
QT_END_NAMESPACE QT_QML_END_NAMESPACE

View File

@@ -1,351 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "qmlerror.h"
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qvector.h>
#include <QtCore/qpointer.h>
QT_BEGIN_NAMESPACE
/*!
\class QmlError
\since 5.0
\inmodule QtQml
\brief The QmlError class encapsulates a QML error.
QmlError includes a textual description of the error, as well
as location information (the file, line, and column). The toString()
method creates a single-line, human-readable string containing all of
this information, for example:
\code
file:///home/user/test.qml:7:8: Invalid property assignment: double expected
\endcode
You can use qDebug(), qInfo(), or qWarning() to output errors to the console.
This method will attempt to open the file indicated by the error
and include additional contextual information.
\code
file:///home/user/test.qml:7:8: Invalid property assignment: double expected
y: "hello"
^
\endcode
Note that the \l {Qt Quick 1} version is named QDeclarativeError
\sa QQuickView::errors(), QmlComponent::errors()
*/
static quint16 qmlSourceCoordinate(int n)
{
return (n > 0 && n <= static_cast<int>(USHRT_MAX)) ? static_cast<quint16>(n) : 0;
}
class QmlErrorPrivate
{
public:
QmlErrorPrivate();
QUrl url;
QString description;
quint16 line;
quint16 column;
QtMsgType messageType;
QPointer<QObject> object;
};
QmlErrorPrivate::QmlErrorPrivate()
: line(0), column(0), messageType(QtMsgType::QtWarningMsg), object()
{
}
/*!
Creates an empty error object.
*/
QmlError::QmlError()
: d(nullptr)
{
}
/*!
Creates a copy of \a other.
*/
QmlError::QmlError(const QmlError &other)
: d(nullptr)
{
*this = other;
}
/*!
Assigns \a other to this error object.
*/
QmlError &QmlError::operator=(const QmlError &other)
{
if (!other.d) {
delete d;
d = nullptr;
} else {
if (!d)
d = new QmlErrorPrivate;
d->url = other.d->url;
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
d->object = other.d->object;
d->messageType = other.d->messageType;
}
return *this;
}
/*!
\internal
*/
QmlError::~QmlError()
{
delete d; d = nullptr;
}
/*!
Returns true if this error is valid, otherwise false.
*/
bool QmlError::isValid() const
{
return d != nullptr;
}
/*!
Returns the url for the file that caused this error.
*/
QUrl QmlError::url() const
{
if (d)
return d->url;
return QUrl();
}
/*!
Sets the \a url for the file that caused this error.
*/
void QmlError::setUrl(const QUrl &url)
{
if (!d)
d = new QmlErrorPrivate;
d->url = url;
}
/*!
Returns the error description.
*/
QString QmlError::description() const
{
if (d)
return d->description;
return QString();
}
/*!
Sets the error \a description.
*/
void QmlError::setDescription(const QString &description)
{
if (!d)
d = new QmlErrorPrivate;
d->description = description;
}
/*!
Returns the error line number.
*/
int QmlError::line() const
{
if (d)
return qmlSourceCoordinate(d->line);
return -1;
}
/*!
Sets the error \a line number.
*/
void QmlError::setLine(int line)
{
if (!d)
d = new QmlErrorPrivate;
d->line = qmlSourceCoordinate(line);
}
/*!
Returns the error column number.
*/
int QmlError::column() const
{
if (d)
return qmlSourceCoordinate(d->column);
return -1;
}
/*!
Sets the error \a column number.
*/
void QmlError::setColumn(int column)
{
if (!d)
d = new QmlErrorPrivate;
d->column = qmlSourceCoordinate(column);
}
/*!
Returns the nearest object where this error occurred.
Exceptions in bound property expressions set this to the object
to which the property belongs. It will be 0 for all
other exceptions.
*/
QObject *QmlError::object() const
{
if (d)
return d->object;
return nullptr;
}
/*!
Sets the nearest \a object where this error occurred.
*/
void QmlError::setObject(QObject *object)
{
if (!d)
d = new QmlErrorPrivate;
d->object = object;
}
/*!
\since 5.9
Returns the message type.
*/
QtMsgType QmlError::messageType() const
{
if (d)
return d->messageType;
return QtMsgType::QtWarningMsg;
}
/*!
\since 5.9
Sets the \a messageType for this message. The message type determines which
QDebug handlers are responsible for receiving the message.
*/
void QmlError::setMessageType(QtMsgType messageType)
{
if (!d)
d = new QmlErrorPrivate;
d->messageType = messageType;
}
/*!
Returns the error as a human readable string.
*/
QString QmlError::toString() const
{
QString rv;
QUrl u(url());
int l(line());
if (u.isEmpty() || (u.isLocalFile() && u.path().isEmpty()))
rv += QLatin1String("<Unknown File>");
else
rv += u.toString();
if (l != -1) {
rv += QLatin1Char(':') + QString::number(l);
int c(column());
if (c != -1)
rv += QLatin1Char(':') + QString::number(c);
}
rv += QLatin1String(": ") + description();
return rv;
}
/*!
\relates QmlError
\fn QDebug operator<<(QDebug debug, const QmlError &error)
Outputs a human readable version of \a error to \a debug.
*/
QDebug operator<<(QDebug debug, const QmlError &error)
{
debug << qPrintable(error.toString());
QUrl url = error.url();
if (error.line() > 0 && url.scheme() == QLatin1String("file")) {
QString file = url.toLocalFile();
QFile f(file);
if (f.open(QIODevice::ReadOnly)) {
QByteArray data = f.readAll();
QTextStream stream(data, QIODevice::ReadOnly);
#if QT_CONFIG(textcodec)
stream.setCodec("UTF-8");
#endif
const QString code = stream.readAll();
const auto lines = code.splitRef(QLatin1Char('\n'));
if (lines.count() >= error.line()) {
const QStringRef &line = lines.at(error.line() - 1);
debug << "\n " << line.toLocal8Bit().constData();
if (error.column() > 0) {
int column = qMax(0, error.column() - 1);
column = qMin(column, line.length());
QByteArray ind;
ind.reserve(column);
for (int i = 0; i < column; ++i) {
const QChar ch = line.at(i);
if (ch.isSpace())
ind.append(ch.unicode());
else
ind.append(' ');
}
ind.append('^');
debug << "\n " << ind.constData();
}
}
}
}
return debug;
}
QT_END_NAMESPACE

View File

@@ -73,13 +73,14 @@
%token T_VAR "var" T_VOID "void" T_WHILE "while" %token T_VAR "var" T_VOID "void" T_WHILE "while"
%token T_WITH "with" T_XOR "^" T_XOR_EQ "^=" %token T_WITH "with" T_XOR "^" T_XOR_EQ "^="
%token T_NULL "null" T_TRUE "true" T_FALSE "false" %token T_NULL "null" T_TRUE "true" T_FALSE "false"
%token T_CONST "const" T_LET "let" %token T_CONST "const" T_LET "let" T_AT "@"
%token T_DEBUGGER "debugger" %token T_DEBUGGER "debugger"
%token T_RESERVED_WORD "reserved word" %token T_RESERVED_WORD "reserved word"
%token T_MULTILINE_STRING_LITERAL "multiline string literal" %token T_MULTILINE_STRING_LITERAL "multiline string literal"
%token T_COMMENT "comment" %token T_COMMENT "comment"
%token T_COMPATIBILITY_SEMICOLON %token T_COMPATIBILITY_SEMICOLON
%token T_ARROW "=>" %token T_ARROW "=>"
%token T_QUESTION_QUESTION "??"
%token T_ENUM "enum" %token T_ENUM "enum"
%token T_ELLIPSIS "..." %token T_ELLIPSIS "..."
%token T_YIELD "yield" %token T_YIELD "yield"
@@ -90,6 +91,7 @@
%token T_EXPORT "export" %token T_EXPORT "export"
%token T_FROM "from" %token T_FROM "from"
%token T_REQUIRED "required" %token T_REQUIRED "required"
%token T_COMPONENT "component"
--- template strings --- template strings
%token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)" %token T_NO_SUBSTITUTION_TEMPLATE"(no subst template)"
@@ -122,9 +124,10 @@
%token T_FOR_LOOKAHEAD_OK "(for lookahead ok)" %token T_FOR_LOOKAHEAD_OK "(for lookahead ok)"
--%left T_PLUS T_MINUS --%left T_PLUS T_MINUS
%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_OF T_STATIC T_FROM T_AS T_REQUIRED %nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET T_OF T_STATIC T_FROM T_AS T_REQUIRED T_COMPONENT
%nonassoc REDUCE_HERE %nonassoc REDUCE_HERE
%right T_THEN T_ELSE %right T_THEN T_ELSE
%right T_WITHOUTAS T_AS
%start TopLevel %start TopLevel
@@ -167,10 +170,10 @@
** **
****************************************************************************/ ****************************************************************************/
#include "qmljsengine_p.h" #include "qmljs/parser/qmljsengine_p.h"
#include "qmljslexer_p.h" #include "qmljs/parser/qmljslexer_p.h"
#include "qmljsast_p.h" #include "qmljs/parser/qmljsast_p.h"
#include "qmljsmemorypool_p.h" #include "qmljs/parser/qmljsmemorypool_p.h"
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
@@ -245,10 +248,11 @@
#ifndef QMLJSPARSER_P_H #ifndef QMLJSPARSER_P_H
#define QMLJSPARSER_P_H #define QMLJSPARSER_P_H
#include "qmljsglobal_p.h" #include "qmljs/parser/qmljsglobal_p.h"
#include "qmljsgrammar_p.h" #include "qmljs/parser/qmljsgrammar_p.h"
#include "qmljsast_p.h" #include "qmljs/parser/qmljsast_p.h"
#include "qmljsengine_p.h" #include "qmljs/parser/qmljsengine_p.h"
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
@@ -322,6 +326,8 @@ public:
AST::UiQualifiedId *UiQualifiedId; AST::UiQualifiedId *UiQualifiedId;
AST::UiEnumMemberList *UiEnumMemberList; AST::UiEnumMemberList *UiEnumMemberList;
AST::UiVersionSpecifier *UiVersionSpecifier; AST::UiVersionSpecifier *UiVersionSpecifier;
AST::UiAnnotation *UiAnnotation;
AST::UiAnnotationList *UiAnnotationList;
}; };
public: public:
@@ -403,7 +409,7 @@ protected:
inline QStringRef &rawStringRef(int index) inline QStringRef &rawStringRef(int index)
{ return rawString_stack [tos + index - 1]; } { return rawString_stack [tos + index - 1]; }
inline AST::SourceLocation &loc(int index) inline SourceLocation &loc(int index)
{ return location_stack [tos + index - 1]; } { return location_stack [tos + index - 1]; }
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
@@ -411,20 +417,20 @@ protected:
void pushToken(int token); void pushToken(int token);
int lookaheadToken(Lexer *lexer); int lookaheadToken(Lexer *lexer);
static DiagnosticMessage compileError(const AST::SourceLocation &location, static DiagnosticMessage compileError(const SourceLocation &location,
const QString &message, Severity::Enum kind = Severity::Error) const QString &message, QtMsgType kind = QtCriticalMsg)
{ {
DiagnosticMessage error; DiagnosticMessage error;
error.loc = location; error.loc = location;
error.message = message; error.message = message;
error.kind = kind; error.kind = DiagnosticMessage::qtMsgTypeToKind(kind);
return error; return error;
} }
void syntaxError(const AST::SourceLocation &location, const char *message) { void syntaxError(const SourceLocation &location, const char *message) {
diagnostic_messages.append(compileError(location, QLatin1String(message))); diagnostic_messages.append(compileError(location, QLatin1String(message)));
} }
void syntaxError(const AST::SourceLocation &location, const QString &message) { void syntaxError(const SourceLocation &location, const QString &message) {
diagnostic_messages.append(compileError(location, message)); diagnostic_messages.append(compileError(location, message));
} }
@@ -437,7 +443,7 @@ protected:
int stack_size = 0; int stack_size = 0;
Value *sym_stack = nullptr; Value *sym_stack = nullptr;
int *state_stack = nullptr; int *state_stack = nullptr;
AST::SourceLocation *location_stack = nullptr; SourceLocation *location_stack = nullptr;
QVector<QStringRef> string_stack; QVector<QStringRef> string_stack;
QVector<QStringRef> rawString_stack; QVector<QStringRef> rawString_stack;
@@ -449,7 +455,7 @@ protected:
struct SavedToken { struct SavedToken {
int token; int token;
double dval; double dval;
AST::SourceLocation loc; SourceLocation loc;
QStringRef spell; QStringRef spell;
QStringRef raw; QStringRef raw;
}; };
@@ -458,8 +464,8 @@ protected:
double yylval = 0.; double yylval = 0.;
QStringRef yytokenspell; QStringRef yytokenspell;
QStringRef yytokenraw; QStringRef yytokenraw;
AST::SourceLocation yylloc; SourceLocation yylloc;
AST::SourceLocation yyprevlloc; SourceLocation yyprevlloc;
SavedToken token_buffer[TOKEN_BUFFER_SIZE]; SavedToken token_buffer[TOKEN_BUFFER_SIZE];
SavedToken *first_token = nullptr; SavedToken *first_token = nullptr;
@@ -472,7 +478,7 @@ protected:
CE_ParenthesizedExpression, CE_ParenthesizedExpression,
CE_FormalParameterList CE_FormalParameterList
}; };
AST::SourceLocation coverExpressionErrorLocation; SourceLocation coverExpressionErrorLocation;
CoverExpressionType coverExpressionType = CE_Invalid; CoverExpressionType coverExpressionType = CE_Invalid;
QList<DiagnosticMessage> diagnostic_messages; QList<DiagnosticMessage> diagnostic_messages;
@@ -517,7 +523,7 @@ void Parser::reallocateStack()
sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); location_stack = reinterpret_cast<SourceLocation*> (realloc(location_stack, stack_size * sizeof(SourceLocation)));
string_stack.resize(stack_size); string_stack.resize(stack_size);
rawString_stack.resize(stack_size); rawString_stack.resize(stack_size);
} }
@@ -537,9 +543,9 @@ Parser::~Parser()
} }
} }
static inline AST::SourceLocation location(Lexer *lexer) static inline SourceLocation location(Lexer *lexer)
{ {
AST::SourceLocation loc; SourceLocation loc;
loc.offset = lexer->tokenOffset(); loc.offset = lexer->tokenOffset();
loc.length = lexer->tokenLength(); loc.length = lexer->tokenLength();
loc.startLine = lexer->tokenStartLine(); loc.startLine = lexer->tokenStartLine();
@@ -550,7 +556,7 @@ static inline AST::SourceLocation location(Lexer *lexer)
AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr) AST::UiQualifiedId *Parser::reparseAsQualifiedId(AST::ExpressionNode *expr)
{ {
QVarLengthArray<QStringRef, 4> nameIds; QVarLengthArray<QStringRef, 4> nameIds;
QVarLengthArray<AST::SourceLocation, 4> locations; QVarLengthArray<SourceLocation, 4> locations;
AST::ExpressionNode *it = expr; AST::ExpressionNode *it = expr;
while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) { while (AST::FieldMemberExpression *m = AST::cast<AST::FieldMemberExpression *>(it)) {
@@ -734,7 +740,7 @@ TopLevel: T_FEED_JS_EXPRESSION Expression;
} break; } break;
./ ./
TopLevel: T_FEED_UI_OBJECT_MEMBER UiObjectMember; TopLevel: T_FEED_UI_OBJECT_MEMBER UiAnnotatedObjectMember;
/. /.
case $rule_number: { case $rule_number: {
sym(1).Node = sym(2).Node; sym(1).Node = sym(2).Node;
@@ -849,13 +855,7 @@ UiVersionSpecifier: T_VERSION_NUMBER;
UiImport: UiImportHead UiVersionSpecifier Semicolon; UiImport: UiImportHead UiVersionSpecifier Semicolon;
/. /.
case $rule_number: { case $rule_number: {
auto versionToken = loc(2); sym(1).UiImport->version = sym(2).UiVersionSpecifier;
auto version = sym(2).UiVersionSpecifier;
sym(1).UiImport->version = version;
if (version->minorToken.isValid()) {
versionToken.length += version->minorToken.length + (version->minorToken.offset - versionToken.offset - versionToken.length);
}
sym(1).UiImport->versionToken = versionToken;
sym(1).UiImport->semicolonToken = loc(3); sym(1).UiImport->semicolonToken = loc(3);
} break; } break;
./ ./
@@ -863,13 +863,7 @@ UiImport: UiImportHead UiVersionSpecifier Semicolon;
UiImport: UiImportHead UiVersionSpecifier T_AS QmlIdentifier Semicolon; UiImport: UiImportHead UiVersionSpecifier T_AS QmlIdentifier Semicolon;
/. /.
case $rule_number: { case $rule_number: {
auto versionToken = loc(2); sym(1).UiImport->version = sym(2).UiVersionSpecifier;
auto version = sym(2).UiVersionSpecifier;
sym(1).UiImport->version = version;
if (version->minorToken.isValid()) {
versionToken.length += version->minorToken.length + (version->minorToken.offset - versionToken.offset - versionToken.length);
}
sym(1).UiImport->versionToken = versionToken;
sym(1).UiImport->asToken = loc(3); sym(1).UiImport->asToken = loc(3);
sym(1).UiImport->importIdToken = loc(4); sym(1).UiImport->importIdToken = loc(4);
sym(1).UiImport->importId = stringRef(4); sym(1).UiImport->importId = stringRef(4);
@@ -920,21 +914,92 @@ Empty: ;
} break; } break;
./ ./
UiRootMember: UiObjectDefinition; UiRootMember: UiAnnotatedObject;
/. /.
case $rule_number: { case $rule_number: {
sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break; } break;
./ ./
UiObjectMemberList: UiObjectMember; UiSimpleQualifiedId: T_IDENTIFIER;
/.
case $rule_number: {
AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1));
node->identifierToken = loc(1);
sym(1).Node = node;
} break;
./
UiSimpleQualifiedId: UiSimpleQualifiedId T_DOT T_IDENTIFIER;
/.
case $rule_number: {
AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3));
node->dotToken = loc(2);
node->identifierToken = loc(3);
sym(1).Node = node;
} break;
./
UiAnnotationObjectDefinition: UiSimpleQualifiedId UiObjectInitializer;
/.
case $rule_number: {
if (AST::UiQualifiedId *qualifiedId = reparseAsQualifiedId(sym(1).Expression)) {
sym(1).UiQualifiedId = qualifiedId;
} else {
sym(1).UiQualifiedId = 0;
diagnostic_messages.append(compileError(loc(1),
QLatin1String("Expected a qualified name id")));
return false;
}
AST::UiAnnotation *node = new (pool) AST::UiAnnotation(sym(1).UiQualifiedId, sym(2).UiObjectInitializer);
sym(1).Node = node;
} break;
./
UiAnnotation: T_AT UiAnnotationObjectDefinition;
/.
case $rule_number: {
sym(1).Node = sym(2).Node;
} break;
./
UiAnnotationList: UiAnnotation;
/.
case $rule_number: {
sym(1).Node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotation);
} break;
./
UiAnnotationList: UiAnnotationList UiAnnotation;
/.
case $rule_number: {
AST::UiAnnotationList *node = new (pool) AST::UiAnnotationList(sym(1).UiAnnotationList, sym(2).UiAnnotation);
sym(1).Node = node;
} break;
./
UiAnnotatedObject: UiAnnotationList UiObjectDefinition;
/.
case $rule_number: {
AST::UiObjectDefinition *node = sym(2).UiObjectDefinition;
node->annotations = sym(1).UiAnnotationList->finish();
sym(1).Node = node;
} break;
./
UiAnnotatedObject: UiObjectDefinition;
UiObjectMemberList: UiAnnotatedObjectMember;
/. /.
case $rule_number: { case $rule_number: {
sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember); sym(1).Node = new (pool) AST::UiObjectMemberList(sym(1).UiObjectMember);
} break; } break;
./ ./
UiObjectMemberList: UiObjectMemberList UiObjectMember; UiObjectMemberList: UiObjectMemberList UiAnnotatedObjectMember;
/. /.
case $rule_number: { case $rule_number: {
AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember); AST::UiObjectMemberList *node = new (pool) AST:: UiObjectMemberList(sym(1).UiObjectMemberList, sym(2).UiObjectMember);
@@ -986,6 +1051,17 @@ UiObjectDefinition: UiQualifiedId UiObjectInitializer;
} break; } break;
./ ./
UiAnnotatedObjectMember: UiAnnotationList UiObjectMember;
/.
case $rule_number: {
AST::UiObjectMember *node = sym(2).UiObjectMember;
node->annotations = sym(1).UiAnnotationList->finish();
sym(1).Node = sym(2).Node;
} break;
./
UiAnnotatedObjectMember: UiObjectMember;
UiObjectMember: UiObjectDefinition; UiObjectMember: UiObjectDefinition;
UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET; UiObjectMember: UiQualifiedId T_COLON ExpressionStatementLookahead T_LBRACKET UiArrayMemberList T_RBRACKET;
@@ -1021,15 +1097,27 @@ UiObjectMember: UiQualifiedId T_ON UiQualifiedId UiObjectInitializer;
./ ./
UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE; UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_RBRACE Semicolon;
/. case $rule_number: Q_FALLTHROUGH(); ./
UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE;
/. /.
case $rule_number: { case $rule_number: {
AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish()); AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish());
l->lbraceToken = loc(1); l->lbraceToken = loc(1);
l->rbraceToken = loc(4); l->rbraceToken = loc(4);
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l); AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l);
node->semicolonToken = loc(5);
sym(1).Node = node;
} break;
./
UiObjectLiteral: T_LBRACE ExpressionStatementLookahead UiPropertyDefinitionList T_COMMA T_RBRACE Semicolon;
/.
case $rule_number: {
AST::ObjectPattern *l = new (pool) AST::ObjectPattern(sym(3).PatternPropertyList->finish());
l->lbraceToken = loc(1);
l->rbraceToken = loc(5);
AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(l);
node->semicolonToken = loc(6);
sym(1).Node = node; sym(1).Node = node;
} break; } break;
./ ./
@@ -1242,12 +1330,49 @@ UiObjectMember: T_DEFAULT UiObjectMemberListPropertyNoInitialiser;
} break; } break;
./ ./
UiObjectMember: T_DEFAULT T_REQUIRED UiObjectMemberPropertyNoInitialiser;
/.
case $rule_number: {
AST::UiPublicMember *node = sym(3).UiPublicMember;
node->isDefaultMember = true;
node->defaultToken = loc(1);
node->isRequired = true;
node->requiredToken = loc(2);
sym(1).Node = node;
} break;
./
UiObjectMember: T_REQUIRED T_DEFAULT UiObjectMemberPropertyNoInitialiser;
/.
case $rule_number: {
AST::UiPublicMember *node = sym(3).UiPublicMember;
node->isDefaultMember = true;
node->defaultToken = loc(2);
node->isRequired = true;
node->requiredToken = loc(1);
sym(1).Node = node;
} break;
./
OptionalSemicolon: | Semicolon; OptionalSemicolon: | Semicolon;
/. /.
/* we need OptionalSemicolon because UiScriptStatement might already parse the last semicolon /* we need OptionalSemicolon because UiScriptStatement might already parse the last semicolon
and then we would miss a semicolon (see tests/auto/quick/qquickvisualdatamodel/data/objectlist.qml)*/ and then we would miss a semicolon (see tests/auto/quick/qquickvisualdatamodel/data/objectlist.qml)*/
./ ./
UiRequired: T_REQUIRED QmlIdentifier Semicolon;
/.
case $rule_number: {
AST::UiRequired *node = new (pool) AST::UiRequired(stringRef(2));
node->requiredToken = loc(1);
node->semicolonToken = loc(3);
sym(1).Node = node;
} break;
./
UiObjectMember: UiRequired;
UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser; UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser;
/. /.
case $rule_number: { case $rule_number: {
@@ -1258,7 +1383,6 @@ UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser;
} break; } break;
./ ./
UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon; UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
/. /.
case $rule_number: { case $rule_number: {
@@ -1393,7 +1517,7 @@ UiQualifiedId: MemberExpression;
case $rule_number: { case $rule_number: {
if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) {
diagnostic_messages.append(compileError(mem->lbracketToken, diagnostic_messages.append(compileError(mem->lbracketToken,
QLatin1String("Ignored annotation"), Severity::Warning)); QLatin1String("Ignored annotation"), QtWarningMsg));
sym(1).Expression = mem->base; sym(1).Expression = mem->base;
} }
@@ -1422,6 +1546,19 @@ UiObjectMember: T_ENUM T_IDENTIFIER T_LBRACE EnumMemberList T_RBRACE;
} }
./ ./
UiObjectMember: T_COMPONENT T_IDENTIFIER T_COLON UiObjectDefinition;
/.
case $rule_number: {
if (!stringRef(2).front().isUpper()) {
diagnostic_messages.append(compileError(loc(2),
QLatin1String("Type name must be upper case"), QtWarningMsg));
}
auto inlineComponent = new (pool) AST::UiInlineComponent(stringRef(2), sym(4).UiObjectDefinition);
inlineComponent->componentToken = loc(1);
sym(1).Node = inlineComponent;
} break;
./
EnumMemberList: T_IDENTIFIER; EnumMemberList: T_IDENTIFIER;
/. /.
case $rule_number: { case $rule_number: {
@@ -1464,29 +1601,31 @@ EnumMemberList: EnumMemberList T_COMMA T_IDENTIFIER T_EQ T_NUMERIC_LITERAL;
} }
./ ./
QmlIdentifier: T_IDENTIFIER; QmlIdentifier: T_IDENTIFIER
QmlIdentifier: T_PROPERTY; | T_PROPERTY
QmlIdentifier: T_SIGNAL; | T_SIGNAL
QmlIdentifier: T_READONLY; | T_READONLY
QmlIdentifier: T_ON; | T_ON
QmlIdentifier: T_GET; | T_GET
QmlIdentifier: T_SET; | T_SET
QmlIdentifier: T_FROM; | T_FROM
QmlIdentifier: T_OF; | T_OF
QmlIdentifier: T_REQUIRED; | T_REQUIRED
| T_COMPONENT;
JsIdentifier: T_IDENTIFIER; JsIdentifier: T_IDENTIFIER
JsIdentifier: T_PROPERTY; | T_PROPERTY
JsIdentifier: T_SIGNAL; | T_SIGNAL
JsIdentifier: T_READONLY; | T_READONLY
JsIdentifier: T_ON; | T_ON
JsIdentifier: T_GET; | T_GET
JsIdentifier: T_SET; | T_SET
JsIdentifier: T_FROM; | T_FROM
JsIdentifier: T_STATIC; | T_STATIC
JsIdentifier: T_OF; | T_OF
JsIdentifier: T_AS; | T_AS
JsIdentifier: T_REQUIRED; | T_REQUIRED
| T_COMPONENT;
IdentifierReference: JsIdentifier; IdentifierReference: JsIdentifier;
BindingIdentifier: IdentifierReference; BindingIdentifier: IdentifierReference;
@@ -2510,6 +2649,20 @@ RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression;
} break; } break;
./ ./
TypeAssertExpression_In: RelationalExpression_In T_AS Type;
/. case $rule_number: Q_FALLTHROUGH(); ./
TypeAssertExpression: RelationalExpression T_AS Type;
/.
case $rule_number: {
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::As, sym(3).Expression);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
./
RelationalExpression_In: TypeAssertExpression_In;
RelationalExpression: TypeAssertExpression;
EqualityExpression_In: RelationalExpression_In; EqualityExpression_In: RelationalExpression_In;
EqualityExpression: RelationalExpression; EqualityExpression: RelationalExpression;
@@ -2621,13 +2774,48 @@ LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In;
} break; } break;
./ ./
CoalesceExpression: LogicalORExpression;
CoalesceExpression_In: LogicalORExpression_In;
ConditionalExpression: LogicalORExpression; CoalesceExpression: CoalesceExpression T_QUESTION_QUESTION LogicalORExpression;
ConditionalExpression_In: LogicalORExpression_In;
ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression;
/. case $rule_number: Q_FALLTHROUGH(); ./ /. case $rule_number: Q_FALLTHROUGH(); ./
ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In; CoalesceExpression_In: CoalesceExpression_In T_QUESTION_QUESTION LogicalORExpression_In;
/.
case $rule_number: {
auto *lhs = sym(1).Expression;
auto *rhs = sym(3).Expression;
// Check if lhs or rhs contain || or &&
if (lhs->binaryExpressionCast() != nullptr) {
auto *binaryExpr = lhs->binaryExpressionCast();
if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) {
syntaxError(binaryExpr->operatorToken, "Left-hand side may not contain || or &&");
return false;
}
}
if (rhs->binaryExpressionCast() != nullptr) {
auto *binaryExpr = rhs->binaryExpressionCast();
if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) {
syntaxError(binaryExpr->operatorToken, "Right-hand side may not contain || or &&");
return false;
}
}
AST::BinaryExpression *node = new (pool) AST::BinaryExpression(lhs, QSOperator::Coalesce, rhs);
node->operatorToken = loc(2);
sym(1).Node = node;
} break;
./
ConditionalExpression: CoalesceExpression;
ConditionalExpression_In: CoalesceExpression_In;
ConditionalExpression: CoalesceExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression;
/. case $rule_number: Q_FALLTHROUGH(); ./
ConditionalExpression_In: CoalesceExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In;
/. /.
case $rule_number: { case $rule_number: {
AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression);
@@ -2653,7 +2841,7 @@ AssignmentExpression_In: LeftHandSideExpression T_EQ AssignmentExpression_In;
case $rule_number: { case $rule_number: {
// need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral
if (AST::Pattern *p = sym(1).Expression->patternCast()) { if (AST::Pattern *p = sym(1).Expression->patternCast()) {
AST::SourceLocation errorLoc; SourceLocation errorLoc;
QString errorMsg; QString errorMsg;
if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) {
syntaxError(errorLoc, errorMsg); syntaxError(errorLoc, errorMsg);
@@ -3319,7 +3507,7 @@ IterationStatement: T_FOR T_LPAREN LeftHandSideExpression InOrOf Expression_In T
case $rule_number: { case $rule_number: {
// need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral // need to convert the LHS to an AssignmentPattern if it was an Array/ObjectLiteral
if (AST::Pattern *p = sym(3).Expression->patternCast()) { if (AST::Pattern *p = sym(3).Expression->patternCast()) {
AST::SourceLocation errorLoc; SourceLocation errorLoc;
QString errorMsg; QString errorMsg;
if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) { if (!p->convertLiteralToAssignmentPattern(pool, &errorLoc, &errorMsg)) {
syntaxError(errorLoc, errorMsg); syntaxError(errorLoc, errorMsg);
@@ -4366,7 +4554,10 @@ ImportsList: ImportsList T_COMMA ImportSpecifier;
} break; } break;
./ ./
ImportSpecifier: ImportedBinding; -- When enconutering an IdentifierReference it can resolve to both ImportedBinding and IdentifierName
-- Using %right and %prec, we tell qlalr that it should not reduce immediately, but rather shift
-- so that we have a chance of actually parsing the correct rule if there is an "as" identifier
ImportSpecifier: ImportedBinding %prec T_WITHOUTAS;
/. /.
case $rule_number: { case $rule_number: {
auto importSpecifier = new (pool) AST::ImportSpecifier(stringRef(1)); auto importSpecifier = new (pool) AST::ImportSpecifier(stringRef(1));
@@ -4572,7 +4763,7 @@ ExportSpecifier: IdentifierName T_AS IdentifierName;
yylloc.length = 0; yylloc.length = 0;
//const QString msg = QCoreApplication::translate("QmlParser", "Missing `;'"); //const QString msg = QCoreApplication::translate("QmlParser", "Missing `;'");
//diagnostic_messages.append(compileError(yyloc, msg, Severity::Warning)); //diagnostic_messages.append(compileError(yyloc, msg, QtWarningMsg));
first_token = &token_buffer[0]; first_token = &token_buffer[0];
last_token = &token_buffer[1]; last_token = &token_buffer[1];

View File

@@ -153,7 +153,7 @@ UiObjectMember *UiObjectMember::uiObjectMemberCast()
return this; return this;
} }
void NestedExpression::accept0(Visitor *visitor) void NestedExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -171,7 +171,7 @@ ClassExpression *NestedExpression::asClassDefinition()
return expression->asClassDefinition(); return expression->asClassDefinition();
} }
void ThisExpression::accept0(Visitor *visitor) void ThisExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -179,7 +179,7 @@ void ThisExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void IdentifierExpression::accept0(Visitor *visitor) void IdentifierExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -187,7 +187,7 @@ void IdentifierExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NullExpression::accept0(Visitor *visitor) void NullExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -195,7 +195,7 @@ void NullExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TrueLiteral::accept0(Visitor *visitor) void TrueLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -203,7 +203,7 @@ void TrueLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void FalseLiteral::accept0(Visitor *visitor) void FalseLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -211,7 +211,7 @@ void FalseLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void SuperLiteral::accept0(Visitor *visitor) void SuperLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -220,7 +220,7 @@ void SuperLiteral::accept0(Visitor *visitor)
} }
void StringLiteral::accept0(Visitor *visitor) void StringLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -228,7 +228,7 @@ void StringLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TemplateLiteral::accept0(Visitor *visitor) void TemplateLiteral::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (TemplateLiteral *it = this; it && accepted; it = it->next) { for (TemplateLiteral *it = this; it && accepted; it = it->next) {
@@ -237,7 +237,7 @@ void TemplateLiteral::accept0(Visitor *visitor)
} }
} }
void NumericLiteral::accept0(Visitor *visitor) void NumericLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -245,7 +245,7 @@ void NumericLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void RegExpLiteral::accept0(Visitor *visitor) void RegExpLiteral::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -253,7 +253,7 @@ void RegExpLiteral::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ArrayPattern::accept0(Visitor *visitor) void ArrayPattern::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) if (visitor->visit(this))
accept(elements, visitor); accept(elements, visitor);
@@ -273,7 +273,7 @@ bool ArrayPattern::isValidArrayLiteral(SourceLocation *errorLocation) const {
return true; return true;
} }
void ObjectPattern::accept0(Visitor *visitor) void ObjectPattern::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(properties, visitor); accept(properties, visitor);
@@ -448,7 +448,7 @@ bool PatternProperty::convertLiteralToAssignmentPattern(MemoryPool *pool, Source
} }
void Elision::accept0(Visitor *visitor) void Elision::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// ### // ###
@@ -457,7 +457,7 @@ void Elision::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void IdentifierPropertyName::accept0(Visitor *visitor) void IdentifierPropertyName::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -465,7 +465,7 @@ void IdentifierPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void StringLiteralPropertyName::accept0(Visitor *visitor) void StringLiteralPropertyName::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -473,7 +473,7 @@ void StringLiteralPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NumericLiteralPropertyName::accept0(Visitor *visitor) void NumericLiteralPropertyName::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -503,7 +503,7 @@ QString NumericLiteralPropertyName::asString()const
return locale.toString(id, 'g', 16); return locale.toString(id, 'g', 16);
} }
void ArrayMemberExpression::accept0(Visitor *visitor) void ArrayMemberExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -513,7 +513,7 @@ void ArrayMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void FieldMemberExpression::accept0(Visitor *visitor) void FieldMemberExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -522,7 +522,7 @@ void FieldMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NewMemberExpression::accept0(Visitor *visitor) void NewMemberExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -532,7 +532,7 @@ void NewMemberExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NewExpression::accept0(Visitor *visitor) void NewExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -541,7 +541,7 @@ void NewExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void CallExpression::accept0(Visitor *visitor) void CallExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -551,7 +551,7 @@ void CallExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ArgumentList::accept0(Visitor *visitor) void ArgumentList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (ArgumentList *it = this; it; it = it->next) { for (ArgumentList *it = this; it; it = it->next) {
@@ -562,7 +562,7 @@ void ArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void PostIncrementExpression::accept0(Visitor *visitor) void PostIncrementExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -571,7 +571,7 @@ void PostIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void PostDecrementExpression::accept0(Visitor *visitor) void PostDecrementExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -580,7 +580,7 @@ void PostDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void DeleteExpression::accept0(Visitor *visitor) void DeleteExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -589,7 +589,7 @@ void DeleteExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void VoidExpression::accept0(Visitor *visitor) void VoidExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -598,7 +598,7 @@ void VoidExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TypeOfExpression::accept0(Visitor *visitor) void TypeOfExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -607,7 +607,7 @@ void TypeOfExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void PreIncrementExpression::accept0(Visitor *visitor) void PreIncrementExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -616,7 +616,7 @@ void PreIncrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void PreDecrementExpression::accept0(Visitor *visitor) void PreDecrementExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -625,7 +625,7 @@ void PreDecrementExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UnaryPlusExpression::accept0(Visitor *visitor) void UnaryPlusExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -634,7 +634,7 @@ void UnaryPlusExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UnaryMinusExpression::accept0(Visitor *visitor) void UnaryMinusExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -643,7 +643,7 @@ void UnaryMinusExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TildeExpression::accept0(Visitor *visitor) void TildeExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -652,7 +652,7 @@ void TildeExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NotExpression::accept0(Visitor *visitor) void NotExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -661,7 +661,7 @@ void NotExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void BinaryExpression::accept0(Visitor *visitor) void BinaryExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(left, visitor); accept(left, visitor);
@@ -671,7 +671,7 @@ void BinaryExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ConditionalExpression::accept0(Visitor *visitor) void ConditionalExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -682,7 +682,7 @@ void ConditionalExpression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void Expression::accept0(Visitor *visitor) void Expression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(left, visitor); accept(left, visitor);
@@ -692,7 +692,7 @@ void Expression::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void Block::accept0(Visitor *visitor) void Block::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statements, visitor); accept(statements, visitor);
@@ -701,7 +701,7 @@ void Block::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void StatementList::accept0(Visitor *visitor) void StatementList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (StatementList *it = this; it; it = it->next) { for (StatementList *it = this; it; it = it->next) {
@@ -712,7 +712,7 @@ void StatementList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void VariableStatement::accept0(Visitor *visitor) void VariableStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(declarations, visitor); accept(declarations, visitor);
@@ -721,7 +721,7 @@ void VariableStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void VariableDeclarationList::accept0(Visitor *visitor) void VariableDeclarationList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (VariableDeclarationList *it = this; it; it = it->next) { for (VariableDeclarationList *it = this; it; it = it->next) {
@@ -732,7 +732,7 @@ void VariableDeclarationList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void EmptyStatement::accept0(Visitor *visitor) void EmptyStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -740,7 +740,7 @@ void EmptyStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ExpressionStatement::accept0(Visitor *visitor) void ExpressionStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -749,7 +749,7 @@ void ExpressionStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void IfStatement::accept0(Visitor *visitor) void IfStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -760,7 +760,7 @@ void IfStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void DoWhileStatement::accept0(Visitor *visitor) void DoWhileStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statement, visitor); accept(statement, visitor);
@@ -770,7 +770,7 @@ void DoWhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void WhileStatement::accept0(Visitor *visitor) void WhileStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -780,7 +780,7 @@ void WhileStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ForStatement::accept0(Visitor *visitor) void ForStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(initialiser, visitor); accept(initialiser, visitor);
@@ -793,7 +793,7 @@ void ForStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ForEachStatement::accept0(Visitor *visitor) void ForEachStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(lhs, visitor); accept(lhs, visitor);
@@ -804,7 +804,7 @@ void ForEachStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ContinueStatement::accept0(Visitor *visitor) void ContinueStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -812,7 +812,7 @@ void ContinueStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void BreakStatement::accept0(Visitor *visitor) void BreakStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -820,7 +820,7 @@ void BreakStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ReturnStatement::accept0(Visitor *visitor) void ReturnStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -829,7 +829,7 @@ void ReturnStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void YieldExpression::accept0(Visitor *visitor) void YieldExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -839,7 +839,7 @@ void YieldExpression::accept0(Visitor *visitor)
} }
void WithStatement::accept0(Visitor *visitor) void WithStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -849,7 +849,7 @@ void WithStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void SwitchStatement::accept0(Visitor *visitor) void SwitchStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -859,7 +859,7 @@ void SwitchStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void CaseBlock::accept0(Visitor *visitor) void CaseBlock::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(clauses, visitor); accept(clauses, visitor);
@@ -870,7 +870,7 @@ void CaseBlock::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void CaseClauses::accept0(Visitor *visitor) void CaseClauses::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (CaseClauses *it = this; it; it = it->next) { for (CaseClauses *it = this; it; it = it->next) {
@@ -881,7 +881,7 @@ void CaseClauses::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void CaseClause::accept0(Visitor *visitor) void CaseClause::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -891,7 +891,7 @@ void CaseClause::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void DefaultClause::accept0(Visitor *visitor) void DefaultClause::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statements, visitor); accept(statements, visitor);
@@ -900,7 +900,7 @@ void DefaultClause::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void LabelledStatement::accept0(Visitor *visitor) void LabelledStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statement, visitor); accept(statement, visitor);
@@ -909,7 +909,7 @@ void LabelledStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ThrowStatement::accept0(Visitor *visitor) void ThrowStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -918,7 +918,7 @@ void ThrowStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TryStatement::accept0(Visitor *visitor) void TryStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statement, visitor); accept(statement, visitor);
@@ -929,7 +929,7 @@ void TryStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void Catch::accept0(Visitor *visitor) void Catch::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(patternElement, visitor); accept(patternElement, visitor);
@@ -939,7 +939,7 @@ void Catch::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void Finally::accept0(Visitor *visitor) void Finally::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statement, visitor); accept(statement, visitor);
@@ -948,7 +948,7 @@ void Finally::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void FunctionDeclaration::accept0(Visitor *visitor) void FunctionDeclaration::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(formals, visitor); accept(formals, visitor);
@@ -959,7 +959,7 @@ void FunctionDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void FunctionExpression::accept0(Visitor *visitor) void FunctionExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(formals, visitor); accept(formals, visitor);
@@ -1004,7 +1004,7 @@ BoundNames FormalParameterList::boundNames() const
return names; return names;
} }
void FormalParameterList::accept0(Visitor *visitor) void FormalParameterList::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (FormalParameterList *it = this; it && accepted; it = it->next) { for (FormalParameterList *it = this; it && accepted; it = it->next) {
@@ -1029,7 +1029,7 @@ FormalParameterList *FormalParameterList::finish(QmlJS::MemoryPool *pool)
return front; return front;
} }
void Program::accept0(Visitor *visitor) void Program::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(statements, visitor); accept(statements, visitor);
@@ -1038,7 +1038,7 @@ void Program::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ImportSpecifier::accept0(Visitor *visitor) void ImportSpecifier::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -1046,7 +1046,7 @@ void ImportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ImportsList::accept0(Visitor *visitor) void ImportsList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (ImportsList *it = this; it; it = it->next) { for (ImportsList *it = this; it; it = it->next) {
@@ -1057,7 +1057,7 @@ void ImportsList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NamedImports::accept0(Visitor *visitor) void NamedImports::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(importsList, visitor); accept(importsList, visitor);
@@ -1066,7 +1066,7 @@ void NamedImports::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void FromClause::accept0(Visitor *visitor) void FromClause::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1074,7 +1074,7 @@ void FromClause::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void NameSpaceImport::accept0(Visitor *visitor) void NameSpaceImport::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1082,7 +1082,7 @@ void NameSpaceImport::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ImportClause::accept0(Visitor *visitor) void ImportClause::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(nameSpaceImport, visitor); accept(nameSpaceImport, visitor);
@@ -1092,7 +1092,7 @@ void ImportClause::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ImportDeclaration::accept0(Visitor *visitor) void ImportDeclaration::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(importClause, visitor); accept(importClause, visitor);
@@ -1102,7 +1102,7 @@ void ImportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ExportSpecifier::accept0(Visitor *visitor) void ExportSpecifier::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
@@ -1111,7 +1111,7 @@ void ExportSpecifier::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ExportsList::accept0(Visitor *visitor) void ExportsList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (ExportsList *it = this; it; it = it->next) { for (ExportsList *it = this; it; it = it->next) {
@@ -1122,7 +1122,7 @@ void ExportsList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ExportClause::accept0(Visitor *visitor) void ExportClause::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(exportsList, visitor); accept(exportsList, visitor);
@@ -1131,7 +1131,7 @@ void ExportClause::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ExportDeclaration::accept0(Visitor *visitor) void ExportDeclaration::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(fromClause, visitor); accept(fromClause, visitor);
@@ -1142,7 +1142,7 @@ void ExportDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ESModule::accept0(Visitor *visitor) void ESModule::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(body, visitor); accept(body, visitor);
@@ -1151,7 +1151,7 @@ void ESModule::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void DebuggerStatement::accept0(Visitor *visitor) void DebuggerStatement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1159,7 +1159,7 @@ void DebuggerStatement::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiProgram::accept0(Visitor *visitor) void UiProgram::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(headers, visitor); accept(headers, visitor);
@@ -1169,19 +1169,23 @@ void UiProgram::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiPublicMember::accept0(Visitor *visitor) void UiPublicMember::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
// accept(memberType, visitor); // accept manually in visit if interested
accept(statement, visitor); accept(statement, visitor);
accept(binding, visitor); accept(binding, visitor);
// accept(parameters, visitor); // accept manually in visit if interested
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiObjectDefinition::accept0(Visitor *visitor) void UiObjectDefinition::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedTypeNameId, visitor); accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor); accept(initializer, visitor);
} }
@@ -1189,7 +1193,7 @@ void UiObjectDefinition::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiObjectInitializer::accept0(Visitor *visitor) void UiObjectInitializer::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(members, visitor); accept(members, visitor);
@@ -1198,16 +1202,18 @@ void UiObjectInitializer::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiParameterList::accept0(Visitor *visitor) void UiParameterList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(type, visitor); // accept manually in visit if interested
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiObjectBinding::accept0(Visitor *visitor) void UiObjectBinding::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor); accept(qualifiedId, visitor);
accept(qualifiedTypeNameId, visitor); accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor); accept(initializer, visitor);
@@ -1216,9 +1222,10 @@ void UiObjectBinding::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiScriptBinding::accept0(Visitor *visitor) void UiScriptBinding::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor); accept(qualifiedId, visitor);
accept(statement, visitor); accept(statement, visitor);
} }
@@ -1226,9 +1233,10 @@ void UiScriptBinding::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiArrayBinding::accept0(Visitor *visitor) void UiArrayBinding::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(qualifiedId, visitor); accept(qualifiedId, visitor);
accept(members, visitor); accept(members, visitor);
} }
@@ -1236,7 +1244,7 @@ void UiArrayBinding::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiObjectMemberList::accept0(Visitor *visitor) void UiObjectMemberList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (UiObjectMemberList *it = this; it; it = it->next) for (UiObjectMemberList *it = this; it; it = it->next)
@@ -1246,7 +1254,7 @@ void UiObjectMemberList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiArrayMemberList::accept0(Visitor *visitor) void UiArrayMemberList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (UiArrayMemberList *it = this; it; it = it->next) for (UiArrayMemberList *it = this; it; it = it->next)
@@ -1256,15 +1264,16 @@ void UiArrayMemberList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiQualifiedId::accept0(Visitor *visitor) void UiQualifiedId::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(next, visitor) // accept manually in visit if interested
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void Type::accept0(Visitor *visitor) void Type::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(typeId, visitor); accept(typeId, visitor);
@@ -1274,7 +1283,7 @@ void Type::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TypeArgumentList::accept0(Visitor *visitor) void TypeArgumentList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
for (TypeArgumentList *it = this; it; it = it->next) for (TypeArgumentList *it = this; it; it = it->next)
@@ -1284,7 +1293,7 @@ void TypeArgumentList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TypeAnnotation::accept0(Visitor *visitor) void TypeAnnotation::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(type, visitor); accept(type, visitor);
@@ -1293,16 +1302,17 @@ void TypeAnnotation::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiImport::accept0(Visitor *visitor) void UiImport::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(importUri, visitor); accept(importUri, visitor);
// accept(version, visitor); // accept manually in visit if interested
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiPragma::accept0(Visitor *visitor) void UiPragma::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1310,7 +1320,7 @@ void UiPragma::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiHeaderItemList::accept0(Visitor *visitor) void UiHeaderItemList::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (UiHeaderItemList *it = this; it && accepted; it = it->next) { for (UiHeaderItemList *it = this; it && accepted; it = it->next) {
@@ -1323,25 +1333,27 @@ void UiHeaderItemList::accept0(Visitor *visitor)
} }
void UiSourceElement::accept0(Visitor *visitor) void UiSourceElement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(sourceElement, visitor); accept(sourceElement, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiEnumDeclaration::accept0(Visitor *visitor) void UiEnumDeclaration::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(members, visitor); accept(members, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }
void UiEnumMemberList::accept0(Visitor *visitor) void UiEnumMemberList::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1349,7 +1361,7 @@ void UiEnumMemberList::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void TaggedTemplate::accept0(Visitor *visitor) void TaggedTemplate::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(base, visitor); accept(base, visitor);
@@ -1359,7 +1371,7 @@ void TaggedTemplate::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void PatternElement::accept0(Visitor *visitor) void PatternElement::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(bindingTarget, visitor); accept(bindingTarget, visitor);
@@ -1382,7 +1394,7 @@ void PatternElement::boundNames(BoundNames *names)
} }
} }
void PatternElementList::accept0(Visitor *visitor) void PatternElementList::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (PatternElementList *it = this; it && accepted; it = it->next) { for (PatternElementList *it = this; it && accepted; it = it->next) {
@@ -1403,7 +1415,7 @@ void PatternElementList::boundNames(BoundNames *names)
} }
} }
void PatternProperty::accept0(Visitor *visitor) void PatternProperty::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(name, visitor); accept(name, visitor);
@@ -1420,7 +1432,7 @@ void PatternProperty::boundNames(BoundNames *names)
PatternElement::boundNames(names); PatternElement::boundNames(names);
} }
void PatternPropertyList::accept0(Visitor *visitor) void PatternPropertyList::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (PatternPropertyList *it = this; it && accepted; it = it->next) { for (PatternPropertyList *it = this; it && accepted; it = it->next) {
@@ -1437,7 +1449,7 @@ void PatternPropertyList::boundNames(BoundNames *names)
it->property->boundNames(names); it->property->boundNames(names);
} }
void ComputedPropertyName::accept0(Visitor *visitor) void ComputedPropertyName::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(expression, visitor); accept(expression, visitor);
@@ -1446,7 +1458,7 @@ void ComputedPropertyName::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ClassExpression::accept0(Visitor *visitor) void ClassExpression::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(heritage, visitor); accept(heritage, visitor);
@@ -1461,7 +1473,7 @@ ClassExpression *ClassExpression::asClassDefinition()
return this; return this;
} }
void ClassDeclaration::accept0(Visitor *visitor) void ClassDeclaration::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(heritage, visitor); accept(heritage, visitor);
@@ -1471,7 +1483,7 @@ void ClassDeclaration::accept0(Visitor *visitor)
visitor->endVisit(this); visitor->endVisit(this);
} }
void ClassElementList::accept0(Visitor *visitor) void ClassElementList::accept0(BaseVisitor *visitor)
{ {
bool accepted = true; bool accepted = true;
for (ClassElementList *it = this; it && accepted; it = it->next) { for (ClassElementList *it = this; it && accepted; it = it->next) {
@@ -1500,7 +1512,7 @@ LeftHandSideExpression *LeftHandSideExpression::leftHandSideExpressionCast()
return this; return this;
} }
void UiVersionSpecifier::accept0(Visitor *visitor) void UiVersionSpecifier::accept0(BaseVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
} }
@@ -1531,6 +1543,44 @@ void Type::toString(QString *out) const
}; };
} }
void UiInlineComponent::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
// accept(annotations, visitor); // accept manually in visit if interested
accept(component, visitor);
}
visitor->endVisit(this);
}
void UiRequired::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
}
visitor->endVisit(this);
}
void UiAnnotationList::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
for (UiAnnotationList *it = this; it; it = it->next)
accept(it->annotation, visitor);
}
visitor->endVisit(this);
}
void UiAnnotation::accept0(BaseVisitor *visitor)
{
if (visitor->visit(this)) {
accept(qualifiedTypeNameId, visitor);
accept(initializer, visitor);
}
visitor->endVisit(this);
}
} } // namespace QmlJS::AST } } // namespace QmlJS::AST
QT_QML_END_NAMESPACE QT_QML_END_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@@ -26,8 +26,9 @@
#pragma once #pragma once
#include "qmljsglobal_p.h" #include "qmljsglobal_p.h"
#include "qmljs/parser/qmljssourcelocation_p.h"
#include <QtCore/qglobal.h> #include "qmljsglobal_p.h"
// //
// W A R N I N G // W A R N I N G
@@ -44,27 +45,7 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace AST { namespace QmlJS { namespace AST {
class SourceLocation class BaseVisitor;
{
public:
explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
: offset(offset), length(length),
startLine(line), startColumn(column)
{ }
bool isValid() const { return length != 0; }
quint32 begin() const { return offset; }
quint32 end() const { return offset + length; }
// attributes
// ### encode
quint32 offset;
quint32 length;
quint32 startLine;
quint32 startColumn;
};
class Visitor; class Visitor;
class Node; class Node;
class ExpressionNode; class ExpressionNode;
@@ -156,7 +137,6 @@ class NamedImport;
class ImportClause; class ImportClause;
class FromClause; class FromClause;
class ImportDeclaration; class ImportDeclaration;
class ModuleItem;
class ESModule; class ESModule;
class DebuggerStatement; class DebuggerStatement;
class NestedExpression; class NestedExpression;
@@ -174,6 +154,7 @@ class UiImport;
class UiPublicMember; class UiPublicMember;
class UiParameterList; class UiParameterList;
class UiObjectDefinition; class UiObjectDefinition;
class UiInlineComponent;
class UiObjectInitializer; class UiObjectInitializer;
class UiObjectBinding; class UiObjectBinding;
class UiScriptBinding; class UiScriptBinding;
@@ -187,8 +168,12 @@ class UiHeaderItemList;
class UiEnumDeclaration; class UiEnumDeclaration;
class UiEnumMemberList; class UiEnumMemberList;
class UiVersionSpecifier; class UiVersionSpecifier;
class UiRequired;
class UiAnnotation;
class UiAnnotationList;
} } // namespace AST } // namespace AST
} // namespace QmlJS
QT_QML_END_NAMESPACE QT_QML_END_NAMESPACE

View File

@@ -29,11 +29,13 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace AST { namespace QmlJS { namespace AST {
Visitor::Visitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth) Visitor::Visitor(quint16 parentRecursionDepth) : BaseVisitor(parentRecursionDepth)
{ {
} }
Visitor::~Visitor() BaseVisitor::BaseVisitor(quint16 parentRecursionDepth) : m_recursionDepth(parentRecursionDepth) {}
BaseVisitor::~BaseVisitor()
{ {
} }

View File

@@ -43,7 +43,7 @@ QT_QML_BEGIN_NAMESPACE
namespace QmlJS { namespace AST { namespace QmlJS { namespace AST {
class QML_PARSER_EXPORT Visitor class QML_PARSER_EXPORT BaseVisitor
{ {
public: public:
class RecursionDepthCheck class RecursionDepthCheck
@@ -53,7 +53,7 @@ public:
RecursionDepthCheck(RecursionDepthCheck &&) = delete; RecursionDepthCheck(RecursionDepthCheck &&) = delete;
RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete; RecursionDepthCheck &operator=(RecursionDepthCheck &&) = delete;
RecursionDepthCheck(Visitor *visitor) : m_visitor(visitor) RecursionDepthCheck(BaseVisitor *visitor) : m_visitor(visitor)
{ {
++(m_visitor->m_recursionDepth); ++(m_visitor->m_recursionDepth);
} }
@@ -69,335 +69,340 @@ public:
private: private:
static const quint16 s_recursionLimit = 4096; static const quint16 s_recursionLimit = 4096;
Visitor *m_visitor; BaseVisitor *m_visitor;
}; };
Visitor(quint16 parentRecursionDepth = 0); BaseVisitor(quint16 parentRecursionDepth = 0);
virtual ~Visitor(); virtual ~BaseVisitor();
virtual bool preVisit(Node *) { return true; } virtual bool preVisit(Node *) = 0;
virtual void postVisit(Node *) {} virtual void postVisit(Node *) = 0;
// Ui // Ui
virtual bool visit(UiProgram *) { return true; } virtual bool visit(UiProgram *) = 0;
virtual bool visit(UiHeaderItemList *) { return true; } virtual bool visit(UiHeaderItemList *) = 0;
virtual bool visit(UiPragma *) { return true; } virtual bool visit(UiPragma *) = 0;
virtual bool visit(UiImport *) { return true; } virtual bool visit(UiImport *) = 0;
virtual bool visit(UiPublicMember *) { return true; } virtual bool visit(UiPublicMember *) = 0;
virtual bool visit(UiSourceElement *) { return true; } virtual bool visit(UiSourceElement *) = 0;
virtual bool visit(UiObjectDefinition *) { return true; } virtual bool visit(UiObjectDefinition *) = 0;
virtual bool visit(UiObjectInitializer *) { return true; } virtual bool visit(UiObjectInitializer *) = 0;
virtual bool visit(UiObjectBinding *) { return true; } virtual bool visit(UiObjectBinding *) = 0;
virtual bool visit(UiScriptBinding *) { return true; } virtual bool visit(UiScriptBinding *) = 0;
virtual bool visit(UiArrayBinding *) { return true; } virtual bool visit(UiArrayBinding *) = 0;
virtual bool visit(UiParameterList *) { return true; } virtual bool visit(UiParameterList *) = 0;
virtual bool visit(UiObjectMemberList *) { return true; } virtual bool visit(UiObjectMemberList *) = 0;
virtual bool visit(UiArrayMemberList *) { return true; } virtual bool visit(UiArrayMemberList *) = 0;
virtual bool visit(UiQualifiedId *) { return true; } virtual bool visit(UiQualifiedId *) = 0;
virtual bool visit(UiEnumDeclaration *) { return true; } virtual bool visit(UiEnumDeclaration *) = 0;
virtual bool visit(UiEnumMemberList *) { return true; } virtual bool visit(UiEnumMemberList *) = 0;
virtual bool visit(UiVersionSpecifier *) { return true; } virtual bool visit(UiVersionSpecifier *) = 0;
virtual bool visit(UiInlineComponent *) = 0;
virtual bool visit(UiAnnotation *) = 0;
virtual bool visit(UiAnnotationList *) = 0;
virtual bool visit(UiRequired *) = 0;
virtual void endVisit(UiProgram *) {} virtual void endVisit(UiProgram *) = 0;
virtual void endVisit(UiImport *) {} virtual void endVisit(UiImport *) = 0;
virtual void endVisit(UiHeaderItemList *) {} virtual void endVisit(UiHeaderItemList *) = 0;
virtual void endVisit(UiPragma *) {} virtual void endVisit(UiPragma *) = 0;
virtual void endVisit(UiPublicMember *) {} virtual void endVisit(UiPublicMember *) = 0;
virtual void endVisit(UiSourceElement *) {} virtual void endVisit(UiSourceElement *) = 0;
virtual void endVisit(UiObjectDefinition *) {} virtual void endVisit(UiObjectDefinition *) = 0;
virtual void endVisit(UiObjectInitializer *) {} virtual void endVisit(UiObjectInitializer *) = 0;
virtual void endVisit(UiObjectBinding *) {} virtual void endVisit(UiObjectBinding *) = 0;
virtual void endVisit(UiScriptBinding *) {} virtual void endVisit(UiScriptBinding *) = 0;
virtual void endVisit(UiArrayBinding *) {} virtual void endVisit(UiArrayBinding *) = 0;
virtual void endVisit(UiParameterList *) {} virtual void endVisit(UiParameterList *) = 0;
virtual void endVisit(UiObjectMemberList *) {} virtual void endVisit(UiObjectMemberList *) = 0;
virtual void endVisit(UiArrayMemberList *) {} virtual void endVisit(UiArrayMemberList *) = 0;
virtual void endVisit(UiQualifiedId *) {} virtual void endVisit(UiQualifiedId *) = 0;
virtual void endVisit(UiEnumDeclaration *) {} virtual void endVisit(UiEnumDeclaration *) = 0;
virtual void endVisit(UiEnumMemberList *) { } virtual void endVisit(UiEnumMemberList *) = 0;
virtual void endVisit(UiVersionSpecifier *) {} virtual void endVisit(UiVersionSpecifier *) = 0;
virtual void endVisit(UiInlineComponent *) = 0;
virtual void endVisit(UiAnnotation *) = 0;
virtual void endVisit(UiAnnotationList *) = 0;
virtual void endVisit(UiRequired *) = 0;
// QmlJS // QmlJS
virtual bool visit(ThisExpression *) { return true; } virtual bool visit(ThisExpression *) = 0;
virtual void endVisit(ThisExpression *) {} virtual void endVisit(ThisExpression *) = 0;
virtual bool visit(IdentifierExpression *) { return true; } virtual bool visit(IdentifierExpression *) = 0;
virtual void endVisit(IdentifierExpression *) {} virtual void endVisit(IdentifierExpression *) = 0;
virtual bool visit(NullExpression *) { return true; } virtual bool visit(NullExpression *) = 0;
virtual void endVisit(NullExpression *) {} virtual void endVisit(NullExpression *) = 0;
virtual bool visit(TrueLiteral *) { return true; } virtual bool visit(TrueLiteral *) = 0;
virtual void endVisit(TrueLiteral *) {} virtual void endVisit(TrueLiteral *) = 0;
virtual bool visit(FalseLiteral *) { return true; } virtual bool visit(FalseLiteral *) = 0;
virtual void endVisit(FalseLiteral *) {} virtual void endVisit(FalseLiteral *) = 0;
virtual bool visit(SuperLiteral *) { return true; } virtual bool visit(SuperLiteral *) = 0;
virtual void endVisit(SuperLiteral *) {} virtual void endVisit(SuperLiteral *) = 0;
virtual bool visit(StringLiteral *) { return true; } virtual bool visit(StringLiteral *) = 0;
virtual void endVisit(StringLiteral *) {} virtual void endVisit(StringLiteral *) = 0;
virtual bool visit(TemplateLiteral *) { return true; } virtual bool visit(TemplateLiteral *) = 0;
virtual void endVisit(TemplateLiteral *) {} virtual void endVisit(TemplateLiteral *) = 0;
virtual bool visit(NumericLiteral *) { return true; } virtual bool visit(NumericLiteral *) = 0;
virtual void endVisit(NumericLiteral *) {} virtual void endVisit(NumericLiteral *) = 0;
virtual bool visit(RegExpLiteral *) { return true; } virtual bool visit(RegExpLiteral *) = 0;
virtual void endVisit(RegExpLiteral *) {} virtual void endVisit(RegExpLiteral *) = 0;
virtual bool visit(ArrayPattern *) { return true; } virtual bool visit(ArrayPattern *) = 0;
virtual void endVisit(ArrayPattern *) {} virtual void endVisit(ArrayPattern *) = 0;
virtual bool visit(ObjectPattern *) { return true; } virtual bool visit(ObjectPattern *) = 0;
virtual void endVisit(ObjectPattern *) {} virtual void endVisit(ObjectPattern *) = 0;
virtual bool visit(PatternElementList *) { return true; } virtual bool visit(PatternElementList *) = 0;
virtual void endVisit(PatternElementList *) {} virtual void endVisit(PatternElementList *) = 0;
virtual bool visit(PatternPropertyList *) { return true; } virtual bool visit(PatternPropertyList *) = 0;
virtual void endVisit(PatternPropertyList *) {} virtual void endVisit(PatternPropertyList *) = 0;
virtual bool visit(PatternElement *) { return true; } virtual bool visit(PatternElement *) = 0;
virtual void endVisit(PatternElement *) {} virtual void endVisit(PatternElement *) = 0;
virtual bool visit(PatternProperty *) { return true; } virtual bool visit(PatternProperty *) = 0;
virtual void endVisit(PatternProperty *) {} virtual void endVisit(PatternProperty *) = 0;
virtual bool visit(Elision *) { return true; } virtual bool visit(Elision *) = 0;
virtual void endVisit(Elision *) {} virtual void endVisit(Elision *) = 0;
virtual bool visit(NestedExpression *) { return true; } virtual bool visit(NestedExpression *) = 0;
virtual void endVisit(NestedExpression *) {} virtual void endVisit(NestedExpression *) = 0;
virtual bool visit(IdentifierPropertyName *) { return true; } virtual bool visit(IdentifierPropertyName *) = 0;
virtual void endVisit(IdentifierPropertyName *) {} virtual void endVisit(IdentifierPropertyName *) = 0;
virtual bool visit(StringLiteralPropertyName *) { return true; } virtual bool visit(StringLiteralPropertyName *) = 0;
virtual void endVisit(StringLiteralPropertyName *) {} virtual void endVisit(StringLiteralPropertyName *) = 0;
virtual bool visit(NumericLiteralPropertyName *) { return true; } virtual bool visit(NumericLiteralPropertyName *) = 0;
virtual void endVisit(NumericLiteralPropertyName *) {} virtual void endVisit(NumericLiteralPropertyName *) = 0;
virtual bool visit(ComputedPropertyName *) { return true; } virtual bool visit(ComputedPropertyName *) = 0;
virtual void endVisit(ComputedPropertyName *) {} virtual void endVisit(ComputedPropertyName *) = 0;
virtual bool visit(ArrayMemberExpression *) { return true; } virtual bool visit(ArrayMemberExpression *) = 0;
virtual void endVisit(ArrayMemberExpression *) {} virtual void endVisit(ArrayMemberExpression *) = 0;
virtual bool visit(FieldMemberExpression *) { return true; } virtual bool visit(FieldMemberExpression *) = 0;
virtual void endVisit(FieldMemberExpression *) {} virtual void endVisit(FieldMemberExpression *) = 0;
virtual bool visit(TaggedTemplate *) { return true; } virtual bool visit(TaggedTemplate *) = 0;
virtual void endVisit(TaggedTemplate *) {} virtual void endVisit(TaggedTemplate *) = 0;
virtual bool visit(NewMemberExpression *) { return true; } virtual bool visit(NewMemberExpression *) = 0;
virtual void endVisit(NewMemberExpression *) {} virtual void endVisit(NewMemberExpression *) = 0;
virtual bool visit(NewExpression *) { return true; } virtual bool visit(NewExpression *) = 0;
virtual void endVisit(NewExpression *) {} virtual void endVisit(NewExpression *) = 0;
virtual bool visit(CallExpression *) { return true; } virtual bool visit(CallExpression *) = 0;
virtual void endVisit(CallExpression *) {} virtual void endVisit(CallExpression *) = 0;
virtual bool visit(ArgumentList *) { return true; } virtual bool visit(ArgumentList *) = 0;
virtual void endVisit(ArgumentList *) {} virtual void endVisit(ArgumentList *) = 0;
virtual bool visit(PostIncrementExpression *) { return true; } virtual bool visit(PostIncrementExpression *) = 0;
virtual void endVisit(PostIncrementExpression *) {} virtual void endVisit(PostIncrementExpression *) = 0;
virtual bool visit(PostDecrementExpression *) { return true; } virtual bool visit(PostDecrementExpression *) = 0;
virtual void endVisit(PostDecrementExpression *) {} virtual void endVisit(PostDecrementExpression *) = 0;
virtual bool visit(DeleteExpression *) { return true; } virtual bool visit(DeleteExpression *) = 0;
virtual void endVisit(DeleteExpression *) {} virtual void endVisit(DeleteExpression *) = 0;
virtual bool visit(VoidExpression *) { return true; } virtual bool visit(VoidExpression *) = 0;
virtual void endVisit(VoidExpression *) {} virtual void endVisit(VoidExpression *) = 0;
virtual bool visit(TypeOfExpression *) { return true; } virtual bool visit(TypeOfExpression *) = 0;
virtual void endVisit(TypeOfExpression *) {} virtual void endVisit(TypeOfExpression *) = 0;
virtual bool visit(PreIncrementExpression *) { return true; } virtual bool visit(PreIncrementExpression *) = 0;
virtual void endVisit(PreIncrementExpression *) {} virtual void endVisit(PreIncrementExpression *) = 0;
virtual bool visit(PreDecrementExpression *) { return true; } virtual bool visit(PreDecrementExpression *) = 0;
virtual void endVisit(PreDecrementExpression *) {} virtual void endVisit(PreDecrementExpression *) = 0;
virtual bool visit(UnaryPlusExpression *) { return true; } virtual bool visit(UnaryPlusExpression *) = 0;
virtual void endVisit(UnaryPlusExpression *) {} virtual void endVisit(UnaryPlusExpression *) = 0;
virtual bool visit(UnaryMinusExpression *) { return true; } virtual bool visit(UnaryMinusExpression *) = 0;
virtual void endVisit(UnaryMinusExpression *) {} virtual void endVisit(UnaryMinusExpression *) = 0;
virtual bool visit(TildeExpression *) { return true; } virtual bool visit(TildeExpression *) = 0;
virtual void endVisit(TildeExpression *) {} virtual void endVisit(TildeExpression *) = 0;
virtual bool visit(NotExpression *) { return true; } virtual bool visit(NotExpression *) = 0;
virtual void endVisit(NotExpression *) {} virtual void endVisit(NotExpression *) = 0;
virtual bool visit(BinaryExpression *) { return true; } virtual bool visit(BinaryExpression *) = 0;
virtual void endVisit(BinaryExpression *) {} virtual void endVisit(BinaryExpression *) = 0;
virtual bool visit(ConditionalExpression *) { return true; } virtual bool visit(ConditionalExpression *) = 0;
virtual void endVisit(ConditionalExpression *) {} virtual void endVisit(ConditionalExpression *) = 0;
virtual bool visit(Expression *) { return true; } virtual bool visit(Expression *) = 0;
virtual void endVisit(Expression *) {} virtual void endVisit(Expression *) = 0;
virtual bool visit(Block *) { return true; } virtual bool visit(Block *) = 0;
virtual void endVisit(Block *) {} virtual void endVisit(Block *) = 0;
virtual bool visit(StatementList *) { return true; } virtual bool visit(StatementList *) = 0;
virtual void endVisit(StatementList *) {} virtual void endVisit(StatementList *) = 0;
virtual bool visit(VariableStatement *) { return true; } virtual bool visit(VariableStatement *) = 0;
virtual void endVisit(VariableStatement *) {} virtual void endVisit(VariableStatement *) = 0;
virtual bool visit(VariableDeclarationList *) { return true; } virtual bool visit(VariableDeclarationList *) = 0;
virtual void endVisit(VariableDeclarationList *) {} virtual void endVisit(VariableDeclarationList *) = 0;
virtual bool visit(EmptyStatement *) { return true; } virtual bool visit(EmptyStatement *) = 0;
virtual void endVisit(EmptyStatement *) {} virtual void endVisit(EmptyStatement *) = 0;
virtual bool visit(ExpressionStatement *) { return true; } virtual bool visit(ExpressionStatement *) = 0;
virtual void endVisit(ExpressionStatement *) {} virtual void endVisit(ExpressionStatement *) = 0;
virtual bool visit(IfStatement *) { return true; } virtual bool visit(IfStatement *) = 0;
virtual void endVisit(IfStatement *) {} virtual void endVisit(IfStatement *) = 0;
virtual bool visit(DoWhileStatement *) { return true; } virtual bool visit(DoWhileStatement *) = 0;
virtual void endVisit(DoWhileStatement *) {} virtual void endVisit(DoWhileStatement *) = 0;
virtual bool visit(WhileStatement *) { return true; } virtual bool visit(WhileStatement *) = 0;
virtual void endVisit(WhileStatement *) {} virtual void endVisit(WhileStatement *) = 0;
virtual bool visit(ForStatement *) { return true; } virtual bool visit(ForStatement *) = 0;
virtual void endVisit(ForStatement *) {} virtual void endVisit(ForStatement *) = 0;
virtual bool visit(ForEachStatement *) { return true; } virtual bool visit(ForEachStatement *) = 0;
virtual void endVisit(ForEachStatement *) {} virtual void endVisit(ForEachStatement *) = 0;
virtual bool visit(ContinueStatement *) { return true; } virtual bool visit(ContinueStatement *) = 0;
virtual void endVisit(ContinueStatement *) {} virtual void endVisit(ContinueStatement *) = 0;
virtual bool visit(BreakStatement *) { return true; } virtual bool visit(BreakStatement *) = 0;
virtual void endVisit(BreakStatement *) {} virtual void endVisit(BreakStatement *) = 0;
virtual bool visit(ReturnStatement *) { return true; } virtual bool visit(ReturnStatement *) = 0;
virtual void endVisit(ReturnStatement *) {} virtual void endVisit(ReturnStatement *) = 0;
virtual bool visit(YieldExpression *) { return true; } virtual bool visit(YieldExpression *) = 0;
virtual void endVisit(YieldExpression *) {} virtual void endVisit(YieldExpression *) = 0;
virtual bool visit(WithStatement *) { return true; } virtual bool visit(WithStatement *) = 0;
virtual void endVisit(WithStatement *) {} virtual void endVisit(WithStatement *) = 0;
virtual bool visit(SwitchStatement *) { return true; } virtual bool visit(SwitchStatement *) = 0;
virtual void endVisit(SwitchStatement *) {} virtual void endVisit(SwitchStatement *) = 0;
virtual bool visit(CaseBlock *) { return true; } virtual bool visit(CaseBlock *) = 0;
virtual void endVisit(CaseBlock *) {} virtual void endVisit(CaseBlock *) = 0;
virtual bool visit(CaseClauses *) { return true; } virtual bool visit(CaseClauses *) = 0;
virtual void endVisit(CaseClauses *) {} virtual void endVisit(CaseClauses *) = 0;
virtual bool visit(CaseClause *) { return true; } virtual bool visit(CaseClause *) = 0;
virtual void endVisit(CaseClause *) {} virtual void endVisit(CaseClause *) = 0;
virtual bool visit(DefaultClause *) { return true; } virtual bool visit(DefaultClause *) = 0;
virtual void endVisit(DefaultClause *) {} virtual void endVisit(DefaultClause *) = 0;
virtual bool visit(LabelledStatement *) { return true; } virtual bool visit(LabelledStatement *) = 0;
virtual void endVisit(LabelledStatement *) {} virtual void endVisit(LabelledStatement *) = 0;
virtual bool visit(ThrowStatement *) { return true; } virtual bool visit(ThrowStatement *) = 0;
virtual void endVisit(ThrowStatement *) {} virtual void endVisit(ThrowStatement *) = 0;
virtual bool visit(TryStatement *) { return true; } virtual bool visit(TryStatement *) = 0;
virtual void endVisit(TryStatement *) {} virtual void endVisit(TryStatement *) = 0;
virtual bool visit(Catch *) { return true; } virtual bool visit(Catch *) = 0;
virtual void endVisit(Catch *) {} virtual void endVisit(Catch *) = 0;
virtual bool visit(Finally *) { return true; } virtual bool visit(Finally *) = 0;
virtual void endVisit(Finally *) {} virtual void endVisit(Finally *) = 0;
virtual bool visit(FunctionDeclaration *) { return true; } virtual bool visit(FunctionDeclaration *) = 0;
virtual void endVisit(FunctionDeclaration *) {} virtual void endVisit(FunctionDeclaration *) = 0;
virtual bool visit(FunctionExpression *) { return true; } virtual bool visit(FunctionExpression *) = 0;
virtual void endVisit(FunctionExpression *) {} virtual void endVisit(FunctionExpression *) = 0;
virtual bool visit(FormalParameterList *) { return true; } virtual bool visit(FormalParameterList *) = 0;
virtual void endVisit(FormalParameterList *) {} virtual void endVisit(FormalParameterList *) = 0;
virtual bool visit(ClassExpression *) { return true; } virtual bool visit(ClassExpression *) = 0;
virtual void endVisit(ClassExpression *) {} virtual void endVisit(ClassExpression *) = 0;
virtual bool visit(ClassDeclaration *) { return true; } virtual bool visit(ClassDeclaration *) = 0;
virtual void endVisit(ClassDeclaration *) {} virtual void endVisit(ClassDeclaration *) = 0;
virtual bool visit(ClassElementList *) { return true; } virtual bool visit(ClassElementList *) = 0;
virtual void endVisit(ClassElementList *) {} virtual void endVisit(ClassElementList *) = 0;
virtual bool visit(Program *) { return true; } virtual bool visit(Program *) = 0;
virtual void endVisit(Program *) {} virtual void endVisit(Program *) = 0;
virtual bool visit(NameSpaceImport *) { return true; } virtual bool visit(NameSpaceImport *) = 0;
virtual void endVisit(NameSpaceImport *) {} virtual void endVisit(NameSpaceImport *) = 0;
virtual bool visit(ImportSpecifier *) { return true; } virtual bool visit(ImportSpecifier *) = 0;
virtual void endVisit(ImportSpecifier *) {} virtual void endVisit(ImportSpecifier *) = 0;
virtual bool visit(ImportsList *) { return true; } virtual bool visit(ImportsList *) = 0;
virtual void endVisit(ImportsList *) {} virtual void endVisit(ImportsList *) = 0;
virtual bool visit(NamedImports *) { return true; } virtual bool visit(NamedImports *) = 0;
virtual void endVisit(NamedImports *) {} virtual void endVisit(NamedImports *) = 0;
virtual bool visit(FromClause *) { return true; } virtual bool visit(FromClause *) = 0;
virtual void endVisit(FromClause *) {} virtual void endVisit(FromClause *) = 0;
virtual bool visit(ImportClause *) { return true; } virtual bool visit(ImportClause *) = 0;
virtual void endVisit(ImportClause *) {} virtual void endVisit(ImportClause *) = 0;
virtual bool visit(ImportDeclaration *) { return true; } virtual bool visit(ImportDeclaration *) = 0;
virtual void endVisit(ImportDeclaration *) {} virtual void endVisit(ImportDeclaration *) = 0;
virtual bool visit(ExportSpecifier *) { return true; } virtual bool visit(ExportSpecifier *) = 0;
virtual void endVisit(ExportSpecifier *) {} virtual void endVisit(ExportSpecifier *) = 0;
virtual bool visit(ExportsList *) { return true; } virtual bool visit(ExportsList *) = 0;
virtual void endVisit(ExportsList *) {} virtual void endVisit(ExportsList *) = 0;
virtual bool visit(ExportClause *) { return true; } virtual bool visit(ExportClause *) = 0;
virtual void endVisit(ExportClause *) {} virtual void endVisit(ExportClause *) = 0;
virtual bool visit(ExportDeclaration *) { return true; } virtual bool visit(ExportDeclaration *) = 0;
virtual void endVisit(ExportDeclaration *) {} virtual void endVisit(ExportDeclaration *) = 0;
virtual bool visit(ModuleItem *) { return true; } virtual bool visit(ESModule *) = 0;
virtual void endVisit(ModuleItem *) {} virtual void endVisit(ESModule *) = 0;
virtual bool visit(ESModule *) { return true; } virtual bool visit(DebuggerStatement *) = 0;
virtual void endVisit(ESModule *) {} virtual void endVisit(DebuggerStatement *) = 0;
virtual bool visit(DebuggerStatement *) { return true; } virtual bool visit(Type *) = 0;
virtual void endVisit(DebuggerStatement *) {} virtual void endVisit(Type *) = 0;
virtual bool visit(Type *) { return true; } virtual bool visit(TypeArgumentList *) = 0;
virtual void endVisit(Type *) {} virtual void endVisit(TypeArgumentList *) = 0;
virtual bool visit(TypeArgumentList *) { return true; } virtual bool visit(TypeAnnotation *) = 0;
virtual void endVisit(TypeArgumentList *) {} virtual void endVisit(TypeAnnotation *) = 0;
virtual bool visit(TypeAnnotation *) { return true; } virtual void throwRecursionDepthError() = 0;
virtual void endVisit(TypeAnnotation *) {}
virtual void throwRecursionDepthError() {}
quint16 recursionDepth() const { return m_recursionDepth; } quint16 recursionDepth() const { return m_recursionDepth; }
@@ -406,6 +411,339 @@ protected:
friend class RecursionDepthCheck; friend class RecursionDepthCheck;
}; };
class QML_PARSER_EXPORT Visitor: public BaseVisitor
{
public:
Visitor(quint16 parentRecursionDepth = 0);
bool preVisit(Node *) override { return true; }
void postVisit(Node *) override {}
// Ui
bool visit(UiProgram *) override { return true; }
bool visit(UiHeaderItemList *) override { return true; }
bool visit(UiPragma *) override { return true; }
bool visit(UiImport *) override { return true; }
bool visit(UiPublicMember *) override { return true; }
bool visit(UiSourceElement *) override { return true; }
bool visit(UiObjectDefinition *) override { return true; }
bool visit(UiObjectInitializer *) override { return true; }
bool visit(UiObjectBinding *) override { return true; }
bool visit(UiScriptBinding *) override { return true; }
bool visit(UiArrayBinding *) override { return true; }
bool visit(UiParameterList *) override { return true; }
bool visit(UiObjectMemberList *) override { return true; }
bool visit(UiArrayMemberList *) override { return true; }
bool visit(UiQualifiedId *) override { return true; }
bool visit(UiEnumDeclaration *) override { return true; }
bool visit(UiEnumMemberList *) override { return true; }
bool visit(UiVersionSpecifier *) override { return true; }
bool visit(UiInlineComponent *) override { return true; }
bool visit(UiAnnotation *) override { return true; }
bool visit(UiAnnotationList *) override { return true; }
bool visit(UiRequired *) override { return true; }
void endVisit(UiProgram *) override {}
void endVisit(UiImport *) override {}
void endVisit(UiHeaderItemList *) override {}
void endVisit(UiPragma *) override {}
void endVisit(UiPublicMember *) override {}
void endVisit(UiSourceElement *) override {}
void endVisit(UiObjectDefinition *) override {}
void endVisit(UiObjectInitializer *) override {}
void endVisit(UiObjectBinding *) override {}
void endVisit(UiScriptBinding *) override {}
void endVisit(UiArrayBinding *) override {}
void endVisit(UiParameterList *) override {}
void endVisit(UiObjectMemberList *) override {}
void endVisit(UiArrayMemberList *) override {}
void endVisit(UiQualifiedId *) override {}
void endVisit(UiEnumDeclaration *) override {}
void endVisit(UiEnumMemberList *) override {}
void endVisit(UiVersionSpecifier *) override {}
void endVisit(UiInlineComponent *) override {}
void endVisit(UiAnnotation *) override {}
void endVisit(UiAnnotationList *) override {}
void endVisit(UiRequired *) override {}
// QmlJS
bool visit(ThisExpression *) override { return true; }
void endVisit(ThisExpression *) override {}
bool visit(IdentifierExpression *) override { return true; }
void endVisit(IdentifierExpression *) override {}
bool visit(NullExpression *) override { return true; }
void endVisit(NullExpression *) override {}
bool visit(TrueLiteral *) override { return true; }
void endVisit(TrueLiteral *) override {}
bool visit(FalseLiteral *) override { return true; }
void endVisit(FalseLiteral *) override {}
bool visit(SuperLiteral *) override { return true; }
void endVisit(SuperLiteral *) override {}
bool visit(StringLiteral *) override { return true; }
void endVisit(StringLiteral *) override {}
bool visit(TemplateLiteral *) override { return true; }
void endVisit(TemplateLiteral *) override {}
bool visit(NumericLiteral *) override { return true; }
void endVisit(NumericLiteral *) override {}
bool visit(RegExpLiteral *) override { return true; }
void endVisit(RegExpLiteral *) override {}
bool visit(ArrayPattern *) override { return true; }
void endVisit(ArrayPattern *) override {}
bool visit(ObjectPattern *) override { return true; }
void endVisit(ObjectPattern *) override {}
bool visit(PatternElementList *) override { return true; }
void endVisit(PatternElementList *) override {}
bool visit(PatternPropertyList *) override { return true; }
void endVisit(PatternPropertyList *) override {}
bool visit(PatternElement *) override { return true; }
void endVisit(PatternElement *) override {}
bool visit(PatternProperty *) override { return true; }
void endVisit(PatternProperty *) override {}
bool visit(Elision *) override { return true; }
void endVisit(Elision *) override {}
bool visit(NestedExpression *) override { return true; }
void endVisit(NestedExpression *) override {}
bool visit(IdentifierPropertyName *) override { return true; }
void endVisit(IdentifierPropertyName *) override {}
bool visit(StringLiteralPropertyName *) override { return true; }
void endVisit(StringLiteralPropertyName *) override {}
bool visit(NumericLiteralPropertyName *) override { return true; }
void endVisit(NumericLiteralPropertyName *) override {}
bool visit(ComputedPropertyName *) override { return true; }
void endVisit(ComputedPropertyName *) override {}
bool visit(ArrayMemberExpression *) override { return true; }
void endVisit(ArrayMemberExpression *) override {}
bool visit(FieldMemberExpression *) override { return true; }
void endVisit(FieldMemberExpression *) override {}
bool visit(TaggedTemplate *) override { return true; }
void endVisit(TaggedTemplate *) override {}
bool visit(NewMemberExpression *) override { return true; }
void endVisit(NewMemberExpression *) override {}
bool visit(NewExpression *) override { return true; }
void endVisit(NewExpression *) override {}
bool visit(CallExpression *) override { return true; }
void endVisit(CallExpression *) override {}
bool visit(ArgumentList *) override { return true; }
void endVisit(ArgumentList *) override {}
bool visit(PostIncrementExpression *) override { return true; }
void endVisit(PostIncrementExpression *) override {}
bool visit(PostDecrementExpression *) override { return true; }
void endVisit(PostDecrementExpression *) override {}
bool visit(DeleteExpression *) override { return true; }
void endVisit(DeleteExpression *) override {}
bool visit(VoidExpression *) override { return true; }
void endVisit(VoidExpression *) override {}
bool visit(TypeOfExpression *) override { return true; }
void endVisit(TypeOfExpression *) override {}
bool visit(PreIncrementExpression *) override { return true; }
void endVisit(PreIncrementExpression *) override {}
bool visit(PreDecrementExpression *) override { return true; }
void endVisit(PreDecrementExpression *) override {}
bool visit(UnaryPlusExpression *) override { return true; }
void endVisit(UnaryPlusExpression *) override {}
bool visit(UnaryMinusExpression *) override { return true; }
void endVisit(UnaryMinusExpression *) override {}
bool visit(TildeExpression *) override { return true; }
void endVisit(TildeExpression *) override {}
bool visit(NotExpression *) override { return true; }
void endVisit(NotExpression *) override {}
bool visit(BinaryExpression *) override { return true; }
void endVisit(BinaryExpression *) override {}
bool visit(ConditionalExpression *) override { return true; }
void endVisit(ConditionalExpression *) override {}
bool visit(Expression *) override { return true; }
void endVisit(Expression *) override {}
bool visit(Block *) override { return true; }
void endVisit(Block *) override {}
bool visit(StatementList *) override { return true; }
void endVisit(StatementList *) override {}
bool visit(VariableStatement *) override { return true; }
void endVisit(VariableStatement *) override {}
bool visit(VariableDeclarationList *) override { return true; }
void endVisit(VariableDeclarationList *) override {}
bool visit(EmptyStatement *) override { return true; }
void endVisit(EmptyStatement *) override {}
bool visit(ExpressionStatement *) override { return true; }
void endVisit(ExpressionStatement *) override {}
bool visit(IfStatement *) override { return true; }
void endVisit(IfStatement *) override {}
bool visit(DoWhileStatement *) override { return true; }
void endVisit(DoWhileStatement *) override {}
bool visit(WhileStatement *) override { return true; }
void endVisit(WhileStatement *) override {}
bool visit(ForStatement *) override { return true; }
void endVisit(ForStatement *) override {}
bool visit(ForEachStatement *) override { return true; }
void endVisit(ForEachStatement *) override {}
bool visit(ContinueStatement *) override { return true; }
void endVisit(ContinueStatement *) override {}
bool visit(BreakStatement *) override { return true; }
void endVisit(BreakStatement *) override {}
bool visit(ReturnStatement *) override { return true; }
void endVisit(ReturnStatement *) override {}
bool visit(YieldExpression *) override { return true; }
void endVisit(YieldExpression *) override {}
bool visit(WithStatement *) override { return true; }
void endVisit(WithStatement *) override {}
bool visit(SwitchStatement *) override { return true; }
void endVisit(SwitchStatement *) override {}
bool visit(CaseBlock *) override { return true; }
void endVisit(CaseBlock *) override {}
bool visit(CaseClauses *) override { return true; }
void endVisit(CaseClauses *) override {}
bool visit(CaseClause *) override { return true; }
void endVisit(CaseClause *) override {}
bool visit(DefaultClause *) override { return true; }
void endVisit(DefaultClause *) override {}
bool visit(LabelledStatement *) override { return true; }
void endVisit(LabelledStatement *) override {}
bool visit(ThrowStatement *) override { return true; }
void endVisit(ThrowStatement *) override {}
bool visit(TryStatement *) override { return true; }
void endVisit(TryStatement *) override {}
bool visit(Catch *) override { return true; }
void endVisit(Catch *) override {}
bool visit(Finally *) override { return true; }
void endVisit(Finally *) override {}
bool visit(FunctionDeclaration *) override { return true; }
void endVisit(FunctionDeclaration *) override {}
bool visit(FunctionExpression *) override { return true; }
void endVisit(FunctionExpression *) override {}
bool visit(FormalParameterList *) override { return true; }
void endVisit(FormalParameterList *) override {}
bool visit(ClassExpression *) override { return true; }
void endVisit(ClassExpression *) override {}
bool visit(ClassDeclaration *) override { return true; }
void endVisit(ClassDeclaration *) override {}
bool visit(ClassElementList *) override { return true; }
void endVisit(ClassElementList *) override {}
bool visit(Program *) override { return true; }
void endVisit(Program *) override {}
bool visit(NameSpaceImport *) override { return true; }
void endVisit(NameSpaceImport *) override {}
bool visit(ImportSpecifier *) override { return true; }
void endVisit(ImportSpecifier *) override {}
bool visit(ImportsList *) override { return true; }
void endVisit(ImportsList *) override {}
bool visit(NamedImports *) override { return true; }
void endVisit(NamedImports *) override {}
bool visit(FromClause *) override { return true; }
void endVisit(FromClause *) override {}
bool visit(ImportClause *) override { return true; }
void endVisit(ImportClause *) override {}
bool visit(ImportDeclaration *) override { return true; }
void endVisit(ImportDeclaration *) override {}
bool visit(ExportSpecifier *) override { return true; }
void endVisit(ExportSpecifier *) override {}
bool visit(ExportsList *) override { return true; }
void endVisit(ExportsList *) override {}
bool visit(ExportClause *) override { return true; }
void endVisit(ExportClause *) override {}
bool visit(ExportDeclaration *) override { return true; }
void endVisit(ExportDeclaration *) override {}
bool visit(ESModule *) override { return true; }
void endVisit(ESModule *) override {}
bool visit(DebuggerStatement *) override { return true; }
void endVisit(DebuggerStatement *) override {}
bool visit(Type *) override { return true; }
void endVisit(Type *) override {}
bool visit(TypeArgumentList *) override { return true; }
void endVisit(TypeArgumentList *) override {}
bool visit(TypeAnnotation *) override { return true; }
void endVisit(TypeAnnotation *) override {}
};
} } // namespace AST } } // namespace AST
QT_QML_END_NAMESPACE QT_QML_END_NAMESPACE

View File

@@ -0,0 +1,98 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/qlogging.h>
#include <QtCore/qstring.h>
#include "qmljsglobal_p.h"
#include "qmljs/qmljsconstants.h"
// Include the API version here, to avoid complications when querying it for the
// QmlSourceLocation -> line/column change.
#include "qmljssourcelocation_p.h"
QT_BEGIN_NAMESPACE
namespace QmlJS {
class DiagnosticMessage
{
public:
QString message;
Severity::Enum kind = Severity::Error;
SourceLocation loc;
static Severity::Enum qtMsgTypeToKind(QtMsgType msgType) {
switch (msgType) {
case QtDebugMsg:
return Severity::Hint;
case QtWarningMsg:
return Severity::Warning;
case QtCriticalMsg:
return Severity::Error;
case QtFatalMsg:
return Severity::Error;
case QtInfoMsg:
return Severity::MaybeWarning;
}
}
DiagnosticMessage() {}
DiagnosticMessage(Severity::Enum kind, SourceLocation loc, QString message):
message(message), kind(kind), loc(loc)
{ }
bool isError() const
{
return kind == Severity::Error;
}
bool isWarning() const
{
return kind == Severity::Warning;
}
bool isValid() const
{
return !message.isEmpty();
}
};
} // namespace QmlJS
Q_DECLARE_TYPEINFO(QmlJS::DiagnosticMessage, Q_MOVABLE_TYPE);
QT_END_NAMESPACE

View File

@@ -109,9 +109,9 @@ void Engine::setCode(const QString &code)
{ _code = code; } { _code = code; }
void Engine::addComment(int pos, int len, int line, int col) void Engine::addComment(int pos, int len, int line, int col)
{ if (len > 0) _comments.append(QmlJS::AST::SourceLocation(pos, len, line, col)); } { if (len > 0) _comments.append(QmlJS::SourceLocation(pos, len, line, col)); }
QList<QmlJS::AST::SourceLocation> Engine::comments() const QList<QmlJS::SourceLocation> Engine::comments() const
{ return _comments; } { return _comments; }
Lexer *Engine::lexer() const Lexer *Engine::lexer() const

View File

@@ -37,8 +37,9 @@
// //
#include "qmljsglobal_p.h" #include "qmljsglobal_p.h"
#include "qmljsastfwd_p.h" #include "qmljs/parser/qmljssourcelocation_p.h"
#include "qmljsmemorypool_p.h"
#include "qmljs/parser/qmljsmemorypool_p.h"
#include <QString> #include <QString>
#include <QSet> #include <QSet>
@@ -61,49 +62,28 @@ public:
virtual void importFile(const QString &jsfile, const QString &module, int line, int column) virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
{ {
Q_UNUSED(jsfile) Q_UNUSED(jsfile);
Q_UNUSED(module) Q_UNUSED(module);
Q_UNUSED(line) Q_UNUSED(line);
Q_UNUSED(column) Q_UNUSED(column);
} }
virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column) virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
{ {
Q_UNUSED(uri) Q_UNUSED(uri);
Q_UNUSED(version) Q_UNUSED(version);
Q_UNUSED(module) Q_UNUSED(module);
Q_UNUSED(line) Q_UNUSED(line);
Q_UNUSED(column) Q_UNUSED(column);
} }
}; };
class QML_PARSER_EXPORT DiagnosticMessage
{
public:
DiagnosticMessage() {}
DiagnosticMessage(Severity::Enum kind, const AST::SourceLocation &loc, const QString &message)
: kind(kind), loc(loc), message(message) {}
bool isWarning() const
{ return kind == Severity::Warning; }
bool isError() const
{ return kind == Severity::Error; }
Severity::Enum kind = Severity::Error;
AST::SourceLocation loc;
QString message;
};
class QML_PARSER_EXPORT Engine class QML_PARSER_EXPORT Engine
{ {
Lexer *_lexer; Lexer *_lexer;
Directives *_directives; Directives *_directives;
MemoryPool _pool; MemoryPool _pool;
QList<AST::SourceLocation> _comments; QList<SourceLocation> _comments;
QString _extraCode; QString _extraCode;
QString _code; QString _code;
@@ -115,7 +95,7 @@ public:
const QString &code() const { return _code; } const QString &code() const { return _code; }
void addComment(int pos, int len, int line, int col); void addComment(int pos, int len, int line, int col);
QList<AST::SourceLocation> comments() const; QList<SourceLocation> comments() const;
Lexer *lexer() const; Lexer *lexer() const;
void setLexer(Lexer *lexer); void setLexer(Lexer *lexer);

File diff suppressed because it is too large Load Diff

View File

@@ -3,9 +3,8 @@
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Toolkit. ** This file is part of Qt Creator.
** **
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage ** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in ** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the ** accordance with the commercial license agreement provided with the
@@ -22,84 +21,69 @@
** information to ensure the GNU General Public License requirements will ** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
** **
** $QT_END_LICENSE$ ***************************************************************************/
**
****************************************************************************/
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
// This file was generated by qlalr - DO NOT EDIT! // This file was generated by qlalr - DO NOT EDIT!
#ifndef QMLJSGRAMMAR_P_H #ifndef QMLJSGRAMMAR_P_H
#define QMLJSGRAMMAR_P_H #define QMLJSGRAMMAR_P_H
#include "qmljsglobal_p.h" #include "qmljsglobal_p.h"
QT_BEGIN_NAMESPACE
class QML_PARSER_EXPORT QmlJSGrammar class QML_PARSER_EXPORT QmlJSGrammar
{ {
public: public:
enum VariousConstants { enum VariousConstants {
EOF_SYMBOL = 0, EOF_SYMBOL = 0,
REDUCE_HERE = 128, REDUCE_HERE = 131,
T_AND = 1, T_AND = 1,
T_AND_AND = 2, T_AND_AND = 2,
T_AND_EQ = 3, T_AND_EQ = 3,
T_ARROW = 95, T_ARROW = 96,
T_AS = 113, T_AS = 116,
T_AT = 90,
T_AUTOMATIC_SEMICOLON = 64, T_AUTOMATIC_SEMICOLON = 64,
T_BREAK = 4, T_BREAK = 4,
T_CASE = 5, T_CASE = 5,
T_CATCH = 6, T_CATCH = 6,
T_CLASS = 100, T_CLASS = 102,
T_COLON = 7, T_COLON = 7,
T_COMMA = 8, T_COMMA = 8,
T_COMMENT = 93, T_COMMENT = 94,
T_COMPATIBILITY_SEMICOLON = 94, T_COMPATIBILITY_SEMICOLON = 95,
T_COMPONENT = 108,
T_CONST = 88, T_CONST = 88,
T_CONTINUE = 9, T_CONTINUE = 9,
T_DEBUGGER = 90, T_DEBUGGER = 91,
T_DEFAULT = 10, T_DEFAULT = 10,
T_DELETE = 11, T_DELETE = 11,
T_DIVIDE_ = 12, T_DIVIDE_ = 12,
T_DIVIDE_EQ = 13, T_DIVIDE_EQ = 13,
T_DO = 14, T_DO = 14,
T_DOT = 15, T_DOT = 15,
T_ELLIPSIS = 97, T_ELLIPSIS = 99,
T_ELSE = 16, T_ELSE = 16,
T_ENUM = 96, T_ENUM = 98,
T_EQ = 17, T_EQ = 17,
T_EQ_EQ = 18, T_EQ_EQ = 18,
T_EQ_EQ_EQ = 19, T_EQ_EQ_EQ = 19,
T_ERROR = 117, T_ERROR = 120,
T_EXPORT = 103, T_EXPORT = 105,
T_EXTENDS = 101, T_EXTENDS = 103,
T_FALSE = 87, T_FALSE = 87,
T_FEED_JS_EXPRESSION = 121, T_FEED_JS_EXPRESSION = 124,
T_FEED_JS_MODULE = 123, T_FEED_JS_MODULE = 126,
T_FEED_JS_SCRIPT = 122, T_FEED_JS_SCRIPT = 125,
T_FEED_JS_STATEMENT = 120, T_FEED_JS_STATEMENT = 123,
T_FEED_UI_OBJECT_MEMBER = 119, T_FEED_UI_OBJECT_MEMBER = 122,
T_FEED_UI_PROGRAM = 118, T_FEED_UI_PROGRAM = 121,
T_FINALLY = 20, T_FINALLY = 20,
T_FOR = 21, T_FOR = 21,
T_FORCE_BLOCK = 125, T_FORCE_BLOCK = 128,
T_FORCE_DECLARATION = 124, T_FORCE_DECLARATION = 127,
T_FOR_LOOKAHEAD_OK = 126, T_FOR_LOOKAHEAD_OK = 129,
T_FROM = 104, T_FROM = 106,
T_FUNCTION = 23, T_FUNCTION = 23,
T_FUNCTION_STAR = 22, T_FUNCTION_STAR = 22,
T_GE = 24, T_GE = 24,
T_GET = 115, T_GET = 118,
T_GT = 25, T_GT = 25,
T_GT_GT = 26, T_GT_GT = 26,
T_GT_GT_EQ = 27, T_GT_GT_EQ = 27,
@@ -107,7 +91,7 @@ public:
T_GT_GT_GT_EQ = 29, T_GT_GT_GT_EQ = 29,
T_IDENTIFIER = 30, T_IDENTIFIER = 30,
T_IF = 31, T_IF = 31,
T_IMPORT = 111, T_IMPORT = 114,
T_IN = 32, T_IN = 32,
T_INSTANCEOF = 33, T_INSTANCEOF = 33,
T_LBRACE = 34, T_LBRACE = 34,
@@ -121,50 +105,51 @@ public:
T_MINUS = 41, T_MINUS = 41,
T_MINUS_EQ = 42, T_MINUS_EQ = 42,
T_MINUS_MINUS = 43, T_MINUS_MINUS = 43,
T_MULTILINE_STRING_LITERAL = 92, T_MULTILINE_STRING_LITERAL = 93,
T_NEW = 44, T_NEW = 44,
T_NOT = 45, T_NOT = 45,
T_NOT_EQ = 46, T_NOT_EQ = 46,
T_NOT_EQ_EQ = 47, T_NOT_EQ_EQ = 47,
T_NO_SUBSTITUTION_TEMPLATE = 106, T_NO_SUBSTITUTION_TEMPLATE = 109,
T_NULL = 85, T_NULL = 85,
T_NUMERIC_LITERAL = 48, T_NUMERIC_LITERAL = 48,
T_OF = 114, T_OF = 117,
T_ON = 127, T_ON = 130,
T_OR = 49, T_OR = 49,
T_OR_EQ = 51, T_OR_EQ = 51,
T_OR_OR = 52, T_OR_OR = 52,
T_PLUS = 53, T_PLUS = 53,
T_PLUS_EQ = 54, T_PLUS_EQ = 54,
T_PLUS_PLUS = 55, T_PLUS_PLUS = 55,
T_PRAGMA = 112, T_PRAGMA = 115,
T_PROPERTY = 70, T_PROPERTY = 70,
T_PUBLIC = 110, T_PUBLIC = 113,
T_QUESTION = 56, T_QUESTION = 56,
T_QUESTION_QUESTION = 97,
T_RBRACE = 57, T_RBRACE = 57,
T_RBRACKET = 58, T_RBRACKET = 58,
T_READONLY = 72, T_READONLY = 72,
T_REMAINDER = 59, T_REMAINDER = 59,
T_REMAINDER_EQ = 60, T_REMAINDER_EQ = 60,
T_REQUIRED = 105, T_REQUIRED = 107,
T_RESERVED_WORD = 91, T_RESERVED_WORD = 92,
T_RETURN = 61, T_RETURN = 61,
T_RPAREN = 62, T_RPAREN = 62,
T_SEMICOLON = 63, T_SEMICOLON = 63,
T_SET = 116, T_SET = 119,
T_SIGNAL = 71, T_SIGNAL = 71,
T_STAR = 65, T_STAR = 65,
T_STAR_EQ = 68, T_STAR_EQ = 68,
T_STAR_STAR = 66, T_STAR_STAR = 66,
T_STAR_STAR_EQ = 67, T_STAR_STAR_EQ = 67,
T_STATIC = 102, T_STATIC = 104,
T_STRING_LITERAL = 69, T_STRING_LITERAL = 69,
T_SUPER = 99, T_SUPER = 101,
T_SWITCH = 73, T_SWITCH = 73,
T_TEMPLATE_HEAD = 107, T_TEMPLATE_HEAD = 110,
T_TEMPLATE_MIDDLE = 108, T_TEMPLATE_MIDDLE = 111,
T_TEMPLATE_TAIL = 109, T_TEMPLATE_TAIL = 112,
T_THEN = 129, T_THEN = 132,
T_THIS = 74, T_THIS = 74,
T_THROW = 75, T_THROW = 75,
T_TILDE = 76, T_TILDE = 76,
@@ -176,24 +161,31 @@ public:
T_VOID = 80, T_VOID = 80,
T_WHILE = 81, T_WHILE = 81,
T_WITH = 82, T_WITH = 82,
T_WITHOUTAS = 133,
T_XOR = 83, T_XOR = 83,
T_XOR_EQ = 84, T_XOR_EQ = 84,
T_YIELD = 98, T_YIELD = 100,
ACCEPT_STATE = 1055, ACCEPT_STATE = 1098,
RULE_COUNT = 591, RULE_COUNT = 616,
STATE_COUNT = 1056, STATE_COUNT = 1099,
TERMINAL_COUNT = 130, TERMINAL_COUNT = 134,
NON_TERMINAL_COUNT = 227, NON_TERMINAL_COUNT = 238,
GOTO_INDEX_OFFSET = 1056, GOTO_INDEX_OFFSET = 1099,
GOTO_INFO_OFFSET = 6757, GOTO_INFO_OFFSET = 6942,
GOTO_CHECK_OFFSET = 6757 GOTO_CHECK_OFFSET = 6942
}; };
static const char *const spell[]; static const char *const spell[];
static const short lhs[]; static const short lhs[];
static const short rhs[]; static const short rhs[];
#ifndef QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
static const int rule_index[];
static const int rule_info[];
#endif // QLALR_NO_QMLJSGRAMMAR_DEBUG_INFO
static const short goto_default[]; static const short goto_default[];
static const short action_default[]; static const short action_default[];
static const short action_index[]; static const short action_index[];
@@ -221,6 +213,5 @@ public:
}; };
QT_END_NAMESPACE
#endif // QMLJSGRAMMAR_P_H #endif // QMLJSGRAMMAR_P_H

View File

@@ -821,6 +821,25 @@ static inline int classify9(const QChar *s, int parseModeFlags) {
} }
} }
} }
else if (s[0].unicode() == 'c') {
if (s[1].unicode() == 'o') {
if (s[2].unicode() == 'm') {
if (s[3].unicode() == 'p') {
if (s[4].unicode() == 'o') {
if (s[5].unicode() == 'n') {
if (s[6].unicode() == 'e') {
if (s[7].unicode() == 'n') {
if (s[8].unicode() == 't') {
return (parseModeFlags & Lexer::QmlMode) ? int(Lexer::T_COMPONENT) : int(Lexer::T_IDENTIFIER);
}
}
}
}
}
}
}
}
}
return Lexer::T_IDENTIFIER; return Lexer::T_IDENTIFIER;
} }

View File

@@ -25,17 +25,19 @@
#include "qmljslexer_p.h" #include "qmljslexer_p.h"
#include "qmljsengine_p.h" #include "qmljsengine_p.h"
#include "qmljsmemorypool_p.h"
#include "qmljskeywords_p.h" #include "qmljskeywords_p.h"
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
#include "qmljs/parser/qmljsmemorypool_p.h"
#include <QtCore/qcoreapplication.h> #include <QtCore/qcoreapplication.h>
#include <QtCore/qvarlengtharray.h> #include <QtCore/qvarlengtharray.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
#include <QtCore/QScopedValueRollback> #include <QtCore/QScopedValueRollback>
QT_BEGIN_NAMESPACE QT_QML_BEGIN_NAMESPACE
Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
QT_END_NAMESPACE QT_QML_END_NAMESPACE
using namespace QmlJS; using namespace QmlJS;
@@ -564,7 +566,14 @@ again:
case ']': return T_RBRACKET; case ']': return T_RBRACKET;
case '[': return T_LBRACKET; case '[': return T_LBRACKET;
case '?': return T_QUESTION; case '?': {
if (_char == QLatin1Char('?')) {
scanChar();
return T_QUESTION_QUESTION;
}
return T_QUESTION;
}
case '>': case '>':
if (_char == QLatin1Char('>')) { if (_char == QLatin1Char('>')) {
@@ -696,6 +705,8 @@ again:
case ')': return T_RPAREN; case ')': return T_RPAREN;
case '(': return T_LPAREN; case '(': return T_LPAREN;
case '@': return T_AT;
case '&': case '&':
if (_char == QLatin1Char('=')) { if (_char == QLatin1Char('=')) {
scanChar(); scanChar();

View File

@@ -36,8 +36,8 @@
// We mean it. // We mean it.
// //
#include "qmljsglobal_p.h" #include "qmljs/parser/qmljsglobal_p.h"
#include "qmljsgrammar_p.h" #include "qmljs/parser/qmljsgrammar_p.h"
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
#include <QtCore/qstack.h> #include <QtCore/qstack.h>

View File

@@ -37,8 +37,6 @@
// //
#include "qmljsglobal_p.h" #include "qmljsglobal_p.h"
#include <QtCore/qglobal.h>
#include <QtCore/qshareddata.h> #include <QtCore/qshareddata.h>
#include <QtCore/qdebug.h> #include <QtCore/qdebug.h>
@@ -50,7 +48,7 @@ namespace QmlJS {
class Managed; class Managed;
class QML_PARSER_EXPORT MemoryPool : public QSharedData class MemoryPool : public QSharedData
{ {
MemoryPool(const MemoryPool &other); MemoryPool(const MemoryPool &other);
void operator =(const MemoryPool &other); void operator =(const MemoryPool &other);
@@ -73,7 +71,7 @@ public:
inline void *allocate(size_t size) inline void *allocate(size_t size)
{ {
size = (size + 7) & ~7; size = (size + 7) & ~size_t(7);
if (Q_LIKELY(_ptr && (_ptr + size < _end))) { if (Q_LIKELY(_ptr && (_ptr + size < _end))) {
void *addr = _ptr; void *addr = _ptr;
_ptr += size; _ptr += size;
@@ -89,6 +87,8 @@ public:
} }
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); } template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
template <typename Tp, typename... Ta> Tp *New(Ta... args)
{ return new (this->allocate(sizeof(Tp))) Tp(args...); }
QStringRef newString(const QString &string) { QStringRef newString(const QString &string) {
strings.append(new QString(string)); strings.append(new QString(string));
@@ -98,7 +98,9 @@ public:
private: private:
Q_NEVER_INLINE void *allocate_helper(size_t size) Q_NEVER_INLINE void *allocate_helper(size_t size)
{ {
Q_ASSERT(size < BLOCK_SIZE); size_t currentBlockSize = DEFAULT_BLOCK_SIZE;
while (Q_UNLIKELY(size >= currentBlockSize))
currentBlockSize *= 2;
if (++_blockCount == _allocatedBlocks) { if (++_blockCount == _allocatedBlocks) {
if (! _allocatedBlocks) if (! _allocatedBlocks)
@@ -106,7 +108,7 @@ private:
else else
_allocatedBlocks *= 2; _allocatedBlocks *= 2;
_blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks); _blocks = reinterpret_cast<char **>(realloc(_blocks, sizeof(char *) * size_t(_allocatedBlocks)));
Q_CHECK_PTR(_blocks); Q_CHECK_PTR(_blocks);
for (int index = _blockCount; index < _allocatedBlocks; ++index) for (int index = _blockCount; index < _allocatedBlocks; ++index)
@@ -116,12 +118,12 @@ private:
char *&block = _blocks[_blockCount]; char *&block = _blocks[_blockCount];
if (! block) { if (! block) {
block = (char *) malloc(BLOCK_SIZE); block = reinterpret_cast<char *>(malloc(currentBlockSize));
Q_CHECK_PTR(block); Q_CHECK_PTR(block);
} }
_ptr = block; _ptr = block;
_end = _ptr + BLOCK_SIZE; _end = _ptr + currentBlockSize;
void *addr = _ptr; void *addr = _ptr;
_ptr += size; _ptr += size;
@@ -138,12 +140,12 @@ private:
enum enum
{ {
BLOCK_SIZE = 8 * 1024, DEFAULT_BLOCK_SIZE = 8 * 1024,
DEFAULT_BLOCK_COUNT = 8 DEFAULT_BLOCK_COUNT = 8
}; };
}; };
class QML_PARSER_EXPORT Managed class Managed
{ {
Q_DISABLE_COPY(Managed) Q_DISABLE_COPY(Managed)
public: public:

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +1,10 @@
#line 182 "qmljs.g"
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtQml module of the Qt Toolkit. ** This file is part of Qt Creator.
** **
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage ** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in ** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the ** accordance with the commercial license agreement provided with the
@@ -16,28 +13,16 @@
** and conditions see https://www.qt.io/terms-conditions. For further ** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us. ** information use the contact form at https://www.qt.io/contact-us.
** **
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage ** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU ** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General ** General Public License version 3 as published by the Free Software
** Public license version 3 or any later version approved by the KDE Free ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following ** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will ** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
** **
****************************************************************************/ ****************************************************************************/
#line 223 "qmljs.g"
// //
@@ -66,10 +51,11 @@
#ifndef QMLJSPARSER_P_H #ifndef QMLJSPARSER_P_H
#define QMLJSPARSER_P_H #define QMLJSPARSER_P_H
#include "qmljsglobal_p.h" #include "qmljs/parser/qmljsglobal_p.h"
#include "qmljsgrammar_p.h" #include "qmljs/parser/qmljsgrammar_p.h"
#include "qmljsast_p.h" #include "qmljs/parser/qmljsast_p.h"
#include "qmljsengine_p.h" #include "qmljs/parser/qmljsengine_p.h"
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
#include <QtCore/qlist.h> #include <QtCore/qlist.h>
#include <QtCore/qstring.h> #include <QtCore/qstring.h>
@@ -143,6 +129,8 @@ public:
AST::UiQualifiedId *UiQualifiedId; AST::UiQualifiedId *UiQualifiedId;
AST::UiEnumMemberList *UiEnumMemberList; AST::UiEnumMemberList *UiEnumMemberList;
AST::UiVersionSpecifier *UiVersionSpecifier; AST::UiVersionSpecifier *UiVersionSpecifier;
AST::UiAnnotation *UiAnnotation;
AST::UiAnnotationList *UiAnnotationList;
}; };
public: public:
@@ -224,7 +212,7 @@ protected:
inline QStringRef &rawStringRef(int index) inline QStringRef &rawStringRef(int index)
{ return rawString_stack [tos + index - 1]; } { return rawString_stack [tos + index - 1]; }
inline AST::SourceLocation &loc(int index) inline SourceLocation &loc(int index)
{ return location_stack [tos + index - 1]; } { return location_stack [tos + index - 1]; }
AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr); AST::UiQualifiedId *reparseAsQualifiedId(AST::ExpressionNode *expr);
@@ -232,20 +220,20 @@ protected:
void pushToken(int token); void pushToken(int token);
int lookaheadToken(Lexer *lexer); int lookaheadToken(Lexer *lexer);
static DiagnosticMessage compileError(const AST::SourceLocation &location, static DiagnosticMessage compileError(const SourceLocation &location,
const QString &message, Severity::Enum kind = Severity::Error) const QString &message, QtMsgType kind = QtCriticalMsg)
{ {
DiagnosticMessage error; DiagnosticMessage error;
error.loc = location; error.loc = location;
error.message = message; error.message = message;
error.kind = kind; error.kind = DiagnosticMessage::qtMsgTypeToKind(kind);
return error; return error;
} }
void syntaxError(const AST::SourceLocation &location, const char *message) { void syntaxError(const SourceLocation &location, const char *message) {
diagnostic_messages.append(compileError(location, QLatin1String(message))); diagnostic_messages.append(compileError(location, QLatin1String(message)));
} }
void syntaxError(const AST::SourceLocation &location, const QString &message) { void syntaxError(const SourceLocation &location, const QString &message) {
diagnostic_messages.append(compileError(location, message)); diagnostic_messages.append(compileError(location, message));
} }
@@ -258,7 +246,7 @@ protected:
int stack_size = 0; int stack_size = 0;
Value *sym_stack = nullptr; Value *sym_stack = nullptr;
int *state_stack = nullptr; int *state_stack = nullptr;
AST::SourceLocation *location_stack = nullptr; SourceLocation *location_stack = nullptr;
QVector<QStringRef> string_stack; QVector<QStringRef> string_stack;
QVector<QStringRef> rawString_stack; QVector<QStringRef> rawString_stack;
@@ -270,7 +258,7 @@ protected:
struct SavedToken { struct SavedToken {
int token; int token;
double dval; double dval;
AST::SourceLocation loc; SourceLocation loc;
QStringRef spell; QStringRef spell;
QStringRef raw; QStringRef raw;
}; };
@@ -279,8 +267,8 @@ protected:
double yylval = 0.; double yylval = 0.;
QStringRef yytokenspell; QStringRef yytokenspell;
QStringRef yytokenraw; QStringRef yytokenraw;
AST::SourceLocation yylloc; SourceLocation yylloc;
AST::SourceLocation yyprevlloc; SourceLocation yyprevlloc;
SavedToken token_buffer[TOKEN_BUFFER_SIZE]; SavedToken token_buffer[TOKEN_BUFFER_SIZE];
SavedToken *first_token = nullptr; SavedToken *first_token = nullptr;
@@ -293,7 +281,7 @@ protected:
CE_ParenthesizedExpression, CE_ParenthesizedExpression,
CE_FormalParameterList CE_FormalParameterList
}; };
AST::SourceLocation coverExpressionErrorLocation; SourceLocation coverExpressionErrorLocation;
CoverExpressionType coverExpressionType = CE_Invalid; CoverExpressionType coverExpressionType = CE_Invalid;
QList<DiagnosticMessage> diagnostic_messages; QList<DiagnosticMessage> diagnostic_messages;
@@ -303,27 +291,27 @@ protected:
#line 1686 "qmljs.g" #line 1828 "qmljs.g"
#define J_SCRIPT_REGEXPLITERAL_RULE1 144 #define J_SCRIPT_REGEXPLITERAL_RULE1 161
#line 1698 "qmljs.g" #line 1840 "qmljs.g"
#define J_SCRIPT_REGEXPLITERAL_RULE2 145 #define J_SCRIPT_REGEXPLITERAL_RULE2 162
#line 3198 "qmljs.g" #line 3389 "qmljs.g"
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 435 #define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 460
#line 3850 "qmljs.g" #line 4041 "qmljs.g"
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 505 #define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 530
#line 4389 "qmljs.g" #line 4583 "qmljs.g"
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 574 #define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 599
#line 4673 "qmljs.g" #line 4867 "qmljs.g"
QT_QML_END_NAMESPACE QT_QML_END_NAMESPACE

View File

@@ -25,45 +25,45 @@
#pragma once #pragma once
#include <QtCore/qurl.h> #include "qmljsglobal_p.h"
#include <QtCore/qstring.h>
QT_BEGIN_NAMESPACE //
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
// ### Qt 6: should this be called QmlMessage, since it can have a message type? QT_QML_BEGIN_NAMESPACE
class QDebug;
class QmlErrorPrivate; namespace QmlJS {
class QmlError
class SourceLocation
{ {
public: public:
QmlError(); explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
QmlError(const QmlError &); : offset(offset), length(length),
QmlError &operator=(const QmlError &); startLine(line), startColumn(column)
~QmlError(); { }
bool isValid() const; bool isValid() const { return length != 0; }
QUrl url() const; quint32 begin() const { return offset; }
void setUrl(const QUrl &); quint32 end() const { return offset + length; }
QString description() const;
void setDescription(const QString &);
int line() const;
void setLine(int);
int column() const;
void setColumn(int);
QObject *object() const;
void setObject(QObject *);
QtMsgType messageType() const;
void setMessageType(QtMsgType messageType);
QString toString() const; // attributes
private: // ### encode
QmlErrorPrivate *d; quint32 offset;
quint32 length;
quint32 startLine;
quint32 startColumn;
}; };
QDebug operator<<(QDebug debug, const QmlError &error); } // namespace QmlJS
Q_DECLARE_TYPEINFO(QmlError, Q_MOVABLE_TYPE); QT_QML_END_NAMESPACE
QT_END_NAMESPACE

View File

@@ -62,7 +62,6 @@ Project {
prefix: "parser/" prefix: "parser/"
files: [ files: [
"qmldirparser.cpp", "qmldirparser_p.h", "qmldirparser.cpp", "qmldirparser_p.h",
"qmlerror.cpp", "qmlerror.h",
"qmljsast.cpp", "qmljsast_p.h", "qmljsast.cpp", "qmljsast_p.h",
"qmljsastfwd_p.h", "qmljsastfwd_p.h",
"qmljsastvisitor.cpp", "qmljsastvisitor_p.h", "qmljsastvisitor.cpp", "qmljsastvisitor_p.h",
@@ -73,6 +72,7 @@ Project {
"qmljslexer.cpp", "qmljslexer_p.h", "qmljslexer.cpp", "qmljslexer_p.h",
"qmljsmemorypool_p.h", "qmljsmemorypool_p.h",
"qmljsparser.cpp", "qmljsparser_p.h", "qmljsparser.cpp", "qmljsparser_p.h",
"qmljssourcelocation.cpp", "qmljssourcelocation_p.h",
] ]
} }

View File

@@ -162,6 +162,11 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
return switchObjectValue(parentObjectValue); return switchObjectValue(parentObjectValue);
} }
void Bind::throwRecursionDepthError()
{
_diagnosticMessages->append(DiagnosticMessage(Severity::Error, SourceLocation(), tr("Hit maximal recursion depth in AST visit")));
}
void Bind::accept(Node *node) void Bind::accept(Node *node)
{ {
Node::accept(node, this); Node::accept(node, this);
@@ -194,14 +199,8 @@ void Bind::endVisit(UiProgram *)
bool Bind::visit(UiImport *ast) bool Bind::visit(UiImport *ast)
{ {
ComponentVersion version; ComponentVersion version;
if (ast->versionToken.isValid()) { if (ast->version)
const QString versionString = _doc->source().mid(ast->versionToken.offset, ast->versionToken.length); version = ComponentVersion(ast->version->majorVersion, ast->version->minorVersion);
version = ComponentVersion(versionString);
if (!version.isValid()) {
_diagnosticMessages->append(
errorMessage(ast->versionToken, tr("expected two numbers separated by a dot")));
}
}
if (ast->importUri) { if (ast->importUri) {
if (!version.isValid()) { if (!version.isValid()) {

View File

@@ -84,6 +84,8 @@ protected:
ObjectValue *switchObjectValue(ObjectValue *newObjectValue); ObjectValue *switchObjectValue(ObjectValue *newObjectValue);
ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer); ObjectValue *bindObject(AST::UiQualifiedId *qualifiedTypeNameId, AST::UiObjectInitializer *initializer);
void throwRecursionDepthError() override;
private: private:
Document *_doc; Document *_doc;
ValueOwner _valueOwner; ValueOwner _valueOwner;

View File

@@ -313,6 +313,12 @@ protected:
_state = ReachesEnd; _state = ReachesEnd;
return false; return false;
} }
void throwRecursionDepthError() override
{
// handle differently? ReturnOrThrow declares unreachable code, but probably leads to bogus warnings
_state = ReachesEnd;
}
}; };
class MarkUnreachableCode : protected ReachesEndCheck class MarkUnreachableCode : protected ReachesEndCheck
@@ -352,6 +358,11 @@ protected:
if (message.isValid()) if (message.isValid())
_messages += message; _messages += message;
} }
void throwRecursionDepthError() override
{
_messages.append(Message(ErrHitMaximumRecursion, SourceLocation()));
}
}; };
class DeclarationsCheck : protected Visitor class DeclarationsCheck : protected Visitor
@@ -510,6 +521,11 @@ protected:
--_block; --_block;
} }
void throwRecursionDepthError() override
{
addMessage(ErrHitMaximumRecursion, SourceLocation());
}
private: private:
void addMessage(StaticAnalysis::Type type, const SourceLocation &loc, const QString &arg1 = QString()) void addMessage(StaticAnalysis::Type type, const SourceLocation &loc, const QString &arg1 = QString())
{ {
@@ -808,6 +824,11 @@ void Check::endVisit(UiObjectInitializer *)
m_idStack.pop(); m_idStack.pop();
} }
void Check::throwRecursionDepthError()
{
addMessage(ErrHitMaximumRecursion, SourceLocation());
}
void Check::checkProperty(UiQualifiedId *qualifiedId) void Check::checkProperty(UiQualifiedId *qualifiedId)
{ {
const QString id = toString(qualifiedId); const QString id = toString(qualifiedId);

View File

@@ -99,12 +99,13 @@ protected:
void endVisit(QmlJS::AST::UiObjectInitializer *) override; void endVisit(QmlJS::AST::UiObjectInitializer *) override;
void throwRecursionDepthError() override;
private: private:
void visitQmlObject(AST::Node *ast, AST::UiQualifiedId *typeId, void visitQmlObject(AST::Node *ast, AST::UiQualifiedId *typeId,
AST::UiObjectInitializer *initializer); AST::UiObjectInitializer *initializer);
const Value *checkScopeObjectMember(const AST::UiQualifiedId *id); const Value *checkScopeObjectMember(const AST::UiQualifiedId *id);
void checkAssignInCondition(AST::ExpressionNode *condition); void checkAssignInCondition(AST::ExpressionNode *condition);
void checkCaseFallthrough(AST::StatementList *statements, AST::SourceLocation errorLoc, AST::SourceLocation nextLoc); void checkCaseFallthrough(AST::StatementList *statements, SourceLocation errorLoc, SourceLocation nextLoc);
void checkProperty(QmlJS::AST::UiQualifiedId *); void checkProperty(QmlJS::AST::UiQualifiedId *);
void checkNewExpression(AST::ExpressionNode *node); void checkNewExpression(AST::ExpressionNode *node);
void checkBindingRhs(AST::Statement *statement); void checkBindingRhs(AST::Statement *statement);
@@ -112,7 +113,7 @@ private:
void addMessages(const QList<StaticAnalysis::Message> &messages); void addMessages(const QList<StaticAnalysis::Message> &messages);
void addMessage(const StaticAnalysis::Message &message); void addMessage(const StaticAnalysis::Message &message);
void addMessage(StaticAnalysis::Type type, const AST::SourceLocation &location, void addMessage(StaticAnalysis::Type type, const SourceLocation &location,
const QString &arg1 = QString(), const QString &arg2 = QString()); const QString &arg1 = QString(), const QString &arg2 = QString());
void scanCommentsForAnnotations(); void scanCommentsForAnnotations();
@@ -143,7 +144,7 @@ private:
class MessageTypeAndSuppression class MessageTypeAndSuppression
{ {
public: public:
AST::SourceLocation suppressionSource; SourceLocation suppressionSource;
StaticAnalysis::Type type; StaticAnalysis::Type type;
bool wasSuppressed; bool wasSuppressed;
}; };

View File

@@ -97,7 +97,7 @@ public:
QString path() const; QString path() const;
QString componentName() const; QString componentName() const;
QList<AST::SourceLocation> jsDirectives() const; QList<SourceLocation> jsDirectives() const;
private: private:
bool parse_helper(int kind); bool parse_helper(int kind);
@@ -111,7 +111,7 @@ private:
QString _path; QString _path;
QString _componentName; QString _componentName;
QString _source; QString _source;
QList<AST::SourceLocation> _jsdirectives; QList<SourceLocation> _jsdirectives;
QWeakPointer<Document> _ptr; QWeakPointer<Document> _ptr;
QByteArray _fingerprint; QByteArray _fingerprint;
int _editorRevision; int _editorRevision;

View File

@@ -29,6 +29,8 @@
#include "qmljsvalueowner.h" #include "qmljsvalueowner.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <QDebug>
using namespace QmlJS; using namespace QmlJS;
/*! /*!
@@ -668,3 +670,8 @@ bool Evaluate::visit(AST::DebuggerStatement *)
{ {
return false; return false;
} }
void Evaluate::throwRecursionDepthError()
{
qWarning("Evaluate hit maximum recursion error when visiting AST");
}

View File

@@ -145,6 +145,8 @@ protected:
bool visit(AST::StatementList *ast) override; bool visit(AST::StatementList *ast) override;
bool visit(AST::DebuggerStatement *ast) override; bool visit(AST::DebuggerStatement *ast) override;
void throwRecursionDepthError() override;
private: private:
QmlJS::Document::Ptr _doc; QmlJS::Document::Ptr _doc;
ValueOwner *_valueOwner; ValueOwner *_valueOwner;

View File

@@ -38,6 +38,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QApplication> #include <QApplication>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QString> #include <QString>
@@ -1992,7 +1993,7 @@ public:
} }
protected: protected:
bool visit(ArrayMemberExpression *ast) bool visit(ArrayMemberExpression *ast) override
{ {
if (IdentifierExpression *idExp = cast<IdentifierExpression *>(ast->base)) { if (IdentifierExpression *idExp = cast<IdentifierExpression *>(ast->base)) {
if (idExp->name == QLatin1String("arguments")) if (idExp->name == QLatin1String("arguments"))
@@ -2002,8 +2003,12 @@ protected:
} }
// don't go into nested functions // don't go into nested functions
bool visit(Program *) { return false; } bool visit(Program *) override { return false; }
bool visit(StatementList *) { return false; } bool visit(StatementList *) override { return false; }
void throwRecursionDepthError() override {
qWarning("Warning: Hit maximum recursion error visiting AST in UsesArgumentsArray");
}
}; };
} // anonymous namespace } // anonymous namespace

View File

@@ -101,8 +101,8 @@ public:
void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc); void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports); void loadImplicitDefaultImports(Imports *imports);
void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message); void error(const Document::Ptr &doc, const SourceLocation &loc, const QString &message);
void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message); void warning(const Document::Ptr &doc, const SourceLocation &loc, const QString &message);
void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message); void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message);
private: private:
@@ -516,13 +516,13 @@ bool LinkPrivate::importLibrary(const Document::Ptr &doc,
return true; return true;
} }
void LinkPrivate::error(const Document::Ptr &doc, const AST::SourceLocation &loc, void LinkPrivate::error(const Document::Ptr &doc, const SourceLocation &loc,
const QString &message) const QString &message)
{ {
appendDiagnostic(doc, DiagnosticMessage(Severity::Error, loc, message)); appendDiagnostic(doc, DiagnosticMessage(Severity::Error, loc, message));
} }
void LinkPrivate::warning(const Document::Ptr &doc, const AST::SourceLocation &loc, void LinkPrivate::warning(const Document::Ptr &doc, const SourceLocation &loc,
const QString &message) const QString &message)
{ {
appendDiagnostic(doc, DiagnosticMessage(Severity::Warning, loc, message)); appendDiagnostic(doc, DiagnosticMessage(Severity::Warning, loc, message));

View File

@@ -585,9 +585,11 @@ protected:
out(QString::fromLatin1("\"%1\"").arg(ast->fileName.toString())); out(QString::fromLatin1("\"%1\"").arg(ast->fileName.toString()));
else else
accept(ast->importUri); accept(ast->importUri);
if (ast->versionToken.isValid()) { if (ast->version) {
out(" "); out(" ");
out(ast->versionToken); out(QString::number(ast->version->majorVersion).toUtf8());
out(".");
out(QString::number(ast->version->minorVersion).toUtf8());
} }
if (!ast->importId.isNull()) { if (!ast->importId.isNull()) {
out(" as ", ast->asToken); out(" as ", ast->asToken);
@@ -1339,6 +1341,10 @@ protected:
} }
return false; return false;
} }
void throwRecursionDepthError() override {
out("/* ERROR: Hit recursion limit visiting AST, rewrite failed */");
}
}; };
} // anonymous namespace } // anonymous namespace

View File

@@ -26,6 +26,7 @@
#include "qmljsscopeastpath.h" #include "qmljsscopeastpath.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <QDebug>
using namespace QmlJS; using namespace QmlJS;
using namespace AST; using namespace AST;
@@ -112,6 +113,11 @@ bool ScopeAstPath::visit(FunctionExpression *node)
return false; return false;
} }
void ScopeAstPath::throwRecursionDepthError()
{
qWarning("ScopeAstPath hit the maximum recursion limit while visiting the AST.");
}
bool ScopeAstPath::containsOffset(SourceLocation start, SourceLocation end) bool ScopeAstPath::containsOffset(SourceLocation start, SourceLocation end)
{ {
return _offset >= start.begin() && _offset <= end.end(); return _offset >= start.begin() && _offset <= end.end();

View File

@@ -51,8 +51,9 @@ protected:
bool visit(AST::FunctionDeclaration *node) override; bool visit(AST::FunctionDeclaration *node) override;
bool visit(AST::FunctionExpression *node) override; bool visit(AST::FunctionExpression *node) override;
void throwRecursionDepthError() override;
private: private:
bool containsOffset(AST::SourceLocation start, AST::SourceLocation end); bool containsOffset(SourceLocation start, SourceLocation end);
QList<AST::Node *> _result; QList<AST::Node *> _result;
Document::Ptr _doc; Document::Ptr _doc;

View File

@@ -287,7 +287,7 @@ void ScopeChain::update() const
static void addInstantiatingComponents(ContextPtr context, QmlComponentChain *chain) static void addInstantiatingComponents(ContextPtr context, QmlComponentChain *chain)
{ {
const QRegExp importCommentPattern(QLatin1String("@scope\\s+(.*)")); const QRegExp importCommentPattern(QLatin1String("@scope\\s+(.*)"));
foreach (const AST::SourceLocation &commentLoc, chain->document()->engine()->comments()) { foreach (const SourceLocation &commentLoc, chain->document()->engine()->comments()) {
const QString &comment = chain->document()->source().mid(commentLoc.begin(), commentLoc.length); const QString &comment = chain->document()->source().mid(commentLoc.begin(), commentLoc.length);
// find all @scope annotations // find all @scope annotations

View File

@@ -125,7 +125,7 @@ bool SimpleAbstractStreamReader::readFile(const QString &fileName)
bool SimpleAbstractStreamReader::readFromSource(const QString &source) bool SimpleAbstractStreamReader::readFromSource(const QString &source)
{ {
m_errors.clear(); m_errors.clear();
m_currentSourceLocation = AST::SourceLocation(); m_currentSourceLocation = SourceLocation();
m_source = source; m_source = source;
@@ -151,7 +151,7 @@ QStringList SimpleAbstractStreamReader::errors() const
return m_errors; return m_errors;
} }
void SimpleAbstractStreamReader::addError(const QString &error, const AST::SourceLocation &sourceLocation) void SimpleAbstractStreamReader::addError(const QString &error, const SourceLocation &sourceLocation)
{ {
m_errors << QString::fromLatin1("%1:%2: %3\n").arg( m_errors << QString::fromLatin1("%1:%2: %3\n").arg(
QString::number(sourceLocation.startLine), QString::number(sourceLocation.startLine),
@@ -159,7 +159,7 @@ void SimpleAbstractStreamReader::addError(const QString &error, const AST::Sourc
error); error);
} }
AST::SourceLocation SimpleAbstractStreamReader::currentSourceLocation() const SourceLocation SimpleAbstractStreamReader::currentSourceLocation() const
{ {
return m_currentSourceLocation; return m_currentSourceLocation;
} }
@@ -278,13 +278,13 @@ QVariant SimpleAbstractStreamReader::parsePropertyExpression(AST::ExpressionNode
return textAt(expressionNode->firstSourceLocation(), expressionNode->lastSourceLocation()); return textAt(expressionNode->firstSourceLocation(), expressionNode->lastSourceLocation());
} }
void SimpleAbstractStreamReader::setSourceLocation(const AST::SourceLocation &sourceLocation) void SimpleAbstractStreamReader::setSourceLocation(const SourceLocation &sourceLocation)
{ {
m_currentSourceLocation = sourceLocation; m_currentSourceLocation = sourceLocation;
} }
QString SimpleAbstractStreamReader::textAt(const AST::SourceLocation &from, QString SimpleAbstractStreamReader::textAt(const SourceLocation &from,
const AST::SourceLocation &to) const SourceLocation &to)
{ {
return m_source.mid(from.offset, to.end() - from.begin()); return m_source.mid(from.offset, to.end() - from.begin());
} }

View File

@@ -85,8 +85,8 @@ public:
QStringList errors() const; QStringList errors() const;
protected: protected:
void addError(const QString &error, const AST::SourceLocation &sourceLocation = AST::SourceLocation()); void addError(const QString &error, const SourceLocation &sourceLocation = SourceLocation());
AST::SourceLocation currentSourceLocation() const; SourceLocation currentSourceLocation() const;
virtual void elementStart(const QString &name) = 0; virtual void elementStart(const QString &name) = 0;
virtual void elementEnd() = 0; virtual void elementEnd() = 0;
@@ -100,11 +100,11 @@ private:
void readProperty(AST::UiScriptBinding *uiScriptBinding); void readProperty(AST::UiScriptBinding *uiScriptBinding);
QVariant parsePropertyScriptBinding(AST::UiScriptBinding *ExpressionNode); QVariant parsePropertyScriptBinding(AST::UiScriptBinding *ExpressionNode);
QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode); QVariant parsePropertyExpression(AST::ExpressionNode *expressionNode);
void setSourceLocation(const AST::SourceLocation &sourceLocation); void setSourceLocation(const SourceLocation &sourceLocation);
QString textAt(const AST::SourceLocation &from, const AST::SourceLocation &to); QString textAt(const SourceLocation &from, const SourceLocation &to);
QStringList m_errors; QStringList m_errors;
AST::SourceLocation m_currentSourceLocation; SourceLocation m_currentSourceLocation;
QString m_source; QString m_source;
}; };

View File

@@ -26,6 +26,7 @@
#include "qmljsstaticanalysismessage.h" #include "qmljsstaticanalysismessage.h"
#include "qmljsconstants.h" #include "qmljsconstants.h"
#include "parser/qmljsengine_p.h" #include "parser/qmljsengine_p.h"
#include "parser/qmljsdiagnosticmessage_p.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -242,6 +243,8 @@ StaticAnalysisMessages::StaticAnalysisMessages()
tr("A State cannot have a child item (%1)."), 1); tr("A State cannot have a child item (%1)."), 1);
newMsg(WarnDuplicateImport, Warning, newMsg(WarnDuplicateImport, Warning,
tr("Duplicate import (%1)."), 1); tr("Duplicate import (%1)."), 1);
newMsg(ErrHitMaximumRecursion, Error,
tr("Hit Maximum recursion limit when visiting AST"));
} }
} // anonymous namespace } // anonymous namespace
@@ -258,7 +261,7 @@ Message::Message()
{} {}
Message::Message(Type type, Message::Message(Type type,
AST::SourceLocation location, SourceLocation location,
const QString &arg1, const QString &arg1,
const QString &arg2, const QString &arg2,
bool appendTypeId) bool appendTypeId)

View File

@@ -129,6 +129,7 @@ enum Type
ErrLongerStringValueExpected = 321, ErrLongerStringValueExpected = 321,
ErrShorterStringValueExpected = 322, ErrShorterStringValueExpected = 322,
ErrInvalidArrayValueLength = 323, ErrInvalidArrayValueLength = 323,
ErrHitMaximumRecursion = 324,
WarnDuplicateImport = 400 WarnDuplicateImport = 400
}; };
@@ -144,7 +145,7 @@ class QMLJS_EXPORT Message
{ {
public: public:
Message(); Message();
Message(Type type, AST::SourceLocation location, Message(Type type, SourceLocation location,
const QString &arg1 = QString(), const QString &arg1 = QString(),
const QString &arg2 = QString(), const QString &arg2 = QString(),
bool appendTypeId = true); bool appendTypeId = true);
@@ -157,7 +158,7 @@ public:
QString suppressionString() const; QString suppressionString() const;
static QRegExp suppressionPattern(); static QRegExp suppressionPattern();
AST::SourceLocation location; SourceLocation location;
QString message; QString message;
Type type; Type type;
Severity::Enum severity = Severity::Enum::Hint; Severity::Enum severity = Severity::Enum::Hint;

View File

@@ -107,16 +107,13 @@ void TypeDescriptionReader::readDocument(UiProgram *ast)
} }
ComponentVersion version; ComponentVersion version;
const QString versionString = _source.mid(import->versionToken.offset, import->versionToken.length); if (UiVersionSpecifier *uiVersion = import->version) {
const int dotIdx = versionString.indexOf(QLatin1Char('.')); version = ComponentVersion(import->version->majorVersion, import->version->minorVersion);
if (dotIdx != -1) {
version = ComponentVersion(versionString.leftRef(dotIdx).toInt(),
versionString.midRef(dotIdx + 1).toInt());
}
if (version.majorVersion() != 1) { if (version.majorVersion() != 1) {
addError(import->versionToken, tr("Major version different from 1 not supported.")); addError(uiVersion->majorToken, tr("Major version different from 1 not supported."));
return; return;
} }
}
if (!ast->members || !ast->members->member || ast->members->next) { if (!ast->members || !ast->members->member || ast->members->next) {
addError(SourceLocation(), tr("Expected document to contain a single object definition.")); addError(SourceLocation(), tr("Expected document to contain a single object definition."));

View File

@@ -39,13 +39,13 @@ class QBuffer;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace QmlJS { namespace QmlJS {
class SourceLocation;
class ModuleApiInfo; class ModuleApiInfo;
namespace AST { namespace AST {
class UiProgram; class UiProgram;
class UiObjectDefinition; class UiObjectDefinition;
class UiScriptBinding; class UiScriptBinding;
class SourceLocation;
} }
class QMLJS_EXPORT TypeDescriptionReader class QMLJS_EXPORT TypeDescriptionReader
@@ -83,8 +83,8 @@ private:
void readMetaObjectRevisions(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaObject::Ptr fmo); void readMetaObjectRevisions(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaObject::Ptr fmo);
void readEnumValues(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaEnum *fme); void readEnumValues(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaEnum *fme);
void addError(const AST::SourceLocation &loc, const QString &message); void addError(const SourceLocation &loc, const QString &message);
void addWarning(const AST::SourceLocation &loc, const QString &message); void addWarning(const SourceLocation &loc, const QString &message);
QString _fileName; QString _fileName;
QString _source; QString _source;

View File

@@ -191,7 +191,7 @@ UiQualifiedId *QmlJS::qualifiedTypeNameId(Node *node)
return nullptr; return nullptr;
} }
DiagnosticMessage QmlJS::errorMessage(const AST::SourceLocation &loc, const QString &message) DiagnosticMessage QmlJS::errorMessage(const SourceLocation &loc, const QString &message)
{ {
return DiagnosticMessage(Severity::Error, loc, message); return DiagnosticMessage(Severity::Error, loc, message);
} }

View File

@@ -29,6 +29,7 @@
#include "qmljsconstants.h" #include "qmljsconstants.h"
#include "parser/qmljsastfwd_p.h" #include "parser/qmljsastfwd_p.h"
#include "parser/qmljsengine_p.h" #include "parser/qmljsengine_p.h"
#include "parser/qmljsdiagnosticmessage_p.h"
QT_FORWARD_DECLARE_CLASS(QColor) QT_FORWARD_DECLARE_CLASS(QColor)
@@ -38,10 +39,10 @@ QMLJS_EXPORT QColor toQColor(const QString &qmlColorString);
QMLJS_EXPORT QString toString(AST::UiQualifiedId *qualifiedId, QMLJS_EXPORT QString toString(AST::UiQualifiedId *qualifiedId,
const QChar delimiter = QLatin1Char('.')); const QChar delimiter = QLatin1Char('.'));
QMLJS_EXPORT AST::SourceLocation locationFromRange(const AST::SourceLocation &start, QMLJS_EXPORT SourceLocation locationFromRange(const SourceLocation &start,
const AST::SourceLocation &end); const SourceLocation &end);
QMLJS_EXPORT AST::SourceLocation fullLocationForQualifiedId(AST::UiQualifiedId *); QMLJS_EXPORT SourceLocation fullLocationForQualifiedId(AST::UiQualifiedId *);
QMLJS_EXPORT QString idOfObject(AST::Node *object, AST::UiScriptBinding **idBinding = nullptr); QMLJS_EXPORT QString idOfObject(AST::Node *object, AST::UiScriptBinding **idBinding = nullptr);
@@ -51,7 +52,7 @@ QMLJS_EXPORT AST::UiQualifiedId *qualifiedTypeNameId(AST::Node *node);
QMLJS_EXPORT bool isValidBuiltinPropertyType(const QString &name); QMLJS_EXPORT bool isValidBuiltinPropertyType(const QString &name);
QMLJS_EXPORT DiagnosticMessage errorMessage(const AST::SourceLocation &loc, QMLJS_EXPORT DiagnosticMessage errorMessage(const SourceLocation &loc,
const QString &message); const QString &message);
QMLJS_EXPORT bool maybeModuleVersion(const QString &version); QMLJS_EXPORT bool maybeModuleVersion(const QString &version);
@@ -60,7 +61,7 @@ QMLJS_EXPORT QString modulePath(const QString &moduleImportName, const QString &
const QStringList &importPaths); const QStringList &importPaths);
template <class T> template <class T>
AST::SourceLocation locationFromRange(const T *node) SourceLocation locationFromRange(const T *node)
{ {
return locationFromRange(node->firstSourceLocation(), node->lastSourceLocation()); return locationFromRange(node->firstSourceLocation(), node->lastSourceLocation());
} }

View File

@@ -33,6 +33,8 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDebug>
namespace Autotest { namespace Autotest {
namespace Internal { namespace Internal {
@@ -177,6 +179,11 @@ bool TestQmlVisitor::visit(QmlJS::AST::StringLiteral *ast)
return false; return false;
} }
void TestQmlVisitor::throwRecursionDepthError()
{
qWarning("Warning: Hit maximum recursion depth while visiting AST in TestQmlVisitor");
}
/************************************** QuickTestAstVisitor *************************************/ /************************************** QuickTestAstVisitor *************************************/
QuickTestAstVisitor::QuickTestAstVisitor(CPlusPlus::Document::Ptr doc, QuickTestAstVisitor::QuickTestAstVisitor(CPlusPlus::Document::Ptr doc,

View File

@@ -65,6 +65,8 @@ public:
bool visit(QmlJS::AST::FunctionDeclaration *ast) override; bool visit(QmlJS::AST::FunctionDeclaration *ast) override;
bool visit(QmlJS::AST::StringLiteral *ast) override; bool visit(QmlJS::AST::StringLiteral *ast) override;
void throwRecursionDepthError() override;
QVector<QuickTestCaseSpec> testCases() const { return m_testCases; } QVector<QuickTestCaseSpec> testCases() const { return m_testCases; }
bool isValid() const { return !m_testCases.isEmpty(); } bool isValid() const { return !m_testCases.isEmpty(); }

View File

@@ -35,6 +35,8 @@
#include <qmljs/qmljsscopebuilder.h> #include <qmljs/qmljsscopebuilder.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <QDebug>
namespace { namespace {
using namespace QmlJS; using namespace QmlJS;
@@ -42,7 +44,7 @@ using namespace QmlJS;
class FindImplementationVisitor: protected AST::Visitor class FindImplementationVisitor: protected AST::Visitor
{ {
public: public:
using Results = QList<AST::SourceLocation>; using Results = QList<SourceLocation>;
FindImplementationVisitor(const Document::Ptr &doc, const ContextPtr &context) FindImplementationVisitor(const Document::Ptr &doc, const ContextPtr &context)
: m_document(doc) : m_document(doc)
@@ -66,13 +68,13 @@ public:
} }
protected: protected:
QString textAt(const AST::SourceLocation &location) QString textAt(const SourceLocation &location)
{ {
return m_document->source().mid(location.offset, location.length); return m_document->source().mid(location.offset, location.length);
} }
QString textAt(const AST::SourceLocation &from, QString textAt(const SourceLocation &from,
const AST::SourceLocation &to) const SourceLocation &to)
{ {
return m_document->source().mid(from.offset, to.end() - from.begin()); return m_document->source().mid(from.offset, to.end() - from.begin());
} }
@@ -206,7 +208,10 @@ protected:
return false; return false;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visiting AST in FindImplementationVisitor");
}
private: private:
bool checkTypeName(AST::UiQualifiedId *id) bool checkTypeName(AST::UiQualifiedId *id)
{ {
@@ -223,7 +228,7 @@ private:
} }
Results m_implemenations; Results m_implemenations;
AST::SourceLocation m_formLocation; SourceLocation m_formLocation;
Document::Ptr m_document; Document::Ptr m_document;
ContextPtr m_context; ContextPtr m_context;
@@ -281,7 +286,7 @@ QList<QmlJSEditor::FindReferences::Usage> FindImplementation::run(const QString
FindImplementationVisitor visitor(document, context); FindImplementationVisitor visitor(document, context);
FindImplementationVisitor::Results results = visitor(typeName, itemName, targetValue); FindImplementationVisitor::Results results = visitor(typeName, itemName, targetValue);
foreach (const AST::SourceLocation &location, results) { foreach (const SourceLocation &location, results) {
usages.append(QmlJSEditor::FindReferences::Usage(fileName, usages.append(QmlJSEditor::FindReferences::Usage(fileName,
matchingLine(location.offset, document->source()), matchingLine(location.offset, document->source()),
location.startLine, location.startColumn - 1, location.length)); location.startLine, location.startColumn - 1, location.length));

View File

@@ -79,8 +79,8 @@ bool AddPropertyVisitor::visit(QmlJS::AST::UiObjectBinding *ast)
void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializer) void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializer)
{ {
QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder); QmlJS::AST::UiObjectMemberList *insertAfter = searchMemberToInsertAfter(initializer->members, m_name, m_propertyOrder);
QmlJS::AST::SourceLocation endOfPreviousMember; QmlJS::SourceLocation endOfPreviousMember;
QmlJS::AST::SourceLocation startOfNextMember; QmlJS::SourceLocation startOfNextMember;
bool previousMemberSemicolon = false; bool previousMemberSemicolon = false;
unsigned depth; unsigned depth;

View File

@@ -27,6 +27,8 @@
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <QDebug>
using namespace QmlDesigner; using namespace QmlDesigner;
ASTObjectTextExtractor::ASTObjectTextExtractor(const QString &text): ASTObjectTextExtractor::ASTObjectTextExtractor(const QString &text):
@@ -69,3 +71,8 @@ bool ASTObjectTextExtractor::visit(QmlJS::AST::UiObjectDefinition *ast)
return m_text.isEmpty(); return m_text.isEmpty();
} }
void ASTObjectTextExtractor::throwRecursionDepthError()
{
qWarning("Warning: Hit maximum recursion depth while visiting the AST in ASTObjectTextExtractor");
}

View File

@@ -43,6 +43,8 @@ protected:
bool visit(QmlJS::AST::UiObjectBinding *ast) override; bool visit(QmlJS::AST::UiObjectBinding *ast) override;
bool visit(QmlJS::AST::UiObjectDefinition *ast) override; bool visit(QmlJS::AST::UiObjectDefinition *ast) override;
void throwRecursionDepthError() override;
private: private:
QmlJS::Document::MutablePtr m_document; QmlJS::Document::MutablePtr m_document;
quint32 m_location = 0; quint32 m_location = 0;

View File

@@ -98,3 +98,8 @@ bool FirstDefinitionFinder::visit(QmlJS::AST::UiObjectDefinition *ast)
} }
return true; return true;
} }
void FirstDefinitionFinder::throwRecursionDepthError()
{
qWarning("Warning: Hit maximum recursion depth while visiting the AST in FirstDefinitionFinder");
}

View File

@@ -43,6 +43,8 @@ protected:
bool visit(QmlJS::AST::UiObjectBinding *ast) override; bool visit(QmlJS::AST::UiObjectBinding *ast) override;
bool visit(QmlJS::AST::UiObjectDefinition *ast) override; bool visit(QmlJS::AST::UiObjectDefinition *ast) override;
void throwRecursionDepthError() override;
void extractFirstObjectDefinition(QmlJS::AST::UiObjectInitializer* ast); void extractFirstObjectDefinition(QmlJS::AST::UiObjectInitializer* ast);
private: private:

View File

@@ -147,7 +147,7 @@ void MoveObjectBeforeObjectVisitor::doMove()
moveInfo.prefixToInsert = QString(moveInfo.leadingCharsToRemove, QLatin1Char(' ')); moveInfo.prefixToInsert = QString(moveInfo.leadingCharsToRemove, QLatin1Char(' '));
moveInfo.suffixToInsert = separator + QStringLiteral("\n\n"); moveInfo.suffixToInsert = separator + QStringLiteral("\n\n");
} else { } else {
const QmlJS::AST::SourceLocation insertionPoint = lastParentLocation(); const QmlJS::SourceLocation insertionPoint = lastParentLocation();
Q_ASSERT(insertionPoint.isValid()); Q_ASSERT(insertionPoint.isValid());
moveInfo.destination = insertionPoint.offset; moveInfo.destination = insertionPoint.offset;
int dummy = -1; int dummy = -1;
@@ -169,7 +169,7 @@ QmlJS::AST::Node *MoveObjectBeforeObjectVisitor::movingObjectParent() const
return nullptr; return nullptr;
} }
QmlJS::AST::SourceLocation MoveObjectBeforeObjectVisitor::lastParentLocation() const QmlJS::SourceLocation MoveObjectBeforeObjectVisitor::lastParentLocation() const
{ {
dump(movingObjectParents); dump(movingObjectParents);
@@ -179,5 +179,5 @@ QmlJS::AST::SourceLocation MoveObjectBeforeObjectVisitor::lastParentLocation() c
else if (auto initializer = QmlJS::AST::cast<QmlJS::AST::UiArrayBinding*>(parent)) else if (auto initializer = QmlJS::AST::cast<QmlJS::AST::UiArrayBinding*>(parent))
return initializer->rbracketToken; return initializer->rbracketToken;
else else
return QmlJS::AST::SourceLocation(); return QmlJS::SourceLocation();
} }

View File

@@ -58,7 +58,7 @@ private:
void doMove(); void doMove();
QmlJS::AST::Node *movingObjectParent() const; QmlJS::AST::Node *movingObjectParent() const;
QmlJS::AST::SourceLocation lastParentLocation() const; QmlJS::SourceLocation lastParentLocation() const;
private: private:
QStack<QmlJS::AST::Node *> parents; QStack<QmlJS::AST::Node *> parents;

View File

@@ -88,3 +88,8 @@ bool ObjectLengthCalculator::visit(QmlJS::AST::UiObjectDefinition *ast)
return m_offset < end; return m_offset < end;
} }
void ObjectLengthCalculator::throwRecursionDepthError()
{
qWarning("Warning: Hit maximum recursion depth while visiting the AST in ObjectLengthCalculator");
}

View File

@@ -43,6 +43,8 @@ protected:
bool visit(QmlJS::AST::UiObjectBinding *ast) override; bool visit(QmlJS::AST::UiObjectBinding *ast) override;
bool visit(QmlJS::AST::UiObjectDefinition *ast) override; bool visit(QmlJS::AST::UiObjectDefinition *ast) override;
void throwRecursionDepthError() override;
private: private:
QmlJS::Document::MutablePtr m_doc; QmlJS::Document::MutablePtr m_doc;
quint32 m_offset = 0; quint32 m_offset = 0;

View File

@@ -68,12 +68,12 @@ QString QMLRewriter::textBetween(int startPosition, int endPosition) const
return m_textModifier->text().mid(startPosition, endPosition - startPosition); return m_textModifier->text().mid(startPosition, endPosition - startPosition);
} }
QString QMLRewriter::textAt(const QmlJS::AST::SourceLocation &location) const QString QMLRewriter::textAt(const QmlJS::SourceLocation &location) const
{ {
return m_textModifier->text().mid(location.offset, location.length); return m_textModifier->text().mid(location.offset, location.length);
} }
unsigned QMLRewriter::calculateIndentDepth(const QmlJS::AST::SourceLocation &position) const unsigned QMLRewriter::calculateIndentDepth(const QmlJS::SourceLocation &position) const
{ {
QTextDocument *doc = m_textModifier->textDocument(); QTextDocument *doc = m_textModifier->textDocument();
QTextCursor tc(doc); QTextCursor tc(doc);
@@ -151,20 +151,20 @@ QString QMLRewriter::removeIndentation(const QString &text, unsigned depth)
return result; return result;
} }
QmlJS::AST::SourceLocation QMLRewriter::calculateLocation(QmlJS::AST::UiQualifiedId *id) QmlJS::SourceLocation QMLRewriter::calculateLocation(QmlJS::AST::UiQualifiedId *id)
{ {
Q_ASSERT(id != nullptr); Q_ASSERT(id != nullptr);
const QmlJS::AST::SourceLocation startLocation = id->identifierToken; const QmlJS::SourceLocation startLocation = id->identifierToken;
QmlJS::AST::UiQualifiedId *nextId = id; QmlJS::AST::UiQualifiedId *nextId = id;
while (nextId->next) { while (nextId->next) {
nextId = nextId->next; nextId = nextId->next;
} }
const QmlJS::AST::SourceLocation endLocation = nextId->identifierToken; const QmlJS::SourceLocation endLocation = nextId->identifierToken;
return QmlJS::AST::SourceLocation(startLocation.offset, endLocation.end() - startLocation.offset); return QmlJS::SourceLocation(startLocation.offset, endLocation.end() - startLocation.offset);
} }
bool QMLRewriter::isMissingSemicolon(QmlJS::AST::UiObjectMember *member) bool QMLRewriter::isMissingSemicolon(QmlJS::AST::UiObjectMember *member)
@@ -340,3 +340,8 @@ void QMLRewriter::dump(const ASTPath &path)
qCDebug(qmlRewriter).noquote() << QString(i + 1, QLatin1Char('-')) << typeid(*node).name(); qCDebug(qmlRewriter).noquote() << QString(i + 1, QLatin1Char('-')) << typeid(*node).name();
} }
} }
void QMLRewriter::throwRecursionDepthError()
{
qCWarning(qmlRewriter) << "Warning: Hit maximum recursion level while visiting AST in QMLRewriter";
}

View File

@@ -51,20 +51,22 @@ public:
protected: protected:
using QmlJS::AST::Visitor::visit; using QmlJS::AST::Visitor::visit;
void throwRecursionDepthError() override;
virtual void replace(int offset, int length, const QString &text); virtual void replace(int offset, int length, const QString &text);
virtual void move(const QmlDesigner::TextModifier::MoveInfo &moveInfo); virtual void move(const QmlDesigner::TextModifier::MoveInfo &moveInfo);
QString textBetween(int startPosition, int endPosition) const; QString textBetween(int startPosition, int endPosition) const;
QString textAt(const QmlJS::AST::SourceLocation &location) const; QString textAt(const QmlJS::SourceLocation &location) const;
int indentDepth() const int indentDepth() const
{ return textModifier()->indentDepth(); } { return textModifier()->indentDepth(); }
unsigned calculateIndentDepth(const QmlJS::AST::SourceLocation &position) const; unsigned calculateIndentDepth(const QmlJS::SourceLocation &position) const;
static QString addIndentation(const QString &text, unsigned depth); static QString addIndentation(const QString &text, unsigned depth);
static QString removeIndentation(const QString &text, unsigned depth); static QString removeIndentation(const QString &text, unsigned depth);
static QString removeIndentationFromLine(const QString &text, int depth); static QString removeIndentationFromLine(const QString &text, int depth);
static QmlJS::AST::SourceLocation calculateLocation(QmlJS::AST::UiQualifiedId *id); static QmlJS::SourceLocation calculateLocation(QmlJS::AST::UiQualifiedId *id);
static bool isMissingSemicolon(QmlJS::AST::UiObjectMember *member); static bool isMissingSemicolon(QmlJS::AST::UiObjectMember *member);
static bool isMissingSemicolon(QmlJS::AST::Statement *stmt); static bool isMissingSemicolon(QmlJS::AST::Statement *stmt);

View File

@@ -93,7 +93,7 @@ bool BaseTextEditModifier::renameId(const QString &oldId, const QString &newId)
if (auto bte = qobject_cast<TextEditor::TextEditorWidget*>(plainTextEdit())) { if (auto bte = qobject_cast<TextEditor::TextEditorWidget*>(plainTextEdit())) {
if (auto document = qobject_cast<QmlJSEditor::QmlJSEditorDocument *>(bte->textDocument())) { if (auto document = qobject_cast<QmlJSEditor::QmlJSEditorDocument *>(bte->textDocument())) {
Utils::ChangeSet changeSet; Utils::ChangeSet changeSet;
foreach (const QmlJS::AST::SourceLocation &loc, foreach (const QmlJS::SourceLocation &loc,
document->semanticInfo().idLocations.value(oldId)) { document->semanticInfo().idLocations.value(oldId)) {
changeSet.replace(loc.begin(), loc.end(), newId); changeSet.replace(loc.begin(), loc.end(), newId);
} }

View File

@@ -26,6 +26,7 @@
#include <documentmessage.h> #include <documentmessage.h>
#include <qmljs/parser/qmljsengine_p.h> #include <qmljs/parser/qmljsengine_p.h>
#include <qmljs/parser/qmljsdiagnosticmessage_p.h>
namespace QmlDesigner { namespace QmlDesigner {

View File

@@ -772,8 +772,8 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc,
continue; continue;
QString version; QString version;
if (import->versionToken.isValid()) if (import->version != nullptr)
version = textAt(doc, import->versionToken); version = QLatin1String("%1.%2").arg(import->version->majorVersion).arg(import->version->minorVersion);
const QString &as = import->importId.toString(); const QString &as = import->importId.toString();
if (!import->fileName.isEmpty()) { if (!import->fileName.isEmpty()) {
@@ -2036,7 +2036,7 @@ void TextToModelMerger::collectLinkErrors(QList<DocumentMessage> *errors, const
void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors) void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
{ {
if (m_rewriterView->model()->imports().isEmpty()) { if (m_rewriterView->model()->imports().isEmpty()) {
const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, AST::SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found")); const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found"));
errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName()))); errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName())));
} }
@@ -2047,7 +2047,7 @@ void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
if (supportedQtQuickVersion(import.version())) { if (supportedQtQuickVersion(import.version())) {
hasQtQuick = true; hasQtQuick = true;
} else { } else {
const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, AST::SourceLocation(0, 0, 0, 0), const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, SourceLocation(0, 0, 0, 0),
QCoreApplication::translate("QmlDesigner::TextToModelMerger", "Unsupported QtQuick version")); QCoreApplication::translate("QmlDesigner::TextToModelMerger", "Unsupported QtQuick version"));
errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName()))); errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName())));
} }
@@ -2172,14 +2172,14 @@ QSet<QPair<QString, QString> > TextToModelMerger::qrcMapping() const
} }
QString TextToModelMerger::textAt(const Document::Ptr &doc, QString TextToModelMerger::textAt(const Document::Ptr &doc,
const AST::SourceLocation &location) const SourceLocation &location)
{ {
return doc->source().mid(location.offset, location.length); return doc->source().mid(location.offset, location.length);
} }
QString TextToModelMerger::textAt(const Document::Ptr &doc, QString TextToModelMerger::textAt(const Document::Ptr &doc,
const AST::SourceLocation &from, const SourceLocation &from,
const AST::SourceLocation &to) const SourceLocation &to)
{ {
return doc->source().mid(from.offset, to.end() - from.begin()); return doc->source().mid(from.offset, to.end() - from.begin());
} }

View File

@@ -144,10 +144,10 @@ private:
void addIsoIconQrcMapping(const QUrl &fileUrl); void addIsoIconQrcMapping(const QUrl &fileUrl);
static QString textAt(const QmlJS::Document::Ptr &doc, static QString textAt(const QmlJS::Document::Ptr &doc,
const QmlJS::AST::SourceLocation &location); const QmlJS::SourceLocation &location);
static QString textAt(const QmlJS::Document::Ptr &doc, static QString textAt(const QmlJS::Document::Ptr &doc,
const QmlJS::AST::SourceLocation &from, const QmlJS::SourceLocation &from,
const QmlJS::AST::SourceLocation &to); const QmlJS::SourceLocation &to);
private: private:
RewriterView *m_rewriterView; RewriterView *m_rewriterView;

View File

@@ -51,6 +51,7 @@
#include <QMessageBox> #include <QMessageBox>
using namespace QmlJS::AST; using namespace QmlJS::AST;
using QmlJS::SourceLocation;
using namespace QmlJSTools; using namespace QmlJSTools;
namespace QmlJSEditor { namespace QmlJSEditor {

View File

@@ -86,6 +86,7 @@
#include <QTextCodec> #include <QTextCodec>
#include <QTimer> #include <QTimer>
#include <QTreeView> #include <QTreeView>
#include <QDebug>
enum { enum {
UPDATE_USES_DEFAULT_INTERVAL = 150, UPDATE_USES_DEFAULT_INTERVAL = 150,
@@ -230,7 +231,7 @@ bool QmlJSEditorWidget::isOutlineCursorChangesBlocked()
void QmlJSEditorWidget::jumpToOutlineElement(int /*index*/) void QmlJSEditorWidget::jumpToOutlineElement(int /*index*/)
{ {
QModelIndex index = m_outlineCombo->view()->currentIndex(); QModelIndex index = m_outlineCombo->view()->currentIndex();
AST::SourceLocation location = m_qmlJsEditorDocument->outlineModel()->sourceLocation(index); SourceLocation location = m_qmlJsEditorDocument->outlineModel()->sourceLocation(index);
if (!location.isValid()) if (!location.isValid())
return; return;
@@ -332,7 +333,7 @@ void QmlJSEditorWidget::updateUses()
return; return;
QList<QTextEdit::ExtraSelection> selections; QList<QTextEdit::ExtraSelection> selections;
foreach (const AST::SourceLocation &loc, foreach (const SourceLocation &loc,
m_qmlJsEditorDocument->semanticInfo().idLocations.value(wordUnderCursor())) { m_qmlJsEditorDocument->semanticInfo().idLocations.value(wordUnderCursor())) {
if (! loc.isValid()) if (! loc.isValid())
continue; continue;
@@ -432,6 +433,11 @@ protected:
} }
} }
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth visiting AST in SelectedElement");
}
}; };
void QmlJSEditorWidget::setSelectedElements() void QmlJSEditorWidget::setSelectedElements()
@@ -941,7 +947,7 @@ QModelIndex QmlJSEditorWidget::indexForPosition(unsigned cursorPosition, const Q
const int rowCount = model->rowCount(rootIndex); const int rowCount = model->rowCount(rootIndex);
for (int i = 0; i < rowCount; ++i) { for (int i = 0; i < rowCount; ++i) {
QModelIndex childIndex = model->index(i, 0, rootIndex); QModelIndex childIndex = model->index(i, 0, rootIndex);
AST::SourceLocation location = model->sourceLocation(childIndex); SourceLocation location = model->sourceLocation(childIndex);
if ((cursorPosition >= location.offset) if ((cursorPosition >= location.offset)
&& (cursorPosition <= location.offset + location.length)) { && (cursorPosition <= location.offset + location.length)) {

View File

@@ -43,6 +43,8 @@
#include <qmljstools/qmljsmodelmanager.h> #include <qmljstools/qmljsmodelmanager.h>
#include <qmljstools/qmljsqtstylecodeformatter.h> #include <qmljstools/qmljsqtstylecodeformatter.h>
#include <QDebug>
const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning"; const char QML_UI_FILE_WARNING[] = "QmlJSEditor.QmlUiFileWarning";
using namespace QmlJSEditor; using namespace QmlJSEditor;
@@ -69,7 +71,7 @@ struct Declaration
class FindIdDeclarations: protected Visitor class FindIdDeclarations: protected Visitor
{ {
public: public:
using Result = QHash<QString, QList<AST::SourceLocation> >; using Result = QHash<QString, QList<SourceLocation> >;
Result operator()(Document::Ptr doc) Result operator()(Document::Ptr doc)
{ {
@@ -110,7 +112,7 @@ protected:
if (auto idExpr = AST::cast<const AST::IdentifierExpression *>(stmt->expression)) { if (auto idExpr = AST::cast<const AST::IdentifierExpression *>(stmt->expression)) {
if (!idExpr->name.isEmpty()) { if (!idExpr->name.isEmpty()) {
const QString &id = idExpr->name.toString(); const QString &id = idExpr->name.toString();
QList<AST::SourceLocation> *locs = &_ids[id]; QList<SourceLocation> *locs = &_ids[id];
locs->append(idExpr->firstSourceLocation()); locs->append(idExpr->firstSourceLocation());
locs->append(_maybeIds.value(id)); locs->append(_maybeIds.value(id));
_maybeIds.remove(id); _maybeIds.remove(id);
@@ -138,6 +140,11 @@ protected:
return false; return false;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visiting AST in FindIdDeclarations");
}
private: private:
Result _ids; Result _ids;
Result _maybeIds; Result _maybeIds;
@@ -414,6 +421,11 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visiting AST in CreateRanges");
}
Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast) Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast)
{ {
return createRange(member, member->firstSourceLocation(), ast->rbraceToken); return createRange(member, member->firstSourceLocation(), ast->rbraceToken);
@@ -429,7 +441,7 @@ protected:
return createRange(ast, block->lbraceToken, block->rbraceToken); return createRange(ast, block->lbraceToken, block->rbraceToken);
} }
Range createRange(AST::Node *ast, AST::SourceLocation start, AST::SourceLocation end) Range createRange(AST::Node *ast, SourceLocation start, SourceLocation end)
{ {
Range range; Range range;

View File

@@ -51,6 +51,7 @@
#include <QTimer> #include <QTimer>
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <QtConcurrentMap> #include <QtConcurrentMap>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QApplication> #include <QApplication>
#include <QLabel> #include <QLabel>
@@ -70,7 +71,7 @@ namespace {
class FindUsages: protected Visitor class FindUsages: protected Visitor
{ {
public: public:
using Result = QList<AST::SourceLocation>; using Result = QList<SourceLocation>;
FindUsages(Document::Ptr doc, const ContextPtr &context) FindUsages(Document::Ptr doc, const ContextPtr &context)
: _doc(doc) : _doc(doc)
@@ -236,6 +237,11 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visitin AST in FindUsages");
}
private: private:
bool contains(const QmlComponentChain *chain) bool contains(const QmlComponentChain *chain)
{ {
@@ -294,7 +300,7 @@ private:
class FindTypeUsages: protected Visitor class FindTypeUsages: protected Visitor
{ {
public: public:
using Result = QList<AST::SourceLocation>; using Result = QList<SourceLocation>;
FindTypeUsages(Document::Ptr doc, const ContextPtr &context) FindTypeUsages(Document::Ptr doc, const ContextPtr &context)
: _doc(doc) : _doc(doc)
@@ -427,6 +433,10 @@ protected:
return false; return false;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visitin AST in FindTypeUsages");
}
private: private:
bool checkTypeName(UiQualifiedId *id) bool checkTypeName(UiQualifiedId *id)
@@ -624,6 +634,11 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth visiting AST in FindUsages");
}
private: private:
bool containsOffset(SourceLocation start, SourceLocation end) bool containsOffset(SourceLocation start, SourceLocation end)
{ {
@@ -720,7 +735,7 @@ public:
// find all idenfifier expressions, try to resolve them and check if the result is in scope // find all idenfifier expressions, try to resolve them and check if the result is in scope
FindUsages findUsages(doc, context); FindUsages findUsages(doc, context);
FindUsages::Result results = findUsages(name, scope); FindUsages::Result results = findUsages(name, scope);
foreach (const AST::SourceLocation &loc, results) foreach (const SourceLocation &loc, results)
usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
if (future->isPaused()) if (future->isPaused())
future->waitForResume(); future->waitForResume();
@@ -762,7 +777,7 @@ public:
// find all idenfifier expressions, try to resolve them and check if the result is in scope // find all idenfifier expressions, try to resolve them and check if the result is in scope
FindTypeUsages findUsages(doc, context); FindTypeUsages findUsages(doc, context);
FindTypeUsages::Result results = findUsages(name, scope); FindTypeUsages::Result results = findUsages(name, scope);
foreach (const AST::SourceLocation &loc, results) foreach (const SourceLocation &loc, results)
usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); usages.append(Usage(fileName, matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
if (future->isPaused()) if (future->isPaused())
future->waitForResume(); future->waitForResume();
@@ -944,7 +959,7 @@ QList<FindReferences::Usage> FindReferences::findUsageOfType(const QString &file
foreach (const QmlJS::Document::Ptr &doc, snapshot) { foreach (const QmlJS::Document::Ptr &doc, snapshot) {
FindTypeUsages findUsages(doc, context); FindTypeUsages findUsages(doc, context);
FindTypeUsages::Result results = findUsages(typeName, targetValue); FindTypeUsages::Result results = findUsages(typeName, targetValue);
foreach (const AST::SourceLocation &loc, results) { foreach (const SourceLocation &loc, results) {
usages.append(Usage(doc->fileName(), matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); usages.append(Usage(doc->fileName(), matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length));
} }
} }

View File

@@ -63,8 +63,8 @@ namespace QmlJSEditor {
namespace { namespace {
QString textAt(const Document::Ptr doc, QString textAt(const Document::Ptr doc,
const AST::SourceLocation &from, const SourceLocation &from,
const AST::SourceLocation &to) const SourceLocation &to)
{ {
return doc->source().mid(from.offset, to.end() - from.begin()); return doc->source().mid(from.offset, to.end() - from.begin());
} }

View File

@@ -206,7 +206,7 @@ void QmlJSOutlineWidget::updateTextCursor(const QModelIndex &index)
if (!m_editor->isOutlineCursorChangesBlocked()) { if (!m_editor->isOutlineCursorChangesBlocked()) {
QModelIndex sourceIndex = m_filterModel->mapToSource(index); QModelIndex sourceIndex = m_filterModel->mapToSource(index);
AST::SourceLocation location SourceLocation location
= m_editor->qmlJsEditorDocument()->outlineModel()->sourceLocation(sourceIndex); = m_editor->qmlJsEditorDocument()->outlineModel()->sourceLocation(sourceIndex);
if (!location.isValid()) if (!location.isValid())

View File

@@ -46,6 +46,7 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <QDebug>
#include <QTextDocument> #include <QTextDocument>
#include <QThreadPool> #include <QThreadPool>
@@ -163,6 +164,11 @@ protected:
return false; return false;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visitin AST in CollectStateNames");
}
}; };
class CollectionTask : protected Visitor class CollectionTask : protected Visitor
@@ -453,6 +459,11 @@ protected:
} }
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit Maximum recursion depth when visiting AST in CollectionTask");
}
private: private:
void addUse(const SourceLocation &location, SemanticHighlighter::UseType type) void addUse(const SourceLocation &location, SemanticHighlighter::UseType type)
{ {

View File

@@ -32,7 +32,7 @@
#include <QVector> #include <QVector>
namespace QmlJS { namespace QmlJS {
namespace AST { class SourceLocation; } class SourceLocation;
} }
namespace TextEditor { class FontSettings; } namespace TextEditor { class FontSettings; }

View File

@@ -35,6 +35,7 @@
#include <qmljs/qmljsbind.h> #include <qmljs/qmljsbind.h>
#include <qmljstools/qmljsrefactoringchanges.h> #include <qmljstools/qmljsrefactoringchanges.h>
#include <QDebug>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QCoreApplication> #include <QCoreApplication>
@@ -71,6 +72,11 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visitin AST in FindIds");
}
Result result; Result result;
}; };

View File

@@ -64,7 +64,7 @@ QmlOutlineItem::QmlOutlineItem(QmlOutlineModel *model) :
QVariant QmlOutlineItem::data(int role) const QVariant QmlOutlineItem::data(int role) const
{ {
if (role == Qt::ToolTipRole) { if (role == Qt::ToolTipRole) {
AST::SourceLocation location = m_outlineModel->sourceLocation(index()); SourceLocation location = m_outlineModel->sourceLocation(index());
AST::UiQualifiedId *uiQualifiedId = m_outlineModel->idNode(index()); AST::UiQualifiedId *uiQualifiedId = m_outlineModel->idNode(index());
if (!uiQualifiedId || !location.isValid() || !m_outlineModel->m_semanticInfo.isValid()) if (!uiQualifiedId || !location.isValid() || !m_outlineModel->m_semanticInfo.isValid())
return QVariant(); return QVariant();
@@ -146,6 +146,11 @@ private:
parent.insert(objMember, stack.last()); parent.insert(objMember, stack.last());
} }
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth while visiting AST in ObjectMemberParentVisitor");
}
}; };
@@ -304,6 +309,11 @@ private:
} }
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion limit visiting AST in QmlOutlineModelSync");
}
QmlOutlineModel *m_model; QmlOutlineModel *m_model;
QHash<AST::Node*, QModelIndex> m_nodeToIndex; QHash<AST::Node*, QModelIndex> m_nodeToIndex;
@@ -341,7 +351,7 @@ QMimeData *QmlOutlineModel::mimeData(const QModelIndexList &indexes) const
stream << indexes.size(); stream << indexes.size();
for (const auto &index : indexes) { for (const auto &index : indexes) {
AST::SourceLocation location = sourceLocation(index); SourceLocation location = sourceLocation(index);
data->addFile(m_editorDocument->filePath().toString(), location.startLine, data->addFile(m_editorDocument->filePath().toString(), location.startLine,
location.startColumn - 1 /*editors have 0-based column*/); location.startColumn - 1 /*editors have 0-based column*/);
@@ -719,9 +729,9 @@ AST::Node *QmlOutlineModel::nodeForIndex(const QModelIndex &index) const
return nullptr; return nullptr;
} }
AST::SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) const SourceLocation QmlOutlineModel::sourceLocation(const QModelIndex &index) const
{ {
AST::SourceLocation location; SourceLocation location;
QTC_ASSERT(index.isValid() && (index.model() == this), return location); QTC_ASSERT(index.isValid() && (index.model() == this), return location);
AST::Node *node = nodeForIndex(index); AST::Node *node = nodeForIndex(index);
if (node) { if (node) {
@@ -981,8 +991,8 @@ QString QmlOutlineModel::asString(AST::UiQualifiedId *id)
return text; return text;
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::UiObjectMember *objMember) { SourceLocation QmlOutlineModel::getLocation(AST::UiObjectMember *objMember) {
AST::SourceLocation location; SourceLocation location;
location = objMember->firstSourceLocation(); location = objMember->firstSourceLocation();
location.length = objMember->lastSourceLocation().offset location.length = objMember->lastSourceLocation().offset
- objMember->firstSourceLocation().offset - objMember->firstSourceLocation().offset
@@ -990,8 +1000,8 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::UiObjectMember *objMember)
return location; return location;
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode) { SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode) {
AST::SourceLocation location; SourceLocation location;
location = exprNode->firstSourceLocation(); location = exprNode->firstSourceLocation();
location.length = exprNode->lastSourceLocation().offset location.length = exprNode->lastSourceLocation().offset
- exprNode->firstSourceLocation().offset - exprNode->firstSourceLocation().offset
@@ -999,14 +1009,14 @@ AST::SourceLocation QmlOutlineModel::getLocation(AST::ExpressionNode *exprNode)
return location; return location;
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternPropertyList *propertyNode) { SourceLocation QmlOutlineModel::getLocation(AST::PatternPropertyList *propertyNode) {
if (auto assignment = AST::cast<AST::PatternProperty *>(propertyNode->property)) if (auto assignment = AST::cast<AST::PatternProperty *>(propertyNode->property))
return getLocation(assignment); return getLocation(assignment);
return propertyNode->firstSourceLocation(); // should never happen return propertyNode->firstSourceLocation(); // should never happen
} }
AST::SourceLocation QmlOutlineModel::getLocation(AST::PatternProperty *propertyNode) { SourceLocation QmlOutlineModel::getLocation(AST::PatternProperty *propertyNode) {
AST::SourceLocation location; SourceLocation location;
location = propertyNode->name->propertyNameToken; location = propertyNode->name->propertyNameToken;
location.length = propertyNode->initializer->lastSourceLocation().end() - location.offset; location.length = propertyNode->initializer->lastSourceLocation().end() - location.offset;

View File

@@ -90,7 +90,7 @@ public:
void update(const QmlJSTools::SemanticInfo &semanticInfo); void update(const QmlJSTools::SemanticInfo &semanticInfo);
QmlJS::AST::Node *nodeForIndex(const QModelIndex &index) const; QmlJS::AST::Node *nodeForIndex(const QModelIndex &index) const;
QmlJS::AST::SourceLocation sourceLocation(const QModelIndex &index) const; QmlJS::SourceLocation sourceLocation(const QModelIndex &index) const;
QmlJS::AST::UiQualifiedId *idNode(const QModelIndex &index) const; QmlJS::AST::UiQualifiedId *idNode(const QModelIndex &index) const;
QIcon icon(const QModelIndex &index) const; QIcon icon(const QModelIndex &index) const;
@@ -138,10 +138,10 @@ private:
QStandardItem *parentItem(); QStandardItem *parentItem();
static QString asString(QmlJS::AST::UiQualifiedId *id); static QString asString(QmlJS::AST::UiQualifiedId *id);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember); static QmlJS::SourceLocation getLocation(QmlJS::AST::UiObjectMember *objMember);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::ExpressionNode *exprNode); static QmlJS::SourceLocation getLocation(QmlJS::AST::ExpressionNode *exprNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternProperty *propertyNode); static QmlJS::SourceLocation getLocation(QmlJS::AST::PatternProperty *propertyNode);
static QmlJS::AST::SourceLocation getLocation(QmlJS::AST::PatternPropertyList *propertyNode); static QmlJS::SourceLocation getLocation(QmlJS::AST::PatternPropertyList *propertyNode);
QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef); QIcon getIcon(QmlJS::AST::UiQualifiedId *objDef);
QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer); QString getAnnotation(QmlJS::AST::UiObjectInitializer *objInitializer);

View File

@@ -33,6 +33,7 @@
//#include <qmljs/qmljsinterpreter.h> //#include <qmljs/qmljsinterpreter.h>
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <QDebug>
#include <QMutexLocker> #include <QMutexLocker>
using namespace QmlJSTools::Internal; using namespace QmlJSTools::Internal;
@@ -224,6 +225,11 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion limit visiting AST in FunctionFinder.");
}
}; };
} // anonymous namespace } // anonymous namespace

View File

@@ -149,7 +149,7 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
return m_qmljsDocument; return m_qmljsDocument;
} }
unsigned QmlJSRefactoringFile::startOf(const AST::SourceLocation &loc) const unsigned QmlJSRefactoringFile::startOf(const SourceLocation &loc) const
{ {
return position(loc.startLine, loc.startColumn); return position(loc.startLine, loc.startColumn);
} }
@@ -176,7 +176,7 @@ bool QmlJSRefactoringFile::isCursorOn(AST::UiQualifiedId *ast) const
return pos <= ast->identifierToken.end(); return pos <= ast->identifierToken.end();
} }
bool QmlJSRefactoringFile::isCursorOn(AST::SourceLocation loc) const bool QmlJSRefactoringFile::isCursorOn(SourceLocation loc) const
{ {
const unsigned pos = cursor().position(); const unsigned pos = cursor().position();
return pos >= loc.begin() && pos <= loc.end(); return pos >= loc.begin() && pos <= loc.end();

View File

@@ -49,11 +49,11 @@ public:
\returns the offset in the document for the start position of the given \returns the offset in the document for the start position of the given
source location. source location.
*/ */
unsigned startOf(const QmlJS::AST::SourceLocation &loc) const; unsigned startOf(const QmlJS::SourceLocation &loc) const;
bool isCursorOn(QmlJS::AST::UiObjectMember *ast) const; bool isCursorOn(QmlJS::AST::UiObjectMember *ast) const;
bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const; bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const;
bool isCursorOn(QmlJS::AST::SourceLocation loc) const; bool isCursorOn(QmlJS::SourceLocation loc) const;
protected: protected:
QmlJSRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data); QmlJSRefactoringFile(const QString &fileName, const QSharedPointer<TextEditor::RefactoringChangesData> &data);

View File

@@ -30,6 +30,8 @@
#include <qmljs/qmljsscopechain.h> #include <qmljs/qmljsscopechain.h>
#include <qmljs/parser/qmljsengine_p.h> #include <qmljs/parser/qmljsengine_p.h>
#include <QDebug>
using namespace QmlJS; using namespace QmlJS;
using namespace QmlJS::AST; using namespace QmlJS::AST;
@@ -63,13 +65,13 @@ protected:
node->accept(this); node->accept(this);
} }
bool containsOffset(AST::SourceLocation start, AST::SourceLocation end) bool containsOffset(SourceLocation start, SourceLocation end)
{ {
return _offset >= start.begin() && _offset <= end.end(); return _offset >= start.begin() && _offset <= end.end();
} }
bool handle(AST::Node *ast, bool handle(AST::Node *ast,
AST::SourceLocation start, AST::SourceLocation end, SourceLocation start, SourceLocation end,
bool addToPath = true) bool addToPath = true)
{ {
if (containsOffset(start, end)) { if (containsOffset(start, end)) {
@@ -99,8 +101,8 @@ protected:
bool visit(AST::UiQualifiedId *ast) override bool visit(AST::UiQualifiedId *ast) override
{ {
AST::SourceLocation first = ast->identifierToken; SourceLocation first = ast->identifierToken;
AST::SourceLocation last; SourceLocation last;
for (AST::UiQualifiedId *it = ast; it; it = it->next) for (AST::UiQualifiedId *it = ast; it; it = it->next)
last = it->identifierToken; last = it->identifierToken;
if (containsOffset(first, last)) if (containsOffset(first, last))
@@ -125,6 +127,10 @@ protected:
return handleLocationAst(ast); return handleLocationAst(ast);
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit maximum recursion depth when visiting the AST in AstPath");
}
}; };
} // anonmymous } // anonmymous

View File

@@ -85,7 +85,7 @@ public: // attributes
QmlJS::Snapshot snapshot; QmlJS::Snapshot snapshot;
QmlJS::ContextPtr context; QmlJS::ContextPtr context;
QList<Range> ranges; QList<Range> ranges;
QHash<QString, QList<QmlJS::AST::SourceLocation> > idLocations; QHash<QString, QList<QmlJS::SourceLocation> > idLocations;
// these are in addition to the parser messages in the document // these are in addition to the parser messages in the document
QList<QmlJS::DiagnosticMessage> semanticMessages; QList<QmlJS::DiagnosticMessage> semanticMessages;

View File

@@ -38,6 +38,8 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QDebug>
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
@@ -78,12 +80,16 @@ protected:
return true; return true;
} }
void throwRecursionDepthError() override
{
qWarning("Warning: Hit mximum recursion depth while visiting AST in PropertyVisitor");
}
private: private:
QmlJS::AST::Node *m_lastValidNode = nullptr; QmlJS::AST::Node *m_lastValidNode = nullptr;
quint32 m_line = 0; quint32 m_line = 0;
quint32 m_column = 0; quint32 m_column = 0;
bool containsLocation(QmlJS::AST::SourceLocation start, QmlJS::AST::SourceLocation end) bool containsLocation(QmlJS::SourceLocation start, QmlJS::SourceLocation end)
{ {
return (m_line > start.startLine return (m_line > start.startLine
|| (m_line == start.startLine && m_column >= start.startColumn)) || (m_line == start.startLine && m_column >= start.startColumn))

View File

@@ -78,7 +78,7 @@ void QmlJsTodoItemsScanner::processDocument(QmlJS::Document::Ptr doc)
{ {
QList<TodoItem> itemList; QList<TodoItem> itemList;
foreach (const QmlJS::AST::SourceLocation &sourceLocation, doc->engine()->comments()) { foreach (const QmlJS::SourceLocation &sourceLocation, doc->engine()->comments()) {
QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed(); QString source = doc->source().mid(sourceLocation.begin(), sourceLocation.length).trimmed();
// Process every line // Process every line