Fix semicolon insertion before pre-incr/decr operators.
authorErik Verbruggen <erik.verbruggen@digia.com>
Thu, 20 Dec 2012 09:31:46 +0000 (10:31 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Tue, 8 Jan 2013 14:12:17 +0000 (15:12 +0100)
Do not insert a semicolon if the previous token was a binop or a
question mark.

Change-Id: Id2ee1d3cb57fa3fe20bfc0078d06f9e2619d88f1
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/parser/qqmljslexer.cpp
tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon2.qml [new file with mode: 0644]
tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp

index 532826f..f31140a 100644 (file)
@@ -179,6 +179,55 @@ void Lexer::scanChar()
     }
 }
 
+namespace {
+inline bool isBinop(int tok)
+{
+    switch (tok) {
+    case Lexer::T_AND:
+    case Lexer::T_AND_AND:
+    case Lexer::T_AND_EQ:
+    case Lexer::T_DIVIDE_:
+    case Lexer::T_DIVIDE_EQ:
+    case Lexer::T_EQ:
+    case Lexer::T_EQ_EQ:
+    case Lexer::T_EQ_EQ_EQ:
+    case Lexer::T_GE:
+    case Lexer::T_GT:
+    case Lexer::T_GT_GT:
+    case Lexer::T_GT_GT_EQ:
+    case Lexer::T_GT_GT_GT:
+    case Lexer::T_GT_GT_GT_EQ:
+    case Lexer::T_LE:
+    case Lexer::T_LT:
+    case Lexer::T_LT_LT:
+    case Lexer::T_LT_LT_EQ:
+    case Lexer::T_MINUS:
+    case Lexer::T_MINUS_EQ:
+    case Lexer::T_MINUS_MINUS:
+    case Lexer::T_NOT_EQ:
+    case Lexer::T_NOT_EQ_EQ:
+    case Lexer::T_OR:
+    case Lexer::T_OR_EQ:
+    case Lexer::T_OR_OR:
+    case Lexer::T_PLUS:
+    case Lexer::T_PLUS_EQ:
+    case Lexer::T_PLUS_PLUS:
+    case Lexer::T_REMAINDER:
+    case Lexer::T_REMAINDER_EQ:
+    case Lexer::T_RETURN:
+    case Lexer::T_STAR:
+    case Lexer::T_STAR_EQ:
+    case Lexer::T_TILDE:
+    case Lexer::T_XOR:
+    case Lexer::T_XOR_EQ:
+        return true;
+
+    default:
+        return false;
+    }
+}
+} // anonymous namespace
+
 int Lexer::lex()
 {
     const int previousTokenKind = _tokenKind;
@@ -195,9 +244,14 @@ int Lexer::lex()
     switch (_tokenKind) {
     case T_LBRACE:
     case T_SEMICOLON:
+    case T_QUESTION:
     case T_COLON:
         _delimited = true;
         break;
+    default:
+        if (isBinop(_tokenKind))
+            _delimited = true;
+        break;
 
     case T_IF:
     case T_FOR:
diff --git a/tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml b/tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon1.qml
new file mode 100644 (file)
index 0000000..b9a30ef
--- /dev/null
@@ -0,0 +1,47 @@
+import QtQuick 2.0
+
+QtObject {
+
+    // PLEASE NOTE: the function below is whitespace and newline sensitive,
+    //              because that is what the test is all about.
+    //
+    // So: DO NOT REFORMAT THE CODE BELOW!
+
+    function code() {
+var x=0, y=0;
+var z=
+x
++
+++
+y
+
+//////////////////////////////////////////////////////////////////////////////
+if (false) {
+    ;
+}
+//////////////////////////////////////////////////////////////////////////////
+
+z=
+x
++ ++
+y
+
+//////////////////////////////////////////////////////////////////////////////
+if (false) {
+    ;
+}
+//////////////////////////////////////////////////////////////////////////////
+
+z=
+x
++    ++
+y
+
+//////////////////////////////////////////////////////////////////////////////
+if (false) {
+    ;
+}
+
+    }
+}
+
diff --git a/tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon2.qml b/tests/auto/qml/qqmlecmascript/data/incrDecrSemicolon2.qml
new file mode 100644 (file)
index 0000000..717cdb5
--- /dev/null
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+QtObject {
+
+    // PLEASE NOTE: the function below is whitespace and newline sensitive,
+    //              because that is what the test is all about.
+    //
+    // So: DO NOT REFORMAT THE CODE BELOW!
+
+    function code() {
+var a, b, c;
+a=b
+++c
+
+if (a === b) {
+}
+    }
+}
+
index baee100..a1a51d4 100644 (file)
@@ -266,6 +266,8 @@ private slots:
     void deleteLaterObjectMethodCall();
     void automaticSemicolon();
     void compatibilitySemicolon();
+    void incrDecrSemicolon1();
+    void incrDecrSemicolon2();
     void unaryExpression();
     void switchStatement();
     void withStatement();
@@ -6627,6 +6629,20 @@ void tst_qqmlecmascript::compatibilitySemicolon()
     QVERIFY(object != 0);
 }
 
+void tst_qqmlecmascript::incrDecrSemicolon1()
+{
+    QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon1.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+}
+
+void tst_qqmlecmascript::incrDecrSemicolon2()
+{
+    QQmlComponent component(&engine, testFileUrl("incrDecrSemicolon2.qml"));
+    QObject *object = component.create();
+    QVERIFY(object != 0);
+}
+
 void tst_qqmlecmascript::unaryExpression()
 {
     QQmlComponent component(&engine, testFileUrl("unaryExpression.qml"));