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:
Fawzi Mohamed
2021-12-03 15:49:28 +01:00
parent 16ced8a7d6
commit 125d7c0cce
25 changed files with 5669 additions and 5969 deletions

View File

@@ -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
+