| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| import '../src/dart/resolution/node_text_expectations.dart'; |
| import '../src/diagnostics/parser_diagnostics.dart'; |
| |
| main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(NNBDParserTest); |
| defineReflectiveTests(UpdateNodeTextExpectations); |
| }); |
| } |
| |
| @reflectiveTest |
| class NNBDParserTest extends ParserDiagnosticsTest { |
| void test_assignment_complex() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X? x1; |
| X? x2 = x + bar(7); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: X |
| question: ? |
| variables |
| VariableDeclaration |
| name: x1 |
| semicolon: ; |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: X |
| question: ? |
| variables |
| VariableDeclaration |
| name: x2 |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: MethodInvocation |
| methodName: SimpleIdentifier |
| token: bar |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| IntegerLiteral |
| literal: 7 |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_assignment_complex2() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| A? a; |
| String? s = ''; |
| a |
| ?..foo().length |
| ..x27 = s! |
| ..toString().length; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: A |
| question: ? |
| variables |
| VariableDeclaration |
| name: a |
| semicolon: ; |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: String |
| question: ? |
| variables |
| VariableDeclaration |
| name: s |
| equals: = |
| initializer: SimpleStringLiteral |
| literal: '' |
| semicolon: ; |
| ExpressionStatement |
| expression: CascadeExpression |
| target: SimpleIdentifier |
| token: a |
| cascadeSections |
| PropertyAccess |
| target: MethodInvocation |
| operator: ?.. |
| methodName: SimpleIdentifier |
| token: foo |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: . |
| propertyName: SimpleIdentifier |
| token: length |
| AssignmentExpression |
| leftHandSide: PropertyAccess |
| operator: .. |
| propertyName: SimpleIdentifier |
| token: x27 |
| operator: = |
| rightHandSide: PostfixExpression |
| operand: SimpleIdentifier |
| token: s |
| operator: ! |
| PropertyAccess |
| target: MethodInvocation |
| operator: .. |
| methodName: SimpleIdentifier |
| token: toString |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: . |
| propertyName: SimpleIdentifier |
| token: length |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_assignment_simple() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X? x1; |
| X? x2 = x; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: X |
| question: ? |
| variables |
| VariableDeclaration |
| name: x1 |
| semicolon: ; |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: X |
| question: ? |
| variables |
| VariableDeclaration |
| name: x2 |
| equals: = |
| initializer: SimpleIdentifier |
| token: x |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_bangBeforeFunctionCall1() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| Function? f1; |
| f1!(42); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: Function |
| question: ? |
| variables |
| VariableDeclaration |
| name: f1 |
| semicolon: ; |
| ExpressionStatement |
| expression: FunctionExpressionInvocation |
| function: PostfixExpression |
| operand: SimpleIdentifier |
| token: f1 |
| operator: ! |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| IntegerLiteral |
| literal: 42 |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_bangBeforeFunctionCall2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| Function f2; |
| f2!<int>(42); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: NamedType |
| name: Function |
| variables |
| VariableDeclaration |
| name: f2 |
| semicolon: ; |
| ExpressionStatement |
| expression: FunctionExpressionInvocation |
| function: PostfixExpression |
| operand: SimpleIdentifier |
| token: f2 |
| operator: ! |
| typeArguments: TypeArgumentList |
| leftBracket: < |
| arguments |
| NamedType |
| name: int |
| rightBracket: > |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| IntegerLiteral |
| literal: 42 |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_bangQuestionIndex() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(dynamic a) { |
| a!?[0]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: a |
| operator: ! |
| question: ? |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 0 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_binary_expression_statement() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X ?? x2; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: X |
| operator: ?? |
| rightOperand: SimpleIdentifier |
| token: x2 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_cascade_withNullCheck_indexExpression() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| a?..[27]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: CascadeExpression |
| target: SimpleIdentifier |
| token: a |
| cascadeSections |
| IndexExpression |
| period: ?.. |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 27 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_cascade_withNullCheck_invalid() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { a..[27]?..x; } |
| // ^^^ |
| // [diag.nullAwareCascadeOutOfOrder] The '?..' cascade operator must be first in the cascade sequence. |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: CascadeExpression |
| target: SimpleIdentifier |
| token: a |
| cascadeSections |
| IndexExpression |
| period: .. |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 27 |
| rightBracket: ] |
| PropertyAccess |
| operator: ?.. |
| propertyName: SimpleIdentifier |
| token: x |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_cascade_withNullCheck_methodInvocation() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| a?..foo(); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: CascadeExpression |
| target: SimpleIdentifier |
| token: a |
| cascadeSections |
| MethodInvocation |
| operator: ?.. |
| methodName: SimpleIdentifier |
| token: foo |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_cascade_withNullCheck_propertyAccess() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| a?..x27; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: CascadeExpression |
| target: SimpleIdentifier |
| token: a |
| cascadeSections |
| PropertyAccess |
| operator: ?.. |
| propertyName: SimpleIdentifier |
| token: x27 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_conditional() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X ? 7 : y; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: X |
| question: ? |
| thenExpression: IntegerLiteral |
| literal: 7 |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: y |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_conditional_complex() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X ? x2 = x + bar(7) : y; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: X |
| question: ? |
| thenExpression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| token: x2 |
| operator: = |
| rightHandSide: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: MethodInvocation |
| methodName: SimpleIdentifier |
| token: bar |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| IntegerLiteral |
| literal: 7 |
| rightParenthesis: ) |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: y |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_conditional_error() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { X ? ? x2 = x + bar(7) : y; } |
| // ^ |
| // [diag.missingIdentifier] Expected an identifier. |
| // ^ |
| // [diag.expectedToken] Expected to find ':'. |
| // [diag.missingIdentifier] Expected an identifier. |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: X |
| question: ? |
| thenExpression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: <empty> <synthetic> |
| question: ? |
| thenExpression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| token: x2 |
| operator: = |
| rightHandSide: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: MethodInvocation |
| methodName: SimpleIdentifier |
| token: bar |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| IntegerLiteral |
| literal: 7 |
| rightParenthesis: ) |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: y |
| colon: : <synthetic> |
| elseExpression: SimpleIdentifier |
| token: <empty> <synthetic> |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_conditional_simple() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| D? foo(X? x) { |
| X ? x2 = x : y; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: X |
| question: ? |
| thenExpression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| token: x2 |
| operator: = |
| rightHandSide: SimpleIdentifier |
| token: x |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: y |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_for() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| for (int x = 0; x < 7; ++x) {} |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ForStatement |
| forKeyword: for |
| leftParenthesis: ( |
| forLoopParts: ForPartsWithDeclarations |
| variables: VariableDeclarationList |
| type: NamedType |
| name: int |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 0 |
| leftSeparator: ; |
| condition: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: < |
| rightOperand: IntegerLiteral |
| literal: 7 |
| rightSeparator: ; |
| updaters |
| PrefixExpression |
| operator: ++ |
| operand: SimpleIdentifier |
| token: x |
| rightParenthesis: ) |
| body: Block |
| leftBracket: { |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| void test_for_conditional() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| for (x ? y = 7 : y = 8; y < 10; ++y) {} |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ForStatement |
| forKeyword: for |
| leftParenthesis: ( |
| forLoopParts: ForPartsWithExpression |
| initialization: ConditionalExpression |
| condition: SimpleIdentifier |
| token: x |
| question: ? |
| thenExpression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| token: y |
| operator: = |
| rightHandSide: IntegerLiteral |
| literal: 7 |
| colon: : |
| elseExpression: AssignmentExpression |
| leftHandSide: SimpleIdentifier |
| token: y |
| operator: = |
| rightHandSide: IntegerLiteral |
| literal: 8 |
| leftSeparator: ; |
| condition: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: y |
| operator: < |
| rightOperand: IntegerLiteral |
| literal: 10 |
| rightSeparator: ; |
| updaters |
| PrefixExpression |
| operator: ++ |
| operand: SimpleIdentifier |
| token: y |
| rightParenthesis: ) |
| body: Block |
| leftBracket: { |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| void test_for_nullable() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| for (int? x = 0; x < 7; ++x) {} |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ForStatement |
| forKeyword: for |
| leftParenthesis: ( |
| forLoopParts: ForPartsWithDeclarations |
| variables: VariableDeclarationList |
| type: NamedType |
| name: int |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 0 |
| leftSeparator: ; |
| condition: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: < |
| rightOperand: IntegerLiteral |
| literal: 7 |
| rightSeparator: ; |
| updaters |
| PrefixExpression |
| operator: ++ |
| operand: SimpleIdentifier |
| token: x |
| rightParenthesis: ) |
| body: Block |
| leftBracket: { |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| void test_foreach() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| for (int x in [7]) {} |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ForStatement |
| forKeyword: for |
| leftParenthesis: ( |
| forLoopParts: ForEachPartsWithDeclaration |
| loopVariable: DeclaredIdentifier |
| type: NamedType |
| name: int |
| name: x |
| inKeyword: in |
| iterable: ListLiteral |
| leftBracket: [ |
| elements |
| IntegerLiteral |
| literal: 7 |
| rightBracket: ] |
| rightParenthesis: ) |
| body: Block |
| leftBracket: { |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| void test_foreach_nullable() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| for (int? x in [7, null]) {} |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ForStatement |
| forKeyword: for |
| leftParenthesis: ( |
| forLoopParts: ForEachPartsWithDeclaration |
| loopVariable: DeclaredIdentifier |
| type: NamedType |
| name: int |
| question: ? |
| name: x |
| inKeyword: in |
| iterable: ListLiteral |
| leftBracket: [ |
| elements |
| IntegerLiteral |
| literal: 7 |
| NullLiteral |
| literal: null |
| rightBracket: ] |
| rightParenthesis: ) |
| body: Block |
| leftBracket: { |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| test_fuzz_38113() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| +t{{r?this}} |
| // [diag.expectedExecutable][column 1][length 1] Expected a method, getter, setter or operator declaration. |
| // [diag.missingFunctionParameters][column 2][length 1] Functions must have an explicit list of parameters. |
| // ^^^^ |
| // [diag.expectedToken] Expected to find ';'. |
| // ^ |
| // [diag.expectedToken] Expected to find ':'. |
| // [diag.missingIdentifier] Expected an identifier. |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: SimpleIdentifier |
| token: r |
| question: ? |
| thenExpression: ThisExpression |
| thisKeyword: this |
| colon: : <synthetic> |
| elseExpression: SimpleIdentifier |
| token: <empty> <synthetic> |
| semicolon: ; <synthetic> |
| rightBracket: } |
| rightBracket: } |
| '''); |
| } |
| |
| void test_gft_nullable() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| C? Function() x = 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: GenericFunctionType |
| returnType: NamedType |
| name: C |
| question: ? |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_gft_nullable_1() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| C Function()? x = 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: GenericFunctionType |
| returnType: NamedType |
| name: C |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_gft_nullable_2() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| C? Function()? x = 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: GenericFunctionType |
| returnType: NamedType |
| name: C |
| question: ? |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_gft_nullable_3() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| C? Function()? Function()? x = 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: GenericFunctionType |
| returnType: GenericFunctionType |
| returnType: NamedType |
| name: C |
| question: ? |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| question: ? |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_gft_nullable_prefixed() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| C.a? Function()? x = 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| type: GenericFunctionType |
| returnType: NamedType |
| importPrefix: ImportPrefixReference |
| name: C |
| period: . |
| name: a |
| question: ? |
| functionKeyword: Function |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_indexed() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| a[7]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: SimpleIdentifier |
| token: a |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 7 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_indexed_nullAware() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| a?[7]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: SimpleIdentifier |
| token: a |
| question: ? |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 7 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_is_nullable() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| x is String? ? (x + y) : z; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: IsExpression |
| expression: SimpleIdentifier |
| token: x |
| isOperator: is |
| type: NamedType |
| name: String |
| question: ? |
| question: ? |
| thenExpression: ParenthesizedExpression |
| leftParenthesis: ( |
| expression: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: SimpleIdentifier |
| token: y |
| rightParenthesis: ) |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: z |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_is_nullable_parenthesis() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| (x is String?) ? (x + y) : z; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: ConditionalExpression |
| condition: ParenthesizedExpression |
| leftParenthesis: ( |
| expression: IsExpression |
| expression: SimpleIdentifier |
| token: x |
| isOperator: is |
| type: NamedType |
| name: String |
| question: ? |
| rightParenthesis: ) |
| question: ? |
| thenExpression: ParenthesizedExpression |
| leftParenthesis: ( |
| expression: BinaryExpression |
| leftOperand: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: SimpleIdentifier |
| token: y |
| rightParenthesis: ) |
| colon: : |
| elseExpression: SimpleIdentifier |
| token: z |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_late_as_identifier() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| class C { |
| int late; |
| } |
| |
| void f(C c) { |
| print(c.late); |
| } |
| |
| main() { |
| f(new C()); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: MethodInvocation |
| methodName: SimpleIdentifier |
| token: print |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: c |
| period: . |
| identifier: SimpleIdentifier |
| token: late |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_late_as_identifier_optOut() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| // @dart = 2.2 |
| class C { |
| int late; |
| } |
| |
| void f(C c) { |
| print(c.late); |
| } |
| |
| main() { |
| f(new C()); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: MethodInvocation |
| methodName: SimpleIdentifier |
| token: print |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: c |
| period: . |
| identifier: SimpleIdentifier |
| token: late |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullableTypeInInitializerList_01() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| class Foo { |
| String? x; |
| int y; |
| |
| Foo(Object? o) : x = o as String?, y = 0; |
| } |
| '''); |
| var node = parseResult.findNode.unit; |
| assertParsedNodeText(node, r''' |
| CompilationUnit |
| declarations |
| ClassDeclaration |
| classKeyword: class |
| namePart: NameWithTypeParameters |
| typeName: Foo |
| body: BlockClassBody |
| leftBracket: { |
| members |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: String |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| semicolon: ; |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: int |
| variables |
| VariableDeclaration |
| name: y |
| semicolon: ; |
| ConstructorDeclaration |
| typeName: SimpleIdentifier |
| token: Foo |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| parameter: RegularFormalParameter |
| type: NamedType |
| name: Object |
| question: ? |
| name: o |
| rightParenthesis: ) |
| separator: : |
| initializers |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: x |
| equals: = |
| expression: AsExpression |
| expression: SimpleIdentifier |
| token: o |
| asOperator: as |
| type: NamedType |
| name: String |
| question: ? |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: y |
| equals: = |
| expression: IntegerLiteral |
| literal: 0 |
| body: EmptyFunctionBody |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullableTypeInInitializerList_02() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| class Foo { |
| String? x; |
| int y; |
| |
| Foo(Object? o) : y = o is String? ? o.length : null, x = null; |
| } |
| '''); |
| var node = parseResult.findNode.unit; |
| assertParsedNodeText(node, r''' |
| CompilationUnit |
| declarations |
| ClassDeclaration |
| classKeyword: class |
| namePart: NameWithTypeParameters |
| typeName: Foo |
| body: BlockClassBody |
| leftBracket: { |
| members |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: String |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| semicolon: ; |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: int |
| variables |
| VariableDeclaration |
| name: y |
| semicolon: ; |
| ConstructorDeclaration |
| typeName: SimpleIdentifier |
| token: Foo |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| parameter: RegularFormalParameter |
| type: NamedType |
| name: Object |
| question: ? |
| name: o |
| rightParenthesis: ) |
| separator: : |
| initializers |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: y |
| equals: = |
| expression: ConditionalExpression |
| condition: IsExpression |
| expression: SimpleIdentifier |
| token: o |
| isOperator: is |
| type: NamedType |
| name: String |
| question: ? |
| question: ? |
| thenExpression: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: o |
| period: . |
| identifier: SimpleIdentifier |
| token: length |
| colon: : |
| elseExpression: NullLiteral |
| literal: null |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: x |
| equals: = |
| expression: NullLiteral |
| literal: null |
| body: EmptyFunctionBody |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullableTypeInInitializerList_03() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| class Foo { |
| String? x; |
| int y; |
| |
| Foo(Object? o) : y = o is String ? o.length : null, x = null; |
| } |
| '''); |
| var node = parseResult.findNode.unit; |
| assertParsedNodeText(node, r''' |
| CompilationUnit |
| declarations |
| ClassDeclaration |
| classKeyword: class |
| namePart: NameWithTypeParameters |
| typeName: Foo |
| body: BlockClassBody |
| leftBracket: { |
| members |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: String |
| question: ? |
| variables |
| VariableDeclaration |
| name: x |
| semicolon: ; |
| FieldDeclaration |
| fields: VariableDeclarationList |
| type: NamedType |
| name: int |
| variables |
| VariableDeclaration |
| name: y |
| semicolon: ; |
| ConstructorDeclaration |
| typeName: SimpleIdentifier |
| token: Foo |
| parameters: FormalParameterList |
| leftParenthesis: ( |
| parameter: RegularFormalParameter |
| type: NamedType |
| name: Object |
| question: ? |
| name: o |
| rightParenthesis: ) |
| separator: : |
| initializers |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: y |
| equals: = |
| expression: ConditionalExpression |
| condition: IsExpression |
| expression: SimpleIdentifier |
| token: o |
| isOperator: is |
| type: NamedType |
| name: String |
| question: ? |
| thenExpression: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: o |
| period: . |
| identifier: SimpleIdentifier |
| token: length |
| colon: : |
| elseExpression: NullLiteral |
| literal: null |
| ConstructorFieldInitializer |
| fieldName: SimpleIdentifier |
| token: x |
| equals: = |
| expression: NullLiteral |
| literal: null |
| body: EmptyFunctionBody |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheck() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(int? y) { |
| var x = y!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: SimpleIdentifier |
| token: y |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckAfterGetterAccess() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g.x!.y + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PropertyAccess |
| target: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: g |
| period: . |
| identifier: SimpleIdentifier |
| token: x |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: y |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckAfterMethodCall() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g.m()!.y + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PropertyAccess |
| target: PostfixExpression |
| operand: MethodInvocation |
| target: SimpleIdentifier |
| token: g |
| operator: . |
| methodName: SimpleIdentifier |
| token: m |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: y |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckBeforeGetterAccess() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g!.x + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PropertyAccess |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: g |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: x |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckBeforeIndex() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| foo.bar!.baz[arg]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PropertyAccess |
| target: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: foo |
| period: . |
| identifier: SimpleIdentifier |
| token: bar |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: baz |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckBeforeMethodCall() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g!.m() + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: MethodInvocation |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: g |
| operator: ! |
| operator: . |
| methodName: SimpleIdentifier |
| token: m |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckFunctionResult() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g()! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: MethodInvocation |
| methodName: SimpleIdentifier |
| token: g |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckIndexedValue() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(int? y) { |
| var x = y[0]! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: IndexExpression |
| target: SimpleIdentifier |
| token: y |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 0 |
| rightBracket: ] |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckIndexedValue2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(int? y) { |
| var x = super.y[0]! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: IndexExpression |
| target: PropertyAccess |
| target: SuperExpression |
| superKeyword: super |
| operator: . |
| propertyName: SimpleIdentifier |
| token: y |
| leftBracket: [ |
| index: IntegerLiteral |
| literal: 0 |
| rightBracket: ] |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckInExpression() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(int? y) { |
| var x = y! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: SimpleIdentifier |
| token: y |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckMethodResult() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g.m()! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: MethodInvocation |
| target: SimpleIdentifier |
| token: g |
| operator: . |
| methodName: SimpleIdentifier |
| token: m |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckMethodResult2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g?.m()! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: MethodInvocation |
| target: SimpleIdentifier |
| token: g |
| operator: ?. |
| methodName: SimpleIdentifier |
| token: m |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckMethodResult3() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = super.m()! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: MethodInvocation |
| target: SuperExpression |
| superKeyword: super |
| operator: . |
| methodName: SimpleIdentifier |
| token: m |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnConstConstructor() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = const Foo()!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: InstanceCreationExpression |
| keyword: const |
| constructorName: ConstructorName |
| type: NamedType |
| name: Foo |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnConstructor() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = new Foo()!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: InstanceCreationExpression |
| keyword: new |
| constructorName: ConstructorName |
| type: NamedType |
| name: Foo |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| rightParenthesis: ) |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| obj![arg]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: obj |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| obj![arg]![arg2]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: IndexExpression |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: obj |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg2 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex3() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| foo.bar![arg]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: foo |
| period: . |
| identifier: SimpleIdentifier |
| token: bar |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex4() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| foo!.bar![arg]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: PropertyAccess |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: foo |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: bar |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex5() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| foo.bar![arg]![arg2]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: IndexExpression |
| target: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: foo |
| period: . |
| identifier: SimpleIdentifier |
| token: bar |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg2 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnIndex6() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| foo!.bar![arg]![arg2]; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: IndexExpression |
| target: PostfixExpression |
| operand: IndexExpression |
| target: PostfixExpression |
| operand: PropertyAccess |
| target: PostfixExpression |
| operand: SimpleIdentifier |
| token: foo |
| operator: ! |
| operator: . |
| propertyName: SimpleIdentifier |
| token: bar |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg |
| rightBracket: ] |
| operator: ! |
| leftBracket: [ |
| index: SimpleIdentifier |
| token: arg2 |
| rightBracket: ] |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralDouble() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = 1.2!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: DoubleLiteral |
| literal: 1.2 |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralInt() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = 0!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: IntegerLiteral |
| literal: 0 |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralList() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = [1, 2]!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: ListLiteral |
| leftBracket: [ |
| elements |
| IntegerLiteral |
| literal: 1 |
| IntegerLiteral |
| literal: 2 |
| rightBracket: ] |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralMap() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = {1: 2}!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: SetOrMapLiteral |
| leftBracket: { |
| elements |
| MapLiteralEntry |
| key: IntegerLiteral |
| literal: 1 |
| separator: : |
| value: IntegerLiteral |
| literal: 2 |
| rightBracket: } |
| isMap: false |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralSet() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = {1, 2}!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: SetOrMapLiteral |
| leftBracket: { |
| elements |
| IntegerLiteral |
| literal: 1 |
| IntegerLiteral |
| literal: 2 |
| rightBracket: } |
| isMap: false |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnLiteralString() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = "seven"!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: SimpleStringLiteral |
| literal: "seven" |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnNull() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = null!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: NullLiteral |
| literal: null |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnSend() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| obj!(arg); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: FunctionExpressionInvocation |
| function: PostfixExpression |
| operand: SimpleIdentifier |
| token: obj |
| operator: ! |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| SimpleIdentifier |
| token: arg |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnSend2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| obj!(arg)!(arg2); |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: FunctionExpressionInvocation |
| function: PostfixExpression |
| operand: FunctionExpressionInvocation |
| function: PostfixExpression |
| operand: SimpleIdentifier |
| token: obj |
| operator: ! |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| SimpleIdentifier |
| token: arg |
| rightParenthesis: ) |
| operator: ! |
| argumentList: ArgumentList |
| leftParenthesis: ( |
| arguments |
| SimpleIdentifier |
| token: arg2 |
| rightParenthesis: ) |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnSymbol() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = #seven!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: PostfixExpression |
| operand: SymbolLiteral |
| poundSign: # |
| components |
| seven |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckOnValue() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(Point p) { |
| var x = p.y! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: p |
| period: . |
| identifier: SimpleIdentifier |
| token: y |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckParenthesizedExpression() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f(int? y) { |
| var x = (y)! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: ParenthesizedExpression |
| leftParenthesis: ( |
| expression: SimpleIdentifier |
| token: y |
| rightParenthesis: ) |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckPropertyAccess() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g.p! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: PrefixedIdentifier |
| prefix: SimpleIdentifier |
| token: g |
| period: . |
| identifier: SimpleIdentifier |
| token: p |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckPropertyAccess2() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = g?.p! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: PropertyAccess |
| target: SimpleIdentifier |
| token: g |
| operator: ?. |
| propertyName: SimpleIdentifier |
| token: p |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_nullCheckPropertyAccess3() { |
| var parseResult = parseTestCodeWithDiagnostics(r''' |
| void f() { |
| var x = super.p! + 7; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| VariableDeclarationStatement |
| variables: VariableDeclarationList |
| keyword: var |
| variables |
| VariableDeclaration |
| name: x |
| equals: = |
| initializer: BinaryExpression |
| leftOperand: PostfixExpression |
| operand: PropertyAccess |
| target: SuperExpression |
| superKeyword: super |
| operator: . |
| propertyName: SimpleIdentifier |
| token: p |
| operator: ! |
| operator: + |
| rightOperand: IntegerLiteral |
| literal: 7 |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_postfix_null_assertion_and_unary_prefix_operator_precedence() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| -x!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: PrefixExpression |
| operator: - |
| operand: PostfixExpression |
| operand: SimpleIdentifier |
| token: x |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| |
| void test_postfix_null_assertion_of_postfix_expression() { |
| var parseResult = parseTestCodeWithDiagnostics(''' |
| void f() { |
| x++!; |
| } |
| '''); |
| var node = parseResult.findNode.firstBlock; |
| assertParsedNodeText(node, r''' |
| Block |
| leftBracket: { |
| statements |
| ExpressionStatement |
| expression: PostfixExpression |
| operand: PostfixExpression |
| operand: SimpleIdentifier |
| token: x |
| operator: ++ |
| operator: ! |
| semicolon: ; |
| rightBracket: } |
| '''); |
| } |
| } |