| // 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:_fe_analyzer_shared/src/scanner/abstract_scanner.dart' |
| show AbstractScanner; |
| import 'package:analyzer/dart/ast/ast.dart'; |
| import 'package:analyzer/dart/ast/token.dart'; |
| import 'package:analyzer/src/dart/ast/ast.dart' |
| show InstanceCreationExpressionImpl; |
| import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| import 'package:analyzer/src/generated/testing/token_factory.dart'; |
| import 'package:test/test.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| |
| import '../util/ast_type_matchers.dart'; |
| import 'parser_test_base.dart'; |
| |
| main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(ExpressionParserTest); |
| }); |
| } |
| |
| /// Tests of the fasta parser based on [ExpressionParserTestMixin]. |
| @reflectiveTest |
| class ExpressionParserTest extends FastaParserTestCase { |
| void test_binaryExpression_allOperators() { |
| // https://github.com/dart-lang/sdk/issues/36255 |
| for (TokenType type in TokenType.all) { |
| if (type.precedence > 0) { |
| var source = 'a ${type.lexeme} b'; |
| try { |
| parseExpression(source); |
| } on TestFailure { |
| // Ensure that there are no infinite loops or exceptions thrown |
| // by the parser. Test failures are fine. |
| } |
| } |
| } |
| } |
| |
| void test_invalidExpression_37706() { |
| // https://github.com/dart-lang/sdk/issues/37706 |
| parseExpression('<b?c>()', errors: [ |
| expectedError(ParserErrorCode.EXPECTED_TOKEN, 1, 1), |
| expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 0), |
| expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 7, 0), |
| ]); |
| } |
| |
| void test_listLiteral_invalid_assert() { |
| // https://github.com/dart-lang/sdk/issues/37674 |
| parseExpression('n=<.["\$assert', errors: [ |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 3, 1), |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1), |
| expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 6), |
| expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 12, 1), |
| expectedError(ScannerErrorCode.EXPECTED_TOKEN, 13, 1), |
| ]); |
| } |
| |
| void test_listLiteral_invalidElement_37697() { |
| // https://github.com/dart-lang/sdk/issues/37674 |
| parseExpression('[<y.<z>(){}]', errors: [ |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 1), |
| expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 1), |
| ]); |
| } |
| |
| void test_lt_dot_bracket_quote() { |
| // https://github.com/dart-lang/sdk/issues/37674 |
| var list = parseExpression('<.["', errors: [ |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 1, 1), |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 2, 1), |
| expectedError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 3, 1), |
| expectedError(ScannerErrorCode.EXPECTED_TOKEN, 4, 1), |
| ]) as ListLiteral; |
| expect(list.elements, hasLength(1)); |
| var first = list.elements[0] as StringLiteral; |
| expect(first.length, 1); |
| } |
| |
| void test_lt_dot_listLiteral() { |
| // https://github.com/dart-lang/sdk/issues/37674 |
| var list = parseExpression('<.[]', errors: [ |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 1, 1), |
| expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 2, 2), |
| ]) as ListLiteral; |
| expect(list.elements, hasLength(0)); |
| } |
| |
| void test_mapLiteral() { |
| var map = parseExpression('{3: 6}') as SetOrMapLiteral; |
| expect(map.constKeyword, isNull); |
| expect(map.typeArguments, isNull); |
| expect(map.elements, hasLength(1)); |
| var entry = map.elements[0] as MapLiteralEntry; |
| var key = entry.key as IntegerLiteral; |
| expect(key.value, 3); |
| var value = entry.value as IntegerLiteral; |
| expect(value.value, 6); |
| } |
| |
| void test_mapLiteral_const() { |
| var map = parseExpression('const {3: 6}') as SetOrMapLiteral; |
| expect(map.constKeyword, isNotNull); |
| expect(map.typeArguments, isNull); |
| expect(map.elements, hasLength(1)); |
| var entry = map.elements[0] as MapLiteralEntry; |
| var key = entry.key as IntegerLiteral; |
| expect(key.value, 3); |
| var value = entry.value as IntegerLiteral; |
| expect(value.value, 6); |
| } |
| |
| @failingTest |
| void test_mapLiteral_invalid_too_many_type_arguments1() { |
| var map = parseExpression('<int, int, int>{}', errors: [ |
| // TODO(danrubel): Currently the resolver reports invalid number of |
| // type arguments, but the parser could report this. |
| expectedError( |
| /* ParserErrorCode.EXPECTED_ONE_OR_TWO_TYPE_VARIABLES */ |
| ParserErrorCode.EXPECTED_TOKEN, |
| 11, |
| 3), |
| ]) as SetOrMapLiteral; |
| expect(map.constKeyword, isNull); |
| expect(map.elements, hasLength(0)); |
| } |
| |
| @failingTest |
| void test_mapLiteral_invalid_too_many_type_arguments2() { |
| var map = parseExpression('<int, int, int>{1}', errors: [ |
| // TODO(danrubel): Currently the resolver reports invalid number of |
| // type arguments, but the parser could report this. |
| expectedError( |
| /* ParserErrorCode.EXPECTED_ONE_OR_TWO_TYPE_VARIABLES */ |
| ParserErrorCode.EXPECTED_TOKEN, |
| 11, |
| 3), |
| ]) as SetOrMapLiteral; |
| expect(map.constKeyword, isNull); |
| expect(map.elements, hasLength(0)); |
| } |
| |
| void test_namedArgument() { |
| var invocation = parseExpression('m(a: 1, b: 2)') as MethodInvocation; |
| List<Expression> arguments = invocation.argumentList.arguments; |
| |
| var a = arguments[0] as NamedExpression; |
| expect(a.name.label.name, 'a'); |
| expect(a.expression, isNotNull); |
| |
| var b = arguments[1] as NamedExpression; |
| expect(b.name.label.name, 'b'); |
| expect(b.expression, isNotNull); |
| } |
| |
| void test_parseAdditiveExpression_normal() { |
| Expression expression = parseAdditiveExpression('x + y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.PLUS); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseAdditiveExpression_super() { |
| Expression expression = parseAdditiveExpression('super + y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isSuperExpression); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.PLUS); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_expression_args_dot() { |
| Expression expression = parseAssignableExpression('(x)(y).z', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| FunctionExpressionInvocation invocation = |
| propertyAccess.target as FunctionExpressionInvocation; |
| expect(invocation.function, isNotNull); |
| expect(invocation.typeArguments, isNull); |
| ArgumentList argumentList = invocation.argumentList; |
| expect(argumentList, isNotNull); |
| expect(argumentList.arguments, hasLength(1)); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_expression_args_dot_typeArguments() { |
| Expression expression = parseAssignableExpression('(x)<F>(y).z', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| FunctionExpressionInvocation invocation = |
| propertyAccess.target as FunctionExpressionInvocation; |
| expect(invocation.function, isNotNull); |
| expect(invocation.typeArguments, isNotNull); |
| ArgumentList argumentList = invocation.argumentList; |
| expect(argumentList, isNotNull); |
| expect(argumentList.arguments, hasLength(1)); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_expression_dot() { |
| Expression expression = parseAssignableExpression('(x).y', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.target, isNotNull); |
| expect(propertyAccess.operator.type, TokenType.PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_expression_index() { |
| Expression expression = parseAssignableExpression('(x)[y]', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var indexExpression = expression as IndexExpression; |
| expect(indexExpression.target, isNotNull); |
| expect(indexExpression.leftBracket, isNotNull); |
| expect(indexExpression.index, isNotNull); |
| expect(indexExpression.rightBracket, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_expression_question_dot() { |
| Expression expression = parseAssignableExpression('(x)?.y', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.target, isNotNull); |
| expect(propertyAccess.operator.type, TokenType.QUESTION_PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_identifier() { |
| Expression expression = parseAssignableExpression('x', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var identifier = expression as SimpleIdentifier; |
| expect(identifier, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_identifier_args_dot() { |
| Expression expression = parseAssignableExpression('x(y).z', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| MethodInvocation invocation = propertyAccess.target as MethodInvocation; |
| expect(invocation.methodName.name, "x"); |
| expect(invocation.typeArguments, isNull); |
| ArgumentList argumentList = invocation.argumentList; |
| expect(argumentList, isNotNull); |
| expect(argumentList.arguments, hasLength(1)); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_identifier_args_dot_typeArguments() { |
| Expression expression = parseAssignableExpression('x<E>(y).z', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| MethodInvocation invocation = propertyAccess.target as MethodInvocation; |
| expect(invocation.methodName.name, "x"); |
| expect(invocation.typeArguments, isNotNull); |
| ArgumentList argumentList = invocation.argumentList; |
| expect(argumentList, isNotNull); |
| expect(argumentList.arguments, hasLength(1)); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_identifier_dot() { |
| Expression expression = parseAssignableExpression('x.y', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var identifier = expression as PrefixedIdentifier; |
| expect(identifier.prefix.name, 'x'); |
| expect(identifier.period, isNotNull); |
| expect(identifier.period.type, TokenType.PERIOD); |
| expect(identifier.identifier.name, 'y'); |
| } |
| |
| void test_parseAssignableExpression_identifier_index() { |
| Expression expression = parseAssignableExpression('x[y]', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var indexExpression = expression as IndexExpression; |
| expect(indexExpression.target, isNotNull); |
| expect(indexExpression.leftBracket, isNotNull); |
| expect(indexExpression.index, isNotNull); |
| expect(indexExpression.rightBracket, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_identifier_question_dot() { |
| Expression expression = parseAssignableExpression('x?.y', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.target, isNotNull); |
| expect(propertyAccess.operator.type, TokenType.QUESTION_PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_super_dot() { |
| Expression expression = parseAssignableExpression('super.y', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.target, isSuperExpression); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableExpression_super_index() { |
| Expression expression = parseAssignableExpression('super[y]', false); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var indexExpression = expression as IndexExpression; |
| expect(indexExpression.target, isSuperExpression); |
| expect(indexExpression.leftBracket, isNotNull); |
| expect(indexExpression.index, isNotNull); |
| expect(indexExpression.rightBracket, isNotNull); |
| } |
| |
| void test_parseAssignableSelector_dot() { |
| Expression expression = parseAssignableSelector('.x', true); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.operator.type, TokenType.PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAssignableSelector_index() { |
| Expression expression = parseAssignableSelector('[x]', true); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var indexExpression = expression as IndexExpression; |
| expect(indexExpression.leftBracket, isNotNull); |
| expect(indexExpression.index, isNotNull); |
| expect(indexExpression.rightBracket, isNotNull); |
| } |
| |
| void test_parseAssignableSelector_none() { |
| Expression expression = parseAssignableSelector('', true); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var identifier = expression as SimpleIdentifier; |
| expect(identifier, isNotNull); |
| } |
| |
| void test_parseAssignableSelector_question_dot() { |
| Expression expression = parseAssignableSelector('?.x', true); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.operator.type, TokenType.QUESTION_PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parseAwaitExpression() { |
| AwaitExpression expression = parseAwaitExpression('await x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.awaitKeyword, isNotNull); |
| expect(expression.expression, isNotNull); |
| } |
| |
| void test_parseBitwiseAndExpression_normal() { |
| Expression expression = parseBitwiseAndExpression('x & y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.AMPERSAND); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseBitwiseAndExpression_super() { |
| Expression expression = parseBitwiseAndExpression('super & y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isSuperExpression); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.AMPERSAND); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseBitwiseOrExpression_normal() { |
| Expression expression = parseBitwiseOrExpression('x | y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.BAR); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseBitwiseOrExpression_super() { |
| Expression expression = parseBitwiseOrExpression('super | y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isSuperExpression); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.BAR); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseBitwiseXorExpression_normal() { |
| Expression expression = parseBitwiseXorExpression('x ^ y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.CARET); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseBitwiseXorExpression_super() { |
| Expression expression = parseBitwiseXorExpression('super ^ y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isSuperExpression); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.CARET); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseCascadeSection_i() { |
| Expression expression = parseCascadeSection('..[i]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as IndexExpression; |
| expect(section.target, isNull); |
| expect(section.leftBracket, isNotNull); |
| expect(section.index, isNotNull); |
| expect(section.rightBracket, isNotNull); |
| } |
| |
| void test_parseCascadeSection_ia() { |
| Expression expression = parseCascadeSection('..[i](b)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isIndexExpression); |
| expect(section.typeArguments, isNull); |
| expect(section.argumentList, isNotNull); |
| } |
| |
| void test_parseCascadeSection_ia_typeArguments() { |
| Expression expression = parseCascadeSection('..[i]<E>(b)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isIndexExpression); |
| expect(section.typeArguments, isNotNull); |
| expect(section.argumentList, isNotNull); |
| } |
| |
| void test_parseCascadeSection_ii() { |
| Expression expression = parseCascadeSection('..a(b).c(d)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as MethodInvocation; |
| expect(section.target, isMethodInvocation); |
| expect(section.operator, isNotNull); |
| expect(section.methodName, isNotNull); |
| expect(section.typeArguments, isNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_ii_typeArguments() { |
| Expression expression = parseCascadeSection('..a<E>(b).c<F>(d)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as MethodInvocation; |
| expect(section.target, isMethodInvocation); |
| expect(section.operator, isNotNull); |
| expect(section.methodName, isNotNull); |
| expect(section.typeArguments, isNotNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_p() { |
| Expression expression = parseCascadeSection('..a'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as PropertyAccess; |
| expect(section.target, isNull); |
| expect(section.operator, isNotNull); |
| expect(section.propertyName, isNotNull); |
| } |
| |
| void test_parseCascadeSection_p_assign() { |
| Expression expression = parseCascadeSection('..a = 3'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as AssignmentExpression; |
| expect(section.leftHandSide, isNotNull); |
| expect(section.operator, isNotNull); |
| Expression rhs = section.rightHandSide; |
| expect(rhs, isNotNull); |
| } |
| |
| void test_parseCascadeSection_p_assign_withCascade() { |
| Expression expression = parseCascadeSection('..a = 3..m()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as AssignmentExpression; |
| expect(section.leftHandSide, isNotNull); |
| expect(section.operator, isNotNull); |
| Expression rhs = section.rightHandSide; |
| expect(rhs, isIntegerLiteral); |
| } |
| |
| void test_parseCascadeSection_p_assign_withCascade_typeArguments() { |
| Expression expression = parseCascadeSection('..a = 3..m<E>()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as AssignmentExpression; |
| expect(section.leftHandSide, isNotNull); |
| expect(section.operator, isNotNull); |
| Expression rhs = section.rightHandSide; |
| expect(rhs, isIntegerLiteral); |
| } |
| |
| void test_parseCascadeSection_p_builtIn() { |
| Expression expression = parseCascadeSection('..as'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as PropertyAccess; |
| expect(section.target, isNull); |
| expect(section.operator, isNotNull); |
| expect(section.propertyName, isNotNull); |
| } |
| |
| void test_parseCascadeSection_pa() { |
| Expression expression = parseCascadeSection('..a(b)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as MethodInvocation; |
| expect(section.target, isNull); |
| expect(section.operator, isNotNull); |
| expect(section.methodName, isNotNull); |
| expect(section.typeArguments, isNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_pa_typeArguments() { |
| Expression expression = parseCascadeSection('..a<E>(b)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as MethodInvocation; |
| expect(section.target, isNull); |
| expect(section.operator, isNotNull); |
| expect(section.methodName, isNotNull); |
| expect(section.typeArguments, isNotNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_paa() { |
| Expression expression = parseCascadeSection('..a(b)(c)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isMethodInvocation); |
| expect(section.typeArguments, isNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_paa_typeArguments() { |
| Expression expression = parseCascadeSection('..a<E>(b)<F>(c)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isMethodInvocation); |
| expect(section.typeArguments, isNotNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_paapaa() { |
| Expression expression = parseCascadeSection('..a(b)(c).d(e)(f)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isMethodInvocation); |
| expect(section.typeArguments, isNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_paapaa_typeArguments() { |
| Expression expression = |
| parseCascadeSection('..a<E>(b)<F>(c).d<G>(e)<H>(f)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as FunctionExpressionInvocation; |
| expect(section.function, isMethodInvocation); |
| expect(section.typeArguments, isNotNull); |
| expect(section.argumentList, isNotNull); |
| expect(section.argumentList.arguments, hasLength(1)); |
| } |
| |
| void test_parseCascadeSection_pap() { |
| Expression expression = parseCascadeSection('..a(b).c'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as PropertyAccess; |
| expect(section.target, isNotNull); |
| expect(section.operator, isNotNull); |
| expect(section.propertyName, isNotNull); |
| } |
| |
| void test_parseCascadeSection_pap_typeArguments() { |
| Expression expression = parseCascadeSection('..a<E>(b).c'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var section = expression as PropertyAccess; |
| expect(section.target, isNotNull); |
| expect(section.operator, isNotNull); |
| expect(section.propertyName, isNotNull); |
| } |
| |
| void test_parseConditionalExpression() { |
| ConditionalExpression expression = parseConditionalExpression('x ? y : z'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.condition, isNotNull); |
| expect(expression.question, isNotNull); |
| expect(expression.thenExpression, isNotNull); |
| expect(expression.colon, isNotNull); |
| expect(expression.elseExpression, isNotNull); |
| } |
| |
| void test_parseConstExpression_instanceCreation() { |
| Expression expression = parseConstExpression('const A()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression, isInstanceCreationExpression); |
| var instanceCreation = expression as InstanceCreationExpression; |
| expect(instanceCreation.keyword, isNotNull); |
| ConstructorName name = instanceCreation.constructorName; |
| expect(name, isNotNull); |
| expect(name.type, isNotNull); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(instanceCreation.argumentList, isNotNull); |
| } |
| |
| void test_parseConstExpression_listLiteral_typed() { |
| Expression expression = parseConstExpression('const <A> []'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as ListLiteral; |
| expect(literal.constKeyword, isNotNull); |
| expect(literal.typeArguments, isNotNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseConstExpression_listLiteral_untyped() { |
| Expression expression = parseConstExpression('const []'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as ListLiteral; |
| expect(literal.constKeyword, isNotNull); |
| expect(literal.typeArguments, isNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseConstExpression_mapLiteral_typed() { |
| Expression expression = parseConstExpression('const <A, B> {}'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SetOrMapLiteral; |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| expect(literal.typeArguments, isNotNull); |
| } |
| |
| void test_parseConstExpression_mapLiteral_typed_missingGt() { |
| Expression expression = parseExpression('const <A, B {}', |
| errors: [expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1)]); |
| expect(expression, isNotNull); |
| var literal = expression as SetOrMapLiteral; |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| expect(literal.typeArguments, isNotNull); |
| } |
| |
| void test_parseConstExpression_mapLiteral_untyped() { |
| Expression expression = parseConstExpression('const {}'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SetOrMapLiteral; |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| expect(literal.typeArguments, isNull); |
| } |
| |
| void test_parseConstructorInitializer_functionExpression() { |
| // https://github.com/dart-lang/sdk/issues/37414 |
| parseCompilationUnit('class C { C.n() : this()(); }', errors: [ |
| expectedError(ParserErrorCode.INVALID_INITIALIZER, 18, 8), |
| ]); |
| } |
| |
| void test_parseEqualityExpression_normal() { |
| BinaryExpression expression = parseEqualityExpression('x == y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.leftOperand, isNotNull); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.EQ_EQ); |
| expect(expression.rightOperand, isNotNull); |
| } |
| |
| void test_parseEqualityExpression_super() { |
| BinaryExpression expression = parseEqualityExpression('super == y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.leftOperand, isSuperExpression); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.EQ_EQ); |
| expect(expression.rightOperand, isNotNull); |
| } |
| |
| void test_parseExpression_assign() { |
| // TODO(brianwilkerson) Implement more tests for this method. |
| Expression expression = parseExpression('x = y'); |
| var assignmentExpression = expression as AssignmentExpression; |
| expect(assignmentExpression.leftHandSide, isNotNull); |
| expect(assignmentExpression.operator, isNotNull); |
| expect(assignmentExpression.operator.type, TokenType.EQ); |
| expect(assignmentExpression.rightHandSide, isNotNull); |
| } |
| |
| void test_parseExpression_assign_compound() { |
| if (AbstractScanner.LAZY_ASSIGNMENT_ENABLED) { |
| Expression expression = parseExpression('x ||= y'); |
| var assignmentExpression = expression as AssignmentExpression; |
| expect(assignmentExpression.leftHandSide, isNotNull); |
| expect(assignmentExpression.operator, isNotNull); |
| expect(assignmentExpression.operator.type, TokenType.BAR_BAR_EQ); |
| expect(assignmentExpression.rightHandSide, isNotNull); |
| } |
| } |
| |
| void test_parseExpression_comparison() { |
| Expression expression = parseExpression('--a.b == c'); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.EQ_EQ); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseExpression_constAndTypeParameters() { |
| Expression expression = parseExpression('const <E>', codes: [ |
| // TODO(danrubel): Improve this error message. |
| ParserErrorCode.EXPECTED_TOKEN |
| ]); |
| expect(expression, isNotNull); |
| } |
| |
| void test_parseExpression_function_async() { |
| Expression expression = parseExpression('() async {}'); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.body, isNotNull); |
| expect(functionExpression.body.isAsynchronous, isTrue); |
| expect(functionExpression.body.isGenerator, isFalse); |
| expect(functionExpression.parameters, isNotNull); |
| } |
| |
| void test_parseExpression_function_asyncStar() { |
| Expression expression = parseExpression('() async* {}'); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.body, isNotNull); |
| expect(functionExpression.body.isAsynchronous, isTrue); |
| expect(functionExpression.body.isGenerator, isTrue); |
| expect(functionExpression.parameters, isNotNull); |
| } |
| |
| void test_parseExpression_function_sync() { |
| Expression expression = parseExpression('() {}'); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.body, isNotNull); |
| expect(functionExpression.body.isAsynchronous, isFalse); |
| expect(functionExpression.body.isGenerator, isFalse); |
| expect(functionExpression.parameters, isNotNull); |
| } |
| |
| void test_parseExpression_function_syncStar() { |
| Expression expression = parseExpression('() sync* {}'); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.body, isNotNull); |
| expect(functionExpression.body.isAsynchronous, isFalse); |
| expect(functionExpression.body.isGenerator, isTrue); |
| expect(functionExpression.parameters, isNotNull); |
| } |
| |
| void test_parseExpression_invokeFunctionExpression() { |
| Expression expression = parseExpression('(a) {return a + a;} (3)'); |
| var invocation = expression as FunctionExpressionInvocation; |
| expect(invocation.function, isFunctionExpression); |
| FunctionExpression functionExpression = |
| invocation.function as FunctionExpression; |
| expect(functionExpression.parameters, isNotNull); |
| expect(functionExpression.body, isNotNull); |
| expect(invocation.typeArguments, isNull); |
| ArgumentList list = invocation.argumentList; |
| expect(list, isNotNull); |
| expect(list.arguments, hasLength(1)); |
| } |
| |
| void test_parseExpression_nonAwait() { |
| Expression expression = parseExpression('await()'); |
| var invocation = expression as MethodInvocation; |
| expect(invocation.methodName.name, 'await'); |
| expect(invocation.typeArguments, isNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void test_parseExpression_sendWithTypeParam_afterIndex() { |
| final unit = parseCompilationUnit('main() { factories[C]<num, int>(); }'); |
| expect(unit.declarations, hasLength(1)); |
| var mainMethod = unit.declarations[0] as FunctionDeclaration; |
| var body = mainMethod.functionExpression.body as BlockFunctionBody; |
| NodeList<Statement> statements = body.block.statements; |
| expect(statements, hasLength(1)); |
| var statement = statements[0] as ExpressionStatement; |
| var expression = statement.expression as FunctionExpressionInvocation; |
| |
| var function = expression.function as IndexExpression; |
| var target = function.target as SimpleIdentifier; |
| expect(target.name, 'factories'); |
| var index = function.index as SimpleIdentifier; |
| expect(index.name, 'C'); |
| |
| List<TypeAnnotation> typeArguments = expression.typeArguments!.arguments; |
| expect(typeArguments, hasLength(2)); |
| expect((typeArguments[0] as NamedType).name.name, 'num'); |
| expect((typeArguments[1] as NamedType).name.name, 'int'); |
| |
| expect(expression.argumentList.arguments, hasLength(0)); |
| } |
| |
| void test_parseExpression_sendWithTypeParam_afterSend() { |
| final unit = parseCompilationUnit('main() { factories(C)<num, int>(); }'); |
| expect(unit.declarations, hasLength(1)); |
| var mainMethod = unit.declarations[0] as FunctionDeclaration; |
| var body = mainMethod.functionExpression.body as BlockFunctionBody; |
| NodeList<Statement> statements = body.block.statements; |
| expect(statements, hasLength(1)); |
| var statement = statements[0] as ExpressionStatement; |
| var expression = statement.expression as FunctionExpressionInvocation; |
| |
| var invocation = expression.function as MethodInvocation; |
| expect(invocation.methodName.name, 'factories'); |
| NodeList<Expression> invocationArguments = |
| invocation.argumentList.arguments; |
| expect(invocationArguments, hasLength(1)); |
| var index = invocationArguments[0] as SimpleIdentifier; |
| expect(index.name, 'C'); |
| |
| List<TypeAnnotation> typeArguments = expression.typeArguments!.arguments; |
| expect(typeArguments, hasLength(2)); |
| expect((typeArguments[0] as NamedType).name.name, 'num'); |
| expect((typeArguments[1] as NamedType).name.name, 'int'); |
| |
| expect(expression.argumentList.arguments, hasLength(0)); |
| } |
| |
| void test_parseExpression_superMethodInvocation() { |
| Expression expression = parseExpression('super.m()'); |
| var invocation = expression as MethodInvocation; |
| expect(invocation.target, isNotNull); |
| expect(invocation.methodName, isNotNull); |
| expect(invocation.typeArguments, isNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void test_parseExpression_superMethodInvocation_typeArguments() { |
| Expression expression = parseExpression('super.m<E>()'); |
| var invocation = expression as MethodInvocation; |
| expect(invocation.target, isNotNull); |
| expect(invocation.methodName, isNotNull); |
| expect(invocation.typeArguments, isNotNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void test_parseExpression_superMethodInvocation_typeArguments_chained() { |
| Expression expression = parseExpression('super.b.c<D>()'); |
| MethodInvocation invocation = expression as MethodInvocation; |
| var target = invocation.target as Expression; |
| expect(target, isPropertyAccess); |
| expect(invocation.methodName, isNotNull); |
| expect(invocation.methodName.name, 'c'); |
| expect(invocation.typeArguments, isNotNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void test_parseExpressionList_multiple() { |
| List<Expression> result = parseExpressionList('1, 2, 3'); |
| expect(result, isNotNull); |
| assertNoErrors(); |
| expect(result, hasLength(3)); |
| } |
| |
| void test_parseExpressionList_single() { |
| List<Expression> result = parseExpressionList('1'); |
| expect(result, isNotNull); |
| assertNoErrors(); |
| expect(result, hasLength(1)); |
| } |
| |
| void test_parseExpressionWithoutCascade_assign() { |
| // TODO(brianwilkerson) Implement more tests for this method. |
| Expression expression = parseExpressionWithoutCascade('x = y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var assignmentExpression = expression as AssignmentExpression; |
| expect(assignmentExpression.leftHandSide, isNotNull); |
| expect(assignmentExpression.operator, isNotNull); |
| expect(assignmentExpression.operator.type, TokenType.EQ); |
| expect(assignmentExpression.rightHandSide, isNotNull); |
| } |
| |
| void test_parseExpressionWithoutCascade_comparison() { |
| Expression expression = parseExpressionWithoutCascade('--a.b == c'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.EQ_EQ); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseExpressionWithoutCascade_superMethodInvocation() { |
| Expression expression = parseExpressionWithoutCascade('super.m()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var invocation = expression as MethodInvocation; |
| expect(invocation.target, isNotNull); |
| expect(invocation.methodName, isNotNull); |
| expect(invocation.typeArguments, isNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void |
| test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() { |
| Expression expression = parseExpressionWithoutCascade('super.m<E>()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var invocation = expression as MethodInvocation; |
| expect(invocation.target, isNotNull); |
| expect(invocation.methodName, isNotNull); |
| expect(invocation.typeArguments, isNotNull); |
| expect(invocation.argumentList, isNotNull); |
| } |
| |
| void test_parseFunctionExpression_body_inExpression() { |
| FunctionExpression expression = parseFunctionExpression('(int i) => i++'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.body, isNotNull); |
| expect(expression.typeParameters, isNull); |
| expect(expression.parameters, isNotNull); |
| expect((expression.body as ExpressionFunctionBody).semicolon, isNull); |
| } |
| |
| void test_parseFunctionExpression_constAndTypeParameters2() { |
| FunctionExpression expression = |
| parseFunctionExpression('const <E>(E i) => i++'); |
| expect(expression, isNotNull); |
| assertErrorsWithCodes([ParserErrorCode.UNEXPECTED_TOKEN]); |
| expect(expression.body, isNotNull); |
| expect(expression.typeParameters, isNotNull); |
| expect(expression.parameters, isNotNull); |
| expect((expression.body as ExpressionFunctionBody).semicolon, isNull); |
| } |
| |
| void test_parseFunctionExpression_functionInPlaceOfTypeName() { |
| Expression expression = parseExpression('<test(' ', (){});>[0, 1, 2]', |
| codes: [ParserErrorCode.EXPECTED_TOKEN]); |
| expect(expression, isNotNull); |
| var literal = expression as ListLiteral; |
| expect(literal.typeArguments!.arguments, hasLength(1)); |
| } |
| |
| void test_parseFunctionExpression_typeParameters() { |
| FunctionExpression expression = parseFunctionExpression('<E>(E i) => i++'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.body, isNotNull); |
| expect(expression.typeParameters, isNotNull); |
| expect(expression.parameters, isNotNull); |
| expect((expression.body as ExpressionFunctionBody).semicolon, isNull); |
| } |
| |
| void test_parseInstanceCreationExpression_qualifiedType() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A.B()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type.name.name, 'A.B'); |
| expect(type.typeArguments, isNull); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseInstanceCreationExpression_qualifiedType_named() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A.B.c()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments, isNull); |
| expect(name.period, isNotNull); |
| expect(name.name, isNotNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void |
| test_parseInstanceCreationExpression_qualifiedType_named_typeArguments() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A.B<E>.c()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments!.arguments, hasLength(1)); |
| expect(name.period, isNotNull); |
| expect(name.name, isNotNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseInstanceCreationExpression_qualifiedType_typeArguments() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A.B<E>()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments!.arguments, hasLength(1)); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseInstanceCreationExpression_type() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments, isNull); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseInstanceCreationExpression_type_named() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A.c()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments, isNull); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseInstanceCreationExpression_type_named_typeArguments() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| var expression = parseInstanceCreationExpression('A<B>.c()', token) |
| as InstanceCreationExpressionImpl; |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments!.arguments, hasLength(1)); |
| expect(name.period, isNotNull); |
| expect(name.name, isNotNull); |
| expect(expression.argumentList, isNotNull); |
| expect(expression.typeArguments, isNull); |
| } |
| |
| void test_parseInstanceCreationExpression_type_named_typeArguments_34403() { |
| var expression = parseExpression('new a.b.c<C>()', errors: [ |
| expectedError(ParserErrorCode.CONSTRUCTOR_WITH_TYPE_ARGUMENTS, 8, 1) |
| ]) as InstanceCreationExpressionImpl; |
| expect(expression, isNotNull); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments, isNull); |
| expect(name.period, isNotNull); |
| expect(name.name, isNotNull); |
| expect(expression.argumentList, isNotNull); |
| expect(expression.typeArguments!.arguments, hasLength(1)); |
| } |
| |
| void test_parseInstanceCreationExpression_type_typeArguments() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.NEW); |
| InstanceCreationExpression expression = |
| parseInstanceCreationExpression('A<B>()', token); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword!.keyword, Keyword.NEW); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| NamedType type = name.type; |
| expect(type, isNotNull); |
| expect(type.typeArguments!.arguments, hasLength(1)); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parseListLiteral_empty_oneToken() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.CONST); |
| ListLiteral literal = parseListLiteral(token, null, '[]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword!.keyword, Keyword.CONST); |
| expect(literal.typeArguments, isNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListLiteral_empty_oneToken_withComment() { |
| ListLiteral literal = parseListLiteral(null, null, '/* 0 */ []'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword, isNull); |
| expect(literal.typeArguments, isNull); |
| Token leftBracket = literal.leftBracket; |
| expect(leftBracket, isNotNull); |
| expect(leftBracket.precedingComments, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListLiteral_empty_twoTokens() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.CONST); |
| ListLiteral literal = parseListLiteral(token, null, '[ ]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword!.keyword, Keyword.CONST); |
| expect(literal.typeArguments, isNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListLiteral_multiple() { |
| ListLiteral literal = parseListLiteral(null, null, '[1, 2, 3]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword, isNull); |
| expect(literal.typeArguments, isNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(3)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListLiteral_single() { |
| ListLiteral literal = parseListLiteral(null, null, '[1]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword, isNull); |
| expect(literal.typeArguments, isNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(1)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListLiteral_single_withTypeArgument() { |
| ListLiteral literal = parseListLiteral(null, '<int>', '[1]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword, isNull); |
| expect(literal.typeArguments, isNotNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(1)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseListOrMapLiteral_list_noType() { |
| TypedLiteral literal = parseListOrMapLiteral(null, '[1]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| var listLiteral = literal as ListLiteral; |
| expect(listLiteral.constKeyword, isNull); |
| expect(listLiteral.typeArguments, isNull); |
| expect(listLiteral.leftBracket, isNotNull); |
| expect(listLiteral.elements, hasLength(1)); |
| expect(listLiteral.rightBracket, isNotNull); |
| } |
| |
| void test_parseListOrMapLiteral_list_type() { |
| TypedLiteral literal = parseListOrMapLiteral(null, '<int> [1]'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| var listLiteral = literal as ListLiteral; |
| expect(listLiteral.constKeyword, isNull); |
| expect(listLiteral.typeArguments, isNotNull); |
| expect(listLiteral.leftBracket, isNotNull); |
| expect(listLiteral.elements, hasLength(1)); |
| expect(listLiteral.rightBracket, isNotNull); |
| } |
| |
| void test_parseListOrMapLiteral_map_noType() { |
| TypedLiteral literal = parseListOrMapLiteral(null, "{'1' : 1}"); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| var mapLiteral = literal as SetOrMapLiteral; |
| expect(mapLiteral.constKeyword, isNull); |
| expect(mapLiteral.typeArguments, isNull); |
| expect(mapLiteral.leftBracket, isNotNull); |
| expect(mapLiteral.elements, hasLength(1)); |
| expect(mapLiteral.rightBracket, isNotNull); |
| } |
| |
| void test_parseListOrMapLiteral_map_type() { |
| TypedLiteral literal = |
| parseListOrMapLiteral(null, "<String, int> {'1' : 1}"); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| var mapLiteral = literal as SetOrMapLiteral; |
| expect(mapLiteral.constKeyword, isNull); |
| expect(mapLiteral.typeArguments, isNotNull); |
| expect(mapLiteral.leftBracket, isNotNull); |
| expect(mapLiteral.elements, hasLength(1)); |
| expect(mapLiteral.rightBracket, isNotNull); |
| } |
| |
| void test_parseLogicalAndExpression() { |
| Expression expression = parseLogicalAndExpression('x && y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.AMPERSAND_AMPERSAND); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseLogicalOrExpression() { |
| Expression expression = parseLogicalOrExpression('x || y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.BAR_BAR); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseMapLiteral_empty() { |
| Token token = TokenFactory.tokenFromKeyword(Keyword.CONST); |
| SetOrMapLiteral literal = parseMapLiteral(token, '<String, int>', '{}'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.constKeyword!.keyword, Keyword.CONST); |
| expect(literal.typeArguments, isNotNull); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(0)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseMapLiteral_multiple() { |
| SetOrMapLiteral literal = parseMapLiteral(null, null, "{'a' : b, 'x' : y}"); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(2)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseMapLiteral_multiple_trailing_comma() { |
| SetOrMapLiteral literal = |
| parseMapLiteral(null, null, "{'a' : b, 'x' : y,}"); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(2)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseMapLiteral_single() { |
| SetOrMapLiteral literal = parseMapLiteral(null, null, "{'x' : y}"); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.leftBracket, isNotNull); |
| expect(literal.elements, hasLength(1)); |
| expect(literal.rightBracket, isNotNull); |
| } |
| |
| void test_parseMapLiteralEntry_complex() { |
| MapLiteralEntry entry = parseMapLiteralEntry('2 + 2 : y'); |
| expect(entry, isNotNull); |
| assertNoErrors(); |
| expect(entry.key, isNotNull); |
| expect(entry.separator, isNotNull); |
| expect(entry.value, isNotNull); |
| } |
| |
| void test_parseMapLiteralEntry_int() { |
| MapLiteralEntry entry = parseMapLiteralEntry('0 : y'); |
| expect(entry, isNotNull); |
| assertNoErrors(); |
| expect(entry.key, isNotNull); |
| expect(entry.separator, isNotNull); |
| expect(entry.value, isNotNull); |
| } |
| |
| void test_parseMapLiteralEntry_string() { |
| MapLiteralEntry entry = parseMapLiteralEntry("'x' : y"); |
| expect(entry, isNotNull); |
| assertNoErrors(); |
| expect(entry.key, isNotNull); |
| expect(entry.separator, isNotNull); |
| expect(entry.value, isNotNull); |
| } |
| |
| void test_parseMultiplicativeExpression_normal() { |
| Expression expression = parseMultiplicativeExpression('x * y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.STAR); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseMultiplicativeExpression_super() { |
| Expression expression = parseMultiplicativeExpression('super * y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isSuperExpression); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.STAR); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseNewExpression() { |
| InstanceCreationExpression expression = parseNewExpression('new A()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.keyword, isNotNull); |
| ConstructorName name = expression.constructorName; |
| expect(name, isNotNull); |
| expect(name.type, isNotNull); |
| expect(name.period, isNull); |
| expect(name.name, isNull); |
| expect(expression.argumentList, isNotNull); |
| } |
| |
| void test_parsePostfixExpression_decrement() { |
| Expression expression = parsePostfixExpression('i--'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var postfixExpression = expression as PostfixExpression; |
| expect(postfixExpression.operand, isNotNull); |
| expect(postfixExpression.operator, isNotNull); |
| expect(postfixExpression.operator.type, TokenType.MINUS_MINUS); |
| } |
| |
| void test_parsePostfixExpression_increment() { |
| Expression expression = parsePostfixExpression('i++'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var postfixExpression = expression as PostfixExpression; |
| expect(postfixExpression.operand, isNotNull); |
| expect(postfixExpression.operator, isNotNull); |
| expect(postfixExpression.operator.type, TokenType.PLUS_PLUS); |
| } |
| |
| void test_parsePostfixExpression_none_indexExpression() { |
| Expression expression = parsePostfixExpression('a[0]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var indexExpression = expression as IndexExpression; |
| expect(indexExpression.target, isNotNull); |
| expect(indexExpression.index, isNotNull); |
| } |
| |
| void test_parsePostfixExpression_none_methodInvocation() { |
| Expression expression = parsePostfixExpression('a.m()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var methodInvocation = expression as MethodInvocation; |
| expect(methodInvocation.target, isNotNull); |
| expect(methodInvocation.operator!.type, TokenType.PERIOD); |
| expect(methodInvocation.methodName, isNotNull); |
| expect(methodInvocation.typeArguments, isNull); |
| expect(methodInvocation.argumentList, isNotNull); |
| } |
| |
| void test_parsePostfixExpression_none_methodInvocation_question_dot() { |
| Expression expression = parsePostfixExpression('a?.m()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var methodInvocation = expression as MethodInvocation; |
| expect(methodInvocation.target, isNotNull); |
| expect(methodInvocation.operator!.type, TokenType.QUESTION_PERIOD); |
| expect(methodInvocation.methodName, isNotNull); |
| expect(methodInvocation.typeArguments, isNull); |
| expect(methodInvocation.argumentList, isNotNull); |
| } |
| |
| void |
| test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() { |
| Expression expression = parsePostfixExpression('a?.m<E>()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var methodInvocation = expression as MethodInvocation; |
| expect(methodInvocation.target, isNotNull); |
| expect(methodInvocation.operator!.type, TokenType.QUESTION_PERIOD); |
| expect(methodInvocation.methodName, isNotNull); |
| expect(methodInvocation.typeArguments, isNotNull); |
| expect(methodInvocation.argumentList, isNotNull); |
| } |
| |
| void test_parsePostfixExpression_none_methodInvocation_typeArguments() { |
| Expression expression = parsePostfixExpression('a.m<E>()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var methodInvocation = expression as MethodInvocation; |
| expect(methodInvocation.target, isNotNull); |
| expect(methodInvocation.operator!.type, TokenType.PERIOD); |
| expect(methodInvocation.methodName, isNotNull); |
| expect(methodInvocation.typeArguments, isNotNull); |
| expect(methodInvocation.argumentList, isNotNull); |
| } |
| |
| void test_parsePostfixExpression_none_propertyAccess() { |
| Expression expression = parsePostfixExpression('a.b'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var identifier = expression as PrefixedIdentifier; |
| expect(identifier.prefix, isNotNull); |
| expect(identifier.identifier, isNotNull); |
| } |
| |
| void test_parsePrefixedIdentifier_noPrefix() { |
| String lexeme = "bar"; |
| Identifier identifier = parsePrefixedIdentifier(lexeme); |
| expect(identifier, isNotNull); |
| assertNoErrors(); |
| var simpleIdentifier = identifier as SimpleIdentifier; |
| expect(simpleIdentifier.token, isNotNull); |
| expect(simpleIdentifier.name, lexeme); |
| } |
| |
| void test_parsePrefixedIdentifier_prefix() { |
| String lexeme = "foo.bar"; |
| Identifier identifier = parsePrefixedIdentifier(lexeme); |
| expect(identifier, isNotNull); |
| assertNoErrors(); |
| var prefixedIdentifier = identifier as PrefixedIdentifier; |
| expect(prefixedIdentifier.prefix.name, "foo"); |
| expect(prefixedIdentifier.period, isNotNull); |
| expect(prefixedIdentifier.identifier.name, "bar"); |
| } |
| |
| void test_parsePrimaryExpression_const() { |
| Expression expression = parsePrimaryExpression('const A()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_double() { |
| String doubleLiteral = "3.2e4"; |
| Expression expression = parsePrimaryExpression(doubleLiteral); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as DoubleLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, double.parse(doubleLiteral)); |
| } |
| |
| void test_parsePrimaryExpression_false() { |
| Expression expression = parsePrimaryExpression('false'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as BooleanLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, isFalse); |
| } |
| |
| void test_parsePrimaryExpression_function_arguments() { |
| Expression expression = parsePrimaryExpression('(int i) => i + 1'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.parameters, isNotNull); |
| expect(functionExpression.body, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_function_noArguments() { |
| Expression expression = parsePrimaryExpression('() => 42'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.parameters, isNotNull); |
| expect(functionExpression.body, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_genericFunctionExpression() { |
| Expression expression = |
| parsePrimaryExpression('<X, Y>(Map<X, Y> m, X x) => m[x]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var functionExpression = expression as FunctionExpression; |
| expect(functionExpression.typeParameters, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_hex() { |
| String hexLiteral = "3F"; |
| Expression expression = parsePrimaryExpression('0x$hexLiteral'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as IntegerLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, int.parse(hexLiteral, radix: 16)); |
| } |
| |
| void test_parsePrimaryExpression_identifier() { |
| Expression expression = parsePrimaryExpression('a'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var identifier = expression as SimpleIdentifier; |
| expect(identifier, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_int() { |
| String intLiteral = "472"; |
| Expression expression = parsePrimaryExpression(intLiteral); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as IntegerLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, int.parse(intLiteral)); |
| } |
| |
| void test_parsePrimaryExpression_listLiteral() { |
| Expression expression = parsePrimaryExpression('[ ]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as ListLiteral; |
| expect(literal, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_listLiteral_index() { |
| Expression expression = parsePrimaryExpression('[]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as ListLiteral; |
| expect(literal, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_listLiteral_typed() { |
| Expression expression = parsePrimaryExpression('<A>[ ]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as ListLiteral; |
| expect(literal.typeArguments, isNotNull); |
| expect(literal.typeArguments!.arguments, hasLength(1)); |
| } |
| |
| void test_parsePrimaryExpression_mapLiteral() { |
| Expression expression = parsePrimaryExpression('{}'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SetOrMapLiteral; |
| expect(literal.typeArguments, isNull); |
| expect(literal, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_mapLiteral_typed() { |
| Expression expression = parsePrimaryExpression('<A, B>{}'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SetOrMapLiteral; |
| expect(literal.typeArguments, isNotNull); |
| expect(literal.typeArguments!.arguments, hasLength(2)); |
| } |
| |
| void test_parsePrimaryExpression_new() { |
| Expression expression = parsePrimaryExpression('new A()'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var creation = expression as InstanceCreationExpression; |
| expect(creation, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_null() { |
| Expression expression = parsePrimaryExpression('null'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression, isNullLiteral); |
| var literal = expression as NullLiteral; |
| expect(literal.literal, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_parenthesized() { |
| Expression expression = parsePrimaryExpression('(x)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var parens = expression as ParenthesizedExpression; |
| expect(parens, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_string() { |
| Expression expression = parsePrimaryExpression('"string"'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.isMultiline, isFalse); |
| expect(literal.isRaw, isFalse); |
| expect(literal.value, "string"); |
| } |
| |
| void test_parsePrimaryExpression_string_multiline() { |
| Expression expression = parsePrimaryExpression("'''string'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.isMultiline, isTrue); |
| expect(literal.isRaw, isFalse); |
| expect(literal.value, "string"); |
| } |
| |
| void test_parsePrimaryExpression_string_raw() { |
| Expression expression = parsePrimaryExpression("r'string'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.isMultiline, isFalse); |
| expect(literal.isRaw, isTrue); |
| expect(literal.value, "string"); |
| } |
| |
| void test_parsePrimaryExpression_super() { |
| Expression expression = parseExpression('super.x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var propertyAccess = expression as PropertyAccess; |
| expect(propertyAccess.target is SuperExpression, isTrue); |
| expect(propertyAccess.operator, isNotNull); |
| expect(propertyAccess.operator.type, TokenType.PERIOD); |
| expect(propertyAccess.propertyName, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_this() { |
| Expression expression = parsePrimaryExpression('this'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var thisExpression = expression as ThisExpression; |
| expect(thisExpression.thisKeyword, isNotNull); |
| } |
| |
| void test_parsePrimaryExpression_true() { |
| Expression expression = parsePrimaryExpression('true'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as BooleanLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, isTrue); |
| } |
| |
| void test_parseRedirectingConstructorInvocation_named() { |
| var invocation = parseConstructorInitializer('this.a()') |
| as RedirectingConstructorInvocation; |
| assertNoErrors(); |
| expect(invocation.argumentList, isNotNull); |
| expect(invocation.constructorName, isNotNull); |
| expect(invocation.thisKeyword, isNotNull); |
| expect(invocation.period, isNotNull); |
| } |
| |
| void test_parseRedirectingConstructorInvocation_unnamed() { |
| var invocation = parseConstructorInitializer('this()') |
| as RedirectingConstructorInvocation; |
| assertNoErrors(); |
| expect(invocation.argumentList, isNotNull); |
| expect(invocation.constructorName, isNull); |
| expect(invocation.thisKeyword, isNotNull); |
| expect(invocation.period, isNull); |
| } |
| |
| void test_parseRelationalExpression_as_chained() { |
| var asExpression = parseExpression('x as Y as Z', |
| errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 2)]) |
| as AsExpression; |
| expect(asExpression, isNotNull); |
| var identifier = asExpression.expression as SimpleIdentifier; |
| expect(identifier.name, 'x'); |
| expect(asExpression.asOperator, isNotNull); |
| var namedType = asExpression.type as NamedType; |
| expect(namedType.name.name, 'Y'); |
| } |
| |
| void test_parseRelationalExpression_as_functionType_noReturnType() { |
| Expression expression = parseRelationalExpression('x as Function(int)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var asExpression = expression as AsExpression; |
| expect(asExpression.expression, isNotNull); |
| expect(asExpression.asOperator, isNotNull); |
| expect(asExpression.type, isGenericFunctionType); |
| } |
| |
| void test_parseRelationalExpression_as_functionType_returnType() { |
| Expression expression = |
| parseRelationalExpression('x as String Function(int)'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var asExpression = expression as AsExpression; |
| expect(asExpression.expression, isNotNull); |
| expect(asExpression.asOperator, isNotNull); |
| expect(asExpression.type, isGenericFunctionType); |
| } |
| |
| void test_parseRelationalExpression_as_generic() { |
| Expression expression = parseRelationalExpression('x as C<D>'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var asExpression = expression as AsExpression; |
| expect(asExpression.expression, isNotNull); |
| expect(asExpression.asOperator, isNotNull); |
| expect(asExpression.type, isNamedType); |
| } |
| |
| void test_parseRelationalExpression_as_simple() { |
| Expression expression = parseRelationalExpression('x as Y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var asExpression = expression as AsExpression; |
| expect(asExpression.expression, isNotNull); |
| expect(asExpression.asOperator, isNotNull); |
| expect(asExpression.type, isNamedType); |
| } |
| |
| void test_parseRelationalExpression_as_simple_function() { |
| Expression expression = parseRelationalExpression('x as Function'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var asExpression = expression as AsExpression; |
| expect(asExpression.expression, isNotNull); |
| expect(asExpression.asOperator, isNotNull); |
| expect(asExpression.type, isNamedType); |
| } |
| |
| void test_parseRelationalExpression_is() { |
| Expression expression = parseRelationalExpression('x is y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var isExpression = expression as IsExpression; |
| expect(isExpression.expression, isNotNull); |
| expect(isExpression.isOperator, isNotNull); |
| expect(isExpression.notOperator, isNull); |
| expect(isExpression.type, isNotNull); |
| } |
| |
| void test_parseRelationalExpression_is_chained() { |
| var isExpression = parseExpression('x is Y is! Z', |
| errors: [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 2)]) |
| as IsExpression; |
| expect(isExpression, isNotNull); |
| var identifier = isExpression.expression as SimpleIdentifier; |
| expect(identifier.name, 'x'); |
| expect(isExpression.isOperator, isNotNull); |
| var namedType = isExpression.type as NamedType; |
| expect(namedType.name.name, 'Y'); |
| } |
| |
| void test_parseRelationalExpression_isNot() { |
| Expression expression = parseRelationalExpression('x is! y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var isExpression = expression as IsExpression; |
| expect(isExpression.expression, isNotNull); |
| expect(isExpression.isOperator, isNotNull); |
| expect(isExpression.notOperator, isNotNull); |
| expect(isExpression.type, isNotNull); |
| } |
| |
| void test_parseRelationalExpression_normal() { |
| Expression expression = parseRelationalExpression('x < y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.LT); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseRelationalExpression_super() { |
| Expression expression = parseRelationalExpression('super < y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var binaryExpression = expression as BinaryExpression; |
| expect(binaryExpression.leftOperand, isNotNull); |
| expect(binaryExpression.operator, isNotNull); |
| expect(binaryExpression.operator.type, TokenType.LT); |
| expect(binaryExpression.rightOperand, isNotNull); |
| } |
| |
| void test_parseRethrowExpression() { |
| RethrowExpression expression = parseRethrowExpression('rethrow'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.rethrowKeyword, isNotNull); |
| } |
| |
| void test_parseShiftExpression_normal() { |
| BinaryExpression expression = parseShiftExpression('x << y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.leftOperand, isNotNull); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.LT_LT); |
| expect(expression.rightOperand, isNotNull); |
| } |
| |
| void test_parseShiftExpression_super() { |
| BinaryExpression expression = parseShiftExpression('super << y'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.leftOperand, isNotNull); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.LT_LT); |
| expect(expression.rightOperand, isNotNull); |
| } |
| |
| void test_parseSimpleIdentifier1_normalIdentifier() { |
| // TODO(brianwilkerson) Implement tests for this method. |
| } |
| |
| void test_parseSimpleIdentifier_builtInIdentifier() { |
| String lexeme = "as"; |
| SimpleIdentifier identifier = parseSimpleIdentifier(lexeme); |
| expect(identifier, isNotNull); |
| assertNoErrors(); |
| expect(identifier.token, isNotNull); |
| expect(identifier.name, lexeme); |
| } |
| |
| void test_parseSimpleIdentifier_normalIdentifier() { |
| String lexeme = "foo"; |
| SimpleIdentifier identifier = parseSimpleIdentifier(lexeme); |
| expect(identifier, isNotNull); |
| assertNoErrors(); |
| expect(identifier.token, isNotNull); |
| expect(identifier.name, lexeme); |
| } |
| |
| void test_parseStringLiteral_adjacent() { |
| Expression expression = parseStringLiteral("'a' 'b'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as AdjacentStrings; |
| NodeList<StringLiteral> strings = literal.strings; |
| expect(strings, hasLength(2)); |
| StringLiteral firstString = strings[0]; |
| StringLiteral secondString = strings[1]; |
| expect((firstString as SimpleStringLiteral).value, "a"); |
| expect((secondString as SimpleStringLiteral).value, "b"); |
| } |
| |
| void test_parseStringLiteral_endsWithInterpolation() { |
| Expression expression = parseStringLiteral(r"'x$y'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, 'x'); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.leftBracket.lexeme, '\$'); |
| expect(element1.expression, isSimpleIdentifier); |
| expect(element1.rightBracket, isNull); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, ''); |
| } |
| |
| void test_parseStringLiteral_interpolated() { |
| Expression expression = parseStringLiteral("'a \${b} c \$this d'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression, isStringInterpolation); |
| var literal = expression as StringInterpolation; |
| NodeList<InterpolationElement> elements = literal.elements; |
| expect(elements, hasLength(5)); |
| expect(elements[0] is InterpolationString, isTrue); |
| expect(elements[1] is InterpolationExpression, isTrue); |
| expect(elements[2] is InterpolationString, isTrue); |
| expect(elements[3] is InterpolationExpression, isTrue); |
| expect(elements[4] is InterpolationString, isTrue); |
| expect((elements[1] as InterpolationExpression).leftBracket.lexeme, '\${'); |
| expect((elements[1] as InterpolationExpression).rightBracket!.lexeme, '}'); |
| expect((elements[3] as InterpolationExpression).leftBracket.lexeme, '\$'); |
| expect((elements[3] as InterpolationExpression).rightBracket, isNull); |
| } |
| |
| void test_parseStringLiteral_interpolated_void() { |
| Expression expression = parseStringLiteral(r"'<html>$void</html>'"); |
| expect(expression, isNotNull); |
| assertErrors(errors: [ |
| expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 8, 4) |
| ]); |
| expect(expression, isStringInterpolation); |
| var literal = expression as StringInterpolation; |
| NodeList<InterpolationElement> elements = literal.elements; |
| expect(elements, hasLength(3)); |
| expect(elements[0] is InterpolationString, isTrue); |
| expect(elements[1] is InterpolationExpression, isTrue); |
| expect(elements[2] is InterpolationString, isTrue); |
| expect((elements[1] as InterpolationExpression).leftBracket.lexeme, '\$'); |
| expect((elements[1] as InterpolationExpression).rightBracket, isNull); |
| } |
| |
| void test_parseStringLiteral_multiline_encodedSpace() { |
| Expression expression = parseStringLiteral("'''\\x20\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, " \na"); |
| } |
| |
| void test_parseStringLiteral_multiline_endsWithInterpolation() { |
| Expression expression = parseStringLiteral(r"'''x$y'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, 'x'); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.expression, isSimpleIdentifier); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, ''); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedBackslash() { |
| Expression expression = parseStringLiteral("'''\\\\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "\\\na"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedBackslash_raw() { |
| Expression expression = parseStringLiteral("r'''\\\\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "\\\\\na"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedEolMarker() { |
| Expression expression = parseStringLiteral("'''\\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedEolMarker_raw() { |
| Expression expression = parseStringLiteral("r'''\\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedSpaceAndEolMarker() { |
| Expression expression = parseStringLiteral("'''\\ \\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedSpaceAndEolMarker_raw() { |
| Expression expression = parseStringLiteral("r'''\\ \\\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedTab() { |
| Expression expression = parseStringLiteral("'''\\t\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "\t\na"); |
| } |
| |
| void test_parseStringLiteral_multiline_escapedTab_raw() { |
| Expression expression = parseStringLiteral("r'''\\t\na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "\\t\na"); |
| } |
| |
| void test_parseStringLiteral_multiline_quoteAfterInterpolation() { |
| Expression expression = parseStringLiteral(r"""'''$x'y'''"""); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, ''); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.expression, isSimpleIdentifier); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, "'y"); |
| } |
| |
| void test_parseStringLiteral_multiline_startsWithInterpolation() { |
| Expression expression = parseStringLiteral(r"'''${x}y'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, ''); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.expression, isSimpleIdentifier); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, 'y'); |
| } |
| |
| void test_parseStringLiteral_multiline_twoSpaces() { |
| Expression expression = parseStringLiteral("''' \na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_twoSpaces_raw() { |
| Expression expression = parseStringLiteral("r''' \na'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_multiline_untrimmed() { |
| Expression expression = parseStringLiteral("''' a\nb'''"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, " a\nb"); |
| } |
| |
| void test_parseStringLiteral_quoteAfterInterpolation() { |
| Expression expression = parseStringLiteral(r"""'$x"'"""); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, ''); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.expression, isSimpleIdentifier); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, '"'); |
| } |
| |
| void test_parseStringLiteral_single() { |
| Expression expression = parseStringLiteral("'a'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var literal = expression as SimpleStringLiteral; |
| expect(literal.literal, isNotNull); |
| expect(literal.value, "a"); |
| } |
| |
| void test_parseStringLiteral_startsWithInterpolation() { |
| Expression expression = parseStringLiteral(r"'${x}y'"); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var interpolation = expression as StringInterpolation; |
| expect(interpolation.elements, hasLength(3)); |
| expect(interpolation.elements[0], isInterpolationString); |
| var element0 = interpolation.elements[0] as InterpolationString; |
| expect(element0.value, ''); |
| expect(interpolation.elements[1], isInterpolationExpression); |
| var element1 = interpolation.elements[1] as InterpolationExpression; |
| expect(element1.expression, isSimpleIdentifier); |
| expect(interpolation.elements[2], isInterpolationString); |
| var element2 = interpolation.elements[2] as InterpolationString; |
| expect(element2.value, 'y'); |
| } |
| |
| void test_parseSuperConstructorInvocation_named() { |
| var invocation = |
| parseConstructorInitializer('super.a()') as SuperConstructorInvocation; |
| expect(invocation, isNotNull); |
| assertNoErrors(); |
| expect(invocation.argumentList, isNotNull); |
| expect(invocation.constructorName, isNotNull); |
| expect(invocation.superKeyword, isNotNull); |
| expect(invocation.period, isNotNull); |
| } |
| |
| void test_parseSuperConstructorInvocation_unnamed() { |
| var invocation = |
| parseConstructorInitializer('super()') as SuperConstructorInvocation; |
| assertNoErrors(); |
| expect(invocation.argumentList, isNotNull); |
| expect(invocation.constructorName, isNull); |
| expect(invocation.superKeyword, isNotNull); |
| expect(invocation.period, isNull); |
| } |
| |
| void test_parseSymbolLiteral_builtInIdentifier() { |
| SymbolLiteral literal = parseSymbolLiteral('#dynamic.static.abstract'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.poundSign, isNotNull); |
| List<Token> components = literal.components; |
| expect(components, hasLength(3)); |
| expect(components[0].lexeme, "dynamic"); |
| expect(components[1].lexeme, "static"); |
| expect(components[2].lexeme, "abstract"); |
| } |
| |
| void test_parseSymbolLiteral_multiple() { |
| SymbolLiteral literal = parseSymbolLiteral('#a.b.c'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.poundSign, isNotNull); |
| List<Token> components = literal.components; |
| expect(components, hasLength(3)); |
| expect(components[0].lexeme, "a"); |
| expect(components[1].lexeme, "b"); |
| expect(components[2].lexeme, "c"); |
| } |
| |
| void test_parseSymbolLiteral_operator() { |
| SymbolLiteral literal = parseSymbolLiteral('#=='); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.poundSign, isNotNull); |
| List<Token> components = literal.components; |
| expect(components, hasLength(1)); |
| expect(components[0].lexeme, "=="); |
| } |
| |
| void test_parseSymbolLiteral_single() { |
| SymbolLiteral literal = parseSymbolLiteral('#a'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.poundSign, isNotNull); |
| List<Token> components = literal.components; |
| expect(components, hasLength(1)); |
| expect(components[0].lexeme, "a"); |
| } |
| |
| void test_parseSymbolLiteral_void() { |
| SymbolLiteral literal = parseSymbolLiteral('#void'); |
| expect(literal, isNotNull); |
| assertNoErrors(); |
| expect(literal.poundSign, isNotNull); |
| List<Token> components = literal.components; |
| expect(components, hasLength(1)); |
| expect(components[0].lexeme, "void"); |
| } |
| |
| void test_parseThrowExpression() { |
| Expression expression = parseThrowExpression('throw x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var throwExpression = expression as ThrowExpression; |
| expect(throwExpression.throwKeyword, isNotNull); |
| expect(throwExpression.expression, isNotNull); |
| } |
| |
| void test_parseThrowExpressionWithoutCascade() { |
| Expression expression = parseThrowExpressionWithoutCascade('throw x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| var throwExpression = expression as ThrowExpression; |
| expect(throwExpression.throwKeyword, isNotNull); |
| expect(throwExpression.expression, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_decrement_identifier_index() { |
| var expression = parseExpression('--a[0]') as PrefixExpression; |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS_MINUS); |
| expect(expression.operand, isNotNull); |
| IndexExpression operand = expression.operand as IndexExpression; |
| expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>()); |
| expect(operand.index is IntegerLiteral, isTrue); |
| } |
| |
| void test_parseUnaryExpression_decrement_normal() { |
| PrefixExpression expression = parseUnaryExpression('--x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS_MINUS); |
| expect(expression.operand, isNotNull); |
| } |
| |
| @failingTest |
| void test_parseUnaryExpression_decrement_super() { |
| // TODO(danrubel) Reports a different error and different token stream. |
| // Expected: TokenType:<MINUS> |
| // Actual: TokenType:<MINUS_MINUS> |
| PrefixExpression expression = parseUnaryExpression('--super'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS); |
| Expression innerExpression = expression.operand; |
| expect(innerExpression, isNotNull); |
| expect(innerExpression is PrefixExpression, isTrue); |
| PrefixExpression operand = innerExpression as PrefixExpression; |
| expect(operand.operator, isNotNull); |
| expect(operand.operator.type, TokenType.MINUS); |
| expect(operand.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_decrement_super_propertyAccess() { |
| PrefixExpression expression = parseUnaryExpression('--super.x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS_MINUS); |
| expect(expression.operand, isNotNull); |
| PropertyAccess operand = expression.operand as PropertyAccess; |
| expect(operand.target is SuperExpression, isTrue); |
| expect(operand.propertyName.name, "x"); |
| } |
| |
| @failingTest |
| void test_parseUnaryExpression_decrement_super_withComment() { |
| // TODO(danrubel) Reports a different error and different token stream. |
| // Expected: TokenType:<MINUS> |
| // Actual: TokenType:<MINUS_MINUS> |
| |
| PrefixExpression expression = parseUnaryExpression('/* 0 */ --super'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS); |
| expect(expression.operator.precedingComments, isNotNull); |
| Expression innerExpression = expression.operand; |
| expect(innerExpression, isNotNull); |
| expect(innerExpression is PrefixExpression, isTrue); |
| PrefixExpression operand = innerExpression as PrefixExpression; |
| expect(operand.operator, isNotNull); |
| expect(operand.operator.type, TokenType.MINUS); |
| expect(operand.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_increment_identifier_index() { |
| var expression = parseExpression('++a[0]') as PrefixExpression; |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.PLUS_PLUS); |
| expect(expression.operand, isNotNull); |
| IndexExpression operand = expression.operand as IndexExpression; |
| expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>()); |
| expect(operand.index is IntegerLiteral, isTrue); |
| } |
| |
| void test_parseUnaryExpression_increment_normal() { |
| PrefixExpression expression = parseUnaryExpression('++x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.PLUS_PLUS); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_increment_super_index() { |
| PrefixExpression expression = parseUnaryExpression('++super[0]'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.PLUS_PLUS); |
| expect(expression.operand, isNotNull); |
| IndexExpression operand = expression.operand as IndexExpression; |
| expect(operand.realTarget is SuperExpression, isTrue); |
| expect(operand.index is IntegerLiteral, isTrue); |
| } |
| |
| void test_parseUnaryExpression_increment_super_propertyAccess() { |
| PrefixExpression expression = parseUnaryExpression('++super.x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.PLUS_PLUS); |
| expect(expression.operand, isNotNull); |
| PropertyAccess operand = expression.operand as PropertyAccess; |
| expect(operand.target is SuperExpression, isTrue); |
| expect(operand.propertyName.name, "x"); |
| } |
| |
| void test_parseUnaryExpression_minus_identifier_index() { |
| var expression = parseExpression('-a[0]') as PrefixExpression; |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS); |
| expect(expression.operand, isNotNull); |
| IndexExpression operand = expression.operand as IndexExpression; |
| expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>()); |
| expect(operand.index is IntegerLiteral, isTrue); |
| } |
| |
| void test_parseUnaryExpression_minus_normal() { |
| PrefixExpression expression = parseUnaryExpression('-x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_minus_super() { |
| PrefixExpression expression = parseUnaryExpression('-super'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.MINUS); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_not_normal() { |
| PrefixExpression expression = parseUnaryExpression('!x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.BANG); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_not_super() { |
| PrefixExpression expression = parseUnaryExpression('!super'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.BANG); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_tilda_normal() { |
| PrefixExpression expression = parseUnaryExpression('~x'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.TILDE); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_tilda_super() { |
| PrefixExpression expression = parseUnaryExpression('~super'); |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.TILDE); |
| expect(expression.operand, isNotNull); |
| } |
| |
| void test_parseUnaryExpression_tilde_identifier_index() { |
| var expression = parseExpression('~a[0]') as PrefixExpression; |
| expect(expression, isNotNull); |
| assertNoErrors(); |
| expect(expression.operator, isNotNull); |
| expect(expression.operator.type, TokenType.TILDE); |
| expect(expression.operand, isNotNull); |
| IndexExpression operand = expression.operand as IndexExpression; |
| expect(operand.realTarget, const TypeMatcher<SimpleIdentifier>()); |
| expect(operand.index is IntegerLiteral, isTrue); |
| } |
| |
| void test_setLiteral() { |
| var set = parseExpression('{3}') as SetOrMapLiteral; |
| expect(set.constKeyword, isNull); |
| expect(set.typeArguments, isNull); |
| expect(set.elements, hasLength(1)); |
| var value = set.elements[0] as IntegerLiteral; |
| expect(value.value, 3); |
| } |
| |
| void test_setLiteral_const() { |
| var set = parseExpression('const {3, 6}') as SetOrMapLiteral; |
| expect(set.constKeyword, isNotNull); |
| expect(set.typeArguments, isNull); |
| expect(set.elements, hasLength(2)); |
| var value1 = set.elements[0] as IntegerLiteral; |
| expect(value1.value, 3); |
| var value2 = set.elements[1] as IntegerLiteral; |
| expect(value2.value, 6); |
| } |
| |
| void test_setLiteral_const_typed() { |
| var set = parseExpression('const <int>{3}') as SetOrMapLiteral; |
| expect(set.constKeyword, isNotNull); |
| expect(set.typeArguments!.arguments, hasLength(1)); |
| var typeArg = set.typeArguments!.arguments[0] as NamedType; |
| expect(typeArg.name.name, 'int'); |
| expect(set.elements.length, 1); |
| var value = set.elements[0] as IntegerLiteral; |
| expect(value.value, 3); |
| } |
| |
| void test_setLiteral_nested_typeArgument() { |
| var set = parseExpression('<Set<int>>{{3}}') as SetOrMapLiteral; |
| expect(set.constKeyword, isNull); |
| expect(set.typeArguments!.arguments, hasLength(1)); |
| var typeArg1 = set.typeArguments!.arguments[0] as NamedType; |
| expect(typeArg1.name.name, 'Set'); |
| expect(typeArg1.typeArguments!.arguments, hasLength(1)); |
| var typeArg2 = typeArg1.typeArguments!.arguments[0] as NamedType; |
| expect(typeArg2.name.name, 'int'); |
| expect(set.elements.length, 1); |
| var intSet = set.elements[0] as SetOrMapLiteral; |
| expect(intSet.elements, hasLength(1)); |
| var value = intSet.elements[0] as IntegerLiteral; |
| expect(value.value, 3); |
| } |
| |
| void test_setLiteral_typed() { |
| var set = parseExpression('<int>{3}') as SetOrMapLiteral; |
| expect(set.constKeyword, isNull); |
| expect(set.typeArguments!.arguments, hasLength(1)); |
| var typeArg = set.typeArguments!.arguments[0] as NamedType; |
| expect(typeArg.name.name, 'int'); |
| expect(set.elements.length, 1); |
| var value = set.elements[0] as IntegerLiteral; |
| expect(value.value, 3); |
| } |
| } |