forked from qt-creator/qt-creator
QMLJS: update to qmljsparser from Qt 5.6
Change-Id: I29a8e07b0b34aa5e8466021cbb71450687f7e11c Reviewed-by: Tim Jenssen <tim.jenssen@theqtcompany.com>
This commit is contained in:
@@ -46,5 +46,3 @@ sed -i -e 's|#include <QtCore/qset.h>|#include <QSet>|g' $me/qmljsengine_p.h
|
||||
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}
|
||||
|
||||
#patch -R -p5 < parser.patch
|
||||
|
@@ -26,8 +26,6 @@
|
||||
#include "qmldirparser_p.h"
|
||||
#include "qmlerror.h"
|
||||
|
||||
|
||||
|
||||
#include <QtCore/QtDebug>
|
||||
|
||||
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 '.'"));
|
||||
} 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) {
|
||||
int major, minor;
|
||||
if (parseVersion(sections[2], &major, &minor)) {
|
||||
const QString &fileName = sections[3];
|
||||
Component entry(sections[1], fileName, majorVersion, minorVersion);
|
||||
Component entry(sections[1], fileName, major, minor);
|
||||
entry.singleton = true;
|
||||
_components.insertMulti(entry.typeName, entry);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").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 <major>.<minor>").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('.'));
|
||||
|
||||
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) {
|
||||
int major, minor;
|
||||
if (parseVersion(sections[1], &major, &minor)) {
|
||||
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);
|
||||
const Script entry(sections[0], fileName, major, minor);
|
||||
_scripts.append(entry);
|
||||
} else {
|
||||
const Component entry(sections[0], fileName, majorVersion, minorVersion);
|
||||
const Component entry(sections[0], fileName, major, minor);
|
||||
_components.insertMulti(entry.typeName, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reportError(lineNumber, 0, QStringLiteral("invalid version %1, expected <major>.<minor>").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<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();
|
||||
QList<QmlError> 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::Plugin> QmlDirParser::plugins() const
|
||||
return _plugins;
|
||||
}
|
||||
|
||||
QHash<QString,QmlDirParser::Component> QmlDirParser::components() const
|
||||
QHash<QString, QmlDirParser::Component> QmlDirParser::components() const
|
||||
{
|
||||
return _components;
|
||||
}
|
||||
|
||||
QHash<QString, QmlDirParser::Component> QmlDirParser::dependencies() const
|
||||
{
|
||||
return _dependencies;
|
||||
}
|
||||
|
||||
QList<QmlDirParser::Script> QmlDirParser::scripts() const
|
||||
{
|
||||
return _scripts;
|
||||
@@ -332,16 +349,21 @@ QList<QmlDirParser::TypeInfo> 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);
|
||||
}
|
||||
|
@@ -40,8 +40,7 @@
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
|
||||
#include "qmljsglobal_p.h"
|
||||
#include "qmljsengine_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@@ -107,8 +106,10 @@ public:
|
||||
};
|
||||
|
||||
QHash<QString,Component> components() const;
|
||||
QHash<QString,Component> dependencies() const;
|
||||
QList<Script> scripts() const;
|
||||
QList<Plugin> plugins() const;
|
||||
bool designerSupported() const;
|
||||
|
||||
#ifdef QT_CREATOR
|
||||
struct TypeInfo
|
||||
@@ -124,14 +125,17 @@ public:
|
||||
#endif
|
||||
|
||||
private:
|
||||
bool maybeAddComponent(const QString &typeName, const QString &fileName, const QString &version, QHash<QString,Component> &hash, int lineNumber = -1, bool multi = true);
|
||||
void reportError(quint16 line, quint16 column, const QString &message);
|
||||
|
||||
private:
|
||||
QList<QmlError> _errors;
|
||||
QList<QmlJS::DiagnosticMessage> _errors;
|
||||
QString _typeNamespace;
|
||||
QHash<QString,Component> _components; // multi hash
|
||||
QHash<QString,Component> _dependencies;
|
||||
QList<Script> _scripts;
|
||||
QList<Plugin> _plugins;
|
||||
bool _designerSupported;
|
||||
#ifdef QT_CREATOR
|
||||
QList<TypeInfo> _typeInfos;
|
||||
#endif
|
||||
|
@@ -48,8 +48,8 @@ QT_BEGIN_NAMESPACE
|
||||
file:///home/user/test.qml:7:8: Invalid property assignment: double expected
|
||||
\endcode
|
||||
|
||||
You can use qDebug() or qWarning() to output errors to the console. This method
|
||||
will attempt to open the file indicated by the error
|
||||
You can use qDebug(), qInfo(), or qWarning() to output errors to the console.
|
||||
This method will attempt to open the file indicated by the error
|
||||
and include additional contextual information.
|
||||
\code
|
||||
file:///home/user/test.qml:7:8: Invalid property assignment: double expected
|
||||
@@ -239,16 +239,17 @@ QString QmlError::toString() const
|
||||
QUrl u(url());
|
||||
int l(line());
|
||||
|
||||
if (u.isEmpty()) {
|
||||
if (u.isEmpty() || (u.isLocalFile() && u.path().isEmpty()))
|
||||
rv = QLatin1String("<Unknown File>");
|
||||
} else if (l != -1) {
|
||||
rv = u.toString() + QLatin1Char(':') + QString::number(l);
|
||||
else
|
||||
rv = u.toString();
|
||||
|
||||
if (l != -1) {
|
||||
rv += QLatin1Char(':') + QString::number(l);
|
||||
|
||||
int c(column());
|
||||
if (c != -1)
|
||||
rv += QLatin1Char(':') + QString::number(c);
|
||||
} else {
|
||||
rv = u.toString();
|
||||
}
|
||||
|
||||
rv += QLatin1String(": ") + description();
|
||||
|
@@ -1,13 +1,21 @@
|
||||
----------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright (C) 2015 The Qt Company Ltd.
|
||||
-- Contact: https://www.qt.io/licensing/
|
||||
-- Contact: http://www.qt.io/licensing/
|
||||
--
|
||||
-- This file is part of the QtQml module of the Qt Toolkit.
|
||||
--
|
||||
-- $QT_BEGIN_LICENSE:LGPL-ONLY$
|
||||
-- $QT_BEGIN_LICENSE:LGPL21$
|
||||
-- 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 http://www.qt.io/terms-conditions. For further
|
||||
-- information use the contact form at http://www.qt.io/contact-us.
|
||||
--
|
||||
-- GNU Lesser General Public License Usage
|
||||
-- This file may be used under the terms of the GNU Lesser
|
||||
-- Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
-- General Public License version 2.1 or version 3 as published by the Free
|
||||
-- Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
-- LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
@@ -15,8 +23,9 @@
|
||||
-- requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
-- 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.io/contact-us.
|
||||
-- As a special exception, The Qt Company gives you certain additional
|
||||
-- rights. These rights are described in The Qt Company LGPL Exception
|
||||
-- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
--
|
||||
-- $QT_END_LICENSE$
|
||||
--
|
||||
@@ -90,38 +99,32 @@
|
||||
|
||||
/./****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtQml module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** 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.
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
@@ -141,43 +144,38 @@
|
||||
|
||||
/:/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtQml module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** 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.
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or any later version approved by the KDE Free
|
||||
** Qt Foundation. The licenses are as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
@@ -507,7 +505,24 @@ bool Parser::parse(int startToken)
|
||||
|
||||
token_buffer[0].token = startToken;
|
||||
first_token = &token_buffer[0];
|
||||
if (startToken == T_FEED_JS_PROGRAM && !lexer->qmlMode()) {
|
||||
Directives ignoreDirectives;
|
||||
Directives *directives = driver->directives();
|
||||
if (!directives)
|
||||
directives = &ignoreDirectives;
|
||||
DiagnosticMessage error;
|
||||
if (!lexer->scanDirectives(directives, &error)) {
|
||||
diagnostic_messages.append(error);
|
||||
return false;
|
||||
}
|
||||
token_buffer[1].token = lexer->tokenKind();
|
||||
token_buffer[1].dval = lexer->tokenValue();
|
||||
token_buffer[1].loc = location(lexer);
|
||||
token_buffer[1].spell = lexer->tokenSpell();
|
||||
last_token = &token_buffer[2];
|
||||
} else {
|
||||
last_token = &token_buffer[1];
|
||||
}
|
||||
|
||||
tos = -1;
|
||||
program = 0;
|
||||
@@ -1085,6 +1100,31 @@ case $rule_number: {
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: T_READONLY T_PROPERTY UiPropertyType JsIdentifier T_COLON UiQualifiedId UiObjectInitializer ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
AST::UiPublicMember *node = new (pool) AST::UiPublicMember(stringRef(3), stringRef(4));
|
||||
node->isReadonlyMember = true;
|
||||
node->readonlyToken = loc(1);
|
||||
node->propertyToken = loc(2);
|
||||
node->typeToken = loc(3);
|
||||
node->identifierToken = loc(4);
|
||||
node->semicolonToken = loc(5); // insert a fake ';' before ':'
|
||||
|
||||
AST::UiQualifiedId *propertyName = new (pool) AST::UiQualifiedId(stringRef(4));
|
||||
propertyName->identifierToken = loc(4);
|
||||
propertyName->next = 0;
|
||||
|
||||
AST::UiObjectBinding *binding = new (pool) AST::UiObjectBinding(
|
||||
propertyName, sym(6).UiQualifiedId, sym(7).UiObjectInitializer);
|
||||
binding->colonToken = loc(5);
|
||||
|
||||
node->binding = binding;
|
||||
|
||||
sym(1).Node = node;
|
||||
} break;
|
||||
./
|
||||
|
||||
UiObjectMember: FunctionDeclaration ;
|
||||
/.
|
||||
case $rule_number: {
|
||||
@@ -3031,9 +3071,9 @@ PropertyAssignmentListOpt: PropertyAssignmentList ;
|
||||
QString msg;
|
||||
int token = token_buffer[0].token;
|
||||
if (token < 0 || token >= TERMINAL_COUNT)
|
||||
msg = qApp->translate("QmlParser", "Syntax error");
|
||||
msg = QCoreApplication::translate("QmlParser", "Syntax error");
|
||||
else
|
||||
msg = qApp->translate("QmlParser", "Unexpected token `%1'").arg(QLatin1String(spell[token]));
|
||||
msg = QCoreApplication::translate("QmlParser", "Unexpected token `%1'").arg(QLatin1String(spell[token]));
|
||||
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
|
||||
|
||||
action = errorState;
|
||||
@@ -3061,7 +3101,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ;
|
||||
for (int *tk = tokens; *tk != EOF_SYMBOL; ++tk) {
|
||||
int a = t_action(errorState, *tk);
|
||||
if (a > 0 && t_action(a, yytoken)) {
|
||||
const QString msg = qApp->translate("QmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk]));
|
||||
const QString msg = QCoreApplication::translate("QmlParser", "Expected token `%1'").arg(QLatin1String(spell[*tk]));
|
||||
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
|
||||
|
||||
yytoken = *tk;
|
||||
@@ -3085,7 +3125,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ;
|
||||
|
||||
int a = t_action(errorState, tk);
|
||||
if (a > 0 && t_action(a, yytoken)) {
|
||||
const QString msg = qApp->translate("QmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk]));
|
||||
const QString msg = QCoreApplication::translate("QmlParser", "Expected token `%1'").arg(QLatin1String(spell[tk]));
|
||||
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
|
||||
|
||||
yytoken = tk;
|
||||
@@ -3098,7 +3138,7 @@ PropertyAssignmentListOpt: PropertyAssignmentList ;
|
||||
}
|
||||
}
|
||||
|
||||
const QString msg = qApp->translate("QmlParser", "Syntax error");
|
||||
const QString msg = QCoreApplication::translate("QmlParser", "Syntax error");
|
||||
diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, token_buffer[0].loc, msg));
|
||||
}
|
||||
|
||||
|
@@ -94,11 +94,11 @@ namespace QmlJS {
|
||||
|
||||
namespace AST {
|
||||
|
||||
template <typename _T1, typename _T2>
|
||||
_T1 cast(_T2 *ast)
|
||||
template <typename T1, typename T2>
|
||||
T1 cast(T2 *ast)
|
||||
{
|
||||
if (ast && ast->kind == static_cast<_T1>(0)->K)
|
||||
return static_cast<_T1>(ast);
|
||||
if (ast && ast->kind == static_cast<T1>(0)->K)
|
||||
return static_cast<T1>(ast);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -586,6 +586,8 @@ public:
|
||||
virtual SourceLocation lastSourceLocation() const
|
||||
{ return propertyNameToken; }
|
||||
|
||||
virtual QString asString() const = 0;
|
||||
|
||||
// attributes
|
||||
SourceLocation propertyNameToken;
|
||||
};
|
||||
@@ -593,7 +595,11 @@ public:
|
||||
class QML_PARSER_EXPORT PropertyAssignment: public Node
|
||||
{
|
||||
public:
|
||||
PropertyAssignment() {}
|
||||
PropertyAssignment(PropertyName *n)
|
||||
: name(n)
|
||||
{}
|
||||
// attributes
|
||||
PropertyName *name;
|
||||
};
|
||||
|
||||
class QML_PARSER_EXPORT PropertyAssignmentList: public Node
|
||||
@@ -641,7 +647,7 @@ public:
|
||||
QMLJS_DECLARE_AST_NODE(PropertyNameAndValue)
|
||||
|
||||
PropertyNameAndValue(PropertyName *n, ExpressionNode *v)
|
||||
: name(n), value(v)
|
||||
: PropertyAssignment(n), value(v)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
@@ -653,7 +659,6 @@ public:
|
||||
{ return value->lastSourceLocation(); }
|
||||
|
||||
// attributes
|
||||
PropertyName *name;
|
||||
SourceLocation colonToken;
|
||||
ExpressionNode *value;
|
||||
SourceLocation commaToken;
|
||||
@@ -670,11 +675,11 @@ public:
|
||||
};
|
||||
|
||||
PropertyGetterSetter(PropertyName *n, FunctionBody *b)
|
||||
: type(Getter), name(n), formals(0), functionBody (b)
|
||||
: PropertyAssignment(n), type(Getter), formals(0), functionBody (b)
|
||||
{ kind = K; }
|
||||
|
||||
PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b)
|
||||
: type(Setter), name(n), formals(f), functionBody (b)
|
||||
: PropertyAssignment(n), type(Setter), formals(f), functionBody (b)
|
||||
{ kind = K; }
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
@@ -688,7 +693,6 @@ public:
|
||||
// attributes
|
||||
Type type;
|
||||
SourceLocation getSetToken;
|
||||
PropertyName *name;
|
||||
SourceLocation lparenToken;
|
||||
FormalParameterList *formals;
|
||||
SourceLocation rparenToken;
|
||||
@@ -707,6 +711,8 @@ public:
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual QString asString() const { return id.toString(); }
|
||||
|
||||
// attributes
|
||||
QStringRef id;
|
||||
};
|
||||
@@ -721,6 +727,8 @@ public:
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual QString asString() const { return id.toString(); }
|
||||
|
||||
// attributes
|
||||
QStringRef id;
|
||||
};
|
||||
@@ -735,6 +743,8 @@ public:
|
||||
|
||||
virtual void accept0(Visitor *visitor);
|
||||
|
||||
virtual QString asString() const { return QString::number(id, 'g', 16); }
|
||||
|
||||
// attributes
|
||||
double id;
|
||||
};
|
||||
|
@@ -47,7 +47,7 @@ namespace QmlJS { namespace AST {
|
||||
class SourceLocation
|
||||
{
|
||||
public:
|
||||
SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
|
||||
explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0)
|
||||
: offset(offset), length(length),
|
||||
startLine(line), startColumn(column)
|
||||
{ }
|
||||
|
@@ -127,12 +127,12 @@ Lexer *Engine::lexer() const
|
||||
void Engine::setLexer(Lexer *lexer)
|
||||
{ _lexer = lexer; }
|
||||
|
||||
void Engine::setDirectives(Directives *directives)
|
||||
{ _directives = directives; }
|
||||
|
||||
Directives *Engine::directives() const
|
||||
{ return _directives; }
|
||||
|
||||
void Engine::setDirectives(Directives *directives)
|
||||
{ _directives = directives; }
|
||||
|
||||
MemoryPool *Engine::pool()
|
||||
{ return &_pool; }
|
||||
|
||||
|
@@ -39,11 +39,11 @@
|
||||
#include "qmljsglobal_p.h"
|
||||
#include "qmljsastfwd_p.h"
|
||||
#include "qmljsmemorypool_p.h"
|
||||
#include <qmljs/qmljsconstants.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QSet>
|
||||
|
||||
#include <qmljs/qmljsconstants.h>
|
||||
QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
@@ -94,8 +94,8 @@ public:
|
||||
Lexer *lexer() const;
|
||||
void setLexer(Lexer *lexer);
|
||||
|
||||
void setDirectives(Directives *directives);
|
||||
Directives *directives() const;
|
||||
void setDirectives(Directives *directives);
|
||||
|
||||
MemoryPool *pool();
|
||||
|
||||
|
@@ -25,6 +25,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifdef QT_CREATOR
|
||||
@@ -46,8 +57,8 @@
|
||||
// QmlDevTools is a static library
|
||||
# define QML_PARSER_EXPORT
|
||||
# elif defined(QT_BUILD_QML_LIB)
|
||||
# define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT
|
||||
# define QML_PARSER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define QML_PARSER_EXPORT
|
||||
# define QML_PARSER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#endif // QT_CREATOR
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -153,15 +153,15 @@ public:
|
||||
T_XOR = 79,
|
||||
T_XOR_EQ = 80,
|
||||
|
||||
ACCEPT_STATE = 663,
|
||||
RULE_COUNT = 357,
|
||||
STATE_COUNT = 664,
|
||||
ACCEPT_STATE = 665,
|
||||
RULE_COUNT = 358,
|
||||
STATE_COUNT = 666,
|
||||
TERMINAL_COUNT = 106,
|
||||
NON_TERMINAL_COUNT = 111,
|
||||
|
||||
GOTO_INDEX_OFFSET = 664,
|
||||
GOTO_INFO_OFFSET = 3104,
|
||||
GOTO_CHECK_OFFSET = 3104
|
||||
GOTO_INDEX_OFFSET = 666,
|
||||
GOTO_INFO_OFFSET = 3018,
|
||||
GOTO_CHECK_OFFSET = 3018
|
||||
};
|
||||
|
||||
static const char *const spell [];
|
||||
|
@@ -341,7 +341,7 @@ static inline bool isIdentifierStart(QChar ch)
|
||||
// fast path for ascii
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
ch == QLatin1Char('$') || ch == QLatin1Char('_'))
|
||||
ch == '$' || ch == '_')
|
||||
return true;
|
||||
|
||||
switch (ch.category()) {
|
||||
@@ -364,7 +364,7 @@ static bool isIdentifierPart(QChar ch)
|
||||
if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') ||
|
||||
(ch.unicode() >= 'A' && ch.unicode() <= 'Z') ||
|
||||
(ch.unicode() >= '0' && ch.unicode() <= '9') ||
|
||||
ch == QLatin1Char('$') || ch == QLatin1Char('_') ||
|
||||
ch == '$' || ch == '_' ||
|
||||
ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */)
|
||||
return true;
|
||||
|
||||
@@ -879,8 +879,7 @@ again:
|
||||
int Lexer::scanNumber(QChar ch)
|
||||
{
|
||||
if (ch != QLatin1Char('0')) {
|
||||
QByteArray buf;
|
||||
buf.reserve(64);
|
||||
QVarLengthArray<char, 64> buf;
|
||||
buf += ch.toLatin1();
|
||||
|
||||
QChar n = _char;
|
||||
@@ -1217,12 +1216,60 @@ bool Lexer::canInsertAutomaticSemicolon(int token) const
|
||||
|| _followsClosingBrace;
|
||||
}
|
||||
|
||||
bool Lexer::scanDirectives(Directives *directives)
|
||||
static const int uriTokens[] = {
|
||||
QmlJSGrammar::T_IDENTIFIER,
|
||||
QmlJSGrammar::T_PROPERTY,
|
||||
QmlJSGrammar::T_SIGNAL,
|
||||
QmlJSGrammar::T_READONLY,
|
||||
QmlJSGrammar::T_ON,
|
||||
QmlJSGrammar::T_BREAK,
|
||||
QmlJSGrammar::T_CASE,
|
||||
QmlJSGrammar::T_CATCH,
|
||||
QmlJSGrammar::T_CONTINUE,
|
||||
QmlJSGrammar::T_DEFAULT,
|
||||
QmlJSGrammar::T_DELETE,
|
||||
QmlJSGrammar::T_DO,
|
||||
QmlJSGrammar::T_ELSE,
|
||||
QmlJSGrammar::T_FALSE,
|
||||
QmlJSGrammar::T_FINALLY,
|
||||
QmlJSGrammar::T_FOR,
|
||||
QmlJSGrammar::T_FUNCTION,
|
||||
QmlJSGrammar::T_IF,
|
||||
QmlJSGrammar::T_IN,
|
||||
QmlJSGrammar::T_INSTANCEOF,
|
||||
QmlJSGrammar::T_NEW,
|
||||
QmlJSGrammar::T_NULL,
|
||||
QmlJSGrammar::T_RETURN,
|
||||
QmlJSGrammar::T_SWITCH,
|
||||
QmlJSGrammar::T_THIS,
|
||||
QmlJSGrammar::T_THROW,
|
||||
QmlJSGrammar::T_TRUE,
|
||||
QmlJSGrammar::T_TRY,
|
||||
QmlJSGrammar::T_TYPEOF,
|
||||
QmlJSGrammar::T_VAR,
|
||||
QmlJSGrammar::T_VOID,
|
||||
QmlJSGrammar::T_WHILE,
|
||||
QmlJSGrammar::T_CONST,
|
||||
QmlJSGrammar::T_DEBUGGER,
|
||||
QmlJSGrammar::T_RESERVED_WORD,
|
||||
QmlJSGrammar::T_WITH,
|
||||
|
||||
QmlJSGrammar::EOF_SYMBOL
|
||||
};
|
||||
static inline bool isUriToken(int token)
|
||||
{
|
||||
if (_qmlMode) {
|
||||
// the directives are a Javascript-only extension.
|
||||
return false;
|
||||
const int *current = uriTokens;
|
||||
while (*current != QmlJSGrammar::EOF_SYMBOL) {
|
||||
if (*current == token)
|
||||
return true;
|
||||
++current;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Lexer::scanDirectives(Directives *directives, DiagnosticMessage *error)
|
||||
{
|
||||
Q_ASSERT(!_qmlMode);
|
||||
|
||||
lex(); // fetch the first token
|
||||
|
||||
@@ -1230,24 +1277,33 @@ bool Lexer::scanDirectives(Directives *directives)
|
||||
return true;
|
||||
|
||||
do {
|
||||
const int lineNumber = tokenStartLine();
|
||||
const int column = tokenStartColumn();
|
||||
|
||||
lex(); // skip T_DOT
|
||||
|
||||
const int lineNumber = tokenStartLine();
|
||||
|
||||
if (! (_tokenKind == T_IDENTIFIER || _tokenKind == T_RESERVED_WORD))
|
||||
return false; // expected a valid QML/JS directive
|
||||
return true; // expected a valid QML/JS directive
|
||||
|
||||
const QString directiveName = tokenText();
|
||||
|
||||
if (! (directiveName == QLatin1String("pragma") ||
|
||||
directiveName == QLatin1String("import")))
|
||||
directiveName == QLatin1String("import"))) {
|
||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false; // not a valid directive name
|
||||
}
|
||||
|
||||
// it must be a pragma or an import directive.
|
||||
if (directiveName == QLatin1String("pragma")) {
|
||||
// .pragma library
|
||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library")))
|
||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("library"))) {
|
||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false; // expected `library
|
||||
}
|
||||
|
||||
// we found a .pragma library directive
|
||||
directives->pragmaLibrary();
|
||||
@@ -1266,22 +1322,53 @@ bool Lexer::scanDirectives(Directives *directives)
|
||||
fileImport = true;
|
||||
pathOrUri = tokenText();
|
||||
|
||||
if (!pathOrUri.endsWith(QLatin1String("js"))) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Imported file must be a script");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (_tokenKind == T_IDENTIFIER) {
|
||||
// .import T_IDENTIFIER (. T_IDENTIFIER)* T_NUMERIC_LITERAL as T_IDENTIFIER
|
||||
|
||||
pathOrUri = tokenText();
|
||||
|
||||
lex(); // skip the first T_IDENTIFIER
|
||||
for (; _tokenKind == T_DOT; lex()) {
|
||||
if (lex() != T_IDENTIFIER)
|
||||
while (true) {
|
||||
if (!isUriToken(_tokenKind)) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false;
|
||||
|
||||
pathOrUri += QLatin1Char('.');
|
||||
pathOrUri += tokenText();
|
||||
}
|
||||
|
||||
if (_tokenKind != T_NUMERIC_LITERAL)
|
||||
pathOrUri.append(tokenText());
|
||||
|
||||
lex();
|
||||
if (tokenStartLine() != lineNumber) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false;
|
||||
}
|
||||
if (_tokenKind != QmlJSGrammar::T_DOT)
|
||||
break;
|
||||
|
||||
pathOrUri.append(QLatin1Char('.'));
|
||||
|
||||
lex();
|
||||
if (tokenStartLine() != lineNumber) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Invalid module URI");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_tokenKind != T_NUMERIC_LITERAL) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Module import requires a version");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false; // expected the module version number
|
||||
}
|
||||
|
||||
version = tokenText();
|
||||
}
|
||||
@@ -1289,22 +1376,51 @@ bool Lexer::scanDirectives(Directives *directives)
|
||||
//
|
||||
// recognize the mandatory `as' followed by the module name
|
||||
//
|
||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as")))
|
||||
return false; // expected `as'
|
||||
|
||||
if (lex() != T_IDENTIFIER)
|
||||
return false; // expected module name
|
||||
|
||||
const QString module = tokenText();
|
||||
|
||||
if (! (lex() == T_IDENTIFIER && tokenText() == QLatin1String("as") && tokenStartLine() == lineNumber)) {
|
||||
if (fileImport)
|
||||
directives->importFile(pathOrUri, module);
|
||||
error->message = QCoreApplication::translate("QmlParser", "File import requires a qualifier");
|
||||
else
|
||||
directives->importModule(pathOrUri, version, module);
|
||||
error->message = QCoreApplication::translate("QmlParser", "Module import requires a qualifier");
|
||||
if (tokenStartLine() != lineNumber) {
|
||||
error->loc.startLine = lineNumber;
|
||||
error->loc.startColumn = column;
|
||||
} else {
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
}
|
||||
return false; // expected `as'
|
||||
}
|
||||
|
||||
if (tokenStartLine() != lineNumber)
|
||||
if (lex() != T_IDENTIFIER || tokenStartLine() != lineNumber) {
|
||||
if (fileImport)
|
||||
error->message = QCoreApplication::translate("QmlParser", "File import requires a qualifier");
|
||||
else
|
||||
error->message = QCoreApplication::translate("QmlParser", "Module import requires a qualifier");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false; // expected module name
|
||||
}
|
||||
|
||||
const QString module = tokenText();
|
||||
if (!module.at(0).isUpper()) {
|
||||
error->message = QCoreApplication::translate("QmlParser","Invalid import qualifier");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fileImport)
|
||||
directives->importFile(pathOrUri, module, lineNumber, column);
|
||||
else
|
||||
directives->importModule(pathOrUri, version, module, lineNumber, column);
|
||||
}
|
||||
|
||||
if (tokenStartLine() != lineNumber) {
|
||||
error->message = QCoreApplication::translate("QmlParser", "Syntax error");
|
||||
error->loc.startLine = tokenStartLine();
|
||||
error->loc.startColumn = tokenStartColumn();
|
||||
return false; // the directives cannot span over multiple lines
|
||||
}
|
||||
|
||||
// fetch the first token after the .pragma/.import directive
|
||||
lex();
|
||||
|
@@ -46,6 +46,7 @@ QT_QML_BEGIN_NAMESPACE
|
||||
namespace QmlJS {
|
||||
|
||||
class Engine;
|
||||
class DiagnosticMessage;
|
||||
|
||||
class QML_PARSER_EXPORT Directives {
|
||||
public:
|
||||
@@ -55,17 +56,21 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
virtual void importFile(const QString &jsfile, const QString &module)
|
||||
virtual void importFile(const QString &jsfile, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(jsfile);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
|
||||
virtual void importModule(const QString &uri, const QString &version, const QString &module)
|
||||
virtual void importModule(const QString &uri, const QString &version, const QString &module, int line, int column)
|
||||
{
|
||||
Q_UNUSED(uri);
|
||||
Q_UNUSED(version);
|
||||
Q_UNUSED(module);
|
||||
Q_UNUSED(line);
|
||||
Q_UNUSED(column);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -137,7 +142,7 @@ public:
|
||||
int lex();
|
||||
|
||||
bool scanRegExp(RegExpBodyPrefix prefix = NoPrefix);
|
||||
bool scanDirectives(Directives *directives);
|
||||
bool scanDirectives(Directives *directives, DiagnosticMessage *error);
|
||||
|
||||
int regExpFlags() const { return _patternFlags; }
|
||||
QString regExpPattern() const { return _tokenText; }
|
||||
|
@@ -48,6 +48,8 @@ QT_QML_BEGIN_NAMESPACE
|
||||
|
||||
namespace QmlJS {
|
||||
|
||||
class Managed;
|
||||
|
||||
class QML_PARSER_EXPORT MemoryPool : public QSharedData
|
||||
{
|
||||
MemoryPool(const MemoryPool &other);
|
||||
@@ -91,6 +93,8 @@ public:
|
||||
_ptr = _end = 0;
|
||||
}
|
||||
|
||||
template <typename Tp> Tp *New() { return new (this->allocate(sizeof(Tp))) Tp(); }
|
||||
|
||||
private:
|
||||
void *allocate_helper(size_t size)
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
@@ -230,8 +231,8 @@ protected:
|
||||
|
||||
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 87
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE1 88
|
||||
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 88
|
||||
#define J_SCRIPT_REGEXPLITERAL_RULE2 89
|
||||
|
||||
QT_QML_END_NAMESPACE
|
||||
|
@@ -1448,13 +1448,13 @@ ModelNode TextToModelMerger::createModelNode(const TypeName &typeName,
|
||||
|
||||
if (isCustomParserType(typeName))
|
||||
nodeSource = textAt(context->doc(),
|
||||
astObjectType->identifierToken.offset,
|
||||
astObjectType->identifierToken,
|
||||
astNode->lastSourceLocation());
|
||||
|
||||
|
||||
if (isComponentType(typeName) || isImplicitComponent) {
|
||||
QString componentSource = extractComponentFromQml(textAt(context->doc(),
|
||||
astObjectType->identifierToken.offset,
|
||||
astObjectType->identifierToken,
|
||||
astNode->lastSourceLocation()));
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user