diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2019-11-29 16:52:16 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2019-12-05 14:28:47 +0100 |
commit | 8fadf5d374936e50b8bce5adb1f10da2f66eac2b (patch) | |
tree | 9fa8808718e47673413980aa4448fe8d11dde0c7 /src/qml/parser/qqmljs.g | |
parent | 79166592d17135309a070065e7cb947ffa293828 (diff) |
qml/parser: Implement nullish coalescing
Implements the '??' operator as specified in https://github.com/tc39/proposal-nullish-coalescing.
Also adds a few tests.
Task-number: QTBUG-77926
Change-Id: I3993450c192d11bf1ade0662d945c1553b4c6976
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/parser/qqmljs.g')
-rw-r--r-- | src/qml/parser/qqmljs.g | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index ea105e7e22..6fbb9df164 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -80,6 +80,7 @@ %token T_COMMENT "comment" %token T_COMPATIBILITY_SEMICOLON %token T_ARROW "=>" +%token T_QUESTION_QUESTION "??" %token T_ENUM "enum" %token T_ELLIPSIS "..." %token T_YIELD "yield" @@ -2638,13 +2639,48 @@ LogicalORExpression_In: LogicalORExpression_In T_OR_OR LogicalANDExpression_In; } break; ./ +CoalesceExpression: LogicalORExpression; +CoalesceExpression_In: LogicalORExpression_In; -ConditionalExpression: LogicalORExpression; -ConditionalExpression_In: LogicalORExpression_In; +CoalesceExpression: CoalesceExpression T_QUESTION_QUESTION LogicalORExpression; +/. case $rule_number: Q_FALLTHROUGH(); ./ +CoalesceExpression_In: CoalesceExpression_In T_QUESTION_QUESTION LogicalORExpression_In; +/. + case $rule_number: { + + auto *lhs = sym(1).Expression; + auto *rhs = sym(3).Expression; + + // Check if lhs or rhs contain || or && + + if (lhs->binaryExpressionCast() != nullptr) { + auto *binaryExpr = lhs->binaryExpressionCast(); + if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) { + syntaxError(binaryExpr->operatorToken, "Left-hand side may not contain || or &&"); + return false; + } + } + + if (rhs->binaryExpressionCast() != nullptr) { + auto *binaryExpr = rhs->binaryExpressionCast(); + if (binaryExpr->op == QSOperator::And || binaryExpr->op == QSOperator::Or) { + syntaxError(binaryExpr->operatorToken, "Right-hand side may not contain || or &&"); + return false; + } + } + + AST::BinaryExpression *node = new (pool) AST::BinaryExpression(lhs, QSOperator::Coalesce, rhs); + node->operatorToken = loc(2); + sym(1).Node = node; + } break; +./ + +ConditionalExpression: CoalesceExpression; +ConditionalExpression_In: CoalesceExpression_In; -ConditionalExpression: LogicalORExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression; +ConditionalExpression: CoalesceExpression T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression; /. case $rule_number: Q_FALLTHROUGH(); ./ -ConditionalExpression_In: LogicalORExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In; +ConditionalExpression_In: CoalesceExpression_In T_QUESTION AssignmentExpression_In T_COLON AssignmentExpression_In; /. case $rule_number: { AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); |