diff options
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 4 | ||||
-rw-r--r-- | src/qml/parser/qqmljs.g | 14 | ||||
-rw-r--r-- | src/qml/parser/qqmljsast_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qml/qqmlparser/tst_qqmlparser.cpp | 42 |
4 files changed, 60 insertions, 1 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index c43ea64e2e..fff6a2fe4c 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1497,7 +1497,9 @@ bool Codegen::visit(BinaryExpression *ast) break; } - + case QSOperator::As: + setExprResult(left); + break; } // switch return false; diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index f7b528ce13..ea105e7e22 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -2513,6 +2513,20 @@ RelationalExpression_In: RelationalExpression_In T_IN ShiftExpression; } break; ./ +TypeAssertExpression_In: RelationalExpression_In T_AS Type; +/. case $rule_number: Q_FALLTHROUGH(); ./ +TypeAssertExpression: RelationalExpression T_AS Type; +/. + case $rule_number: { + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::As, sym(3).Expression); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; +./ + +RelationalExpression_In: TypeAssertExpression_In; +RelationalExpression: TypeAssertExpression; + EqualityExpression_In: RelationalExpression_In; EqualityExpression: RelationalExpression; diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index fcf9933e67..bc0a467f40 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -104,6 +104,7 @@ enum Op { URShift, InplaceURightShift, InplaceXor, + As, Invalid }; diff --git a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp index 4ba6a709df..76b56bd303 100644 --- a/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp +++ b/tests/auto/qml/qqmlparser/tst_qqmlparser.cpp @@ -63,6 +63,8 @@ private slots: void disallowedTypeAnnotations_data(); void disallowedTypeAnnotations(); void semicolonPartOfExpressionStatement(); + void typeAssertion_data(); + void typeAssertion(); private: QStringList excludedDirs; @@ -479,6 +481,46 @@ void tst_qqmlparser::semicolonPartOfExpressionStatement() QVERIFY(observer.endsWithSemicolon); } +void tst_qqmlparser::typeAssertion_data() +{ + QTest::addColumn<QString>("expression"); + QTest::addRow("as A") + << QString::fromLatin1("A { onStuff: (b as A).happen() }"); + QTest::addRow("as double paren") + << QString::fromLatin1("A { onStuff: console.log((12 as double)); }"); + QTest::addRow("as double noparen") + << QString::fromLatin1("A { onStuff: console.log(12 as double); }"); + QTest::addRow("property as double") + << QString::fromLatin1("A { prop: (12 as double); }"); + QTest::addRow("property noparen as double") + << QString::fromLatin1("A { prop: 12 as double; }"); + + // rabbits cannot be discerned from types on a syntactical level. + // We could detect this on a semantical level, once we implement type assertions there. + + QTest::addRow("as rabbit") + << QString::fromLatin1("A { onStuff: (b as rabbit).happen() }"); + QTest::addRow("as rabbit paren") + << QString::fromLatin1("A { onStuff: console.log((12 as rabbit)); }"); + QTest::addRow("as rabbit noparen") + << QString::fromLatin1("A { onStuff: console.log(12 as rabbit); }"); + QTest::addRow("property as rabbit") + << QString::fromLatin1("A { prop: (12 as rabbit); }"); + QTest::addRow("property noparen as rabbit") + << QString::fromLatin1("A { prop: 12 as rabbit; }"); +} + +void tst_qqmlparser::typeAssertion() +{ + QFETCH(QString, expression); + + QQmlJS::Engine engine; + QQmlJS::Lexer lexer(&engine); + lexer.setCode(expression, 1); + QQmlJS::Parser parser(&engine); + QVERIFY(parser.parse()); +} + QTEST_MAIN(tst_qqmlparser) #include "tst_qqmlparser.moc" |