forked from qt-creator/qt-creator
Updating qmljs parser to latest qtdeclarative parser
improves support for string templates, required properties, and other smaller improvements Task-number: QTCREATORBUG-21869 Change-Id: Ia2359e1f75d4bd7b9ea4f27a920acd2251e36108 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
@@ -9,7 +9,7 @@ add_qtc_library(QmlJS
|
||||
parser/qmljsastfwd_p.h
|
||||
parser/qmljsastvisitor.cpp parser/qmljsastvisitor_p.h
|
||||
parser/qmljsdiagnosticmessage_p.h
|
||||
parser/qmljsengine_p.cpp parser/qmljsengine_p.h
|
||||
parser/qmljsengine_p.h
|
||||
parser/qmljsglobal_p.h
|
||||
parser/qmljsgrammar.cpp parser/qmljsgrammar_p.h
|
||||
parser/qmljskeywords_p.h
|
||||
|
@@ -15,7 +15,7 @@
|
||||
# 1. do all changes & commit them
|
||||
# 2. run this script commenting out the two patch commands in the last lines below
|
||||
# 3. update the first patch using
|
||||
# # git diff > grammar.patch
|
||||
# # git diff --cached > grammar.patch
|
||||
# 4. uncomment the first (grammar) patch, re-run script
|
||||
# 5. update the second patch with
|
||||
# # git diff > parser.patch
|
||||
@@ -70,13 +70,26 @@ 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|#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/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
|
||||
perl -p -0777 -i -e 's/QT_QML_BEGIN_NAMESPACE/#include <qmljs\/qmljsconstants.h>\nQT_QML_BEGIN_NAMESPACE/' qmljsengine_p.h
|
||||
|
||||
./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h}
|
||||
|
||||
git add -u
|
||||
git clang-format
|
||||
git add -u
|
||||
git reset gen-parser.sh grammar.patch qmljsgrammar.cpp qmljsgrammar_p.h qmljsparser.cpp qmljsparser_p.h
|
||||
## comment from here to update grammar.patch using
|
||||
## git diff --cached > grammar.patch
|
||||
patch -R -p5 < grammar.patch
|
||||
$QLALR qmljs.g
|
||||
|
||||
./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h}
|
||||
|
||||
git add -u
|
||||
git clang-format
|
||||
git add -u
|
||||
git reset gen-parser.sh grammar.patch parser.patch
|
||||
## comment from here to update parser.patch
|
||||
## git diff --cached > parser.patch
|
||||
patch -p5 -R < parser.patch
|
||||
git reset
|
||||
|
@@ -1,8 +1,340 @@
|
||||
diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
index 747d2010f3..e9d22624ef 100644
|
||||
--- a/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
@@ -25,14 +25,10 @@
|
||||
|
||||
#include "qmldirparser_p.h"
|
||||
|
||||
-#include <utils/qtcassert.h>
|
||||
-
|
||||
#include <QtCore/QtDebug>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
-using namespace LanguageUtils;
|
||||
-
|
||||
static int parseInt(QStringView str, bool *ok)
|
||||
{
|
||||
int pos = 0;
|
||||
@@ -50,45 +46,19 @@ static int parseInt(QStringView str, bool *ok)
|
||||
return number;
|
||||
}
|
||||
|
||||
-static bool parseVersion(const QString &str, int *major, int *minor)
|
||||
+static QTypeRevision parseVersion(const QString &str)
|
||||
{
|
||||
const int dotIndex = str.indexOf(QLatin1Char('.'));
|
||||
if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) {
|
||||
bool ok = false;
|
||||
- *major = parseInt(QStringView(str.constData(), dotIndex), &ok);
|
||||
- if (ok)
|
||||
- *minor = parseInt(QStringView(str.constData() + dotIndex + 1, str.length() - dotIndex - 1),
|
||||
- &ok);
|
||||
- return ok;
|
||||
- }
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-static ComponentVersion parseImportVersion(const QString &str)
|
||||
-{
|
||||
- int minor = -1;
|
||||
- int major = -1;
|
||||
- const int dotIndex = str.indexOf(QLatin1Char('.'));
|
||||
- bool ok = false;
|
||||
- if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) {
|
||||
- major = parseInt(QStringView(str.constData(), dotIndex), &ok);
|
||||
- if (ok) {
|
||||
- if (str.length() > dotIndex + 1) {
|
||||
- minor = parseInt(QStringView(str.constData() + dotIndex + 1, str.length() - dotIndex - 1),
|
||||
- &ok);
|
||||
- if (!ok)
|
||||
- minor = ComponentVersion::NoVersion;
|
||||
- } else {
|
||||
- minor = ComponentVersion::MaxVersion;
|
||||
- }
|
||||
- }
|
||||
- } else if (str.length() > 0) {
|
||||
- QTC_ASSERT(str != QLatin1String("auto"), return ComponentVersion(-1, -1));
|
||||
- major = parseInt(QStringView(str.constData(), str.length()),
|
||||
- &ok);
|
||||
- minor = ComponentVersion::MaxVersion;
|
||||
+ const int major = parseInt(QStringView(str).left(dotIndex), &ok);
|
||||
+ if (!ok)
|
||||
+ return QTypeRevision();
|
||||
+ const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.length() - dotIndex - 1),
|
||||
+ &ok);
|
||||
+ return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision();
|
||||
}
|
||||
- return ComponentVersion(major, minor);
|
||||
+ return QTypeRevision();
|
||||
}
|
||||
|
||||
void QmlDirParser::clear()
|
||||
@@ -132,12 +102,12 @@ bool QmlDirParser::parse(const QString &source)
|
||||
auto readImport = [&](const QString *sections, int sectionCount, Import::Flags flags) {
|
||||
Import import;
|
||||
if (sectionCount == 2) {
|
||||
- import = Import(sections[1], ComponentVersion(), flags);
|
||||
+ import = Import(sections[1], QTypeRevision(), flags);
|
||||
} else if (sectionCount == 3) {
|
||||
if (sections[2] == QLatin1String("auto")) {
|
||||
- import = Import(sections[1], ComponentVersion(), flags | Import::Auto);
|
||||
+ import = Import(sections[1], QTypeRevision(), flags | Import::Auto);
|
||||
} else {
|
||||
- const auto version = parseImportVersion(sections[2]);
|
||||
+ const auto version = parseVersion(sections[2]);
|
||||
if (version.isValid()) {
|
||||
import = Import(sections[1], version, flags);
|
||||
} else {
|
||||
@@ -275,7 +245,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
|
||||
continue;
|
||||
}
|
||||
- Component entry(sections[1], sections[2], -1, -1);
|
||||
+ Component entry(sections[1], sections[2], QTypeRevision());
|
||||
entry.internal = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else if (sections[0] == QLatin1String("singleton")) {
|
||||
@@ -286,16 +256,16 @@ bool QmlDirParser::parse(const QString &source)
|
||||
} else if (sectionCount == 3) {
|
||||
// handle qmldir directory listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType TestSingletonType.qml
|
||||
- Component entry(sections[1], sections[2], -1, -1);
|
||||
+ Component entry(sections[1], sections[2], QTypeRevision());
|
||||
entry.singleton = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else {
|
||||
// handle qmldir module listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType 2.0 TestSingletonType20.qml
|
||||
- int major, minor;
|
||||
- if (parseVersion(sections[2], &major, &minor)) {
|
||||
+ const QTypeRevision version = parseVersion(sections[2]);
|
||||
+ if (version.isValid()) {
|
||||
const QString &fileName = sections[3];
|
||||
- Component entry(sections[1], fileName, major, minor);
|
||||
+ Component entry(sections[1], fileName, version);
|
||||
entry.singleton = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else {
|
||||
@@ -361,19 +331,19 @@ bool QmlDirParser::parse(const QString &source)
|
||||
_linkTarget = sections[1];
|
||||
} else if (sectionCount == 2) {
|
||||
// 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], QTypeRevision());
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else if (sectionCount == 3) {
|
||||
- int major, minor;
|
||||
- if (parseVersion(sections[1], &major, &minor)) {
|
||||
+ const QTypeRevision version = parseVersion(sections[1]);
|
||||
+ if (version.isValid()) {
|
||||
const QString &fileName = sections[2];
|
||||
|
||||
if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) {
|
||||
// A 'js' extension indicates a namespaced script import
|
||||
- const Script entry(sections[0], fileName, major, minor);
|
||||
+ const Script entry(sections[0], fileName, version);
|
||||
_scripts.append(entry);
|
||||
} else {
|
||||
- const Component entry(sections[0], fileName, major, minor);
|
||||
+ const Component entry(sections[0], fileName, version);
|
||||
_components.insert(entry.typeName, entry);
|
||||
}
|
||||
} else {
|
||||
@@ -420,15 +390,19 @@ QList<QmlJS::DiagnosticMessage> QmlDirParser::errors(const QString &uri) const
|
||||
|
||||
QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component)
|
||||
{
|
||||
- const QString output = QStringLiteral("{%1 %2.%3}").
|
||||
- arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion);
|
||||
+ const QString output = QStringLiteral("{%1 %2.%3}")
|
||||
+ .arg(component.typeName)
|
||||
+ .arg(component.version.majorVersion())
|
||||
+ .arg(component.version.minorVersion());
|
||||
return debug << qPrintable(output);
|
||||
}
|
||||
|
||||
QDebug &operator<< (QDebug &debug, const QmlDirParser::Script &script)
|
||||
{
|
||||
- const QString output = QStringLiteral("{%1 %2.%3}").
|
||||
- arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion);
|
||||
+ const QString output = QStringLiteral("{%1 %2.%3}")
|
||||
+ .arg(script.nameSpace)
|
||||
+ .arg(script.version.majorVersion())
|
||||
+ .arg(script.version.minorVersion());
|
||||
return debug << qPrintable(output);
|
||||
}
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmldirparser_p.h b/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
index d5a0aabfd0..c1869b7cc8 100644
|
||||
--- a/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
@@ -36,15 +36,12 @@
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
-#include <QtCore/QUrl>
|
||||
-#include <QtCore/QHash>
|
||||
-#include <QtCore/QDebug>
|
||||
-
|
||||
-#include <languageutils/componentversion.h>
|
||||
-
|
||||
-#include "qmljs/parser/qmljsglobal_p.h"
|
||||
-#include "qmljs/parser/qmljsengine_p.h"
|
||||
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
|
||||
+#include "qmljs/parser/qmljsglobal_p.h"
|
||||
+#include <QtCore/QDebug>
|
||||
+#include <QtCore/QHash>
|
||||
+#include <QtCore/QTypeRevision>
|
||||
+#include <QtCore/QUrl>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -90,17 +87,19 @@ public:
|
||||
{
|
||||
Component() = default;
|
||||
|
||||
- Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
|
||||
- : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
|
||||
- internal(false), singleton(false)
|
||||
+ Component(const QString &typeName, const QString &fileName, QTypeRevision version)
|
||||
+ : typeName(typeName)
|
||||
+ , fileName(fileName)
|
||||
+ , version(version)
|
||||
+ , internal(false)
|
||||
+ , singleton(false)
|
||||
{
|
||||
checkNonRelative("Component", typeName, fileName);
|
||||
}
|
||||
|
||||
QString typeName;
|
||||
QString fileName;
|
||||
- int majorVersion = 0;
|
||||
- int minorVersion = 0;
|
||||
+ QTypeRevision version = QTypeRevision::zero();
|
||||
bool internal = false;
|
||||
bool singleton = false;
|
||||
};
|
||||
@@ -109,16 +108,17 @@ public:
|
||||
{
|
||||
Script() = default;
|
||||
|
||||
- Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
|
||||
- : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion)
|
||||
+ Script(const QString &nameSpace, const QString &fileName, QTypeRevision version)
|
||||
+ : nameSpace(nameSpace)
|
||||
+ , fileName(fileName)
|
||||
+ , version(version)
|
||||
{
|
||||
checkNonRelative("Script", nameSpace, fileName);
|
||||
}
|
||||
|
||||
QString nameSpace;
|
||||
QString fileName;
|
||||
- int majorVersion = 0;
|
||||
- int minorVersion = 0;
|
||||
+ QTypeRevision version = QTypeRevision::zero();
|
||||
};
|
||||
|
||||
struct Import
|
||||
@@ -131,13 +131,15 @@ public:
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
Import() = default;
|
||||
- Import(QString module, LanguageUtils::ComponentVersion version, Flags flags)
|
||||
- : module(module), version(version), flags(flags)
|
||||
+ Import(QString module, QTypeRevision version, Flags flags)
|
||||
+ : module(module)
|
||||
+ , version(version)
|
||||
+ , flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
QString module;
|
||||
- LanguageUtils::ComponentVersion version; // invalid version is latest version, unless Flag::Auto
|
||||
+ QTypeRevision version; // invalid version is latest version, unless Flag::Auto
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmlimportresolver.cpp b/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
index e74c5840c1..e7416ef7f0 100644
|
||||
--- a/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
@@ -40,20 +40,20 @@ enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned };
|
||||
- base/QtQml.2/Models
|
||||
- base/QtQml/Models
|
||||
*/
|
||||
-QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths,
|
||||
- LanguageUtils::ComponentVersion version)
|
||||
+QStringList qQmlResolveImportPaths(QStringView uri,
|
||||
+ const QStringList &basePaths,
|
||||
+ QTypeRevision version)
|
||||
{
|
||||
static const QLatin1Char Slash('/');
|
||||
static const QLatin1Char Backslash('\\');
|
||||
|
||||
- const QList<QStringView> parts = uri.split(u'.', Qt::SkipEmptyParts);
|
||||
+ const QVector<QStringView> parts = uri.split(u'.', Qt::SkipEmptyParts);
|
||||
|
||||
QStringList importPaths;
|
||||
// fully & partially versioned parts + 1 unversioned for each base path
|
||||
importPaths.reserve(2 * parts.count() + 1);
|
||||
|
||||
- auto versionString = [](LanguageUtils::ComponentVersion version, ImportVersion mode)
|
||||
- {
|
||||
+ auto versionString = [](QTypeRevision version, ImportVersion mode) {
|
||||
if (mode == FullyVersioned) {
|
||||
// extension with fully encoded version number (eg. MyModule.3.2)
|
||||
return QString::fromLatin1(".%1.%2").arg(version.majorVersion())
|
||||
@@ -67,7 +67,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
return QString();
|
||||
};
|
||||
|
||||
- auto joinStringRefs = [](const QList<QStringView> &refs, const QChar &sep) {
|
||||
+ auto joinStringRefs = [](const QVector<QStringView> &refs, const QChar &sep) {
|
||||
QString str;
|
||||
for (auto it = refs.cbegin(); it != refs.cend(); ++it) {
|
||||
if (it != refs.cbegin())
|
||||
@@ -77,9 +77,10 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
return str;
|
||||
};
|
||||
|
||||
- const ImportVersion initial = ((version.minorVersion() >= 0)
|
||||
- ? FullyVersioned
|
||||
- : ((version.majorVersion() >= 0) ? PartiallyVersioned : Unversioned));
|
||||
+ const ImportVersion initial = (version.hasMinorVersion())
|
||||
+ ? FullyVersioned
|
||||
+ : (version.hasMajorVersion() ? PartiallyVersioned
|
||||
+ : Unversioned);
|
||||
for (int mode = initial; mode <= Unversioned; ++mode) {
|
||||
const QString ver = versionString(version, ImportVersion(mode));
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmlimportresolver_p.h b/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
index 68c052d408..8f18de3d0b 100644
|
||||
--- a/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
@@ -40,11 +40,12 @@
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include <QtCore/qstring.h>
|
||||
-#include <languageutils/componentversion.h>
|
||||
+#include <QtCore/qversionnumber.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
-QML_PARSER_EXPORT QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths,
|
||||
- LanguageUtils::ComponentVersion version);
|
||||
+QML_PARSER_EXPORT QStringList qQmlResolveImportPaths(QStringView uri,
|
||||
+ const QStringList &basePaths,
|
||||
+ QTypeRevision version);
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g
|
||||
index ae79830d2e..32a2f6f4b0 100644
|
||||
index 5f62edf4d1..19f4e200e5 100644
|
||||
--- a/src/libs/qmljs/parser/qmljs.g
|
||||
+++ b/src/libs/qmljs/parser/qmljs.g
|
||||
@@ -380,7 +380,7 @@ public:
|
||||
@@ -381,7 +381,7 @@ public:
|
||||
inline DiagnosticMessage diagnosticMessage() const
|
||||
{
|
||||
for (const DiagnosticMessage &d : diagnostic_messages) {
|
||||
@@ -11,7 +343,7 @@ index ae79830d2e..32a2f6f4b0 100644
|
||||
return d;
|
||||
}
|
||||
|
||||
@@ -424,7 +424,7 @@ protected:
|
||||
@@ -425,7 +425,7 @@ protected:
|
||||
DiagnosticMessage error;
|
||||
error.loc = location;
|
||||
error.message = message;
|
||||
@@ -20,7 +352,7 @@ index ae79830d2e..32a2f6f4b0 100644
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -445,8 +445,8 @@ protected:
|
||||
@@ -446,8 +446,8 @@ protected:
|
||||
Value *sym_stack = nullptr;
|
||||
int *state_stack = nullptr;
|
||||
SourceLocation *location_stack = nullptr;
|
||||
@@ -31,7 +363,7 @@ index ae79830d2e..32a2f6f4b0 100644
|
||||
|
||||
AST::Node *program = nullptr;
|
||||
|
||||
@@ -838,7 +838,7 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
|
||||
@@ -849,7 +849,7 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
|
||||
case $rule_number: {
|
||||
const int major = sym(1).dval;
|
||||
const int minor = sym(3).dval;
|
||||
@@ -40,7 +372,7 @@ index ae79830d2e..32a2f6f4b0 100644
|
||||
diagnostic_messages.append(
|
||||
compileError(loc(1),
|
||||
QLatin1String("Invalid version. Version numbers must be >= 0 and < 255.")));
|
||||
@@ -851,11 +851,12 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
|
||||
@@ -862,11 +862,12 @@ UiVersionSpecifier: T_VERSION_NUMBER T_DOT T_VERSION_NUMBER;
|
||||
} break;
|
||||
./
|
||||
|
||||
@@ -54,3 +386,119 @@ index ae79830d2e..32a2f6f4b0 100644
|
||||
diagnostic_messages.append(
|
||||
compileError(loc(1),
|
||||
QLatin1String("Invalid major version. Version numbers must be >= 0 and < 255.")));
|
||||
diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h
|
||||
index 78b9f4b080..dcbcb5fd0d 100644
|
||||
--- a/src/libs/qmljs/parser/qmljsast_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljsast_p.h
|
||||
@@ -654,12 +654,14 @@ class QML_PARSER_EXPORT UiVersionSpecifier : public Node
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiVersionSpecifier)
|
||||
|
||||
- UiVersionSpecifier(int majorum) : majorVersion(majorum)
|
||||
+ UiVersionSpecifier(int majorum)
|
||||
+ : version(QTypeRevision::fromMajorVersion(majorum))
|
||||
{
|
||||
kind = K;
|
||||
}
|
||||
|
||||
- UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum)
|
||||
+ UiVersionSpecifier(int majorum, int minorum)
|
||||
+ : version(QTypeRevision::fromVersion(majorum, minorum))
|
||||
{
|
||||
kind = K;
|
||||
}
|
||||
@@ -674,8 +676,7 @@ public:
|
||||
}
|
||||
|
||||
// attributes:
|
||||
- int majorVersion = -1;
|
||||
- int minorVersion = -1;
|
||||
+ QTypeRevision version;
|
||||
SourceLocation majorToken;
|
||||
SourceLocation minorToken;
|
||||
};
|
||||
@@ -881,14 +882,14 @@ struct QML_PARSER_EXPORT BoundName
|
||||
};
|
||||
|
||||
QString id;
|
||||
- TypeAnnotation *typeAnnotation;
|
||||
- Type typeAnnotationType;
|
||||
+ QTaggedPointer<TypeAnnotation, Type> typeAnnotation;
|
||||
BoundName(const QString &id, TypeAnnotation *typeAnnotation, Type type = Declared)
|
||||
- : id(id), typeAnnotation(typeAnnotation), typeAnnotationType(type)
|
||||
+ : id(id)
|
||||
+ , typeAnnotation(typeAnnotation, type)
|
||||
{}
|
||||
BoundName() = default;
|
||||
QString typeName() const { return typeAnnotation ? typeAnnotation->type->toString() : QString(); }
|
||||
- bool isInjected() const { return typeAnnotation && typeAnnotationType == Injected; }
|
||||
+ bool isInjected() const { return typeAnnotation.tag() == Injected; }
|
||||
};
|
||||
|
||||
struct BoundNames : public QVector<BoundName>
|
||||
@@ -3486,7 +3487,6 @@ public:
|
||||
SourceLocation identifierToken;
|
||||
SourceLocation colonToken;
|
||||
SourceLocation semicolonToken;
|
||||
-
|
||||
private:
|
||||
union {
|
||||
SourceLocation m_propertyToken = SourceLocation{};
|
||||
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
index 6c4eb70744..90f567d19c 100644
|
||||
--- a/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "qmljsengine_p.h"
|
||||
#include "qmljskeywords_p.h"
|
||||
|
||||
+#include "qmljs/parser/qlocale_tools_p.h"
|
||||
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
|
||||
#include "qmljs/parser/qmljsmemorypool_p.h"
|
||||
|
||||
@@ -35,14 +36,6 @@
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/QScopedValueRollback>
|
||||
|
||||
-QT_BEGIN_NAMESPACE
|
||||
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
-Q_CORE_EXPORT double qstrntod(const char *s00, int len, char const **se, bool *ok);
|
||||
-#else
|
||||
-Q_CORE_EXPORT double qstrntod(const char *s00, qsizetype len, char const **se, bool *ok);
|
||||
-#endif
|
||||
-QT_END_NAMESPACE
|
||||
-
|
||||
using namespace QmlJS;
|
||||
|
||||
static inline int regExpFlagFromChar(const QChar &ch)
|
||||
diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
index a442748d74..dc7f7f7308 100644
|
||||
--- a/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
@@ -47,7 +47,7 @@ QT_QML_BEGIN_NAMESPACE
|
||||
namespace QmlJS {
|
||||
|
||||
class Engine;
|
||||
-class DiagnosticMessage;
|
||||
+struct DiagnosticMessage;
|
||||
class Directives;
|
||||
|
||||
class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
|
||||
diff --git a/src/libs/qmljs/parser/qmljssourcelocation_p.h b/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
index 29be90fd9b..865c008f19 100644
|
||||
--- a/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
@@ -95,8 +95,11 @@ public:
|
||||
|
||||
friend size_t qHash(const SourceLocation &location, size_t seed = 0)
|
||||
{
|
||||
- return (seed ^ (size_t(location.offset) << 8) ^ size_t(location.length)
|
||||
- ^ (size_t(location.startLine) << 16) ^ (size_t(location.startColumn) << 24));
|
||||
+ return qHashMulti(seed,
|
||||
+ location.offset,
|
||||
+ location.length,
|
||||
+ location.startLine,
|
||||
+ location.startColumn);
|
||||
}
|
||||
|
||||
friend bool operator==(const SourceLocation &a, const SourceLocation &b)
|
||||
|
@@ -1,464 +1,33 @@
|
||||
diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
index cba1cf62c3..404beefe4a 100644
|
||||
--- a/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmldirparser.cpp
|
||||
@@ -25,14 +25,10 @@
|
||||
|
||||
#include "qmldirparser_p.h"
|
||||
|
||||
-#include <utils/qtcassert.h>
|
||||
-
|
||||
#include <QtCore/QtDebug>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
-using namespace LanguageUtils;
|
||||
-
|
||||
static int parseInt(QStringView str, bool *ok)
|
||||
{
|
||||
int pos = 0;
|
||||
@@ -50,45 +46,17 @@ static int parseInt(QStringView str, bool *ok)
|
||||
return number;
|
||||
}
|
||||
|
||||
-static bool parseVersion(const QString &str, int *major, int *minor)
|
||||
+static QTypeRevision parseVersion(const QString &str)
|
||||
{
|
||||
const int dotIndex = str.indexOf(QLatin1Char('.'));
|
||||
if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) {
|
||||
bool ok = false;
|
||||
- *major = parseInt(QStringView(str.constData(), dotIndex), &ok);
|
||||
- if (ok)
|
||||
- *minor = parseInt(QStringView(str.constData() + dotIndex + 1, str.length() - dotIndex - 1),
|
||||
- &ok);
|
||||
- return ok;
|
||||
- }
|
||||
- return false;
|
||||
-}
|
||||
-
|
||||
-static ComponentVersion parseImportVersion(const QString &str)
|
||||
-{
|
||||
- int minor = -1;
|
||||
- int major = -1;
|
||||
- const int dotIndex = str.indexOf(QLatin1Char('.'));
|
||||
- bool ok = false;
|
||||
- if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) {
|
||||
- major = parseInt(QStringView(str.constData(), dotIndex), &ok);
|
||||
- if (ok) {
|
||||
- if (str.length() > dotIndex + 1) {
|
||||
- minor = parseInt(QStringView(str.constData() + dotIndex + 1, str.length() - dotIndex - 1),
|
||||
- &ok);
|
||||
- if (!ok)
|
||||
- minor = ComponentVersion::NoVersion;
|
||||
- } else {
|
||||
- minor = ComponentVersion::MaxVersion;
|
||||
- }
|
||||
- }
|
||||
- } else if (str.length() > 0) {
|
||||
- QTC_ASSERT(str != QLatin1String("auto"), return ComponentVersion(-1, -1));
|
||||
- major = parseInt(QStringView(str.constData(), str.length()),
|
||||
- &ok);
|
||||
- minor = ComponentVersion::MaxVersion;
|
||||
+ const int major = parseInt(QStringView(str).left(dotIndex), &ok);
|
||||
+ if (!ok) return QTypeRevision();
|
||||
+ const int minor = parseInt(QStringView(str).mid(dotIndex + 1, str.length() - dotIndex - 1), &ok);
|
||||
+ return ok ? QTypeRevision::fromVersion(major, minor) : QTypeRevision();
|
||||
}
|
||||
- return ComponentVersion(major, minor);
|
||||
+ return QTypeRevision();
|
||||
}
|
||||
|
||||
void QmlDirParser::clear()
|
||||
@@ -131,12 +99,12 @@ bool QmlDirParser::parse(const QString &source)
|
||||
auto readImport = [&](const QString *sections, int sectionCount, Import::Flags flags) {
|
||||
Import import;
|
||||
if (sectionCount == 2) {
|
||||
- import = Import(sections[1], ComponentVersion(), flags);
|
||||
+ import = Import(sections[1], QTypeRevision(), flags);
|
||||
} else if (sectionCount == 3) {
|
||||
if (sections[2] == QLatin1String("auto")) {
|
||||
- import = Import(sections[1], ComponentVersion(), flags | Import::Auto);
|
||||
+ import = Import(sections[1], QTypeRevision(), flags | Import::Auto);
|
||||
} else {
|
||||
- const auto version = parseImportVersion(sections[2]);
|
||||
+ const auto version = parseVersion(sections[2]);
|
||||
if (version.isValid()) {
|
||||
import = Import(sections[1], version, flags);
|
||||
} else {
|
||||
@@ -274,7 +242,7 @@ bool QmlDirParser::parse(const QString &source)
|
||||
QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1));
|
||||
continue;
|
||||
}
|
||||
- Component entry(sections[1], sections[2], -1, -1);
|
||||
+ Component entry(sections[1], sections[2], QTypeRevision());
|
||||
entry.internal = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else if (sections[0] == QLatin1String("singleton")) {
|
||||
@@ -285,16 +253,16 @@ bool QmlDirParser::parse(const QString &source)
|
||||
} else if (sectionCount == 3) {
|
||||
// handle qmldir directory listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType TestSingletonType.qml
|
||||
- Component entry(sections[1], sections[2], -1, -1);
|
||||
+ Component entry(sections[1], sections[2], QTypeRevision());
|
||||
entry.singleton = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else {
|
||||
// handle qmldir module listing case where singleton is defined in the following pattern:
|
||||
// singleton TestSingletonType 2.0 TestSingletonType20.qml
|
||||
- int major, minor;
|
||||
- if (parseVersion(sections[2], &major, &minor)) {
|
||||
+ const QTypeRevision version = parseVersion(sections[2]);
|
||||
+ if (version.isValid()) {
|
||||
const QString &fileName = sections[3];
|
||||
- Component entry(sections[1], fileName, major, minor);
|
||||
+ Component entry(sections[1], fileName, version);
|
||||
entry.singleton = true;
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else {
|
||||
@@ -341,19 +309,19 @@ bool QmlDirParser::parse(const QString &source)
|
||||
_preferredPath = sections[1];
|
||||
} else if (sectionCount == 2) {
|
||||
// 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], QTypeRevision());
|
||||
_components.insert(entry.typeName, entry);
|
||||
} else if (sectionCount == 3) {
|
||||
- int major, minor;
|
||||
- if (parseVersion(sections[1], &major, &minor)) {
|
||||
+ const QTypeRevision version = parseVersion(sections[1]);
|
||||
+ if (version.isValid()) {
|
||||
const QString &fileName = sections[2];
|
||||
|
||||
if (fileName.endsWith(QLatin1String(".js")) || fileName.endsWith(QLatin1String(".mjs"))) {
|
||||
// A 'js' extension indicates a namespaced script import
|
||||
- const Script entry(sections[0], fileName, major, minor);
|
||||
+ const Script entry(sections[0], fileName, version);
|
||||
_scripts.append(entry);
|
||||
} else {
|
||||
- const Component entry(sections[0], fileName, major, minor);
|
||||
+ const Component entry(sections[0], fileName, version);
|
||||
_components.insert(entry.typeName, entry);
|
||||
}
|
||||
} else {
|
||||
@@ -400,15 +368,17 @@ QList<QmlJS::DiagnosticMessage> QmlDirParser::errors(const QString &uri) const
|
||||
|
||||
QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component)
|
||||
{
|
||||
- const QString output = QStringLiteral("{%1 %2.%3}").
|
||||
- arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion);
|
||||
+ const QString output = QStringLiteral("{%1 %2.%3}")
|
||||
+ .arg(component.typeName).arg(component.version.majorVersion())
|
||||
+ .arg(component.version.minorVersion());
|
||||
return debug << qPrintable(output);
|
||||
}
|
||||
|
||||
QDebug &operator<< (QDebug &debug, const QmlDirParser::Script &script)
|
||||
{
|
||||
- const QString output = QStringLiteral("{%1 %2.%3}").
|
||||
- arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion);
|
||||
+ const QString output = QStringLiteral("{%1 %2.%3}")
|
||||
+ .arg(script.nameSpace).arg(script.version.majorVersion())
|
||||
+ .arg(script.version.minorVersion());
|
||||
return debug << qPrintable(output);
|
||||
}
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmldirparser_p.h b/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
index 529a44078a..f83a4ec8a0 100644
|
||||
--- a/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmldirparser_p.h
|
||||
@@ -39,11 +39,8 @@
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QDebug>
|
||||
-
|
||||
-#include <languageutils/componentversion.h>
|
||||
-
|
||||
+#include <QtCore/QTypeRevision>
|
||||
#include "qmljs/parser/qmljsglobal_p.h"
|
||||
-#include "qmljs/parser/qmljsengine_p.h"
|
||||
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
@@ -90,8 +87,8 @@ public:
|
||||
{
|
||||
Component() = default;
|
||||
|
||||
- Component(const QString &typeName, const QString &fileName, int majorVersion, int minorVersion)
|
||||
- : typeName(typeName), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion),
|
||||
+ Component(const QString &typeName, const QString &fileName, QTypeRevision version)
|
||||
+ : typeName(typeName), fileName(fileName), version(version),
|
||||
internal(false), singleton(false)
|
||||
{
|
||||
checkNonRelative("Component", typeName, fileName);
|
||||
@@ -99,8 +96,7 @@ public:
|
||||
|
||||
QString typeName;
|
||||
QString fileName;
|
||||
- int majorVersion = 0;
|
||||
- int minorVersion = 0;
|
||||
+ QTypeRevision version = QTypeRevision::zero();
|
||||
bool internal = false;
|
||||
bool singleton = false;
|
||||
};
|
||||
@@ -109,16 +105,15 @@ public:
|
||||
{
|
||||
Script() = default;
|
||||
|
||||
- Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion)
|
||||
- : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion)
|
||||
+ Script(const QString &nameSpace, const QString &fileName, QTypeRevision version)
|
||||
+ : nameSpace(nameSpace), fileName(fileName), version(version)
|
||||
{
|
||||
checkNonRelative("Script", nameSpace, fileName);
|
||||
}
|
||||
|
||||
QString nameSpace;
|
||||
QString fileName;
|
||||
- int majorVersion = 0;
|
||||
- int minorVersion = 0;
|
||||
+ QTypeRevision version = QTypeRevision::zero();
|
||||
};
|
||||
|
||||
struct Import
|
||||
@@ -131,13 +126,13 @@ public:
|
||||
Q_DECLARE_FLAGS(Flags, Flag)
|
||||
|
||||
Import() = default;
|
||||
- Import(QString module, LanguageUtils::ComponentVersion version, Flags flags)
|
||||
+ Import(QString module, QTypeRevision version, Flags flags)
|
||||
: module(module), version(version), flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
QString module;
|
||||
- LanguageUtils::ComponentVersion version; // invalid version is latest version, unless Flag::Auto
|
||||
+ QTypeRevision version; // invalid version is latest version, unless Flag::Auto
|
||||
Flags flags;
|
||||
};
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmlimportresolver.cpp b/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
index 06f04a14e7..2a6608a1da 100644
|
||||
--- a/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmlimportresolver.cpp
|
||||
@@ -41,7 +41,7 @@ enum ImportVersion { FullyVersioned, PartiallyVersioned, Unversioned };
|
||||
- base/QtQml/Models
|
||||
*/
|
||||
QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths,
|
||||
- LanguageUtils::ComponentVersion version)
|
||||
+ QTypeRevision version)
|
||||
{
|
||||
static const QLatin1Char Slash('/');
|
||||
static const QLatin1Char Backslash('\\');
|
||||
@@ -46,13 +46,13 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
static const QLatin1Char Slash('/');
|
||||
static const QLatin1Char Backslash('\\');
|
||||
|
||||
- const QList<QStringView> parts = uri.split(u'.', Qt::SkipEmptyParts);
|
||||
+ const QVector<QStringView> parts = uri.split(u'.', Qt::SkipEmptyParts);
|
||||
|
||||
QStringList importPaths;
|
||||
// fully & partially versioned parts + 1 unversioned for each base path
|
||||
importPaths.reserve(2 * parts.count() + 1);
|
||||
|
||||
- auto versionString = [](LanguageUtils::ComponentVersion version, ImportVersion mode)
|
||||
+ auto versionString = [](QTypeRevision version, ImportVersion mode)
|
||||
{
|
||||
if (mode == FullyVersioned) {
|
||||
// extension with fully encoded version number (eg. MyModule.3.2)
|
||||
@@ -67,7 +67,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
return QString();
|
||||
};
|
||||
|
||||
- auto joinStringRefs = [](const QList<QStringView> &refs, const QChar &sep) {
|
||||
+ auto joinStringRefs = [](const QVector<QStringView> &refs, const QChar &sep) {
|
||||
QString str;
|
||||
for (auto it = refs.cbegin(); it != refs.cend(); ++it) {
|
||||
if (it != refs.cbegin())
|
||||
@@ -77,9 +77,9 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
return str;
|
||||
};
|
||||
|
||||
- const ImportVersion initial = ((version.minorVersion() >= 0)
|
||||
+ const ImportVersion initial = (version.hasMinorVersion())
|
||||
? FullyVersioned
|
||||
- : ((version.majorVersion() >= 0) ? PartiallyVersioned : Unversioned));
|
||||
+ : (version.hasMajorVersion() ? PartiallyVersioned : Unversioned);
|
||||
for (int mode = initial; mode <= Unversioned; ++mode) {
|
||||
const QString ver = versionString(version, ImportVersion(mode));
|
||||
|
||||
diff --git a/src/libs/qmljs/parser/qmlimportresolver_p.h b/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
index 8f0bf7f6e4..8d0b4ed838 100644
|
||||
--- a/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmlimportresolver_p.h
|
||||
@@ -40,11 +40,12 @@
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include <QtCore/qstring.h>
|
||||
-#include <languageutils/componentversion.h>
|
||||
+#include <QtCore/qversionnumber.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
QML_PARSER_EXPORT QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths,
|
||||
- LanguageUtils::ComponentVersion version);
|
||||
+ QTypeRevision version);
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
+
|
||||
diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h
|
||||
index ba1f642629..e286571e2e 100644
|
||||
--- a/src/libs/qmljs/parser/qmljsast_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljsast_p.h
|
||||
@@ -654,12 +654,12 @@ class QML_PARSER_EXPORT UiVersionSpecifier : public Node
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiVersionSpecifier)
|
||||
|
||||
- UiVersionSpecifier(int majorum) : majorVersion(majorum)
|
||||
+ UiVersionSpecifier(int majorum) : version(QTypeRevision::fromMajorVersion(majorum))
|
||||
{
|
||||
kind = K;
|
||||
}
|
||||
|
||||
- UiVersionSpecifier(int majorum, int minorum) : majorVersion(majorum), minorVersion(minorum)
|
||||
+ UiVersionSpecifier(int majorum, int minorum) : version(QTypeRevision::fromVersion(majorum, minorum))
|
||||
{
|
||||
kind = K;
|
||||
}
|
||||
@@ -674,8 +674,7 @@ public:
|
||||
}
|
||||
|
||||
// attributes:
|
||||
- int majorVersion = -1;
|
||||
- int minorVersion = -1;
|
||||
+ QTypeRevision version;
|
||||
SourceLocation majorToken;
|
||||
SourceLocation minorToken;
|
||||
};
|
||||
@@ -880,12 +879,11 @@ struct QML_PARSER_EXPORT BoundName
|
||||
};
|
||||
|
||||
QString id;
|
||||
- TypeAnnotation *typeAnnotation;
|
||||
- Type typeAnnotationType;
|
||||
+ QTaggedPointer<TypeAnnotation, Type> typeAnnotation;
|
||||
BoundName(const QString &id, TypeAnnotation *typeAnnotation, Type type = Declared)
|
||||
- : id(id), typeAnnotation(typeAnnotation), typeAnnotationType(type)
|
||||
+ : id(id), typeAnnotation(typeAnnotation, type)
|
||||
{}
|
||||
BoundName() = default;
|
||||
QString typeName() const { return typeAnnotation ? typeAnnotation->type->toString() : QString(); }
|
||||
- bool isInjected() const { return typeAnnotation && typeAnnotationType == Injected; }
|
||||
+ bool isInjected() const { return typeAnnotation.tag() == Injected; }
|
||||
};
|
||||
|
||||
struct BoundNames : public QVector<BoundName>
|
||||
@@ -3724,3 +3722,4 @@ public:
|
||||
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
+
|
||||
diff --git a/src/libs/qmljs/parser/qmljsgrammar.cpp b/src/libs/qmljs/parser/qmljsgrammar.cpp
|
||||
index 3d60e96373..01b98a5033 100644
|
||||
index 0413edb006..373f42747d 100644
|
||||
--- a/src/libs/qmljs/parser/qmljsgrammar.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmljsgrammar.cpp
|
||||
@@ -21,8 +21,7 @@
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
@@ -22,6 +22,7 @@
|
||||
** 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!
|
||||
+ / This file was generated by qlalr
|
||||
+ - DO NOT EDIT !
|
||||
#include "qmljsgrammar_p.h"
|
||||
|
||||
const char *const QmlJSGrammar::spell [] = {
|
||||
diff --git a/src/libs/qmljs/parser/qmljsgrammar_p.h b/src/libs/qmljs/parser/qmljsgrammar_p.h
|
||||
index 43ad1b4950..ae32388aa5 100644
|
||||
index 2e7172b41d..6a057768d4 100644
|
||||
--- a/src/libs/qmljs/parser/qmljsgrammar_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljsgrammar_p.h
|
||||
@@ -21,13 +21,11 @@
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
@@ -22,12 +22,12 @@
|
||||
** 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!
|
||||
+ / This file was generated by qlalr
|
||||
+ - DO NOT EDIT !
|
||||
#ifndef QMLJSGRAMMAR_P_H
|
||||
#define QMLJSGRAMMAR_P_H
|
||||
-#include "qmljsglobal_p.h"
|
||||
|
||||
-class QML_PARSER_EXPORT QmlJSGrammar
|
||||
+class QmlJSGrammar
|
||||
+ class QmlJSGrammar
|
||||
{
|
||||
public:
|
||||
enum VariousConstants {
|
||||
@@ -215,3 +213,4 @@ public:
|
||||
|
||||
|
||||
#endif // QMLJSGRAMMAR_P_H
|
||||
+
|
||||
diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
index 6c4eb70744..ec57f04cb7 100644
|
||||
--- a/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
+++ b/src/libs/qmljs/parser/qmljslexer.cpp
|
||||
@@ -30,19 +30,12 @@
|
||||
#include "qmljs/parser/qmljsdiagnosticmessage_p.h"
|
||||
#include "qmljs/parser/qmljsmemorypool_p.h"
|
||||
|
||||
+
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/QScopedValueRollback>
|
||||
|
||||
-QT_BEGIN_NAMESPACE
|
||||
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
-Q_CORE_EXPORT double qstrntod(const char *s00, int len, char const **se, bool *ok);
|
||||
-#else
|
||||
-Q_CORE_EXPORT double qstrntod(const char *s00, qsizetype len, char const **se, bool *ok);
|
||||
-#endif
|
||||
-QT_END_NAMESPACE
|
||||
-
|
||||
using namespace QmlJS;
|
||||
|
||||
static inline int regExpFlagFromChar(const QChar &ch)
|
||||
diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
index 429c0f6619..794270b032 100644
|
||||
--- a/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljslexer_p.h
|
||||
@@ -47,7 +47,7 @@ QT_QML_BEGIN_NAMESPACE
|
||||
namespace QmlJS {
|
||||
|
||||
class Engine;
|
||||
-class DiagnosticMessage;
|
||||
+struct DiagnosticMessage;
|
||||
class Directives;
|
||||
|
||||
class QML_PARSER_EXPORT Lexer: public QmlJSGrammar
|
||||
diff --git a/src/libs/qmljs/parser/qmljssourcelocation_p.h b/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
index f9ffa21714..5dff8c75dd 100644
|
||||
--- a/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
+++ b/src/libs/qmljs/parser/qmljssourcelocation_p.h
|
||||
@@ -95,14 +95,14 @@ public:
|
||||
|
||||
friend size_t qHash(const SourceLocation &location, size_t seed = 0)
|
||||
{
|
||||
- return (seed ^ (size_t(location.offset) << 8) ^ size_t(location.length)
|
||||
- ^ (size_t(location.startLine) << 16) ^ (size_t(location.startColumn) << 24));
|
||||
+ return qHashMulti(seed, location.offset, location.length,
|
||||
+ location.startLine, location.startColumn);
|
||||
}
|
||||
|
||||
friend bool operator==(const SourceLocation &a, const SourceLocation &b)
|
||||
{
|
||||
- return a.offset == b.offset && a.length == b.length && a.startLine == b.startLine
|
||||
- && a.startColumn == b.startColumn;
|
||||
+ return a.offset == b.offset && a.length == b.length
|
||||
+ && a.startLine == b.startLine && a.startColumn == b.startColumn;
|
||||
}
|
||||
|
||||
friend bool operator!=(const SourceLocation &a, const SourceLocation &b) { return !(a == b); }
|
||||
@@ -124,3 +124,4 @@ public:
|
||||
} // namespace QmlJS
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
+
|
||||
|
@@ -16,7 +16,6 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
$$PWD/qmljsast.cpp \
|
||||
$$PWD/qmljsastvisitor.cpp \
|
||||
$$PWD/qmljsengine_p.cpp \
|
||||
$$PWD/qmlimportresolver.cpp \
|
||||
$$PWD/qmljslexer.cpp \
|
||||
$$PWD/qmldirparser.cpp \
|
||||
|
@@ -103,6 +103,7 @@ void QmlDirParser::clear()
|
||||
_designerSupported = false;
|
||||
_typeInfos.clear();
|
||||
_classNames.clear();
|
||||
_linkTarget.clear();
|
||||
}
|
||||
|
||||
inline static void scanSpace(const QChar *&ch) {
|
||||
@@ -339,6 +340,25 @@ bool QmlDirParser::parse(const QString &source)
|
||||
}
|
||||
|
||||
_preferredPath = sections[1];
|
||||
} else if (sections[0] == QLatin1String("linktarget")) {
|
||||
if (sectionCount < 2) {
|
||||
reportError(lineNumber,
|
||||
0,
|
||||
QStringLiteral("linktarget directive requires an argument, "
|
||||
"but %1 were provided")
|
||||
.arg(sectionCount - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!_linkTarget.isEmpty()) {
|
||||
reportError(lineNumber,
|
||||
0,
|
||||
QStringLiteral(
|
||||
"only one linktarget directive may be defined in a qmldir file"));
|
||||
continue;
|
||||
}
|
||||
|
||||
_linkTarget = sections[1];
|
||||
} else if (sectionCount == 2) {
|
||||
// No version specified (should only be used for relative qmldir files)
|
||||
const Component entry(sections[0], sections[1], -1, -1);
|
||||
|
@@ -151,6 +151,7 @@ public:
|
||||
QStringList typeInfos() const { return _typeInfos; }
|
||||
QStringList classNames() const { return _classNames; }
|
||||
QString preferredPath() const { return _preferredPath; }
|
||||
QString linkTarget() const { return _linkTarget; }
|
||||
|
||||
private:
|
||||
bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash<QString,Component> &hash, int lineNumber = -1, bool multi = true);
|
||||
@@ -168,6 +169,7 @@ private:
|
||||
bool _designerSupported = false;
|
||||
QStringList _typeInfos;
|
||||
QStringList _classNames;
|
||||
QString _linkTarget;
|
||||
};
|
||||
|
||||
using QmlDirComponents = QMultiHash<QString,QmlDirParser::Component>;
|
||||
|
@@ -24,8 +24,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "qmlimportresolver_p.h"
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QStringView>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -48,14 +49,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
static const QLatin1Char Slash('/');
|
||||
static const QLatin1Char Backslash('\\');
|
||||
|
||||
const QList<QStringView> parts
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 2)
|
||||
= uri.split(u'.', Qt::SkipEmptyParts);
|
||||
#else
|
||||
= Utils::transform(uri.toString().split('.', Qt::SkipEmptyParts), [](const QString &s) {
|
||||
return QStringView(s);
|
||||
});
|
||||
#endif
|
||||
const QList<QStringView> parts = uri.split(u'.', Qt::SkipEmptyParts);
|
||||
|
||||
QStringList importPaths;
|
||||
// fully & partially versioned parts + 1 unversioned for each base path
|
||||
@@ -81,7 +75,7 @@ QStringList qQmlResolveImportPaths(QStringView uri, const QStringList &basePaths
|
||||
for (auto it = refs.cbegin(); it != refs.cend(); ++it) {
|
||||
if (it != refs.cbegin())
|
||||
str += sep;
|
||||
str += (*it).toString();
|
||||
str += *it;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
@@ -315,6 +315,7 @@ public:
|
||||
AST::UiPragma *UiPragma;
|
||||
AST::UiImport *UiImport;
|
||||
AST::UiParameterList *UiParameterList;
|
||||
AST::UiPropertyAttributes *UiPropertyAttributes;
|
||||
AST::UiPublicMember *UiPublicMember;
|
||||
AST::UiObjectDefinition *UiObjectDefinition;
|
||||
AST::UiObjectInitializer *UiObjectInitializer;
|
||||
@@ -824,6 +825,16 @@ UiPragma: T_PRAGMA PragmaId Semicolon;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiPragma: T_PRAGMA PragmaId T_COLON JsIdentifier Semicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPragma *pragma = new (pool) AST::UiPragma(stringRef(2), stringRef(4));
|
||||
pragma->pragmaToken = loc(1);
|
||||
pragma->semicolonToken = loc(5);
|
||||
sym(1).Node = pragma;
|
||||
} break;
|
||||
./
|
||||
|
||||
ImportId: MemberExpression;
|
||||
|
||||
UiImport: UiImportHead Semicolon;
|
||||
@@ -1262,7 +1273,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER T_LPAREN UiParameterListOpt T_RPAREN Semic
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
|
||||
node->type = AST::UiPublicMember::Signal;
|
||||
node->propertyToken = loc(1);
|
||||
node->setPropertyToken(loc(1));
|
||||
node->typeToken = loc(2);
|
||||
node->identifierToken = loc(2);
|
||||
node->parameters = sym(4).UiParameterList;
|
||||
@@ -1276,7 +1287,7 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER Semicolon;
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(nullptr, stringRef(2));
|
||||
node->type = AST::UiPublicMember::Signal;
|
||||
node->propertyToken = loc(1);
|
||||
node->setPropertyToken(loc(1));
|
||||
node->typeToken = loc(2);
|
||||
node->identifierToken = loc(2);
|
||||
node->semicolonToken = loc(3);
|
||||
@@ -1284,12 +1295,70 @@ UiObjectMember: T_SIGNAL T_IDENTIFIER Semicolon;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberListPropertyNoInitialiser: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
|
||||
-------------------------------------------------------------------------------
|
||||
-- There is some ambiguity in whether required default property should be parsed
|
||||
-- as required (default (property)) or as ((required (default)) property)
|
||||
-- by reducing after each attribute modifier, we ensure that T_PROPERTY (which
|
||||
-- is always available is used as the base case (so we only have to allocate the
|
||||
-- node in the T_PROPERY case, and all other rules can assume that the node is
|
||||
-- already available).
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
AttrRequired: T_REQUIRED %prec REDUCE_HERE;
|
||||
AttrReadonly: T_READONLY %prec REDUCE_HERE;
|
||||
AttrDefault: T_DEFAULT %prec REDUCE_HERE;
|
||||
|
||||
UiPropertyAttributes: AttrRequired UiPropertyAttributes;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes;
|
||||
if (node->isRequired())
|
||||
diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'required' attribute is not allowed."), QtCriticalMsg));
|
||||
node->m_requiredToken = loc(1);
|
||||
sym(1).UiPropertyAttributes = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiPropertyAttributes: AttrDefault UiPropertyAttributes;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes;
|
||||
if (node->isDefaultMember())
|
||||
diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'default' attribute is not allowed."), QtCriticalMsg));
|
||||
node->m_defaultToken = loc(1);
|
||||
sym(1).UiPropertyAttributes = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiPropertyAttributes: AttrReadonly UiPropertyAttributes;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPropertyAttributes *node = sym(2).UiPropertyAttributes;
|
||||
if (node->isReadonly())
|
||||
diagnostic_messages.append(compileError(node->requiredToken(), QLatin1String("Duplicated 'readonly' attribute is not allowed."), QtCriticalMsg));
|
||||
node->m_readonlyToken = loc(1);
|
||||
sym(1).UiPropertyAttributes = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiPropertyAttributes: T_PROPERTY;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPropertyAttributes *node = new (pool) AST::UiPropertyAttributes();
|
||||
node->m_propertyToken = loc(1);
|
||||
sym(1).UiPropertyAttributes = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberListPropertyNoInitialiser: UiPropertyAttributes T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier Semicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
|
||||
auto attributes = sym(1).UiPropertyAttributes;
|
||||
node->setAttributes(attributes);
|
||||
if (attributes->isReadonly())
|
||||
diagnostic_messages.append(compileError(attributes->readonlyToken(), QLatin1String("Read-only properties require an initializer."), QtWarningMsg));
|
||||
node->typeModifier = stringRef(2);
|
||||
node->propertyToken = loc(1);
|
||||
node->typeModifierToken = loc(2);
|
||||
node->typeToken = loc(4);
|
||||
node->identifierToken = loc(6);
|
||||
@@ -1300,21 +1369,14 @@ UiObjectMemberListPropertyNoInitialiser: T_PROPERTY T_IDENTIFIER T_LT UiProperty
|
||||
|
||||
UiObjectMember: UiObjectMemberListPropertyNoInitialiser;
|
||||
|
||||
UiObjectMember: T_READONLY UiObjectMemberListPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isReadonlyMember = true;
|
||||
node->readonlyToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberPropertyNoInitialiser: T_PROPERTY UiPropertyType QmlIdentifier Semicolon;
|
||||
UiObjectMemberPropertyNoInitialiser: UiPropertyAttributes UiPropertyType QmlIdentifier Semicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
|
||||
node->propertyToken = loc(1);
|
||||
auto attributes = sym(1).UiPropertyAttributes;
|
||||
if (attributes->isReadonly())
|
||||
diagnostic_messages.append(compileError(attributes->readonlyToken(), QLatin1String("Read-only properties require an initializer."), QtCriticalMsg));
|
||||
node->setAttributes(attributes);
|
||||
node->typeToken = loc(2);
|
||||
node->identifierToken = loc(3);
|
||||
node->semicolonToken = loc(4);
|
||||
@@ -1325,86 +1387,6 @@ UiObjectMemberPropertyNoInitialiser: T_PROPERTY UiPropertyType QmlIdentifier Sem
|
||||
|
||||
UiObjectMember: UiObjectMemberPropertyNoInitialiser;
|
||||
|
||||
UiObjectMember: T_DEFAULT UiObjectMemberPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isDefaultMember = true;
|
||||
node->defaultToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
|
||||
UiObjectMember: T_REQUIRED UiObjectMemberListPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isRequired = true;
|
||||
node->requiredToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: T_DEFAULT T_REQUIRED UiObjectMemberListPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(3).UiPublicMember;
|
||||
node->isRequired = true;
|
||||
node->requiredToken = loc(2);
|
||||
node->isDefaultMember = true;
|
||||
node->defaultToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: T_REQUIRED T_DEFAULT UiObjectMemberListPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(3).UiPublicMember;
|
||||
node->isRequired = true;
|
||||
node->requiredToken = loc(1);
|
||||
node->isDefaultMember = true;
|
||||
node->defaultToken = loc(2);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: T_DEFAULT UiObjectMemberListPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isDefaultMember = true;
|
||||
node->defaultToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} 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;
|
||||
/.
|
||||
/* we need OptionalSemicolon because UiScriptStatement might already parse the last semicolon
|
||||
@@ -1423,21 +1405,14 @@ UiRequired: T_REQUIRED QmlIdentifier Semicolon;
|
||||
|
||||
UiObjectMember: UiRequired;
|
||||
|
||||
UiObjectMember: T_REQUIRED UiObjectMemberPropertyNoInitialiser;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->requiredToken = loc(1);
|
||||
node->isRequired = true;
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
|
||||
UiObjectMemberWithScriptStatement: UiPropertyAttributes UiPropertyType QmlIdentifier T_COLON UiScriptStatement OptionalSemicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3), sym(5).Statement);
|
||||
node->propertyToken = loc(1);
|
||||
auto attributes = sym(1).UiPropertyAttributes;
|
||||
if (attributes->isRequired())
|
||||
diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtCriticalMsg));
|
||||
node->setAttributes(attributes);
|
||||
node->typeToken = loc(2);
|
||||
node->identifierToken = loc(3);
|
||||
node->colonToken = loc(4);
|
||||
@@ -1447,32 +1422,15 @@ UiObjectMemberWithScriptStatement: T_PROPERTY UiPropertyType QmlIdentifier T_COL
|
||||
|
||||
UiObjectMember: UiObjectMemberWithScriptStatement;
|
||||
|
||||
UiObjectMember: T_READONLY UiObjectMemberWithScriptStatement;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isReadonlyMember = true;
|
||||
node->readonlyToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: T_DEFAULT UiObjectMemberWithScriptStatement;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isDefaultMember = true;
|
||||
node->defaultToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
|
||||
UiObjectMemberWithArray: UiPropertyAttributes T_IDENTIFIER T_LT UiPropertyType T_GT QmlIdentifier T_COLON T_LBRACKET UiArrayMemberList T_RBRACKET Semicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(4).UiQualifiedId->finish(), stringRef(6));
|
||||
auto attributes = sym(1).UiPropertyAttributes;
|
||||
if (attributes->isRequired())
|
||||
diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtCriticalMsg));
|
||||
node->setAttributes(attributes);
|
||||
node->typeModifier = stringRef(2);
|
||||
node->propertyToken = loc(1);
|
||||
node->typeModifierToken = loc(2);
|
||||
node->typeToken = loc(4);
|
||||
node->identifierToken = loc(6);
|
||||
@@ -1480,7 +1438,7 @@ UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIde
|
||||
|
||||
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(6));
|
||||
propertyName->identifierToken = loc(6);
|
||||
propertyName->next = 0;
|
||||
propertyName->next = nullptr;
|
||||
|
||||
AST::UiArrayBinding *binding = new (pool) AST::UiArrayBinding(propertyName, sym(9).UiArrayMemberList->finish());
|
||||
binding->colonToken = loc(7);
|
||||
@@ -1495,28 +1453,21 @@ UiObjectMemberWithArray: T_PROPERTY T_IDENTIFIER T_LT UiPropertyType T_GT QmlIde
|
||||
|
||||
UiObjectMember: UiObjectMemberWithArray;
|
||||
|
||||
UiObjectMember: T_READONLY UiObjectMemberWithArray;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isReadonlyMember = true;
|
||||
node->readonlyToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMemberExpressionStatementLookahead: T_PROPERTY UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
|
||||
UiObjectMemberExpressionStatementLookahead: UiPropertyAttributes UiPropertyType QmlIdentifier T_COLON ExpressionStatementLookahead UiQualifiedId UiObjectInitializer Semicolon;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(sym(2).UiQualifiedId->finish(), stringRef(3));
|
||||
node->propertyToken = loc(1);
|
||||
auto attributes = sym(1).UiPropertyAttributes;
|
||||
if (attributes->isRequired())
|
||||
diagnostic_messages.append(compileError(attributes->requiredToken(), QLatin1String("Required properties with initializer do not make sense."), QtWarningMsg));
|
||||
node->setAttributes(attributes);
|
||||
node->typeToken = loc(2);
|
||||
node->identifierToken = loc(3);
|
||||
node->semicolonToken = loc(4); // insert a fake ';' before ':'
|
||||
|
||||
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(3));
|
||||
propertyName->identifierToken = loc(3);
|
||||
propertyName->next = 0;
|
||||
propertyName->next = nullptr;
|
||||
|
||||
AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
|
||||
propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
|
||||
@@ -1530,16 +1481,6 @@ UiObjectMemberExpressionStatementLookahead: T_PROPERTY UiPropertyType QmlIdentif
|
||||
|
||||
UiObjectMember: UiObjectMemberExpressionStatementLookahead;
|
||||
|
||||
UiObjectMember: T_READONLY UiObjectMemberExpressionStatementLookahead;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = sym(2).UiPublicMember;
|
||||
node->isReadonlyMember = true;
|
||||
node->readonlyToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: GeneratorDeclaration;
|
||||
/.
|
||||
case $rule_number: {
|
||||
@@ -2113,6 +2054,7 @@ CoverInitializedName: IdentifierReference Initializer_In;
|
||||
if (auto *c = asAnonymousClassDefinition(sym(2).Expression))
|
||||
c->name = stringRef(1);
|
||||
AST::BinaryExpression *assignment = new (pool) AST::BinaryExpression(left, QSOperator::Assign, sym(2).Expression);
|
||||
assignment->operatorToken = loc(2);
|
||||
AST::PatternProperty *node = new (pool) AST::PatternProperty(name, assignment);
|
||||
node->colonToken = loc(1);
|
||||
sym(1).Node = node;
|
||||
@@ -2245,7 +2187,14 @@ InitializerOpt: Initializer;
|
||||
InitializerOpt_In: Initializer_In;
|
||||
|
||||
TemplateLiteral: T_NO_SUBSTITUTION_TEMPLATE;
|
||||
/. case $rule_number: Q_FALLTHROUGH(); ./
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::TemplateLiteral *node = new (pool) AST::TemplateLiteral(stringRef(1), rawStringRef(1), nullptr);
|
||||
node->literalToken = loc(1);
|
||||
node->hasNoSubstitution = true;
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
TemplateSpans: T_TEMPLATE_TAIL;
|
||||
/.
|
||||
@@ -4118,7 +4067,7 @@ ArrowFunction_In: ArrowParameters T_ARROW ConciseBodyLookahead T_FORCE_BLOCK Fun
|
||||
AST::FunctionExpression *f = new (pool) AST::FunctionExpression(QStringView(), sym(1).FormalParameterList, sym(6).StatementList);
|
||||
f->isArrowFunction = true;
|
||||
f->functionToken = sym(1).Node ? sym(1).Node->firstSourceLocation().startZeroLengthLocation() : loc(1).startZeroLengthLocation();
|
||||
f->lbraceToken = loc(6);
|
||||
f->lbraceToken = loc(5);
|
||||
f->rbraceToken = loc(7);
|
||||
sym(1).Node = f;
|
||||
} break;
|
||||
|
@@ -23,12 +23,15 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QLocale>
|
||||
#include "qmljsast_p.h"
|
||||
#include <QLocale>
|
||||
#include <QString>
|
||||
|
||||
#include "qmljsastvisitor_p.h"
|
||||
#include <qlocale.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS { namespace AST {
|
||||
@@ -1582,7 +1585,7 @@ QString Type::toString() const
|
||||
void Type::toString(QString *out) const
|
||||
{
|
||||
for (QmlJS::AST::UiQualifiedId *it = typeId; it; it = it->next) {
|
||||
out->append(it->name.toString());
|
||||
out->append(it->name);
|
||||
|
||||
if (it->next)
|
||||
out->append(QLatin1Char('.'));
|
||||
@@ -1634,6 +1637,25 @@ void UiAnnotation::accept0(BaseVisitor *visitor)
|
||||
visitor->endVisit(this);
|
||||
}
|
||||
|
||||
SourceLocation UiPropertyAttributes::firstSourceLocation() const
|
||||
{
|
||||
std::array<const SourceLocation *, 4> tokens{&m_propertyToken,
|
||||
&m_defaultToken,
|
||||
&m_readonlyToken,
|
||||
&m_requiredToken};
|
||||
const auto it = std::min_element(tokens.begin(), tokens.end(), compareLocationsByBegin<true>);
|
||||
return **it;
|
||||
}
|
||||
|
||||
SourceLocation UiPropertyAttributes::lastSourceLocation() const
|
||||
{
|
||||
std::array<const SourceLocation *, 4> tokens{&m_propertyToken,
|
||||
&m_defaultToken,
|
||||
&m_readonlyToken,
|
||||
&m_requiredToken};
|
||||
const auto it = std::max_element(tokens.begin(), tokens.end(), compareLocationsByBegin<false>);
|
||||
return **it;
|
||||
}
|
||||
} } // namespace QmlJS::AST
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
@@ -41,11 +41,16 @@
|
||||
|
||||
#include "qmljs/parser/qmljsmemorypool_p.h"
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qversionnumber.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
class QString;
|
||||
|
||||
namespace QmlJS {
|
||||
class Parser;
|
||||
}
|
||||
|
||||
#define QMLJS_DECLARE_AST_NODE(name) \
|
||||
enum { K = Kind_##name };
|
||||
|
||||
@@ -238,6 +243,7 @@ public:
|
||||
Kind_UiPragma,
|
||||
Kind_UiProgram,
|
||||
Kind_UiParameterList,
|
||||
Kind_UiPropertyAttributes,
|
||||
Kind_UiPublicMember,
|
||||
Kind_UiQualifiedId,
|
||||
Kind_UiScriptBinding,
|
||||
@@ -292,12 +298,6 @@ public:
|
||||
node->accept(visitor);
|
||||
}
|
||||
|
||||
// ### Remove when we can. This is part of the qmldevtools library, though.
|
||||
inline static void acceptChild(Node *node, BaseVisitor *visitor)
|
||||
{
|
||||
return accept(node, visitor);
|
||||
}
|
||||
|
||||
virtual void accept0(BaseVisitor *visitor) = 0;
|
||||
virtual SourceLocation firstSourceLocation() const = 0;
|
||||
virtual SourceLocation lastSourceLocation() const = 0;
|
||||
@@ -721,6 +721,7 @@ public:
|
||||
|
||||
void accept0(BaseVisitor *visitor) override;
|
||||
|
||||
bool hasNoSubstitution = false;
|
||||
QStringView value;
|
||||
QStringView rawValue;
|
||||
ExpressionNode *expression;
|
||||
@@ -3121,8 +3122,9 @@ class QML_PARSER_EXPORT UiPragma: public Node
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiPragma)
|
||||
|
||||
UiPragma(QStringView name)
|
||||
UiPragma(QStringView name, QStringView value = {})
|
||||
: name(name)
|
||||
, value(value)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(BaseVisitor *visitor) override;
|
||||
@@ -3135,6 +3137,7 @@ public:
|
||||
|
||||
// attributes
|
||||
QStringView name;
|
||||
QStringView value;
|
||||
SourceLocation pragmaToken;
|
||||
SourceLocation semicolonToken;
|
||||
};
|
||||
@@ -3350,34 +3353,77 @@ public:
|
||||
SourceLocation colonToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiPropertyAttributes : public Node
|
||||
{
|
||||
QMLJS_DECLARE_AST_NODE(UiPropertyAttributes)
|
||||
public:
|
||||
UiPropertyAttributes() { kind = K; }
|
||||
|
||||
SourceLocation defaultToken() const { return m_defaultToken; }
|
||||
bool isDefaultMember() const { return defaultToken().isValid(); }
|
||||
SourceLocation requiredToken() const { return m_requiredToken; }
|
||||
bool isRequired() const { return requiredToken().isValid(); }
|
||||
SourceLocation readonlyToken() const { return m_readonlyToken; }
|
||||
bool isReadonly() const { return readonlyToken().isValid(); }
|
||||
|
||||
SourceLocation propertyToken() const { return m_propertyToken; }
|
||||
|
||||
template<bool InvalidIsLargest = true>
|
||||
static bool compareLocationsByBegin(const SourceLocation *&lhs, const SourceLocation *&rhs)
|
||||
{
|
||||
if (lhs->isValid() && rhs->isValid())
|
||||
return lhs->begin() < rhs->begin();
|
||||
else if (lhs->isValid())
|
||||
return InvalidIsLargest;
|
||||
else
|
||||
return !InvalidIsLargest;
|
||||
}
|
||||
|
||||
void accept0(BaseVisitor *) override {} // intentionally do nothing
|
||||
|
||||
SourceLocation firstSourceLocation() const override;
|
||||
|
||||
SourceLocation lastSourceLocation() const override;
|
||||
|
||||
private:
|
||||
friend class QmlJS::Parser;
|
||||
SourceLocation m_defaultToken;
|
||||
SourceLocation m_readonlyToken;
|
||||
SourceLocation m_requiredToken;
|
||||
SourceLocation m_propertyToken;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiPublicMember: public UiObjectMember
|
||||
{
|
||||
public:
|
||||
QMLJS_DECLARE_AST_NODE(UiPublicMember)
|
||||
|
||||
UiPublicMember(UiQualifiedId *memberType,
|
||||
QStringView name)
|
||||
: type(Property), memberType(memberType), name(name), statement(nullptr), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
|
||||
UiPublicMember(UiQualifiedId *memberType, QStringView name)
|
||||
: type(Property)
|
||||
, memberType(memberType)
|
||||
, name(name)
|
||||
, statement(nullptr)
|
||||
, binding(nullptr)
|
||||
, parameters(nullptr)
|
||||
{ kind = K; }
|
||||
|
||||
UiPublicMember(UiQualifiedId *memberType,
|
||||
QStringView name,
|
||||
Statement *statement)
|
||||
: type(Property), memberType(memberType), name(name), statement(statement), binding(nullptr), isDefaultMember(false), isReadonlyMember(false), parameters(nullptr)
|
||||
UiPublicMember(UiQualifiedId *memberType, QStringView name, Statement *statement)
|
||||
: type(Property)
|
||||
, memberType(memberType)
|
||||
, name(name)
|
||||
, statement(statement)
|
||||
, binding(nullptr)
|
||||
, parameters(nullptr)
|
||||
{ kind = K; }
|
||||
|
||||
void accept0(BaseVisitor *visitor) override;
|
||||
|
||||
SourceLocation firstSourceLocation() const override
|
||||
{
|
||||
if (defaultToken.isValid())
|
||||
return defaultToken;
|
||||
else if (readonlyToken.isValid())
|
||||
return readonlyToken;
|
||||
else if (requiredToken.isValid())
|
||||
return requiredToken;
|
||||
|
||||
return propertyToken;
|
||||
if (hasAttributes)
|
||||
return m_attributes->firstSourceLocation();
|
||||
else
|
||||
return m_propertyToken;
|
||||
}
|
||||
|
||||
SourceLocation lastSourceLocation() const override
|
||||
@@ -3390,27 +3436,62 @@ public:
|
||||
return semicolonToken;
|
||||
}
|
||||
|
||||
SourceLocation defaultToken() const
|
||||
{
|
||||
return hasAttributes ? m_attributes->defaultToken() : SourceLocation{};
|
||||
}
|
||||
bool isDefaultMember() const { return defaultToken().isValid(); }
|
||||
|
||||
SourceLocation requiredToken() const
|
||||
{
|
||||
return hasAttributes ? m_attributes->requiredToken() : SourceLocation{};
|
||||
}
|
||||
bool isRequired() const { return requiredToken().isValid(); }
|
||||
|
||||
SourceLocation readonlyToken() const
|
||||
{
|
||||
return hasAttributes ? m_attributes->readonlyToken() : SourceLocation{};
|
||||
}
|
||||
bool isReadonly() const { return readonlyToken().isValid(); }
|
||||
|
||||
void setAttributes(UiPropertyAttributes *attributes)
|
||||
{
|
||||
m_attributes = attributes;
|
||||
hasAttributes = true;
|
||||
}
|
||||
|
||||
SourceLocation propertyToken() const
|
||||
{
|
||||
return hasAttributes ? m_attributes->propertyToken() : m_propertyToken;
|
||||
}
|
||||
|
||||
void setPropertyToken(SourceLocation token)
|
||||
{
|
||||
m_propertyToken = token;
|
||||
hasAttributes = false;
|
||||
}
|
||||
|
||||
// attributes
|
||||
enum { Signal, Property } type;
|
||||
enum : bool { Signal, Property } type;
|
||||
bool hasAttributes = false;
|
||||
QStringView typeModifier;
|
||||
UiQualifiedId *memberType;
|
||||
QStringView name;
|
||||
Statement *statement; // initialized with a JS expression
|
||||
UiObjectMember *binding; // initialized with a QML object or array.
|
||||
bool isDefaultMember;
|
||||
bool isReadonlyMember;
|
||||
bool isRequired = false;
|
||||
UiParameterList *parameters;
|
||||
// TODO: merge source locations
|
||||
SourceLocation defaultToken;
|
||||
SourceLocation readonlyToken;
|
||||
SourceLocation propertyToken;
|
||||
SourceLocation requiredToken;
|
||||
SourceLocation typeModifierToken;
|
||||
SourceLocation typeToken;
|
||||
SourceLocation identifierToken;
|
||||
SourceLocation colonToken;
|
||||
SourceLocation semicolonToken;
|
||||
|
||||
private:
|
||||
union {
|
||||
SourceLocation m_propertyToken = SourceLocation{};
|
||||
UiPropertyAttributes *m_attributes;
|
||||
};
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT UiObjectDefinition: public UiObjectMember
|
||||
|
@@ -1,143 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2021 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 "qmljsengine_p.h"
|
||||
#include "qmljsglobal_p.h"
|
||||
|
||||
#include <QtCore/qnumeric.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
static inline int toDigit(char c)
|
||||
{
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
return c - '0';
|
||||
else if ((c >= 'a') && (c <= 'z'))
|
||||
return 10 + c - 'a';
|
||||
else if ((c >= 'A') && (c <= 'Z'))
|
||||
return 10 + c - 'A';
|
||||
return -1;
|
||||
}
|
||||
|
||||
double integerFromString(const char *buf, int size, int radix)
|
||||
{
|
||||
if (size == 0)
|
||||
return qQNaN();
|
||||
|
||||
double sign = 1.0;
|
||||
int i = 0;
|
||||
if (buf[0] == '+') {
|
||||
++i;
|
||||
} else if (buf[0] == '-') {
|
||||
sign = -1.0;
|
||||
++i;
|
||||
}
|
||||
|
||||
if (((size-i) >= 2) && (buf[i] == '0')) {
|
||||
if (((buf[i+1] == 'x') || (buf[i+1] == 'X'))
|
||||
&& (radix < 34)) {
|
||||
if ((radix != 0) && (radix != 16))
|
||||
return 0;
|
||||
radix = 16;
|
||||
i += 2;
|
||||
} else {
|
||||
if (radix == 0) {
|
||||
radix = 8;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
} else if (radix == 0) {
|
||||
radix = 10;
|
||||
}
|
||||
|
||||
int j = i;
|
||||
for ( ; i < size; ++i) {
|
||||
int d = toDigit(buf[i]);
|
||||
if ((d == -1) || (d >= radix))
|
||||
break;
|
||||
}
|
||||
double result;
|
||||
if (j == i) {
|
||||
if (!qstrcmp(buf, "Infinity"))
|
||||
result = qInf();
|
||||
else
|
||||
result = qQNaN();
|
||||
} else {
|
||||
result = 0;
|
||||
double multiplier = 1;
|
||||
for (--i ; i >= j; --i, multiplier *= radix)
|
||||
result += toDigit(buf[i]) * multiplier;
|
||||
}
|
||||
result *= sign;
|
||||
return result;
|
||||
}
|
||||
|
||||
Engine::Engine()
|
||||
: _lexer(nullptr), _directives(nullptr)
|
||||
{ }
|
||||
|
||||
Engine::~Engine()
|
||||
{ }
|
||||
|
||||
void Engine::setCode(const QString &code)
|
||||
{ _code = code; }
|
||||
|
||||
void Engine::addComment(int pos, int len, int line, int col)
|
||||
{ if (len > 0) _comments.append(QmlJS::SourceLocation(pos, len, line, col)); }
|
||||
|
||||
QList<QmlJS::SourceLocation> Engine::comments() const
|
||||
{ return _comments; }
|
||||
|
||||
Lexer *Engine::lexer() const
|
||||
{ return _lexer; }
|
||||
|
||||
void Engine::setLexer(Lexer *lexer)
|
||||
{ _lexer = lexer; }
|
||||
|
||||
Directives *Engine::directives() const
|
||||
{ return _directives; }
|
||||
|
||||
void Engine::setDirectives(Directives *directives)
|
||||
{ _directives = directives; }
|
||||
|
||||
MemoryPool *Engine::pool()
|
||||
{ return &_pool; }
|
||||
|
||||
QStringView Engine::newStringRef(const QString &text)
|
||||
{
|
||||
_extraCode.append(text);
|
||||
return QStringView{_extraCode.last()};
|
||||
}
|
||||
|
||||
QStringView Engine::newStringRef(const QChar *chars, int size)
|
||||
{ return newStringRef(QString(chars, size)); }
|
||||
|
||||
} // end of namespace QmlJS
|
||||
|
||||
QT_QML_END_NAMESPACE
|
@@ -78,41 +78,50 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT Engine
|
||||
class Engine
|
||||
{
|
||||
Lexer *_lexer;
|
||||
Directives *_directives;
|
||||
Lexer *_lexer = nullptr;
|
||||
Directives *_directives = nullptr;
|
||||
MemoryPool _pool;
|
||||
QList<SourceLocation> _comments;
|
||||
QStringList _extraCode;
|
||||
QString _code;
|
||||
|
||||
public:
|
||||
Engine();
|
||||
~Engine();
|
||||
|
||||
void setCode(const QString &code);
|
||||
void setCode(const QString &code) { _code = code; }
|
||||
const QString &code() const { return _code; }
|
||||
|
||||
void addComment(int pos, int len, int line, int col);
|
||||
QList<SourceLocation> comments() const;
|
||||
void addComment(int pos, int len, int line, int col)
|
||||
{
|
||||
if (len > 0)
|
||||
_comments.append(QmlJS::SourceLocation(pos, len, line, col));
|
||||
}
|
||||
|
||||
Lexer *lexer() const;
|
||||
void setLexer(Lexer *lexer);
|
||||
QList<SourceLocation> comments() const { return _comments; }
|
||||
|
||||
Directives *directives() const;
|
||||
void setDirectives(Directives *directives);
|
||||
Lexer *lexer() const { return _lexer; }
|
||||
void setLexer(Lexer *lexer) { _lexer = lexer; }
|
||||
|
||||
MemoryPool *pool();
|
||||
Directives *directives() const { return _directives; }
|
||||
void setDirectives(Directives *directives) { _directives = directives; }
|
||||
|
||||
inline QStringView midRef(int position, int size) { return QStringView{_code}.mid(position, size); }
|
||||
MemoryPool *pool() { return &_pool; }
|
||||
const MemoryPool *pool() const { return &_pool; }
|
||||
|
||||
QStringView newStringRef(const QString &s);
|
||||
QStringView newStringRef(const QChar *chars, int size);
|
||||
QStringView midRef(int position, int size) { return QStringView{_code}.mid(position, size); }
|
||||
|
||||
QStringView newStringRef(const QString &text)
|
||||
{
|
||||
_extraCode.append(text);
|
||||
return QStringView{_extraCode.last()};
|
||||
}
|
||||
|
||||
QStringView newStringRef(const QChar *chars, int size)
|
||||
{
|
||||
return newStringRef(QString(chars, size));
|
||||
}
|
||||
};
|
||||
|
||||
double integerFromString(const char *buf, int size, int radix);
|
||||
|
||||
} // end of namespace QmlJS
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -167,15 +167,15 @@ public:
|
||||
T_XOR_EQ = 84,
|
||||
T_YIELD = 101,
|
||||
|
||||
ACCEPT_STATE = 1114,
|
||||
RULE_COUNT = 622,
|
||||
STATE_COUNT = 1115,
|
||||
ACCEPT_STATE = 1087,
|
||||
RULE_COUNT = 617,
|
||||
STATE_COUNT = 1088,
|
||||
TERMINAL_COUNT = 135,
|
||||
NON_TERMINAL_COUNT = 236,
|
||||
NON_TERMINAL_COUNT = 240,
|
||||
|
||||
GOTO_INDEX_OFFSET = 1115,
|
||||
GOTO_INFO_OFFSET = 7121,
|
||||
GOTO_CHECK_OFFSET = 7121
|
||||
GOTO_INDEX_OFFSET = 1088,
|
||||
GOTO_INFO_OFFSET = 7358,
|
||||
GOTO_CHECK_OFFSET = 7358
|
||||
};
|
||||
|
||||
static const char *const spell[];
|
||||
|
@@ -37,10 +37,10 @@
|
||||
//
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qvector.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
@@ -48,14 +48,12 @@ namespace QmlJS {
|
||||
|
||||
class Managed;
|
||||
|
||||
class MemoryPool : public QSharedData
|
||||
class MemoryPool
|
||||
{
|
||||
MemoryPool(const MemoryPool &other);
|
||||
void operator =(const MemoryPool &other);
|
||||
Q_DISABLE_COPY_MOVE(MemoryPool);
|
||||
|
||||
public:
|
||||
MemoryPool() {}
|
||||
|
||||
MemoryPool() = default;
|
||||
~MemoryPool()
|
||||
{
|
||||
if (_blocks) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -116,6 +116,7 @@ public:
|
||||
AST::UiPragma *UiPragma;
|
||||
AST::UiImport *UiImport;
|
||||
AST::UiParameterList *UiParameterList;
|
||||
AST::UiPropertyAttributes *UiPropertyAttributes;
|
||||
AST::UiPublicMember *UiPublicMember;
|
||||
AST::UiObjectDefinition *UiObjectDefinition;
|
||||
AST::UiObjectInitializer *UiObjectInitializer;
|
||||
@@ -288,29 +289,27 @@ protected:
|
||||
|
||||
} // end of namespace QmlJS
|
||||
|
||||
#line 1819 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 159
|
||||
|
||||
#line 1878 "qmljs.g"
|
||||
#line 1831 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 164
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 160
|
||||
|
||||
#line 1890 "qmljs.g"
|
||||
#line 3451 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 165
|
||||
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 461
|
||||
|
||||
#line 3502 "qmljs.g"
|
||||
#line 4103 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_EXPRESSIONSTATEMENTLOOKAHEAD_RULE 466
|
||||
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 531
|
||||
|
||||
#line 4154 "qmljs.g"
|
||||
#line 4645 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_CONCISEBODYLOOKAHEAD_RULE 536
|
||||
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 600
|
||||
|
||||
#line 4696 "qmljs.g"
|
||||
|
||||
#define J_SCRIPT_EXPORTDECLARATIONLOOKAHEAD_RULE 605
|
||||
|
||||
#line 4980 "qmljs.g"
|
||||
#line 4929 "qmljs.g"
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
||||
|
@@ -64,7 +64,7 @@ Project {
|
||||
"qmljsast.cpp", "qmljsast_p.h",
|
||||
"qmljsastfwd_p.h",
|
||||
"qmljsastvisitor.cpp", "qmljsastvisitor_p.h",
|
||||
"qmljsengine_p.cpp", "qmljsengine_p.h",
|
||||
"qmljsengine_p.h",
|
||||
"qmljsglobal_p.h",
|
||||
"qmljsgrammar.cpp", "qmljsgrammar_p.h",
|
||||
"qmljskeywords_p.h",
|
||||
|
@@ -1852,7 +1852,7 @@ ASTObjectValue::ASTObjectValue(UiQualifiedId *typeName,
|
||||
if (def->type == UiPublicMember::Property && !def->name.isEmpty()) {
|
||||
ASTPropertyReference *ref = new ASTPropertyReference(def, m_doc, valueOwner);
|
||||
m_properties.append(ref);
|
||||
if (def->defaultToken.isValid())
|
||||
if (def->defaultToken().isValid())
|
||||
m_defaultPropertyRef = ref;
|
||||
} else if (def->type == UiPublicMember::Signal && !def->name.isEmpty()) {
|
||||
ASTSignal *ref = new ASTSignal(def, m_doc, valueOwner);
|
||||
@@ -1884,7 +1884,7 @@ void ASTObjectValue::processMembers(MemberProcessor *processor) const
|
||||
{
|
||||
foreach (ASTPropertyReference *ref, m_properties) {
|
||||
uint pFlags = PropertyInfo::Readable;
|
||||
if (!ref->ast()->isReadonlyMember)
|
||||
if (!ref->ast()->isReadonly())
|
||||
pFlags |= PropertyInfo::Writeable;
|
||||
processor->processProperty(ref->ast()->name.toString(), ref, PropertyInfo(pFlags));
|
||||
// ### Should get a different value?
|
||||
|
@@ -641,13 +641,13 @@ protected:
|
||||
bool visit(UiPublicMember *ast) override
|
||||
{
|
||||
if (ast->type == UiPublicMember::Property) {
|
||||
if (ast->isRequired)
|
||||
out("required ", ast->requiredToken);
|
||||
if (ast->isDefaultMember)
|
||||
out("default ", ast->defaultToken);
|
||||
else if (ast->isReadonlyMember)
|
||||
out("readonly ", ast->readonlyToken);
|
||||
out("property ", ast->propertyToken);
|
||||
if (ast->isRequired())
|
||||
out("required ", ast->requiredToken());
|
||||
if (ast->isDefaultMember())
|
||||
out("default ", ast->defaultToken());
|
||||
else if (ast->isReadonly())
|
||||
out("readonly ", ast->readonlyToken());
|
||||
out("property ", ast->propertyToken());
|
||||
if (!ast->typeModifier.isNull()) {
|
||||
out(ast->typeModifierToken);
|
||||
out("<");
|
||||
|
@@ -79,8 +79,7 @@ protected:
|
||||
return m_document->source().mid(from.offset, to.end() - from.begin());
|
||||
}
|
||||
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
using AST::Visitor::visit;
|
||||
|
||||
|
@@ -86,7 +86,7 @@ static TypeName resolveTypeName(const ASTPropertyReference *ref, const ContextPt
|
||||
{
|
||||
TypeName type = "unknown";
|
||||
|
||||
if (ref->ast()->propertyToken.isValid()) {
|
||||
if (ref->ast()->propertyToken().isValid()) {
|
||||
type = ref->ast()->memberType->name.toUtf8();
|
||||
|
||||
const Value *value = context->lookupReference(ref);
|
||||
|
@@ -101,8 +101,7 @@ protected:
|
||||
return text;
|
||||
}
|
||||
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
using Visitor::visit;
|
||||
using Visitor::endVisit;
|
||||
@@ -186,8 +185,7 @@ protected:
|
||||
return text;
|
||||
}
|
||||
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
void init(Declaration *decl, AST::UiObjectMember *member)
|
||||
{
|
||||
|
@@ -91,8 +91,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
using Visitor::visit;
|
||||
|
||||
@@ -321,8 +320,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
using Visitor::visit;
|
||||
|
||||
@@ -507,8 +505,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void accept(AST::Node *node)
|
||||
{ AST::Node::acceptChild(node, this); }
|
||||
void accept(AST::Node *node) { AST::Node::accept(node, this); }
|
||||
|
||||
using Visitor::visit;
|
||||
|
||||
@@ -596,7 +593,7 @@ protected:
|
||||
bool visit(UiPublicMember *node) override
|
||||
{
|
||||
if (containsOffset(node->typeToken)){
|
||||
if (node->defaultToken.isValid()) {
|
||||
if (node->defaultToken().isValid()) {
|
||||
_name = node->memberType->name.toString();
|
||||
_targetValue = _scopeChain->context()->lookupType(_doc.data(), QStringList(_name));
|
||||
_scope = nullptr;
|
||||
|
Reference in New Issue
Block a user