| // 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/analysis/features.dart'; | |
| 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/error/codes.dart'; | |
| import 'package:analyzer/src/generated/testing/token_factory.dart'; | |
| import 'package:pub_semver/src/version.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 { | |
| final beforeUiAsCode = FeatureSet.fromEnableFlags2( | |
| sdkLanguageVersion: Version.parse('2.2.0'), | |
| flags: [], | |
| ); | |
| 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); | |
| TypeName 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); | |
| TypeName 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); | |
| TypeName 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); | |
| TypeName 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); | |
| TypeName 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); | |
| TypeName 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); | |
| TypeName 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( | |
| CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR, 8, 1) | |
| ]) as InstanceCreationExpressionImpl; | |
| expect(expression, isNotNull); | |
| expect(expression.keyword!.keyword, Keyword.NEW); | |
| ConstructorName name = expression.constructorName; | |
| expect(name, isNotNull); | |
| TypeName 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); | |
| TypeName 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 typeName = asExpression.type as TypeName; | |
| expect(typeName.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, isTypeName); | |
| } | |
| 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, isTypeName); | |
| } | |
| 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, isTypeName); | |
| } | |
| 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 typeName = isExpression.type as TypeName; | |
| expect(typeName.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); | |
| } | |
| } |