diff options
author | Christian Kamm <christian.d.kamm@nokia.com> | 2012-07-31 10:12:26 +0200 |
---|---|---|
committer | Christian Kamm <christian.d.kamm@nokia.com> | 2012-07-31 11:05:03 +0200 |
commit | a14ed0793ccbff3f988e4cb8d77a056035a5a960 (patch) | |
tree | a17fc89a1af6296e3ee2787f6bdaab7785d207bf | |
parent | 26bd1860d14aa24efd1e683d574c8f34b712e551 (diff) | |
download | qt-creator-a14ed0793ccbff3f988e4cb8d77a056035a5a960.tar.gz |
QmlJS: Update to latest QmlJS parser from Qt 5.
Using qtdeclarative revision c9b7582a2e7ad9fcd03dd999c3b7a16b72803238
Change-Id: I9c942fa04c3fab5ef57b38e13471d0a4e2e8a2bf
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
-rw-r--r-- | src/libs/qmljs/parser/cmd.sed | 7 | ||||
-rwxr-xr-x | src/libs/qmljs/parser/gen-parser.sh | 21 | ||||
-rw-r--r-- | src/libs/qmljs/parser/parser.patch | 59 | ||||
-rw-r--r-- | src/libs/qmljs/parser/parser.pri | 4 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmldirparser.cpp | 231 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmldirparser_p.h | 62 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmlerror.cpp | 13 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmlerror.h | 15 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljs.g | 20 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsast_p.h | 2 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsastfwd_p.h | 2 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsglobal_p.h | 2 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsgrammar_p.h | 2 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljslexer.cpp | 231 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljslexer_p.h | 17 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsmemorypool_p.h | 14 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsparser.cpp | 21 | ||||
-rw-r--r-- | src/libs/qmljs/parser/qmljsparser_p.h | 4 | ||||
-rw-r--r-- | src/libs/qmljs/qmljsdocument.cpp | 2 | ||||
-rw-r--r-- | src/plugins/qmljstools/qmljsmodelmanager.cpp | 3 |
20 files changed, 397 insertions, 335 deletions
diff --git a/src/libs/qmljs/parser/cmd.sed b/src/libs/qmljs/parser/cmd.sed index d76372675d..9f8f0db22a 100644 --- a/src/libs/qmljs/parser/cmd.sed +++ b/src/libs/qmljs/parser/cmd.sed @@ -1,8 +1,9 @@ s/private\/qdeclarative/qml/g -s/qdeclarative/qml/g +s/qqml/qml/g s/QDECLARATIVE/QML/g -s/QDeclarative/Qml/g -s/Q_DECLARATIVE_EXPORT //g +s/QQml/Qml/g +s/QQMLJS/QMLJS/g +s/Q_QML_EXPORT //g # adjust pri file s/ \$\$PWD\/qmljsglobal_p.h/ $$PWD\/qmljsglobal_p.h \\\ diff --git a/src/libs/qmljs/parser/gen-parser.sh b/src/libs/qmljs/parser/gen-parser.sh index 2fcff14ba5..8aa7181f95 100755 --- a/src/libs/qmljs/parser/gen-parser.sh +++ b/src/libs/qmljs/parser/gen-parser.sh @@ -2,20 +2,29 @@ me=$(dirname $0) -for i in $QTDIR/src/declarative/qml/parser/*.{g,h,cpp,pri}; do - sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qdeclarativejs/qmljs/) +for i in $QTDIR/src/qml/qml/parser/*.{g,h,cpp,pri}; do + sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqmljs/qmljs/) done -for i in $QTDIR/src/declarative/qml/qdeclarative{error.{h,cpp},dirparser{_p.h,.cpp}}; do - sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qdeclarative/qml/) +for i in $QTDIR/src/qml/qml/qqml{error.{h,cpp},dirparser{_p.h,.cpp}}; do + sed -f $me/cmd.sed $i > $me/$(echo $(basename $i) | sed s/qqml/qml/) done # export QmlDirParser perl -p -0777 -i -e 's/QT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QmlDirParser/#include "qmljsglobal_p.h"\n\nQT_BEGIN_NAMESPACE\n\nclass QmlError;\nclass QML_PARSER_EXPORT QmlDirParser/' qmldirparser_p.h # export QmlJSGrammar perl -p -0777 -i -e 's/#include <QtCore\/qglobal.h>\n\nQT_BEGIN_NAMESPACE\n\nclass QmlJSGrammar\n/#include "qmljsglobal_p.h"\n#include <QtCore\/qglobal.h>\n\nQT_BEGIN_NAMESPACE\n\nclass QML_PARSER_EXPORT QmlJSGrammar\n/' qmljsgrammar_p.h -# replace qmlglobal_p.h include with needed declaration -perl -p -0777 -i -e 's/#include \"qmlglobal_p.h\"/bool Qml_isFileCaseCorrect(const QString &) { return true; }/' qmldirparser.cpp +# remove qmlglobal_p.h include +perl -p -0777 -i -e 's/#include \"qmlglobal_p.h\"//' qmldirparser.cpp +# remove qmlglobal_p.h include +perl -p -0777 -i -e 's/#include \<QtQml\/qmlfile.h\>//' qmldirparser.cpp +# remove QtQml/qtqmlglobal.h include +perl -p -0777 -i -e 's/#include \<QtQml\/qtqmlglobal.h\>//' qmlerror.h +# replace private/qhashedstring_p.h include and QHashedStringRef +perl -p -0777 -i -e 's/#include \<private\/qhashedstring_p.h\>//' qmldirparser_p.h +perl -p -0777 -i -e 's/QHashedStringRef/QString/g' qmldirparser_p.h qmldirparser.cpp +# don't use the new QVarLengthArray::length() +sed -i -e 's/chars.length()/chars.size()/' $me/qmljslexer.cpp ./changeLicense.py $me/../qmljs_global.h qml*.{cpp,h} diff --git a/src/libs/qmljs/parser/parser.patch b/src/libs/qmljs/parser/parser.patch index 755aa27a93..32fc41b90d 100644 --- a/src/libs/qmljs/parser/parser.patch +++ b/src/libs/qmljs/parser/parser.patch @@ -1,19 +1,18 @@ -diff --git b/src/libs/qmljs/parser/qmljs.g a/src/libs/qmljs/parser/qmljs.g -index 6888b65..784e47f 100644 ---- b/src/libs/qmljs/parser/qmljs.g -+++ a/src/libs/qmljs/parser/qmljs.g -@@ -1,23 +1,32 @@ +diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g +index 069be3c..9cbdc23 100644 +--- a/src/libs/qmljs/parser/qmljs.g ++++ b/src/libs/qmljs/parser/qmljs.g +@@ -1,23 +1,30 @@ ---------------------------------------------------------------------------- -- --- Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). ---- All rights reserved. +-- This file is part of Qt Creator +-- +-- Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). +-- -- Contact: http://www.qt-project.org/ -- ---- This file is part of the QtDeclarative module of the Qt Toolkit. +--- This file is part of the QtQml module of the Qt Toolkit. -- --- $QT_BEGIN_LICENSE:LGPL-ONLY$ -- GNU Lesser General Public License Usage @@ -23,7 +22,9 @@ index 6888b65..784e47f 100644 --- packaging of this file. Please review the following information to --- ensure the GNU Lesser General Public License version 2.1 requirements --- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+-- + -- +--- If you have questions regarding the use of this file, please contact +--- us via http://www.qt-project.org/. +-- This file may be used under the terms of the GNU Lesser General Public +-- License version 2.1 as published by the Free Software Foundation and +-- appearing in the file LICENSE.LGPL included in the packaging of this file. @@ -43,11 +44,11 @@ index 6888b65..784e47f 100644 --- $QT_END_LICENSE$ -- ---------------------------------------------------------------------------- - -@@ -83,46 +92,37 @@ - + +@@ -83,46 +90,36 @@ + %start TopLevel - + -/./**************************************************************************** +/./************************************************************************** +** @@ -56,10 +57,9 @@ index 6888b65..784e47f 100644 +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). --** All rights reserved. ** Contact: http://www.qt-project.org/ ** --** This file is part of the QtDeclarative module of the Qt Toolkit. +-** This file is part of the QtQml module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -95,17 +95,19 @@ index 6888b65..784e47f 100644 -** -** -** +-** -** $QT_END_LICENSE$ -** -****************************************************************************/ +**************************************************************************/ - ++ + #include <QtCore/QtDebug> #include <QtCore/QCoreApplication> -@@ -136,46 +136,37 @@ - +@@ -136,46 +133,36 @@ + ./ - + -/:/**************************************************************************** +/:/************************************************************************** +** @@ -114,10 +116,9 @@ index 6888b65..784e47f 100644 +** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies). ** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). --** All rights reserved. ** Contact: http://www.qt-project.org/ ** --** This file is part of the QtDeclarative module of the Qt Toolkit. +-** This file is part of the QtQml module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -153,18 +154,20 @@ index 6888b65..784e47f 100644 -** -** -** +-** -** $QT_END_LICENSE$ -** -****************************************************************************/ +**************************************************************************/ - - ++ + + // diff --git b/src/libs/qmljs/parser/qmljsengine_p.cpp a/src/libs/qmljs/parser/qmljsengine_p.cpp index 5b204c9..10e39ab 100644 --- b/src/libs/qmljs/parser/qmljsengine_p.cpp +++ a/src/libs/qmljs/parser/qmljsengine_p.cpp -@@ -113,7 +113,7 @@ double integerFromString(const QString &str, int radix) +@@ -111,7 +111,7 @@ double integerFromString(const QString &str, int radix) Engine::Engine() @@ -173,7 +176,7 @@ index 5b204c9..10e39ab 100644 { } Engine::~Engine() -@@ -134,6 +134,12 @@ Lexer *Engine::lexer() const +@@ -132,6 +132,12 @@ Lexer *Engine::lexer() const void Engine::setLexer(Lexer *lexer) { _lexer = lexer; } @@ -190,7 +193,7 @@ diff --git b/src/libs/qmljs/parser/qmljsengine_p.h a/src/libs/qmljs/parser/qmljs index 5057ea0..487619e 100644 --- b/src/libs/qmljs/parser/qmljsengine_p.h +++ a/src/libs/qmljs/parser/qmljsengine_p.h -@@ -56,6 +56,7 @@ QT_QML_BEGIN_NAMESPACE +@@ -54,6 +54,7 @@ QT_QML_BEGIN_NAMESPACE namespace QmlJS { class Lexer; @@ -198,7 +201,7 @@ index 5057ea0..487619e 100644 class MemoryPool; class QML_PARSER_EXPORT DiagnosticMessage -@@ -83,6 +84,7 @@ public: +@@ -81,6 +82,7 @@ public: class QML_PARSER_EXPORT Engine { Lexer *_lexer; @@ -206,7 +209,7 @@ index 5057ea0..487619e 100644 MemoryPool _pool; QList<AST::SourceLocation> _comments; QString _extraCode; -@@ -100,6 +102,9 @@ public: +@@ -98,6 +100,9 @@ public: Lexer *lexer() const; void setLexer(Lexer *lexer); @@ -220,7 +223,7 @@ diff --git b/src/libs/qmljs/parser/qmljsparser.cpp a/src/libs/qmljs/parser/qmljs index a731c1a..e986534 100644 --- b/src/libs/qmljs/parser/qmljsparser.cpp +++ a/src/libs/qmljs/parser/qmljsparser.cpp -@@ -138,7 +138,20 @@ bool Parser::parse(int startToken) +@@ -137,7 +137,20 @@ bool Parser::parse(int startToken) token_buffer[0].token = startToken; first_token = &token_buffer[0]; diff --git a/src/libs/qmljs/parser/parser.pri b/src/libs/qmljs/parser/parser.pri index 966570d1e3..aa1069e5c2 100644 --- a/src/libs/qmljs/parser/parser.pri +++ b/src/libs/qmljs/parser/parser.pri @@ -10,7 +10,7 @@ HEADERS += \ $$PWD/qmljsglobal_p.h \ $$PWD/qmldirparser_p.h \ $$PWD/qmlerror.h \ - $$PWD/qmljskeywords_p.h + $$PWD/qmljskeywords_p.h \ SOURCES += \ $$PWD/qmljsast.cpp \ @@ -20,4 +20,4 @@ SOURCES += \ $$PWD/qmljslexer.cpp \ $$PWD/qmljsparser.cpp \ $$PWD/qmldirparser.cpp \ - $$PWD/qmlerror.cpp + $$PWD/qmlerror.cpp \ diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp index 7324abe785..17d70e00e1 100644 --- a/src/libs/qmljs/parser/qmldirparser.cpp +++ b/src/libs/qmljs/parser/qmldirparser.cpp @@ -30,132 +30,130 @@ #include "qmldirparser_p.h" #include "qmlerror.h" -bool Qml_isFileCaseCorrect(const QString &) { return true; } -#include <QTextStream> -#include <QFile> -#include <QtDebug> -QT_BEGIN_NAMESPACE -QmlDirParser::QmlDirParser() - : _isParsed(false) -{ -} +#include <QtCore/QtDebug> -QmlDirParser::~QmlDirParser() -{ -} - -QUrl QmlDirParser::url() const -{ - return _url; -} +QT_BEGIN_NAMESPACE -void QmlDirParser::setUrl(const QUrl &url) +static int parseInt(const QStringRef &str, bool *ok) { - _url = url; + int pos = 0; + int number = 0; + while (pos < str.length() && str.at(pos).isDigit()) { + if (pos != 0) + number *= 10; + number += str.at(pos).unicode() - '0'; + ++pos; + } + if (pos != str.length()) + *ok = false; + else + *ok = true; + return number; } -QString QmlDirParser::fileSource() const +QmlDirParser::QmlDirParser() { - return _filePathSouce; } -void QmlDirParser::setFileSource(const QString &filePath) +QmlDirParser::~QmlDirParser() { - _filePathSouce = filePath; } -QString QmlDirParser::source() const -{ - return _source; +inline static void scanSpace(const QChar *&ch) { + while (ch->isSpace() && !ch->isNull() && *ch != QLatin1Char('\n')) + ++ch; } -void QmlDirParser::setSource(const QString &source) -{ - _isParsed = false; - _source = source; +inline static void scanToEnd(const QChar *&ch) { + while (*ch != QLatin1Char('\n') && !ch->isNull()) + ++ch; } -bool QmlDirParser::isParsed() const -{ - return _isParsed; +inline static void scanWord(const QChar *&ch) { + while (!ch->isSpace() && !ch->isNull()) + ++ch; } -bool QmlDirParser::parse() +/*! +\a url is used for generating errors. +*/ +bool QmlDirParser::parse(const QString &source) { - if (_isParsed) - return true; - - _isParsed = true; _errors.clear(); _plugins.clear(); _components.clear(); + _scripts.clear(); - if (_source.isEmpty() && !_filePathSouce.isEmpty()) { - QFile file(_filePathSouce); - if (!Qml_isFileCaseCorrect(_filePathSouce)) { - QmlError error; - error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce)); - _errors.prepend(error); - return false; - } else if (file.open(QFile::ReadOnly)) { - _source = QString::fromUtf8(file.readAll()); - } else { - QmlError error; - error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce)); - _errors.prepend(error); - return false; - } - } - - QTextStream stream(&_source); int lineNumber = 0; + bool firstLine = true; - forever { + const QChar *ch = source.constData(); + while (!ch->isNull()) { ++lineNumber; - const QString line = stream.readLine(); - if (line.isNull()) + bool invalidLine = false; + const QChar *lineStart = ch; + + scanSpace(ch); + if (*ch == QLatin1Char('\n')) { + ++ch; + continue; + } + if (ch->isNull()) break; QString sections[3]; int sectionCount = 0; - int index = 0; - const int length = line.length(); - - while (index != length) { - const QChar ch = line.at(index); - - if (ch.isSpace()) { - do { ++index; } - while (index != length && line.at(index).isSpace()); - - } else if (ch == QLatin1Char('#')) { - // recognized a comment + do { + if (*ch == QLatin1Char('#')) { + scanToEnd(ch); break; - + } + const QChar *start = ch; + scanWord(ch); + if (sectionCount < 3) { + sections[sectionCount++] = source.mid(start-source.constData(), ch-start); } else { - const int start = index; - - do { ++index; } - while (index != length && !line.at(index).isSpace()); + reportError(lineNumber, start-lineStart, QLatin1String("unexpected token")); + scanToEnd(ch); + invalidLine = true; + break; + } + scanSpace(ch); + } while (*ch != QLatin1Char('\n') && !ch->isNull()); - const QString lexeme = line.mid(start, index - start); + if (!ch->isNull()) + ++ch; - if (sectionCount >= 3) { - reportError(lineNumber, start, QLatin1String("unexpected token")); + if (invalidLine) { + reportError(lineNumber, -1, + QString::fromUtf8("invalid qmldir directive contains too many tokens")); + continue; + } else if (sectionCount == 0) { + continue; // no sections, no party. - } else { - sections[sectionCount++] = lexeme; - } + } else if (sections[0] == QLatin1String("module")) { + if (sectionCount != 2) { + reportError(lineNumber, -1, + QString::fromUtf8("module directive requires one argument, but %1 were provided").arg(sectionCount - 1)); + continue; + } + if (!_typeNamespace.isEmpty()) { + reportError(lineNumber, -1, + QString::fromUtf8("only one module directive may be defined in a qmldir file")); + continue; + } + if (!firstLine) { + reportError(lineNumber, -1, + QString::fromUtf8("module directive must be the first directive in a qmldir file")); + continue; } - } - if (sectionCount == 0) { - continue; // no sections, no party. + _typeNamespace = sections[1]; } else if (sections[0] == QLatin1String("plugin")) { if (sectionCount < 2) { @@ -177,7 +175,7 @@ bool QmlDirParser::parse() } Component entry(sections[1], sections[2], -1, -1); entry.internal = true; - _components.append(entry); + _components.insertMulti(entry.typeName, entry); } else if (sections[0] == QLatin1String("typeinfo")) { if (sectionCount != 2) { reportError(lineNumber, -1, @@ -192,7 +190,7 @@ bool QmlDirParser::parse() } 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.append(entry); + _components.insertMulti(entry.typeName, entry); } else if (sectionCount == 3) { const QString &version = sections[1]; const int dotIndex = version.indexOf(QLatin1Char('.')); @@ -203,15 +201,22 @@ bool QmlDirParser::parse() reportError(lineNumber, -1, QLatin1String("unexpected '.'")); } else { bool validVersionNumber = false; - const int majorVersion = version.left(dotIndex).toInt(&validVersionNumber); + const int majorVersion = parseInt(QStringRef(&version, 0, dotIndex), &validVersionNumber); if (validVersionNumber) { - const int minorVersion = version.mid(dotIndex + 1).toInt(&validVersionNumber); + const int minorVersion = parseInt(QStringRef(&version, dotIndex+1, version.length()-dotIndex-1), &validVersionNumber); if (validVersionNumber) { - const Component entry(sections[0], sections[2], majorVersion, minorVersion); - - _components.append(entry); + 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); + } } } } @@ -219,6 +224,8 @@ bool QmlDirParser::parse() reportError(lineNumber, -1, QString::fromUtf8("a component declaration requires two or three arguments, but %1 were provided").arg(sectionCount)); } + + firstLine = false; } return hasError(); @@ -227,7 +234,6 @@ bool QmlDirParser::parse() void QmlDirParser::reportError(int line, int column, const QString &description) { QmlError error; - error.setUrl(_url); error.setLine(line); error.setColumn(column); error.setDescription(description); @@ -242,28 +248,51 @@ bool QmlDirParser::hasError() const return false; } +void QmlDirParser::setError(const QmlError &e) +{ + _errors.clear(); + _errors.append(e); +} + QList<QmlError> QmlDirParser::errors(const QString &uri) const { + QUrl url(uri); QList<QmlError> errors = _errors; for (int i = 0; i < errors.size(); ++i) { QmlError &e = errors[i]; QString description = e.description(); description.replace(QLatin1String("$$URI$$"), uri); e.setDescription(description); + e.setUrl(url); } return errors; } +QString QmlDirParser::typeNamespace() const +{ + return _typeNamespace; +} + +void QmlDirParser::setTypeNamespace(const QString &s) +{ + _typeNamespace = s; +} + QList<QmlDirParser::Plugin> QmlDirParser::plugins() const { return _plugins; } -QList<QmlDirParser::Component> QmlDirParser::components() const +QHash<QString,QmlDirParser::Component> QmlDirParser::components() const { return _components; } +QList<QmlDirParser::Script> QmlDirParser::scripts() const +{ + return _scripts; +} + #ifdef QT_CREATOR QList<QmlDirParser::TypeInfo> QmlDirParser::typeInfos() const { @@ -271,4 +300,18 @@ QList<QmlDirParser::TypeInfo> QmlDirParser::typeInfos() const } #endif +QDebug &operator<< (QDebug &debug, const QmlDirParser::Component &component) +{ + const QString output = QString::fromLatin1("{%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}"). + arg(script.nameSpace).arg(script.majorVersion).arg(script.minorVersion); + return debug << qPrintable(output); +} + QT_END_NAMESPACE diff --git a/src/libs/qmljs/parser/qmldirparser_p.h b/src/libs/qmljs/parser/qmldirparser_p.h index ca8dd57df7..6cf381c1d7 100644 --- a/src/libs/qmljs/parser/qmldirparser_p.h +++ b/src/libs/qmljs/parser/qmldirparser_p.h @@ -28,8 +28,8 @@ ** **************************************************************************/ -#ifndef QMLDIRPARSER_P_H -#define QMLDIRPARSER_P_H +#ifndef QQMLDIRPARSER_P_H +#define QQMLDIRPARSER_P_H // // W A R N I N G @@ -42,15 +42,16 @@ // We mean it. // -#include <QUrl> -#include <QHash> +#include <QtCore/QUrl> +#include <QtCore/QHash> +#include <QtCore/QDebug> -#include "qmljsglobal_p.h" QT_BEGIN_NAMESPACE class QmlError; -class QML_PARSER_EXPORT QmlDirParser +class QmlEngine; +class Q_AUTOTEST_EXPORT QmlDirParser { Q_DISABLE_COPY(QmlDirParser) @@ -58,21 +59,15 @@ public: QmlDirParser(); ~QmlDirParser(); - QUrl url() const; - void setUrl(const QUrl &url); - - QString fileSource() const; - void setFileSource(const QString &filePath); - - QString source() const; - void setSource(const QString &source); - - bool isParsed() const; - bool parse(); + bool parse(const QString &source); bool hasError() const; + void setError(const QmlError &); QList<QmlError> errors(const QString &uri) const; + QString typeNamespace() const; + void setTypeNamespace(const QString &s); + struct Plugin { Plugin() {} @@ -100,7 +95,22 @@ public: bool internal; }; - QList<Component> components() const; + struct Script + { + Script() + : majorVersion(0), minorVersion(0) {} + + Script(const QString &nameSpace, const QString &fileName, int majorVersion, int minorVersion) + : nameSpace(nameSpace), fileName(fileName), majorVersion(majorVersion), minorVersion(minorVersion) {} + + QString nameSpace; + QString fileName; + int majorVersion; + int minorVersion; + }; + + QHash<QString,Component> components() const; + QList<Script> scripts() const; QList<Plugin> plugins() const; #ifdef QT_CREATOR @@ -121,20 +131,22 @@ private: private: QList<QmlError> _errors; - QUrl _url; - QString _source; - QString _filePathSouce; - QList<Component> _components; + QString _typeNamespace; + QHash<QString,Component> _components; // multi hash + QList<Script> _scripts; QList<Plugin> _plugins; #ifdef QT_CREATOR QList<TypeInfo> _typeInfos; #endif - unsigned _isParsed: 1; }; -typedef QList<QmlDirParser::Component> QmlDirComponents; +typedef QHash<QString,QmlDirParser::Component> QmlDirComponents; +typedef QList<QmlDirParser::Script> QmlDirScripts; +typedef QList<QmlDirParser::Plugin> QmlDirPlugins; +QDebug &operator<< (QDebug &, const QmlDirParser::Component &); +QDebug &operator<< (QDebug &, const QmlDirParser::Script &); QT_END_NAMESPACE -#endif // QMLDIRPARSER_P_H +#endif // QQMLDIRPARSER_P_H diff --git a/src/libs/qmljs/parser/qmlerror.cpp b/src/libs/qmljs/parser/qmlerror.cpp index b3408f7166..9bc41a2cb7 100644 --- a/src/libs/qmljs/parser/qmlerror.cpp +++ b/src/libs/qmljs/parser/qmlerror.cpp @@ -30,15 +30,16 @@ #include "qmlerror.h" -#include <qdebug.h> -#include <qfile.h> -#include <qstringlist.h> +#include <QtCore/qdebug.h> +#include <QtCore/qfile.h> +#include <QtCore/qstringlist.h> QT_BEGIN_NAMESPACE /*! \class QmlError - \since 4.7 + \since 5.0 + \inmodule QtQml \brief The QmlError class encapsulates a QML error. QmlError includes a textual description of the error, as well @@ -58,7 +59,9 @@ QT_BEGIN_NAMESPACE ^ \endcode - \sa QmlView::errors(), QmlComponent::errors() + Note that the QtQuick 1 version is named QDeclarativeError + + \sa QQuickView::errors(), QmlComponent::errors() */ class QmlErrorPrivate { diff --git a/src/libs/qmljs/parser/qmlerror.h b/src/libs/qmljs/parser/qmlerror.h index e5394dfa71..cf27d533da 100644 --- a/src/libs/qmljs/parser/qmlerror.h +++ b/src/libs/qmljs/parser/qmlerror.h @@ -28,17 +28,18 @@ ** **************************************************************************/ -#ifndef QMLERROR_H -#define QMLERROR_H +#ifndef QQMLERROR_H +#define QQMLERROR_H -#include <qurl.h> -#include <qstring.h> + + +#include <QtCore/qurl.h> +#include <QtCore/qstring.h> QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -QT_MODULE(Declarative) class QDebug; class QmlErrorPrivate; @@ -68,8 +69,10 @@ private: QDebug operator<<(QDebug debug, const QmlError &error); +Q_DECLARE_TYPEINFO(QmlError, Q_MOVABLE_TYPE); + QT_END_NAMESPACE QT_END_HEADER -#endif // QMLERROR_H +#endif // QQMLERROR_H diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g index e8c7b8cf20..9cbdc23599 100644 --- a/src/libs/qmljs/parser/qmljs.g +++ b/src/libs/qmljs/parser/qmljs.g @@ -30,7 +30,7 @@ %parser QmlJSGrammar %decl qmljsparser_p.h -%impl qmljsparser.cpp +%impl qdeclarativejsparser.cpp %expect 2 %expect-rr 2 @@ -120,6 +120,7 @@ ** **************************************************************************/ + #include <QtCore/QtDebug> #include <QtCore/QCoreApplication> @@ -163,6 +164,7 @@ **************************************************************************/ + // // W A R N I N G // ------------- @@ -383,10 +385,10 @@ void Parser::reallocateStack() else stack_size <<= 1; - sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); - state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int))); - location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation))); - string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef))); + sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); + state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); + location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); + string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef))); } Parser::Parser(Engine *engine): @@ -406,10 +408,10 @@ Parser::Parser(Engine *engine): Parser::~Parser() { if (stack_size) { - qFree(sym_stack); - qFree(state_stack); - qFree(location_stack); - qFree(string_stack); + free(sym_stack); + free(state_stack); + free(location_stack); + free(string_stack); } } diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h index 0fd68ae5b5..547e2c4cd8 100644 --- a/src/libs/qmljs/parser/qmljsast_p.h +++ b/src/libs/qmljs/parser/qmljsast_p.h @@ -46,7 +46,7 @@ #include "qmljsglobal_p.h" #include "qmljsmemorypool_p.h" -#include <QString> +#include <QtCore/QString> QT_QML_BEGIN_NAMESPACE diff --git a/src/libs/qmljs/parser/qmljsastfwd_p.h b/src/libs/qmljs/parser/qmljsastfwd_p.h index 10fc2534bb..51b6227068 100644 --- a/src/libs/qmljs/parser/qmljsastfwd_p.h +++ b/src/libs/qmljs/parser/qmljsastfwd_p.h @@ -33,7 +33,7 @@ #include "qmljsglobal_p.h" -#include <qglobal.h> +#include <QtCore/qglobal.h> // // W A R N I N G diff --git a/src/libs/qmljs/parser/qmljsglobal_p.h b/src/libs/qmljs/parser/qmljsglobal_p.h index 56fbc3f716..9bb233d04e 100644 --- a/src/libs/qmljs/parser/qmljsglobal_p.h +++ b/src/libs/qmljs/parser/qmljsglobal_p.h @@ -30,7 +30,7 @@ #ifndef QMLJSGLOBAL_P_H #define QMLJSGLOBAL_P_H -#include <qglobal.h> +#include <QtCore/qglobal.h> #ifdef QT_CREATOR # define QT_QML_BEGIN_NAMESPACE diff --git a/src/libs/qmljs/parser/qmljsgrammar_p.h b/src/libs/qmljs/parser/qmljsgrammar_p.h index 0ef10463e4..5adb8dcaaa 100644 --- a/src/libs/qmljs/parser/qmljsgrammar_p.h +++ b/src/libs/qmljs/parser/qmljsgrammar_p.h @@ -44,7 +44,7 @@ #define QMLJSGRAMMAR_P_H #include "qmljsglobal_p.h" -#include <qglobal.h> +#include <QtCore/qglobal.h> QT_BEGIN_NAMESPACE diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp index b868a84bcc..9334c7b8cd 100644 --- a/src/libs/qmljs/parser/qmljslexer.cpp +++ b/src/libs/qmljs/parser/qmljslexer.cpp @@ -32,9 +32,9 @@ #include "qmljsengine_p.h" #include "qmljsmemorypool_p.h" -#include <QCoreApplication> -#include <QVarLengthArray> -#include <QDebug> +#include <QtCore/QCoreApplication> +#include <QtCore/QVarLengthArray> +#include <QtCore/QDebug> QT_BEGIN_NAMESPACE Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); @@ -660,6 +660,17 @@ again: _errorMessage = QCoreApplication::translate("QmlParser", "Unclosed string at end of line"); return T_ERROR; } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return scanNumber(ch); default: if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) { @@ -716,118 +727,127 @@ again: return kind; } } - } else if (ch.isDigit()) { - if (ch != QLatin1Char('0')) { - double integer = ch.unicode() - '0'; - - QChar n = _char; - const QChar *code = _codePtr; - while (n.isDigit()) { - integer = integer * 10 + (n.unicode() - '0'); - n = *code++; - } + } - if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) { - if (code != _codePtr) { - _codePtr = code - 1; - scanChar(); - } - _tokenValue = integer; - return T_NUMERIC_LITERAL; - } - } + break; + } - QVarLengthArray<char,32> chars; - chars.append(ch.unicode()); + return T_ERROR; +} - if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { - // parse hex integer literal +int Lexer::scanNumber(QChar ch) +{ + if (ch != QLatin1Char('0')) { + double integer = ch.unicode() - '0'; + + QChar n = _char; + const QChar *code = _codePtr; + while (n.isDigit()) { + integer = integer * 10 + (n.unicode() - '0'); + n = *code++; + } - chars.append(_char.unicode()); - scanChar(); // consume `x' + if (n != QLatin1Char('.') && n != QLatin1Char('e') && n != QLatin1Char('E')) { + if (code != _codePtr) { + _codePtr = code - 1; + scanChar(); + } + _tokenValue = integer; + return T_NUMERIC_LITERAL; + } + } - while (isHexDigit(_char)) { - chars.append(_char.unicode()); - scanChar(); - } + QVarLengthArray<char,32> chars; + chars.append(ch.unicode()); - _tokenValue = integerFromString(chars.constData(), chars.size(), 16); - return T_NUMERIC_LITERAL; - } + if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { + // parse hex integer literal - // decimal integer literal - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); // consume the digit - } + chars.append(_char.unicode()); + scanChar(); // consume `x' - if (_char == QLatin1Char('.')) { - chars.append(_char.unicode()); - scanChar(); // consume `.' + while (isHexDigit(_char)) { + chars.append(_char.unicode()); + scanChar(); + } - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } + _tokenValue = integerFromString(chars.constData(), chars.size(), 16); + return T_NUMERIC_LITERAL; + } - if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { + // decimal integer literal + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); // consume the digit + } - chars.append(_char.unicode()); - scanChar(); // consume `e' + if (_char == QLatin1Char('.')) { + chars.append(_char.unicode()); + scanChar(); // consume `.' - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); + } - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } + if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { + if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && + _codePtr[1].isDigit())) { + + chars.append(_char.unicode()); + scanChar(); // consume `e' + + if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { + chars.append(_char.unicode()); + scanChar(); // consume the sign } - } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { - if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && - _codePtr[1].isDigit())) { + while (_char.isDigit()) { chars.append(_char.unicode()); - scanChar(); // consume `e' + scanChar(); + } + } + } + } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) { + if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) && + _codePtr[1].isDigit())) { - if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { - chars.append(_char.unicode()); - scanChar(); // consume the sign - } + chars.append(_char.unicode()); + scanChar(); // consume `e' - while (_char.isDigit()) { - chars.append(_char.unicode()); - scanChar(); - } - } + if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) { + chars.append(_char.unicode()); + scanChar(); // consume the sign } - chars.append('\0'); + while (_char.isDigit()) { + chars.append(_char.unicode()); + scanChar(); + } + } + } - const char *begin = chars.constData(); - const char *end = 0; - bool ok = false; + if (chars.size() == 1) { + // if we ended up with a single digit, then it was a '0' + _tokenValue = 0; + return T_NUMERIC_LITERAL; + } - _tokenValue = qstrtod(begin, &end, &ok); + chars.append('\0'); - if (end - begin != chars.size() - 1) { - _errorCode = IllegalExponentIndicator; - _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number"); - return T_ERROR; - } + const char *begin = chars.constData(); + const char *end = 0; + bool ok = false; - return T_NUMERIC_LITERAL; - } + _tokenValue = qstrtod(begin, &end, &ok); - break; + if (end - begin != chars.size() - 1) { + _errorCode = IllegalExponentIndicator; + _errorMessage = QCoreApplication::translate("QmlParser", "Illegal syntax for exponential number"); + return T_ERROR; } - return T_ERROR; + return T_NUMERIC_LITERAL; } bool Lexer::scanRegExp(RegExpBodyPrefix prefix) @@ -959,31 +979,6 @@ bool Lexer::isOctalDigit(ushort c) return (c >= '0' && c <= '7'); } -int Lexer::tokenKind() const -{ - return _tokenKind; -} - -int Lexer::tokenOffset() const -{ - return _tokenStartPtr - _code.unicode(); -} - -int Lexer::tokenLength() const -{ - return _tokenLength; -} - -int Lexer::tokenStartLine() const -{ - return _tokenLine; -} - -int Lexer::tokenStartColumn() const -{ - return _tokenStartPtr - _tokenLinePtr + 1; -} - int Lexer::tokenEndLine() const { return _currentLineNumber; @@ -994,16 +989,6 @@ int Lexer::tokenEndColumn() const return _codePtr - _lastLinePtr; } -QStringRef Lexer::tokenSpell() const -{ - return _tokenSpell; -} - -double Lexer::tokenValue() const -{ - return _tokenValue; -} - QString Lexer::tokenText() const { if (_validTokenText) diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h index cefa538bf5..ad515a6f9e 100644 --- a/src/libs/qmljs/parser/qmljslexer_p.h +++ b/src/libs/qmljs/parser/qmljslexer_p.h @@ -44,7 +44,7 @@ #include "qmljsglobal_p.h" #include "qmljsgrammar_p.h" -#include <QString> +#include <QtCore/QString> QT_QML_BEGIN_NAMESPACE @@ -147,18 +147,18 @@ public: int regExpFlags() const { return _patternFlags; } QString regExpPattern() const { return _tokenText; } - int tokenKind() const; - int tokenOffset() const; - int tokenLength() const; + int tokenKind() const { return _tokenKind; } + int tokenOffset() const { return _tokenStartPtr - _code.unicode(); } + int tokenLength() const { return _tokenLength; } - int tokenStartLine() const; - int tokenStartColumn() const; + int tokenStartLine() const { return _tokenLine; } + int tokenStartColumn() const { return _tokenStartPtr - _tokenLinePtr + 1; } int tokenEndLine() const; int tokenEndColumn() const; - QStringRef tokenSpell() const; - double tokenValue() const; + inline QStringRef tokenSpell() const { return _tokenSpell; } + double tokenValue() const { return _tokenValue; } QString tokenText() const; Error errorCode() const; @@ -180,6 +180,7 @@ protected: private: inline void scanChar(); int scanToken(); + int scanNumber(QChar ch); bool isLineTerminator() const; static bool isIdentLetter(QChar c); diff --git a/src/libs/qmljs/parser/qmljsmemorypool_p.h b/src/libs/qmljs/parser/qmljsmemorypool_p.h index 0f3e46b186..3af1734d69 100644 --- a/src/libs/qmljs/parser/qmljsmemorypool_p.h +++ b/src/libs/qmljs/parser/qmljsmemorypool_p.h @@ -44,9 +44,9 @@ #include "qmljsglobal_p.h" -#include <qglobal.h> -#include <qshareddata.h> -#include <qdebug.h> +#include <QtCore/qglobal.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qdebug.h> #include <cstring> @@ -73,10 +73,10 @@ public: if (_blocks) { for (int i = 0; i < _allocatedBlocks; ++i) { if (char *b = _blocks[i]) - qFree(b); + free(b); } - qFree(_blocks); + free(_blocks); } } @@ -108,7 +108,7 @@ private: else _allocatedBlocks *= 2; - _blocks = (char **) qRealloc(_blocks, sizeof(char *) * _allocatedBlocks); + _blocks = (char **) realloc(_blocks, sizeof(char *) * _allocatedBlocks); for (int index = _blockCount; index < _allocatedBlocks; ++index) _blocks[index] = 0; @@ -117,7 +117,7 @@ private: char *&block = _blocks[_blockCount]; if (! block) - block = (char *) qMalloc(BLOCK_SIZE); + block = (char *) malloc(BLOCK_SIZE); _ptr = block; _end = _ptr + BLOCK_SIZE; diff --git a/src/libs/qmljs/parser/qmljsparser.cpp b/src/libs/qmljs/parser/qmljsparser.cpp index 9895b21df6..6d38568698 100644 --- a/src/libs/qmljs/parser/qmljsparser.cpp +++ b/src/libs/qmljs/parser/qmljsparser.cpp @@ -28,8 +28,8 @@ ** **************************************************************************/ -#include <QtDebug> -#include <QCoreApplication> +#include <QtCore/QtDebug> +#include <QtCore/QCoreApplication> #include <string.h> @@ -59,10 +59,10 @@ void Parser::reallocateStack() else stack_size <<= 1; - sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); - state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int))); - location_stack = reinterpret_cast<AST::SourceLocation*> (qRealloc(location_stack, stack_size * sizeof(AST::SourceLocation))); - string_stack = reinterpret_cast<QStringRef*> (qRealloc(string_stack, stack_size * sizeof(QStringRef))); + sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value))); + state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int))); + location_stack = reinterpret_cast<AST::SourceLocation*> (realloc(location_stack, stack_size * sizeof(AST::SourceLocation))); + string_stack = reinterpret_cast<QStringRef*> (realloc(string_stack, stack_size * sizeof(QStringRef))); } Parser::Parser(Engine *engine): @@ -74,6 +74,7 @@ Parser::Parser(Engine *engine): state_stack(0), location_stack(0), string_stack(0), + program(0), first_token(0), last_token(0) { @@ -82,10 +83,10 @@ Parser::Parser(Engine *engine): Parser::~Parser() { if (stack_size) { - qFree(sym_stack); - qFree(state_stack); - qFree(location_stack); - qFree(string_stack); + free(sym_stack); + free(state_stack); + free(location_stack); + free(string_stack); } } diff --git a/src/libs/qmljs/parser/qmljsparser_p.h b/src/libs/qmljs/parser/qmljsparser_p.h index f68eb5d03e..f9d43c25aa 100644 --- a/src/libs/qmljs/parser/qmljsparser_p.h +++ b/src/libs/qmljs/parser/qmljsparser_p.h @@ -53,8 +53,8 @@ #include "qmljsast_p.h" #include "qmljsengine_p.h" -#include <QList> -#include <QString> +#include <QtCore/QList> +#include <QtCore/QString> QT_QML_BEGIN_NAMESPACE diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index f1cdbc4b2e..53eb99d12e 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -323,7 +323,7 @@ LibraryInfo::LibraryInfo(Status status) LibraryInfo::LibraryInfo(const QmlDirParser &parser) : _status(Found) - , _components(parser.components()) + , _components(parser.components().values()) , _plugins(parser.plugins()) , _typeinfos(parser.typeInfos()) , _dumpStatus(NoTypeInfo) diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index f5d0bb53fe..45ebc6f3f8 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -474,8 +474,7 @@ static bool findNewQmlLibraryInPath(const QString &path, QString qmldirData = QString::fromUtf8(qmldirFile.readAll()); QmlDirParser qmldirParser; - qmldirParser.setSource(qmldirData); - qmldirParser.parse(); + qmldirParser.parse(qmldirData); const QString libraryPath = QFileInfo(qmldirFile).absolutePath(); newLibraries->insert(libraryPath); |