diff --git a/src/libs/qmljs/parser/cmd.sed b/src/libs/qmljs/parser/cmd.sed index fd76d634419d48063b2ff726048712bf0f0dbbe8..d76372675dca1b34b1fbadd7f98775938148824b 100644 --- a/src/libs/qmljs/parser/cmd.sed +++ b/src/libs/qmljs/parser/cmd.sed @@ -1,3 +1,4 @@ +s/private\/qdeclarative/qml/g s/qdeclarative/qml/g s/QDECLARATIVE/QML/g s/QDeclarative/Qml/g diff --git a/src/libs/qmljs/parser/qmldirparser.cpp b/src/libs/qmljs/parser/qmldirparser.cpp index 86ca9f6a60a231173713ecab3a61dfab099eeb63..6f2576f58b52cd2a6922c2c903d409cbe0055f95 100644 --- a/src/libs/qmljs/parser/qmldirparser.cpp +++ b/src/libs/qmljs/parser/qmldirparser.cpp @@ -170,10 +170,9 @@ bool QmlDirParser::parse() const int dotIndex = version.indexOf(QLatin1Char('.')); if (dotIndex == -1) { - qWarning() << "expected '.'"; // ### use reportError + reportError(lineNumber, -1, QLatin1String("expected '.'")); } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) { - qWarning() << "unexpected '.'"; // ### use reportError - + reportError(lineNumber, -1, QLatin1String("unexpected '.'")); } else { bool validVersionNumber = false; const int majorVersion = version.left(dotIndex).toInt(&validVersionNumber); @@ -189,8 +188,8 @@ bool QmlDirParser::parse() } } } else { - // ### use reportError - qWarning() << "a component declaration requires 3 arguments, but" << (sectionCount + 1) << "were provided"; + reportError(lineNumber, -1, + QString::fromUtf8("a component declaration requires 3 arguments, but %1 were provided").arg(sectionCount + 1)); } } diff --git a/src/libs/qmljs/parser/qmlerror.cpp b/src/libs/qmljs/parser/qmlerror.cpp index fc4bcd512ac26e5f07da339d0e76aed3531251c3..d5363ab39745aed4ccdd997dad3edb37aad2b8b5 100644 --- a/src/libs/qmljs/parser/qmlerror.cpp +++ b/src/libs/qmljs/parser/qmlerror.cpp @@ -49,8 +49,27 @@ QT_BEGIN_NAMESPACE /*! \class QmlError - \since 4.7 - \brief The QmlError class encapsulates a QML error + \since 4.7 + \brief The QmlError class encapsulates a QML error. + + QmlError includes a textual description of the error, as well + as location information (the file, line, and column). The toString() + method creates a single-line, human-readable string containing all of + this information, for example: + \code + 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 + and include additional contextual information. + \code + file:///home/user/test.qml:7:8: Invalid property assignment: double expected + y: "hello" + ^ + \endcode + + \sa QmlView::errors(), QmlComponent::errors() */ class QmlErrorPrivate { @@ -69,7 +88,7 @@ QmlErrorPrivate::QmlErrorPrivate() } /*! - Create an empty error object. + Creates an empty error object. */ QmlError::QmlError() : d(0) @@ -77,7 +96,7 @@ QmlError::QmlError() } /*! - Create a copy of \a other. + Creates a copy of \a other. */ QmlError::QmlError(const QmlError &other) : d(0) @@ -86,7 +105,7 @@ QmlError::QmlError(const QmlError &other) } /*! - Assign \a other to this error object. + Assigns \a other to this error object. */ QmlError &QmlError::operator=(const QmlError &other) { @@ -112,7 +131,7 @@ QmlError::~QmlError() } /*! - Return true if this error is valid, otherwise false. + Returns true if this error is valid, otherwise false. */ bool QmlError::isValid() const { @@ -120,7 +139,7 @@ bool QmlError::isValid() const } /*! - Return the url for the file that caused this error. + Returns the url for the file that caused this error. */ QUrl QmlError::url() const { @@ -129,7 +148,7 @@ QUrl QmlError::url() const } /*! - Set the \a url for the file that caused this error. + Sets the \a url for the file that caused this error. */ void QmlError::setUrl(const QUrl &url) { @@ -138,7 +157,7 @@ void QmlError::setUrl(const QUrl &url) } /*! - Return the error description. + Returns the error description. */ QString QmlError::description() const { @@ -147,7 +166,7 @@ QString QmlError::description() const } /*! - Set the error \a description. + Sets the error \a description. */ void QmlError::setDescription(const QString &description) { @@ -156,7 +175,7 @@ void QmlError::setDescription(const QString &description) } /*! - Return the error line number. + Returns the error line number. */ int QmlError::line() const { @@ -165,7 +184,7 @@ int QmlError::line() const } /*! - Set the error \a line number. + Sets the error \a line number. */ void QmlError::setLine(int line) { @@ -174,7 +193,7 @@ void QmlError::setLine(int line) } /*! - Return the error column number. + Returns the error column number. */ int QmlError::column() const { @@ -183,7 +202,7 @@ int QmlError::column() const } /*! - Set the error \a column number. + Sets the error \a column number. */ void QmlError::setColumn(int column) { @@ -192,14 +211,20 @@ void QmlError::setColumn(int column) } /*! - Return the error as a human readable string. + Returns the error as a human readable string. */ QString QmlError::toString() const { QString rv; - rv = url().toString() + QLatin1Char(':') + QString::number(line()); - if(column() != -1) - rv += QLatin1Char(':') + QString::number(column()); + if (url().isEmpty()) { + rv = QLatin1String("<Unknown File>"); + } else if (line() != -1) { + rv = url().toString() + QLatin1Char(':') + QString::number(line()); + if(column() != -1) + rv += QLatin1Char(':') + QString::number(column()); + } else { + rv = url().toString(); + } rv += QLatin1String(": ") + description(); @@ -210,7 +235,7 @@ QString QmlError::toString() const \relates QmlError \fn QDebug operator<<(QDebug debug, const QmlError &error) - Output a human readable version of \a error to \a debug. + Outputs a human readable version of \a error to \a debug. */ QDebug operator<<(QDebug debug, const QmlError &error) @@ -225,7 +250,9 @@ QDebug operator<<(QDebug debug, const QmlError &error) if (f.open(QIODevice::ReadOnly)) { QByteArray data = f.readAll(); QTextStream stream(data, QIODevice::ReadOnly); +#ifndef QT_NO_TEXTCODEC stream.setCodec("UTF-8"); +#endif const QString code = stream.readAll(); const QStringList lines = code.split(QLatin1Char('\n')); diff --git a/src/libs/qmljs/parser/qmljs.g b/src/libs/qmljs/parser/qmljs.g index 86ddd6a29404a9eccee77a79bc111af974f68aa7..ee3ff565731c4500f3ea6fda860d70b6f185b632 100644 --- a/src/libs/qmljs/parser/qmljs.g +++ b/src/libs/qmljs/parser/qmljs.g @@ -1376,7 +1376,7 @@ case $rule_number: { } break; ./ -PropertyName: T_IDENTIFIER %prec REDUCE_HERE ; +PropertyName: T_IDENTIFIER %prec SHIFT_THERE ; /. case $rule_number: { AST::IdentifierPropertyName *node = makeAstNode<AST::IdentifierPropertyName> (driver->nodePool(), sym(1).sval); diff --git a/src/libs/qmljs/parser/qmljsast_p.h b/src/libs/qmljs/parser/qmljsast_p.h index 7bab8f80f6462e27acc7bdb84c2bd1694b8909ef..e6570eaf22cc2b8155ce4bd01ee6828dc4ddfc5e 100644 --- a/src/libs/qmljs/parser/qmljsast_p.h +++ b/src/libs/qmljs/parser/qmljsast_p.h @@ -224,6 +224,9 @@ public: inline Node() : kind(Kind_Undefined) {} + // NOTE: node destructors are never called, + // instead we block free the memory + // (see the NodePool class) virtual ~Node() {} virtual ExpressionNode *expressionCast(); @@ -247,7 +250,6 @@ class QML_PARSER_EXPORT ExpressionNode: public Node { public: ExpressionNode() {} - virtual ~ExpressionNode() {} virtual ExpressionNode *expressionCast(); @@ -259,7 +261,6 @@ class QML_PARSER_EXPORT Statement: public Node { public: Statement() {} - virtual ~Statement() {} virtual Statement *statementCast(); @@ -272,7 +273,7 @@ class QML_PARSER_EXPORT UiFormal: public Node public: QMLJS_DECLARE_AST_NODE(UiFormal) - explicit UiFormal(NameId *name, NameId *alias = 0) + UiFormal(NameId *name, NameId *alias = 0) : name(name), alias(alias) { } @@ -379,7 +380,6 @@ public: QMLJS_DECLARE_AST_NODE(ThisExpression) ThisExpression() { kind = K; } - virtual ~ThisExpression() {} virtual void accept0(Visitor *visitor); @@ -401,8 +401,6 @@ public: IdentifierExpression(NameId *n): name (n) { kind = K; } - virtual ~IdentifierExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -422,7 +420,6 @@ public: QMLJS_DECLARE_AST_NODE(NullExpression) NullExpression() { kind = K; } - virtual ~NullExpression() {} virtual void accept0(Visitor *visitor); @@ -442,7 +439,6 @@ public: QMLJS_DECLARE_AST_NODE(TrueLiteral) TrueLiteral() { kind = K; } - virtual ~TrueLiteral() {} virtual void accept0(Visitor *visitor); @@ -462,7 +458,6 @@ public: QMLJS_DECLARE_AST_NODE(FalseLiteral) FalseLiteral() { kind = K; } - virtual ~FalseLiteral() {} virtual void accept0(Visitor *visitor); @@ -483,7 +478,6 @@ public: NumericLiteral(double v): value(v) { kind = K; } - virtual ~NumericLiteral() {} virtual void accept0(Visitor *visitor); @@ -506,8 +500,6 @@ public: StringLiteral(NameId *v): value (v) { kind = K; } - virtual ~StringLiteral() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -529,8 +521,6 @@ public: RegExpLiteral(NameId *p, int f): pattern (p), flags (f) { kind = K; } - virtual ~RegExpLiteral() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -562,8 +552,6 @@ public: elements (elts), elision (e) { kind = K; } - virtual ~ArrayLiteral() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -591,8 +579,6 @@ public: ObjectLiteral(PropertyNameAndValueList *plist): properties (plist) { kind = K; } - virtual ~ObjectLiteral() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -624,8 +610,6 @@ public: previous->next = this; } - virtual ~ElementList() {} - inline ElementList *finish () { ElementList *front = next; @@ -657,8 +641,6 @@ public: previous->next = this; } - virtual ~Elision() {} - virtual void accept0(Visitor *visitor); inline Elision *finish () @@ -690,8 +672,6 @@ public: previous->next = this; } - virtual ~PropertyNameAndValueList() {} - virtual void accept0(Visitor *visitor); inline PropertyNameAndValueList *finish () @@ -715,7 +695,6 @@ public: QMLJS_DECLARE_AST_NODE(PropertyName) PropertyName() { kind = K; } - virtual ~PropertyName() {} // attributes SourceLocation propertyNameToken; @@ -729,8 +708,6 @@ public: IdentifierPropertyName(NameId *n): id (n) { kind = K; } - virtual ~IdentifierPropertyName() {} - virtual void accept0(Visitor *visitor); // attributes @@ -744,7 +721,6 @@ public: StringLiteralPropertyName(NameId *n): id (n) { kind = K; } - virtual ~StringLiteralPropertyName() {} virtual void accept0(Visitor *visitor); @@ -759,7 +735,6 @@ public: NumericLiteralPropertyName(double n): id (n) { kind = K; } - virtual ~NumericLiteralPropertyName() {} virtual void accept0(Visitor *visitor); @@ -776,8 +751,6 @@ public: base (b), expression (e) { kind = K; } - virtual ~ArrayMemberExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -802,8 +775,6 @@ public: base (b), name (n) { kind = K; } - virtual ~FieldMemberExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -828,8 +799,6 @@ public: base (b), arguments (a) { kind = K; } - virtual ~NewMemberExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -854,8 +823,6 @@ public: NewExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~NewExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -878,8 +845,6 @@ public: base (b), arguments (a) { kind = K; } - virtual ~CallExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -912,8 +877,6 @@ public: previous->next = this; } - virtual ~ArgumentList() {} - virtual void accept0(Visitor *visitor); inline ArgumentList *finish () @@ -937,8 +900,6 @@ public: PostIncrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual ~PostIncrementExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -960,8 +921,6 @@ public: PostDecrementExpression(ExpressionNode *b): base (b) { kind = K; } - virtual ~PostDecrementExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -982,7 +941,6 @@ public: DeleteExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~DeleteExpression() {} virtual void accept0(Visitor *visitor); @@ -1005,8 +963,6 @@ public: VoidExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~VoidExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1028,8 +984,6 @@ public: TypeOfExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~TypeOfExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1051,8 +1005,6 @@ public: PreIncrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~PreIncrementExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1074,8 +1026,6 @@ public: PreDecrementExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~PreDecrementExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1097,8 +1047,6 @@ public: UnaryPlusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~UnaryPlusExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1120,8 +1068,6 @@ public: UnaryMinusExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~UnaryMinusExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1143,8 +1089,6 @@ public: TildeExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~TildeExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1166,8 +1110,6 @@ public: NotExpression(ExpressionNode *e): expression (e) { kind = K; } - virtual ~NotExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1190,8 +1132,6 @@ public: left (l), op (o), right (r) { kind = K; } - virtual ~BinaryExpression() {} - virtual BinaryExpression *binaryExpressionCast(); virtual void accept0(Visitor *visitor); @@ -1218,8 +1158,6 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual ~ConditionalExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1244,8 +1182,6 @@ public: Expression(ExpressionNode *l, ExpressionNode *r): left (l), right (r) { kind = K; } - virtual ~Expression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1268,8 +1204,6 @@ public: Block(StatementList *slist): statements (slist) { kind = K; } - virtual ~Block() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1301,8 +1235,6 @@ public: previous->next = this; } - virtual ~StatementList() {} - virtual void accept0(Visitor *visitor); inline StatementList *finish () @@ -1326,8 +1258,6 @@ public: declarations (vlist) { kind = K; } - virtual ~VariableStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1351,8 +1281,6 @@ public: name (n), expression (e), readOnly(false) { kind = K; } - virtual ~VariableDeclaration() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1379,8 +1307,6 @@ public: previous->next = this; } - virtual ~VariableDeclarationList() {} - virtual void accept0(Visitor *visitor); inline VariableDeclarationList *finish (bool readOnly) @@ -1407,7 +1333,6 @@ public: QMLJS_DECLARE_AST_NODE(EmptyStatement) EmptyStatement() { kind = K; } - virtual ~EmptyStatement() {} virtual void accept0(Visitor *visitor); @@ -1429,8 +1354,6 @@ public: ExpressionStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual ~ExpressionStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1453,8 +1376,6 @@ public: expression (e), ok (t), ko (f) { kind = K; } - virtual ~IfStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1487,8 +1408,6 @@ public: statement (stmt), expression (e) { kind = K; } - virtual ~DoWhileStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1516,8 +1435,6 @@ public: expression (e), statement (stmt) { kind = K; } - virtual ~WhileStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1543,8 +1460,6 @@ public: initialiser (i), condition (c), expression (e), statement (stmt) { kind = K; } - virtual ~ForStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1574,8 +1489,6 @@ public: declarations (vlist), condition (c), expression (e), statement (stmt) { kind = K; } - virtual ~LocalForStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1606,8 +1519,6 @@ public: initialiser (i), expression (e), statement (stmt) { kind = K; } - virtual ~ForEachStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1635,8 +1546,6 @@ public: declaration (v), expression (e), statement (stmt) { kind = K; } - virtual ~LocalForEachStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1664,8 +1573,6 @@ public: ContinueStatement(NameId *l = 0): label (l) { kind = K; } - virtual ~ContinueStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1689,8 +1596,6 @@ public: BreakStatement(NameId *l = 0): label (l) { kind = K; } - virtual ~BreakStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1714,8 +1619,6 @@ public: ReturnStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual ~ReturnStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1739,8 +1642,6 @@ public: expression (e), statement (stmt) { kind = K; } - virtual ~WithStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1762,12 +1663,10 @@ class QML_PARSER_EXPORT CaseBlock: public Node public: QMLJS_DECLARE_AST_NODE(CaseBlock) - explicit CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0): + CaseBlock(CaseClauses *c, DefaultClause *d = 0, CaseClauses *r = 0): clauses (c), defaultClause (d), moreClauses (r) { kind = K; } - virtual ~CaseBlock() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1787,8 +1686,6 @@ public: expression (e), block (b) { kind = K; } - virtual ~SwitchStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1822,8 +1719,6 @@ public: previous->next = this; } - virtual ~CaseClauses() {} - virtual void accept0(Visitor *visitor); inline CaseClauses *finish () @@ -1847,8 +1742,6 @@ public: expression (e), statements (slist) { kind = K; } - virtual ~CaseClause() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1867,8 +1760,6 @@ public: statements (slist) { kind = K; } - virtual ~DefaultClause() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1886,8 +1777,6 @@ public: label (l), statement (stmt) { kind = K; } - virtual ~LabelledStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1911,8 +1800,6 @@ public: ThrowStatement(ExpressionNode *e): expression (e) { kind = K; } - virtual ~ThrowStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -1936,8 +1823,6 @@ public: name (n), statement (stmt) { kind = K; } - virtual ~Catch() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1958,8 +1843,6 @@ public: statement (stmt) { kind = K; } - virtual ~Finally() {} - virtual void accept0(Visitor *visitor); // attributes @@ -1984,8 +1867,6 @@ public: statement (stmt), catchExpression (c), finallyExpression (0) { kind = K; } - virtual ~TryStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -2017,8 +1898,6 @@ public: name (n), formals (f), body (b) { kind = K; } - virtual ~FunctionExpression() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -2048,8 +1927,6 @@ public: FunctionExpression(n, f, b) { kind = K; } - virtual ~FunctionDeclaration() {} - virtual void accept0(Visitor *visitor); }; @@ -2070,8 +1947,6 @@ public: previous->next = this; } - virtual ~FormalParameterList() {} - virtual void accept0(Visitor *visitor); inline FormalParameterList *finish () @@ -2097,8 +1972,6 @@ public: elements (elts) { kind = K; } - virtual ~FunctionBody() {} - virtual void accept0(Visitor *visitor); // attributes @@ -2114,8 +1987,6 @@ public: elements (elts) { kind = K; } - virtual ~Program() {} - virtual void accept0(Visitor *visitor); // attributes @@ -2139,8 +2010,6 @@ public: previous->next = this; } - virtual ~SourceElements() {} - virtual void accept0(Visitor *visitor); inline SourceElements *finish () @@ -2162,8 +2031,6 @@ public: inline SourceElement() { kind = K; } - - virtual ~SourceElement() {} }; class QML_PARSER_EXPORT FunctionSourceElement: public SourceElement @@ -2175,8 +2042,6 @@ public: declaration (f) { kind = K; } - virtual ~FunctionSourceElement() {} - virtual void accept0(Visitor *visitor); // attributes @@ -2192,8 +2057,6 @@ public: statement (stmt) { kind = K; } - virtual ~StatementSourceElement() {} - virtual void accept0(Visitor *visitor); // attributes @@ -2208,8 +2071,6 @@ public: DebuggerStatement() { kind = K; } - virtual ~DebuggerStatement() {} - virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const @@ -2256,8 +2117,6 @@ public: previous->next = this; } - virtual ~UiQualifiedId() {} - UiQualifiedId *finish() { UiQualifiedId *head = next; @@ -2459,8 +2318,6 @@ public: previous->next = this; } - virtual ~UiParameterList() {} - virtual void accept0(Visitor *) {} inline UiParameterList *finish () diff --git a/src/libs/qmljs/parser/qmljsastfwd_p.h b/src/libs/qmljs/parser/qmljsastfwd_p.h index 371739177cc011f2069e96bb76d3b67899a23129..2c42fd9d8963e880194e369424b7c52d5cfab6a2 100644 --- a/src/libs/qmljs/parser/qmljsastfwd_p.h +++ b/src/libs/qmljs/parser/qmljsastfwd_p.h @@ -64,7 +64,7 @@ namespace QmlJS { namespace AST { class SourceLocation { public: - explicit SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) + SourceLocation(quint32 offset = 0, quint32 length = 0, quint32 line = 0, quint32 column = 0) : offset(offset), length(length), startLine(line), startColumn(column) { } diff --git a/src/libs/qmljs/parser/qmljsgrammar.cpp b/src/libs/qmljs/parser/qmljsgrammar.cpp index d50454858b81b147547dd23d29018bb6afb3ff57..a0d026b97e61bd650c344f23926715305f1a6c31 100644 --- a/src/libs/qmljs/parser/qmljsgrammar.cpp +++ b/src/libs/qmljs/parser/qmljsgrammar.cpp @@ -346,9 +346,9 @@ const short QmlJSGrammar::action_index [] = { const short QmlJSGrammar::action_info [] = { 399, 352, 345, -101, 343, 457, 440, 403, 257, -112, - -125, -131, -123, -98, -120, 348, -128, 389, 453, 391, + -125, -131, -123, 346, -120, 348, -128, 389, 453, 391, 416, 401, 408, 563, -101, -123, 416, -120, 539, -131, - -98, -112, -125, 348, 257, 99, 71, 645, 621, 101, + 346, -112, -125, 348, 257, 99, 71, 645, 621, 101, -128, 440, 141, 621, 164, 431, 539, 430, 453, 573, 457, 444, 440, 424, 71, 424, 101, 446, 559, 420, 424, 448, 539, 440, 570, 539, 466, 527, 312, 346, diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp index 0677dd12538600c4c0de30cbcb1b2eecda8b7849..acbc0c214f95970722dc04750a0cb262b5dd070f 100644 --- a/src/libs/qmljs/parser/qmljslexer.cpp +++ b/src/libs/qmljs/parser/qmljslexer.cpp @@ -57,7 +57,7 @@ #include <string.h> QT_BEGIN_NAMESPACE -extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); QT_END_NAMESPACE QT_QML_BEGIN_NAMESPACE @@ -103,7 +103,7 @@ Lexer::Lexer(Engine *eng, bool tokenizeComments) prohibitAutomaticSemicolon(false), tokenizeComments(tokenizeComments) { - driver->setLexer(this); + if (driver) driver->setLexer(this); // allocate space for read buffers buffer8 = new char[size8]; buffer16 = new QChar[size16]; @@ -120,7 +120,7 @@ Lexer::~Lexer() void Lexer::setCode(const QString &c, int lineno) { - errmsg = QString(); + errmsg.clear(); yylineno = lineno; yycolumn = 1; restrKeyword = false; @@ -484,6 +484,8 @@ int Lexer::lex() stackToken = -1; } + bool identifierWithEscapedUnicode = false; + while (!done) { switch (state) { case Start: @@ -508,22 +510,44 @@ int Lexer::lex() setDone(Eof); } } else if (isLineTerminator()) { - shiftWindowsLineBreak(); - yylineno++; - yycolumn = 0; - bol = true; - terminator = true; - syncProhibitAutomaticSemicolon(); if (restrKeyword) { + // automatic semicolon insertion + recordStartPos(); token = QmlJSGrammar::T_SEMICOLON; setDone(Other); + } else { + shiftWindowsLineBreak(); + yylineno++; + yycolumn = 0; + bol = true; + terminator = true; + syncProhibitAutomaticSemicolon(); } } else if (current == '"' || current == '\'') { recordStartPos(); state = InString; multiLineString = false; stringType = current; + } else if (current == '\\' && next1 == 'u') { + identifierWithEscapedUnicode = true; + recordStartPos(); + + shift(2); // skip the unicode escape prefix `\u' + + if (isHexDigit(current) && isHexDigit(next1) && + isHexDigit(next2) && isHexDigit(next3)) { + record16(convertUnicode(current, next1, next2, next3)); + shift(3); + state = InIdentifier; + } else { + setDone(Bad); + err = IllegalUnicodeEscapeSequence; + errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence"); + break; + } + } else if (isIdentLetter(current)) { + identifierWithEscapedUnicode = false; recordStartPos(); record16(current); state = InIdentifier; @@ -656,9 +680,9 @@ int Lexer::lex() setDone(Other); } else state = Start; - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2); } else if (current == 0) { - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2); setDone(Eof); } @@ -668,14 +692,14 @@ int Lexer::lex() setDone(Bad); err = UnclosedComment; errmsg = QCoreApplication::translate("QmlParser", "Unclosed comment at end of file"); - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos+2, tokenLength()-2, startlineno, startcolumn+2); } else if (isLineTerminator()) { shiftWindowsLineBreak(); yylineno++; } else if (current == '*' && next1 == '/') { state = Start; shift(1); - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos+2, tokenLength()-3, startlineno, startcolumn+2); } break; @@ -683,6 +707,21 @@ int Lexer::lex() if (isIdentLetter(current) || isDecimalDigit(current)) { record16(current); break; + } else if (current == '\\' && next1 == 'u') { + identifierWithEscapedUnicode = true; + shift(2); // skip the unicode escape prefix `\u' + + if (isHexDigit(current) && isHexDigit(next1) && + isHexDigit(next2) && isHexDigit(next3)) { + record16(convertUnicode(current, next1, next2, next3)); + shift(3); + break; + } else { + setDone(Bad); + err = IllegalUnicodeEscapeSequence; + errmsg = QCoreApplication::translate("QmlParser", "Illegal unicode escape sequence"); + break; + } } setDone(Identifier); break; @@ -825,7 +864,11 @@ int Lexer::lex() delimited = true; return token; case Identifier: - if ((token = findReservedWord(buffer16, pos16)) < 0) { + token = -1; + if (! identifierWithEscapedUnicode) + token = findReservedWord(buffer16, pos16); + + if (token < 0) { /* TODO: close leak on parse error. same holds true for String */ if (driver) qsyylval.ustr = driver->intern(buffer16, pos16); @@ -1104,47 +1147,97 @@ void Lexer::recordStartPos() bool Lexer::scanRegExp(RegExpBodyPrefix prefix) { pos16 = 0; - bool lastWasEscape = false; + pattern = 0; if (prefix == EqualPrefix) record16(QLatin1Char('=')); - while (1) { - if (isLineTerminator() || current == 0) { + while (true) { + switch (current) { + + case 0: // eof + case '\n': case '\r': // line terminator errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression literal"); return false; - } - else if (current != '/' || lastWasEscape == true) - { - record16(current); - lastWasEscape = !lastWasEscape && (current == '\\'); - } - else { - if (driver) + + case '/': + shift(1); + + if (driver) // create the pattern pattern = driver->intern(buffer16, pos16); - else - pattern = 0; + + // scan the flags pos16 = 0; + flags = 0; + while (isIdentLetter(current)) { + int flag = Ecma::RegExp::flagFromChar(current); + if (flag == 0) { + errmsg = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'") + .arg(QChar(current)); + return false; + } + flags |= flag; + record16(current); + shift(1); + } + return true; + + case '\\': + // regular expression backslash sequence + record16(current); + shift(1); + + if (! current || isLineTerminator()) { + errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence"); + return false; + } + + record16(current); shift(1); break; - } - shift(1); - } - flags = 0; - while (isIdentLetter(current)) { - int flag = Ecma::RegExp::flagFromChar(current); - if (flag == 0) { - errmsg = QCoreApplication::translate("QmlParser", "Invalid regular expression flag '%0'") - .arg(QChar(current)); - return false; - } - flags |= flag; - record16(current); - shift(1); - } + case '[': + // regular expression class + record16(current); + shift(1); + + while (current && ! isLineTerminator()) { + if (current == ']') + break; + else if (current == '\\') { + // regular expression backslash sequence + record16(current); + shift(1); + + if (! current || isLineTerminator()) { + errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression backslash sequence"); + return false; + } + + record16(current); + shift(1); + } else { + record16(current); + shift(1); + } + } + + if (current != ']') { + errmsg = QCoreApplication::translate("QmlParser", "Unterminated regular expression class"); + return false; + } + + record16(current); + shift(1); // skip ] + break; + + default: + record16(current); + shift(1); + } // switch + } // while - return true; + return false; } void Lexer::syncProhibitAutomaticSemicolon() diff --git a/src/libs/qmljs/parser/qmljslexer_p.h b/src/libs/qmljs/parser/qmljslexer_p.h index cf731c7bdb6dfe6ba614c9f05391e7fc7f6a8bd3..8f95a904f44561b259e844b1df90c51606ba53fc 100644 --- a/src/libs/qmljs/parser/qmljslexer_p.h +++ b/src/libs/qmljs/parser/qmljslexer_p.h @@ -67,7 +67,7 @@ class NameId; class QML_PARSER_EXPORT Lexer { public: - explicit Lexer(Engine *eng, bool tokenizeComments = false); + Lexer(Engine *eng, bool tokenizeComments = false); ~Lexer(); void setCode(const QString &c, int lineno);