diff --git a/src/libs/qmljs/parser/gen-parser.sh b/src/libs/qmljs/parser/gen-parser.sh index 856759237d9..ec800098a26 100755 --- a/src/libs/qmljs/parser/gen-parser.sh +++ b/src/libs/qmljs/parser/gen-parser.sh @@ -46,5 +46,3 @@ sed -i -e 's|#include |#include |g' $me/qmljsengine_p.h perl -p -0777 -i -e 's/QT_QML_BEGIN_NAMESPACE/#include \nQT_QML_BEGIN_NAMESPACE/' qmljsengine_p.h ./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h} - -#patch -R -p5 < parser.patch diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp index e96a7d4e35e..cb75a56516e 100644 --- a/src/libs/qmljs/parser/qmldirparser.cpp +++ b/src/libs/qmljs/parser/qmldirparser.cpp @@ -26,8 +26,6 @@ #include "qmldirparser_p.h" #include "qmlerror.h" - - #include QT_BEGIN_NAMESPACE @@ -49,7 +47,20 @@ static int parseInt(const QStringRef &str, bool *ok) return number; } -QmlDirParser::QmlDirParser() +static bool parseVersion(const QString &str, int *major, int *minor) +{ + const int dotIndex = str.indexOf(QLatin1Char('.')); + if (dotIndex != -1 && str.indexOf(QLatin1Char('.'), dotIndex + 1) == -1) { + bool ok = false; + *major = parseInt(QStringRef(&str, 0, dotIndex), &ok); + if (ok) + *minor = parseInt(QStringRef(&str, dotIndex + 1, str.length() - dotIndex - 1), &ok); + return ok; + } + return false; +} + +QmlDirParser::QmlDirParser() : _designerSupported(false) { } @@ -81,6 +92,7 @@ bool QmlDirParser::parse(const QString &source) _plugins.clear(); _components.clear(); _scripts.clear(); + _designerSupported = false; quint16 lineNumber = 0; bool firstLine = true; @@ -126,7 +138,7 @@ bool QmlDirParser::parse(const QString &source) if (invalidLine) { reportError(lineNumber, 0, - QString::fromLatin1("invalid qmldir directive contains too many tokens")); + QStringLiteral("invalid qmldir directive contains too many tokens")); continue; } else if (sectionCount == 0) { continue; // no sections, no party. @@ -134,17 +146,17 @@ bool QmlDirParser::parse(const QString &source) } else if (sections[0] == QLatin1String("module")) { if (sectionCount != 2) { reportError(lineNumber, 0, - QString::fromLatin1("module identifier directive requires one argument, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("module identifier directive requires one argument, but %1 were provided").arg(sectionCount - 1)); continue; } if (!_typeNamespace.isEmpty()) { reportError(lineNumber, 0, - QString::fromLatin1("only one module identifier directive may be defined in a qmldir file")); + QStringLiteral("only one module identifier directive may be defined in a qmldir file")); continue; } if (!firstLine) { reportError(lineNumber, 0, - QString::fromLatin1("module identifier directive must be the first directive in a qmldir file")); + QStringLiteral("module identifier directive must be the first directive in a qmldir file")); continue; } @@ -153,7 +165,7 @@ bool QmlDirParser::parse(const QString &source) } else if (sections[0] == QLatin1String("plugin")) { if (sectionCount < 2 || sectionCount > 3) { reportError(lineNumber, 0, - QString::fromLatin1("plugin directive requires one or two arguments, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("plugin directive requires one or two arguments, but %1 were provided").arg(sectionCount - 1)); continue; } @@ -165,7 +177,7 @@ bool QmlDirParser::parse(const QString &source) } else if (sections[0] == QLatin1String("internal")) { if (sectionCount != 3) { reportError(lineNumber, 0, - QString::fromLatin1("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("internal types require 2 arguments, but %1 were provided").arg(sectionCount - 1)); continue; } Component entry(sections[1], sections[2], -1, -1); @@ -174,7 +186,7 @@ bool QmlDirParser::parse(const QString &source) } else if (sections[0] == QLatin1String("singleton")) { if (sectionCount < 3 || sectionCount > 4) { reportError(lineNumber, 0, - QString::fromLatin1("singleton types require 2 or 3 arguments, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("singleton types require 2 or 3 arguments, but %1 were provided").arg(sectionCount - 1)); continue; } else if (sectionCount == 3) { // handle qmldir directory listing case where singleton is defined in the following pattern: @@ -185,33 +197,20 @@ bool QmlDirParser::parse(const QString &source) } else { // handle qmldir module listing case where singleton is defined in the following pattern: // singleton TestSingletonType 2.0 TestSingletonType20.qml - const QString &version = sections[2]; - const int dotIndex = version.indexOf(QLatin1Char('.')); - - if (dotIndex == -1) { - reportError(lineNumber, 0, QLatin1String("expected '.'")); - } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) { - reportError(lineNumber, 0, QLatin1String("unexpected '.'")); + int major, minor; + if (parseVersion(sections[2], &major, &minor)) { + const QString &fileName = sections[3]; + Component entry(sections[1], fileName, major, minor); + entry.singleton = true; + _components.insertMulti(entry.typeName, entry); } else { - bool validVersionNumber = false; - const int majorVersion = parseInt(QStringRef(&version, 0, dotIndex), &validVersionNumber); - - if (validVersionNumber) { - const int minorVersion = parseInt(QStringRef(&version, dotIndex+1, version.length()-dotIndex-1), &validVersionNumber); - - if (validVersionNumber) { - const QString &fileName = sections[3]; - Component entry(sections[1], fileName, majorVersion, minorVersion); - entry.singleton = true; - _components.insertMulti(entry.typeName, entry); - } - } + reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected .").arg(sections[2])); } } } else if (sections[0] == QLatin1String("typeinfo")) { if (sectionCount != 2) { reportError(lineNumber, 0, - QString::fromLatin1("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1)); + QStringLiteral("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1)); continue; } #ifdef QT_CREATOR @@ -219,42 +218,49 @@ bool QmlDirParser::parse(const QString &source) _typeInfos.append(typeInfo); #endif + } else if (sections[0] == QLatin1String("designersupported")) { + if (sectionCount != 1) + reportError(lineNumber, 0, QStringLiteral("designersupported does not expect any argument")); + else + _designerSupported = true; + } else if (sections[0] == QLatin1String("depends")) { + if (sectionCount != 3) { + reportError(lineNumber, 0, + QStringLiteral("depends requires 2 arguments, but %1 were provided").arg(sectionCount - 1)); + continue; + } + + int major, minor; + if (parseVersion(sections[2], &major, &minor)) { + Component entry(sections[1], QString(), major, minor); + entry.internal = true; + _dependencies.insert(entry.typeName, entry); + } else { + reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected .").arg(sections[2])); + } } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) const Component entry(sections[0], sections[1], -1, -1); _components.insertMulti(entry.typeName, entry); } else if (sectionCount == 3) { - const QString &version = sections[1]; - const int dotIndex = version.indexOf(QLatin1Char('.')); + int major, minor; + if (parseVersion(sections[1], &major, &minor)) { + const QString &fileName = sections[2]; - if (dotIndex == -1) { - reportError(lineNumber, 0, QLatin1String("expected '.'")); - } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) { - reportError(lineNumber, 0, QLatin1String("unexpected '.'")); - } else { - bool validVersionNumber = false; - const int majorVersion = parseInt(QStringRef(&version, 0, dotIndex), &validVersionNumber); - - if (validVersionNumber) { - const int minorVersion = parseInt(QStringRef(&version, dotIndex+1, version.length()-dotIndex-1), &validVersionNumber); - - if (validVersionNumber) { - const QString &fileName = sections[2]; - - if (fileName.endsWith(QLatin1String(".js"))) { - // A 'js' extension indicates a namespaced script import - const Script entry(sections[0], fileName, majorVersion, minorVersion); - _scripts.append(entry); - } else { - const Component entry(sections[0], fileName, majorVersion, minorVersion); - _components.insertMulti(entry.typeName, entry); - } - } + if (fileName.endsWith(QLatin1String(".js"))) { + // A 'js' extension indicates a namespaced script import + const Script entry(sections[0], fileName, major, minor); + _scripts.append(entry); + } else { + const Component entry(sections[0], fileName, major, minor); + _components.insertMulti(entry.typeName, entry); } + } else { + reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected .").arg(sections[1])); } } else { reportError(lineNumber, 0, - QString::fromLatin1("a component declaration requires two or three arguments, but %1 were provided").arg(sectionCount)); + QStringLiteral("a component declaration requires two or three arguments, but %1 were provided").arg(sectionCount)); } firstLine = false; @@ -265,10 +271,10 @@ bool QmlDirParser::parse(const QString &source) void QmlDirParser::reportError(quint16 line, quint16 column, const QString &description) { - QmlError error; - error.setLine(line); - error.setColumn(column); - error.setDescription(description); + QmlJS::DiagnosticMessage error; + error.loc.startLine = line; + error.loc.startColumn = column; + error.message = description; _errors.append(error); } @@ -283,19 +289,25 @@ bool QmlDirParser::hasError() const void QmlDirParser::setError(const QmlError &e) { _errors.clear(); - _errors.append(e); + reportError(e.line(), e.column(), e.description()); } QList QmlDirParser::errors(const QString &uri) const { QUrl url(uri); - QList errors = _errors; - for (int i = 0; i < errors.size(); ++i) { - QmlError &e = errors[i]; - QString description = e.description(); + QList errors; + const int numErrors = _errors.size(); + errors.reserve(numErrors); + for (int i = 0; i < numErrors; ++i) { + const QmlJS::DiagnosticMessage &msg = _errors.at(i); + QmlError e; + QString description = msg.message; description.replace(QLatin1String("$$URI$$"), uri); e.setDescription(description); e.setUrl(url); + e.setLine(msg.loc.startLine); + e.setColumn(msg.loc.startColumn); + errors << e; } return errors; } @@ -315,11 +327,16 @@ QList QmlDirParser::plugins() const return _plugins; } -QHash QmlDirParser::components() const +QHash QmlDirParser::components() const { return _components; } +QHash QmlDirParser::dependencies() const +{ + return _dependencies; +} + QList QmlDirParser::scripts() const { return _scripts; @@ -332,16 +349,21 @@ QList QmlDirParser::typeInfos() const } #endif +bool QmlDirParser::designerSupported() const +{ + return _designerSupported; +} + QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component) { - const QString output = QString::fromLatin1("{%1 %2.%3}"). + const QString output = QStringLiteral("{%1 %2.%3}"). arg(component.typeName).arg(component.majorVersion).arg(component.minorVersion); return debug << qPrintable(output); } QDebug &operator<< (QDebug &debug, const QmlDirParser::Script &script) { - const QString output = QString::fromLatin1("{%1 %2.%3}"). + const QString output = QStringLiteral("{%1 %2.%3}"). arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion); return debug << qPrintable(output); } diff --git a/src/libs/qmljs/parser/qmldirparser_p.h b/src/libs/qmljs/parser/qmldirparser_p.h index 72a2cf9922a..58453d4b0e7 100644 --- a/src/libs/qmljs/parser/qmldirparser_p.h +++ b/src/libs/qmljs/parser/qmldirparser_p.h @@ -40,8 +40,7 @@ #include #include - -#include "qmljsglobal_p.h" +#include "qmljsengine_p.h" QT_BEGIN_NAMESPACE @@ -107,8 +106,10 @@ public: }; QHash components() const; + QHash dependencies() const; QList