// 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. /// @docImport 'complex_parser_test.dart'; library; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/ast/token.dart'; import 'package:analyzer/src/dart/scanner/scanner.dart'; import 'package:analyzer/src/error/codes.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(SimpleParserTest); }); } /// Parser tests that test individual parsing methods. The code fragments should /// be as minimal as possible in order to test the method, but should not test /// the interactions between the method under test and other methods. /// /// More complex tests should be defined in the class [ComplexParserTest]. @reflectiveTest class SimpleParserTest extends FastaParserTestCase { ConstructorName parseConstructorName(String name) { createParser('new $name();'); Statement statement = parser.parseStatement2(); expect(statement, isExpressionStatement); Expression expression = (statement as ExpressionStatement).expression; expect(expression, isInstanceCreationExpression); return (expression as InstanceCreationExpression).constructorName; } ExtendsClause parseExtendsClause(String clause) { createParser('class TestClass $clause {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl, isNotNull); return classDecl.extendsClause!; } List parseIdentifierList(String identifiers) { createParser('show $identifiers'); List combinators = parser.parseCombinators(); expect(combinators, hasLength(1)); return (combinators[0] as ShowCombinator).shownNames; } ImplementsClause parseImplementsClause(String clause) { createParser('class TestClass $clause {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl, isNotNull); return classDecl.implementsClause!; } LibraryIdentifier? parseLibraryIdentifier(String name) { createParser('library $name;'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); expect(unit.directives, hasLength(1)); var directive = unit.directives[0] as LibraryDirective; return directive.name2; } /// Parses the given [content] as a sequence of statements by enclosing it in /// a block. /// /// The [expectedCount] is the number of statements that are expected to be /// parsed. void parseStatementList(String content, int expectedCount) { Statement statement = parseStatement('{$content}'); expect(statement, isBlock); var block = statement as Block; expect(block.statements, hasLength(expectedCount)); } VariableDeclaration parseVariableDeclaration(String declaration) { createParser(declaration); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); expect(unit.declarations, hasLength(1)); var decl = unit.declarations[0] as TopLevelVariableDeclaration; expect(decl, isNotNull); return decl.variables.variables[0]; } WithClause parseWithClause(String clause) { createParser('class TestClass extends Object $clause {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl, isNotNull); return classDecl.withClause!; } void test_classDeclaration_complexTypeParam() { CompilationUnit unit = parseCompilationUnit(''' class C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T> {} '''); var clazz = unit.declarations[0] as ClassDeclaration; expect(clazz.name.lexeme, 'C'); expect(clazz.typeParameters!.typeParameters, hasLength(1)); TypeParameter typeParameter = clazz.typeParameters!.typeParameters[0]; expect(typeParameter.name.lexeme, 'T'); expect(typeParameter.metadata, hasLength(1)); Annotation metadata = typeParameter.metadata[0]; expect(metadata.name.name, 'Foo.bar'); } void test_classDeclaration_invalid_super() { parseCompilationUnit( ''' class C { C() : super.const(); } ''', errors: [ expectedError(ParserErrorCode.INVALID_SUPER_IN_INITIALIZER, 18, 5), expectedError( ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 24, 5, ), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 24, 5), ], ); } void test_classDeclaration_invalid_this() { parseCompilationUnit( ''' class C { C() : this.const(); } ''', errors: [ expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 4), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 23, 5), expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 23, 5), expectedError(ParserErrorCode.CONST_METHOD, 23, 5), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 28, 1), ], ); } void test_method_name_notNull_37733() { // https://github.com/dart-lang/sdk/issues/37733 var unit = parseCompilationUnit( r'class C { f(()); }', errors: [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 12, 1)], ); var classDeclaration = unit.declarations[0] as ClassDeclaration; var method = classDeclaration.members[0] as MethodDeclaration; expect(method.parameters!.parameters, hasLength(1)); var parameter = method.parameters!.parameters[0] as FunctionTypedFormalParameter; expect(parameter.name, isNotNull); } void test_parseAnnotation_n1() { createParser('@A'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNull); expect(annotation.constructorName, isNull); expect(annotation.arguments, isNull); } void test_parseAnnotation_n1_a() { createParser('@A(x,y)'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNull); expect(annotation.constructorName, isNull); expect(annotation.arguments, isNotNull); } void test_parseAnnotation_n2() { createParser('@A.B'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNull); expect(annotation.constructorName, isNull); expect(annotation.arguments, isNull); } void test_parseAnnotation_n2_a() { createParser('@A.B(x,y)'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNull); expect(annotation.constructorName, isNull); expect(annotation.arguments, isNotNull); } void test_parseAnnotation_n3() { createParser('@A.B.C'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNotNull); expect(annotation.constructorName, isNotNull); expect(annotation.arguments, isNull); } void test_parseAnnotation_n3_a() { createParser('@A.B.C(x,y)'); Annotation annotation = parser.parseAnnotation(); expectNotNullIfNoErrors(annotation); assertNoErrors(); expect(annotation.atSign, isNotNull); expect(annotation.name, isNotNull); expect(annotation.period, isNotNull); expect(annotation.constructorName, isNotNull); expect(annotation.arguments, isNotNull); } test_parseArgument() { Expression result = parseArgument('3'); expect(result, const TypeMatcher()); var literal = result as IntegerLiteral; expect(literal.value, 3); } test_parseArgument_named() { Expression result = parseArgument('foo: "a"'); expect(result, const TypeMatcher()); var expression = result as NamedExpression; var literal = expression.expression as StringLiteral; expect(literal.stringValue, 'a'); } void test_parseArgumentList_empty() { createParser('()'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(0)); } void test_parseArgumentList_mixed() { createParser('(w, x, y: y, z: z)'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(4)); } void test_parseArgumentList_noNamed() { createParser('(x, y, z)'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(3)); } void test_parseArgumentList_onlyNamed() { createParser('(x: x, y: y)'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(2)); } void test_parseArgumentList_trailing_comma() { createParser('(x, y, z,)'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(3)); } void test_parseArgumentList_typeArguments() { createParser('(a(d))'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(1)); } void test_parseArgumentList_typeArguments_none() { createParser('(a(d))'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(2)); } void test_parseArgumentList_typeArguments_prefixed() { createParser('(a(d))'); ArgumentList argumentList = parser.parseArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); NodeList arguments = argumentList.arguments; expect(arguments, hasLength(1)); } void test_parseCombinators_h() { createParser('hide a'); List combinators = parser.parseCombinators(); expectNotNullIfNoErrors(combinators); assertNoErrors(); expect(combinators, hasLength(1)); HideCombinator combinator = combinators[0] as HideCombinator; expect(combinator, isNotNull); expect(combinator.keyword, isNotNull); expect(combinator.hiddenNames, hasLength(1)); } void test_parseCombinators_hs() { createParser('hide a show b'); List combinators = parser.parseCombinators(); expectNotNullIfNoErrors(combinators); assertNoErrors(); expect(combinators, hasLength(2)); HideCombinator hideCombinator = combinators[0] as HideCombinator; expect(hideCombinator, isNotNull); expect(hideCombinator.keyword, isNotNull); expect(hideCombinator.hiddenNames, hasLength(1)); ShowCombinator showCombinator = combinators[1] as ShowCombinator; expect(showCombinator, isNotNull); expect(showCombinator.keyword, isNotNull); expect(showCombinator.shownNames, hasLength(1)); } void test_parseCombinators_hshs() { createParser('hide a show b hide c show d'); List combinators = parser.parseCombinators(); expectNotNullIfNoErrors(combinators); assertNoErrors(); expect(combinators, hasLength(4)); } void test_parseCombinators_s() { createParser('show a'); List combinators = parser.parseCombinators(); expectNotNullIfNoErrors(combinators); assertNoErrors(); expect(combinators, hasLength(1)); ShowCombinator combinator = combinators[0] as ShowCombinator; expect(combinator, isNotNull); expect(combinator.keyword, isNotNull); expect(combinator.shownNames, hasLength(1)); } void test_parseCommentAndMetadata_c() { createParser('/** 1 */ class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.metadata, isEmpty); } void test_parseCommentAndMetadata_cmc() { createParser('/** 1 */ @A /** 2 */ class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; Comment comment = declaration.documentationComment!; expect(comment.tokens, hasLength(1)); expect(comment.tokens[0].lexeme, '/** 2 */'); expect(declaration.metadata, hasLength(1)); } void test_parseCommentAndMetadata_cmcm() { createParser('/** 1 */ @A /** 2 */ @B class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.metadata, hasLength(2)); } void test_parseCommentAndMetadata_cmm() { createParser('/** 1 */ @A @B class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.metadata, hasLength(2)); } void test_parseCommentAndMetadata_m() { createParser('@A class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNull); expect(declaration.metadata, hasLength(1)); } void test_parseCommentAndMetadata_mcm() { createParser('@A /** 1 */ @B class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.metadata, hasLength(2)); } void test_parseCommentAndMetadata_mcmc() { createParser('@A /** 1 */ @B /** 2 */ class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.documentationComment!.tokens[0].lexeme, contains('2')); expect(declaration.metadata, hasLength(2)); } void test_parseCommentAndMetadata_mix1() { createParser(r''' /** * aaa */ /** * bbb */ class A {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.metadata, hasLength(0)); List tokens = declaration.documentationComment!.tokens; expect(tokens, hasLength(1)); expect(tokens[0].lexeme, contains('bbb')); } void test_parseCommentAndMetadata_mix2() { createParser(r''' /** * aaa */ /// bbb /// ccc class B {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.metadata, hasLength(0)); List tokens = declaration.documentationComment!.tokens; expect(tokens, hasLength(2)); expect(tokens[0].lexeme, contains('bbb')); expect(tokens[1].lexeme, contains('ccc')); } void test_parseCommentAndMetadata_mix3() { createParser(r''' /// aaa /// bbb /** * ccc */ class C {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.metadata, hasLength(0)); List tokens = declaration.documentationComment!.tokens; expect(tokens, hasLength(1)); expect(tokens[0].lexeme, contains('ccc')); } test_parseCommentAndMetadata_mix4() { createParser(r''' /// aaa /// bbb /** * ccc */ /// ddd class D {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.metadata, hasLength(0)); List tokens = declaration.documentationComment!.tokens; expect(tokens, hasLength(1)); expect(tokens[0].lexeme, contains('ddd')); } test_parseCommentAndMetadata_mix5() { createParser(r''' /** * aaa */ // bbb class E {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.metadata, hasLength(0)); List tokens = declaration.documentationComment!.tokens; expect(tokens, hasLength(1)); expect(tokens[0].lexeme, contains('aaa')); } void test_parseCommentAndMetadata_mm() { createParser('@A @B(x) class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNull); expect(declaration.metadata, hasLength(2)); } void test_parseCommentAndMetadata_none() { createParser('class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNull); expect(declaration.metadata, isEmpty); } void test_parseCommentAndMetadata_singleLine() { createParser(r''' /// 1 /// 2 class C {} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expectNotNullIfNoErrors(unit); assertNoErrors(); var declaration = unit.declarations[0] as ClassDeclaration; expect(declaration.documentationComment, isNotNull); expect(declaration.metadata, isEmpty); } void test_parseCommentReferences_notClosed_noIdentifier() { DocumentationCommentToken docToken = DocumentationCommentToken( TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5, ); createParser(''); var comment = parser.parseComment([docToken]); var references = comment.references; expectNotNullIfNoErrors(references); assertNoErrors(); expect(references, hasLength(1)); CommentReference reference = references[0]; Token referenceToken = reference.expression.beginToken; expect(reference, isNotNull); expect(reference.expression, isNotNull); var identifier = reference.expression as Identifier; expect(identifier.isSynthetic, isTrue); expect(identifier.name, ""); // Should end with EOF token. Token nextToken = referenceToken.next!; expect(nextToken, isNotNull); expect(nextToken.type, TokenType.EOF); } void test_parseConfiguration_noOperator_dottedIdentifier() { createParser("if (a.b) 'c.dart'"); Configuration configuration = parser.parseConfiguration(); expectNotNullIfNoErrors(configuration); assertNoErrors(); expect(configuration.ifKeyword, isNotNull); expect(configuration.leftParenthesis, isNotNull); expectDottedName(configuration.name, ["a", "b"]); expect(configuration.equalToken, isNull); expect(configuration.value, isNull); expect(configuration.rightParenthesis, isNotNull); expect(configuration.uri, isNotNull); } void test_parseConfiguration_noOperator_simpleIdentifier() { createParser("if (a) 'b.dart'"); Configuration configuration = parser.parseConfiguration(); expectNotNullIfNoErrors(configuration); assertNoErrors(); expect(configuration.ifKeyword, isNotNull); expect(configuration.leftParenthesis, isNotNull); expectDottedName(configuration.name, ["a"]); expect(configuration.equalToken, isNull); expect(configuration.value, isNull); expect(configuration.rightParenthesis, isNotNull); expect(configuration.uri, isNotNull); } void test_parseConfiguration_operator_dottedIdentifier() { createParser("if (a.b == 'c') 'd.dart'"); Configuration configuration = parser.parseConfiguration(); expectNotNullIfNoErrors(configuration); assertNoErrors(); expect(configuration.ifKeyword, isNotNull); expect(configuration.leftParenthesis, isNotNull); expectDottedName(configuration.name, ["a", "b"]); expect(configuration.equalToken, isNotNull); expect(configuration.value, isNotNull); expect(configuration.rightParenthesis, isNotNull); expect(configuration.uri, isNotNull); } void test_parseConfiguration_operator_simpleIdentifier() { createParser("if (a == 'b') 'c.dart'"); Configuration configuration = parser.parseConfiguration(); expectNotNullIfNoErrors(configuration); assertNoErrors(); expect(configuration.ifKeyword, isNotNull); expect(configuration.leftParenthesis, isNotNull); expectDottedName(configuration.name, ["a"]); expect(configuration.equalToken, isNotNull); expect(configuration.value, isNotNull); expect(configuration.rightParenthesis, isNotNull); expect(configuration.uri, isNotNull); } void test_parseConstructorName_named_noPrefix() { ConstructorName name = parseConstructorName('A.n'); expectNotNullIfNoErrors(name); assertNoErrors(); expect(name.type, isNotNull); expect(name.period, isNull); expect(name.name, isNull); } void test_parseConstructorName_named_prefixed() { ConstructorName name = parseConstructorName('p.A.n'); expectNotNullIfNoErrors(name); assertNoErrors(); expect(name.type, isNotNull); expect(name.period, isNotNull); expect(name.name, isNotNull); } void test_parseConstructorName_unnamed_noPrefix() { ConstructorName name = parseConstructorName('A'); expectNotNullIfNoErrors(name); assertNoErrors(); expect(name.type, isNotNull); expect(name.period, isNull); expect(name.name, isNull); } void test_parseConstructorName_unnamed_prefixed() { ConstructorName name = parseConstructorName('p.A'); expectNotNullIfNoErrors(name); assertNoErrors(); expect(name.type, isNotNull); expect(name.period, isNull); expect(name.name, isNull); } void test_parseDocumentationComment_block() { createParser('/** */ class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); Comment comment = unit.declarations[0].documentationComment!; expectNotNullIfNoErrors(comment); assertNoErrors(); } void test_parseDocumentationComment_block_withReference() { createParser('/** [a] */ class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); Comment comment = unit.declarations[0].documentationComment!; expectNotNullIfNoErrors(comment); assertNoErrors(); NodeList references = comment.references; expect(references, hasLength(1)); CommentReference reference = references[0]; expect(reference, isNotNull); expect(reference.offset, 5); } void test_parseDocumentationComment_endOfLine() { createParser('/// \n/// \n class C {}'); CompilationUnit unit = parser.parseCompilationUnit2(); Comment comment = unit.declarations[0].documentationComment!; expectNotNullIfNoErrors(comment); assertNoErrors(); } void test_parseExtendsClause() { ExtendsClause clause = parseExtendsClause('extends B'); expectNotNullIfNoErrors(clause); assertNoErrors(); expect(clause.extendsKeyword, isNotNull); expect(clause.superclass, isNotNull); expect(clause.superclass, isNamedType); } void test_parseFunctionBody_block() { createParser('{}'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isBlockFunctionBody); var body = functionBody as BlockFunctionBody; expect(body.keyword, isNull); expect(body.star, isNull); expect(body.block, isNotNull); expect(body.isAsynchronous, isFalse); expect(body.isGenerator, isFalse); expect(body.isSynchronous, isTrue); } void test_parseFunctionBody_block_async() { createParser('async {}'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isBlockFunctionBody); var body = functionBody as BlockFunctionBody; expect(body.keyword, isNotNull); expect(body.keyword!.lexeme, Keyword.ASYNC.lexeme); expect(body.star, isNull); expect(body.block, isNotNull); expect(body.isAsynchronous, isTrue); expect(body.isGenerator, isFalse); expect(body.isSynchronous, isFalse); } void test_parseFunctionBody_block_asyncGenerator() { createParser('async* {}'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isBlockFunctionBody); var body = functionBody as BlockFunctionBody; expect(body.keyword, isNotNull); expect(body.keyword!.lexeme, Keyword.ASYNC.lexeme); expect(body.star, isNotNull); expect(body.block, isNotNull); expect(body.isAsynchronous, isTrue); expect(body.isGenerator, isTrue); expect(body.isSynchronous, isFalse); } void test_parseFunctionBody_block_syncGenerator() { createParser('sync* {}'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isBlockFunctionBody); var body = functionBody as BlockFunctionBody; expect(body.keyword, isNotNull); expect(body.keyword!.lexeme, Keyword.SYNC.lexeme); expect(body.star, isNotNull); expect(body.block, isNotNull); expect(body.isAsynchronous, isFalse); expect(body.isGenerator, isTrue); expect(body.isSynchronous, isTrue); } void test_parseFunctionBody_empty() { createParser(';'); FunctionBody functionBody = parser.parseFunctionBody( true, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isEmptyFunctionBody); var body = functionBody as EmptyFunctionBody; expect(body.semicolon, isNotNull); } void test_parseFunctionBody_expression() { createParser('=> y;'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isExpressionFunctionBody); var body = functionBody as ExpressionFunctionBody; expect(body.keyword, isNull); expect(body.functionDefinition, isNotNull); expect(body.expression, isNotNull); expect(body.semicolon, isNotNull); expect(body.isAsynchronous, isFalse); expect(body.isGenerator, isFalse); expect(body.isSynchronous, isTrue); } void test_parseFunctionBody_expression_async() { createParser('async => y;'); FunctionBody functionBody = parser.parseFunctionBody( false, ParserErrorCode.MISSING_FUNCTION_BODY, false, ); expectNotNullIfNoErrors(functionBody); assertNoErrors(); expect(functionBody, isExpressionFunctionBody); var body = functionBody as ExpressionFunctionBody; expect(body.keyword, isNotNull); expect(body.keyword!.lexeme, Keyword.ASYNC.lexeme); expect(body.functionDefinition, isNotNull); expect(body.expression, isNotNull); expect(body.semicolon, isNotNull); expect(body.isAsynchronous, isTrue); expect(body.isGenerator, isFalse); expect(body.isSynchronous, isFalse); } void test_parseIdentifierList_multiple() { List list = parseIdentifierList('a, b, c'); expectNotNullIfNoErrors(list); assertNoErrors(); expect(list, hasLength(3)); } void test_parseIdentifierList_single() { List list = parseIdentifierList('a'); expectNotNullIfNoErrors(list); assertNoErrors(); expect(list, hasLength(1)); } void test_parseImplementsClause_multiple() { ImplementsClause clause = parseImplementsClause('implements A, B, C'); expectNotNullIfNoErrors(clause); assertNoErrors(); expect(clause.interfaces, hasLength(3)); expect(clause.implementsKeyword, isNotNull); } void test_parseImplementsClause_single() { ImplementsClause clause = parseImplementsClause('implements A'); expectNotNullIfNoErrors(clause); assertNoErrors(); expect(clause.interfaces, hasLength(1)); expect(clause.implementsKeyword, isNotNull); } void test_parseInstanceCreation_keyword_33647() { CompilationUnit unit = parseCompilationUnit(''' var c = new Future.sync(() => 3).then((e) => e); '''); expect(unit, isNotNull); var v = unit.declarations[0] as TopLevelVariableDeclaration; var init = v.variables.variables[0].initializer as MethodInvocation; expect(init.methodName.name, 'then'); NodeList typeArg = init.typeArguments!.arguments; expect(typeArg, hasLength(1)); expect(typeArg[0].beginToken.lexeme, 'int'); } void test_parseInstanceCreation_noKeyword_33647() { CompilationUnit unit = parseCompilationUnit(''' var c = Future.sync(() => 3).then((e) => e); '''); expect(unit, isNotNull); var v = unit.declarations[0] as TopLevelVariableDeclaration; var init = v.variables.variables[0].initializer as MethodInvocation; expect(init.methodName.name, 'then'); NodeList typeArg = init.typeArguments!.arguments; expect(typeArg, hasLength(1)); expect(typeArg[0].beginToken.lexeme, 'int'); } void test_parseInstanceCreation_noKeyword_noPrefix() { createParser('f() => C.n();'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); var f = unit.declarations[0] as FunctionDeclaration; var body = f.functionExpression.body as ExpressionFunctionBody; expect(body.expression, isInstanceCreationExpression); var creation = body.expression as InstanceCreationExpressionImpl; expect(creation.keyword, isNull); ConstructorName constructorName = creation.constructorName; expect(constructorName.type.toSource(), 'C'); expect(constructorName.period, isNotNull); expect(constructorName.name, isNotNull); expect(creation.argumentList, isNotNull); expect(creation.typeArguments, isNull); } void test_parseInstanceCreation_noKeyword_noPrefix_34403() { createParser('f() => C.n();'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); var f = unit.declarations[0] as FunctionDeclaration; var body = f.functionExpression.body as ExpressionFunctionBody; expect(body.expression, isMethodInvocation); var methodInvocation = body.expression as MethodInvocationImpl; var target = methodInvocation.target!; expect(target, isFunctionReference); expect(target.toSource(), 'C'); expect(methodInvocation.methodName.name, 'n'); expect(methodInvocation.argumentList, isNotNull); expect(methodInvocation.typeArguments!.arguments, hasLength(1)); } void test_parseInstanceCreation_noKeyword_prefix() { createParser('f() => p.C.n();'); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); var f = unit.declarations[0] as FunctionDeclaration; var body = f.functionExpression.body as ExpressionFunctionBody; expect(body.expression, isInstanceCreationExpression); var creation = body.expression as InstanceCreationExpression; expect(creation.keyword, isNull); ConstructorName constructorName = creation.constructorName; expect(constructorName.type.toSource(), 'p.C'); expect(constructorName.period, isNotNull); expect(constructorName.name, isNotNull); expect(creation.argumentList, isNotNull); } void test_parseInstanceCreation_noKeyword_varInit() { createParser(''' class C {} void main() {final c = C();} '''); CompilationUnit unit = parser.parseCompilationUnit2(); expect(unit, isNotNull); var f = unit.declarations[1] as FunctionDeclaration; var body = f.functionExpression.body as BlockFunctionBody; var statement = body.block.statements[0] as VariableDeclarationStatement; VariableDeclaration variable = statement.variables.variables[0]; var creation = variable.initializer as MethodInvocation; expect(creation.methodName.name, 'C'); expect(creation.typeArguments!.toSource(), ''); } void test_parseLibraryIdentifier_builtin() { String name = "deferred"; LibraryIdentifier identifier = parseLibraryIdentifier(name)!; expectNotNullIfNoErrors(identifier); assertNoErrors(); expect(identifier.name, name); expect(identifier.beginToken.type.isBuiltIn, isTrue); } void test_parseLibraryIdentifier_invalid() { parseCompilationUnit( 'library ;', errors: [ expectedError(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 0, 7), expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 17, 1), ], ); } void test_parseLibraryIdentifier_multiple() { String name = "a.b.c"; LibraryIdentifier identifier = parseLibraryIdentifier(name)!; expectNotNullIfNoErrors(identifier); assertNoErrors(); expect(identifier.name, name); } void test_parseLibraryIdentifier_pseudo() { String name = "await"; LibraryIdentifier identifier = parseLibraryIdentifier(name)!; expectNotNullIfNoErrors(identifier); assertNoErrors(); expect(identifier.name, name); expect(identifier.beginToken.type.isPseudo, isTrue); } void test_parseLibraryIdentifier_single() { String name = "a"; LibraryIdentifier identifier = parseLibraryIdentifier(name)!; expectNotNullIfNoErrors(identifier); assertNoErrors(); expect(identifier.name, name); } void test_parseOptionalReturnType() { // TODO(brianwilkerson): Implement tests for this method. } void test_parseReturnStatement_noValue() { var statement = parseStatement('return;') as ReturnStatement; expectNotNullIfNoErrors(statement); assertNoErrors(); expect(statement.returnKeyword, isNotNull); expect(statement.expression, isNull); expect(statement.semicolon, isNotNull); } void test_parseReturnStatement_value() { var statement = parseStatement('return x;') as ReturnStatement; expectNotNullIfNoErrors(statement); assertNoErrors(); expect(statement.returnKeyword, isNotNull); expect(statement.expression, isNotNull); expect(statement.semicolon, isNotNull); } void test_parseStatement_function_noReturnType() { createParser(''' Function(core.List x) m() => null; '''); Statement statement = parser.parseStatement2(); expect(statement, isFunctionDeclarationStatement); expect( (statement as FunctionDeclarationStatement) .functionDeclaration .functionExpression .body, isExpressionFunctionBody, ); } void test_parseStatements_multiple() { parseStatementList("return; return;", 2); } void test_parseStatements_single() { parseStatementList("return;", 1); } void test_parseTypeAnnotation_function_noReturnType_noParameters() { createParser('Function()'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNull); expect(functionType.functionKeyword, isNotNull); expect(functionType.typeParameters, isNull); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(0)); } void test_parseTypeAnnotation_function_noReturnType_parameters() { createParser('Function(int, int)'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNull); expect(functionType.functionKeyword, isNotNull); expect(functionType.typeParameters, isNull); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); NodeList parameters = parameterList.parameters; expect(parameters, hasLength(2)); expect(parameters[0], isSimpleFormalParameter); var parameter = parameters[0] as SimpleFormalParameter; expect(parameter.name, isNull); expect(parameter.type, isNamedType); expect((parameter.type as NamedType).name.lexeme, 'int'); expect(parameters[1], isSimpleFormalParameter); parameter = parameters[1] as SimpleFormalParameter; expect(parameter.name, isNull); expect(parameter.type, isNamedType); expect((parameter.type as NamedType).name.lexeme, 'int'); } void test_parseTypeAnnotation_function_noReturnType_typeParameters() { createParser('Function()'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNull); expect(functionType.functionKeyword, isNotNull); var typeParameters = functionType.typeParameters!; expect(typeParameters, isNotNull); expect(typeParameters.typeParameters, hasLength(2)); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(0)); } void test_parseTypeAnnotation_function_noReturnType_typeParameters_parameters() { createParser('Function(String, {T t})'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNull); expect(functionType.functionKeyword, isNotNull); var typeParameters = functionType.typeParameters!; expect(typeParameters, isNotNull); expect(typeParameters.typeParameters, hasLength(1)); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(2)); } void test_parseTypeAnnotation_function_returnType_classFunction() { createParser('Function'); var functionType = parser.parseTypeAnnotation(false) as NamedType; expectNotNullIfNoErrors(functionType); assertNoErrors(); } void test_parseTypeAnnotation_function_returnType_function() { createParser('A Function(B, C) Function(D)'); // TODO(scheglov): improve the test to verify also the node properties var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); } void test_parseTypeAnnotation_function_returnType_noParameters() { createParser('List Function()'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNotNull); expect(functionType.functionKeyword, isNotNull); expect(functionType.typeParameters, isNull); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(0)); } void test_parseTypeAnnotation_function_returnType_parameters() { createParser('List Function(String s, int i)'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNotNull); expect(functionType.functionKeyword, isNotNull); expect(functionType.typeParameters, isNull); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); NodeList parameters = parameterList.parameters; expect(parameters, hasLength(2)); expect(parameters[0], isSimpleFormalParameter); var parameter = parameters[0] as SimpleFormalParameter; expect(parameter.name, isNotNull); expect(parameter.name!.lexeme, 's'); expect(parameter.type, isNamedType); expect((parameter.type as NamedType).name.lexeme, 'String'); expect(parameters[1], isSimpleFormalParameter); parameter = parameters[1] as SimpleFormalParameter; expect(parameter.name, isNotNull); expect(parameter.name!.lexeme, 'i'); expect(parameter.type, isNamedType); expect((parameter.type as NamedType).name.lexeme, 'int'); } void test_parseTypeAnnotation_function_returnType_simple() { createParser('A Function(B, C)'); // TODO(scheglov): improve the test to verify also the node properties var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); } void test_parseTypeAnnotation_function_returnType_typeParameters() { createParser('List Function()'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNotNull); expect(functionType.functionKeyword, isNotNull); var typeParameters = functionType.typeParameters!; expect(typeParameters, isNotNull); expect(typeParameters.typeParameters, hasLength(1)); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(0)); } void test_parseTypeAnnotation_function_returnType_typeParameters_parameters() { createParser('List Function(String s, [T])'); var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); expect(functionType.returnType, isNotNull); expect(functionType.functionKeyword, isNotNull); var typeParameters = functionType.typeParameters!; expect(typeParameters, isNotNull); expect(typeParameters.typeParameters, hasLength(1)); FormalParameterList parameterList = functionType.parameters; expect(parameterList, isNotNull); expect(parameterList.parameters, hasLength(2)); } void test_parseTypeAnnotation_function_returnType_withArguments() { createParser('A Function(C)'); // TODO(scheglov): improve this test to verify also the node properties var functionType = parser.parseTypeAnnotation(false) as GenericFunctionType; expectNotNullIfNoErrors(functionType); assertNoErrors(); } void test_parseTypeAnnotation_named() { createParser('A'); var namedType = parser.parseTypeAnnotation(false) as NamedType; expectNotNullIfNoErrors(namedType); assertNoErrors(); } void test_parseTypeArgumentList_empty() { createParser('<>'); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); listener.assertErrorsWithCodes([ParserErrorCode.EXPECTED_TYPE_NAME]); expect(argumentList.leftBracket, isNotNull); expect(argumentList.arguments, hasLength(1)); expect(argumentList.rightBracket, isNotNull); } void test_parseTypeArgumentList_multiple() { createParser(''); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); expect(argumentList.leftBracket, isNotNull); expect(argumentList.arguments, hasLength(3)); expect(argumentList.rightBracket, isNotNull); } void test_parseTypeArgumentList_nested() { createParser('>'); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); expect(argumentList.leftBracket, isNotNull); expect(argumentList.arguments, hasLength(1)); var argument = argumentList.arguments[0] as NamedType; expect(argument, isNotNull); var innerList = argument.typeArguments!; expect(innerList, isNotNull); expect(innerList.arguments, hasLength(1)); expect(argumentList.rightBracket, isNotNull); } void test_parseTypeArgumentList_nested_withComment_double() { createParser('>'); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); expect(argumentList.leftBracket, isNotNull); expect(argumentList.rightBracket, isNotNull); expect(argumentList.arguments, hasLength(1)); var argument = argumentList.arguments[0] as NamedType; expect(argument, isNotNull); var innerList = argument.typeArguments!; expect(innerList, isNotNull); expect(innerList.leftBracket, isNotNull); expect(innerList.arguments, hasLength(1)); expect(innerList.rightBracket, isNotNull); expect(innerList.rightBracket.precedingComments, isNotNull); } void test_parseTypeArgumentList_nested_withComment_tripple() { createParser('>>'); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); expect(argumentList.leftBracket, isNotNull); expect(argumentList.rightBracket, isNotNull); expect(argumentList.arguments, hasLength(1)); var argument = argumentList.arguments[0] as NamedType; expect(argument, isNotNull); var innerList = argument.typeArguments!; expect(innerList, isNotNull); expect(innerList.leftBracket, isNotNull); expect(innerList.arguments, hasLength(1)); expect(innerList.rightBracket, isNotNull); var innerArgument = innerList.arguments[0] as NamedType; expect(innerArgument, isNotNull); var innerInnerList = innerArgument.typeArguments!; expect(innerInnerList, isNotNull); expect(innerInnerList.leftBracket, isNotNull); expect(innerInnerList.arguments, hasLength(1)); expect(innerInnerList.rightBracket, isNotNull); expect(innerInnerList.rightBracket.precedingComments, isNotNull); } void test_parseTypeArgumentList_single() { createParser(''); TypeArgumentList argumentList = parser.parseTypeArgumentList(); expectNotNullIfNoErrors(argumentList); assertNoErrors(); expect(argumentList.leftBracket, isNotNull); expect(argumentList.arguments, hasLength(1)); expect(argumentList.rightBracket, isNotNull); } void test_parseTypeName_parameterized() { createParser('List'); NamedType namedType = parser.parseTypeName(false); expectNotNullIfNoErrors(namedType); assertNoErrors(); expect(namedType.name, isNotNull); expect(namedType.typeArguments, isNotNull); } void test_parseTypeName_simple() { createParser('int'); NamedType namedType = parser.parseTypeName(false); expectNotNullIfNoErrors(namedType); assertNoErrors(); expect(namedType.name, isNotNull); expect(namedType.typeArguments, isNull); } void test_parseTypeParameter_bounded_functionType_noReturn() { createParser('A extends Function(int)'); TypeParameter parameter = parser.parseTypeParameter(); expectNotNullIfNoErrors(parameter); assertNoErrors(); expect(parameter.bound, isGenericFunctionType); expect(parameter.extendsKeyword, isNotNull); expect(parameter.name, isNotNull); } void test_parseTypeParameter_bounded_functionType_return() { createParser('A extends String Function(int)'); TypeParameter parameter = parser.parseTypeParameter(); expectNotNullIfNoErrors(parameter); assertNoErrors(); expect(parameter.bound, isGenericFunctionType); expect(parameter.extendsKeyword, isNotNull); expect(parameter.name, isNotNull); } void test_parseTypeParameter_bounded_generic() { createParser('A extends B'); TypeParameter parameter = parser.parseTypeParameter(); expectNotNullIfNoErrors(parameter); assertNoErrors(); expect(parameter.bound, isNamedType); expect(parameter.extendsKeyword, isNotNull); expect(parameter.name, isNotNull); } void test_parseTypeParameter_bounded_simple() { createParser('A extends B'); TypeParameter parameter = parser.parseTypeParameter(); expectNotNullIfNoErrors(parameter); assertNoErrors(); expect(parameter.bound, isNamedType); expect(parameter.extendsKeyword, isNotNull); expect(parameter.name, isNotNull); } void test_parseTypeParameter_simple() { createParser('A'); TypeParameter parameter = parser.parseTypeParameter(); expectNotNullIfNoErrors(parameter); assertNoErrors(); expect(parameter.bound, isNull); expect(parameter.extendsKeyword, isNull); expect(parameter.name, isNotNull); } void test_parseTypeParameterList_multiple() { createParser(''); TypeParameterList parameterList = parser.parseTypeParameterList()!; expectNotNullIfNoErrors(parameterList); assertNoErrors(); expect(parameterList.leftBracket, isNotNull); expect(parameterList.rightBracket, isNotNull); expect(parameterList.typeParameters, hasLength(3)); } void test_parseTypeParameterList_parameterizedWithTrailingEquals() { createParser('>=', expectedEndOffset: 16); TypeParameterList parameterList = parser.parseTypeParameterList()!; expectNotNullIfNoErrors(parameterList); assertNoErrors(); expect(parameterList.leftBracket, isNotNull); expect(parameterList.rightBracket, isNotNull); expect(parameterList.typeParameters, hasLength(1)); } void test_parseTypeParameterList_parameterizedWithTrailingEquals2() { createParser('>=', expectedEndOffset: 27); TypeParameterList parameterList = parser.parseTypeParameterList()!; expectNotNullIfNoErrors(parameterList); assertNoErrors(); expect(parameterList.leftBracket, isNotNull); expect(parameterList.rightBracket, isNotNull); expect(parameterList.typeParameters, hasLength(1)); TypeParameter typeParameter = parameterList.typeParameters[0]; expect(typeParameter.name.lexeme, 'A'); var bound = typeParameter.bound as NamedType; expect(bound.name.lexeme, 'B'); var typeArguments = bound.typeArguments!; expect(typeArguments.arguments, hasLength(1)); expect(typeArguments.rightBracket, isNotNull); expect(typeArguments.rightBracket.precedingComments!.lexeme, '/* foo */'); var argument = typeArguments.arguments[0] as NamedType; expect(argument.name.lexeme, 'E'); } void test_parseTypeParameterList_single() { createParser('<', expectedEndOffset: 0); var parameterList = parser.parseTypeParameterList(); // TODO(danrubel): Consider splitting `<<` and marking the first `<` // as an unexpected token. expect(parameterList, isNull); assertNoErrors(); } void test_parseTypeParameterList_withTrailingEquals() { createParser('=', expectedEndOffset: 3); TypeParameterList parameterList = parser.parseTypeParameterList()!; expectNotNullIfNoErrors(parameterList); assertNoErrors(); expect(parameterList.leftBracket, isNotNull); expect(parameterList.rightBracket, isNotNull); expect(parameterList.typeParameters, hasLength(1)); } void test_parseVariableDeclaration_equals() { VariableDeclaration declaration = parseVariableDeclaration('var a = b;'); expectNotNullIfNoErrors(declaration); assertNoErrors(); expect(declaration.name, isNotNull); expect(declaration.equals, isNotNull); expect(declaration.initializer, isNotNull); } void test_parseVariableDeclaration_final_late() { var statement = parseStatement('final late a;') as VariableDeclarationStatement; var declarationList = statement.variables; assertErrors( errors: [expectedError(ParserErrorCode.MODIFIER_OUT_OF_ORDER, 6, 4)], ); expect(declarationList.keyword!.lexeme, 'final'); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late() { var statement = parseStatement('late a;') as VariableDeclarationStatement; var declarationList = statement.variables; assertErrors( errors: [ expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1), ], ); expect(declarationList.keyword, isNull); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late_final() { var statement = parseStatement('late final a;') as VariableDeclarationStatement; var declarationList = statement.variables; assertNoErrors(); expect(declarationList.keyword!.lexeme, 'final'); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late_init() { var statement = parseStatement('late a = 0;') as VariableDeclarationStatement; var declarationList = statement.variables; assertErrors( errors: [ expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 5, 1), ], ); expect(declarationList.keyword, isNull); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late_type() { var statement = parseStatement('late A a;') as VariableDeclarationStatement; var declarationList = statement.variables; assertNoErrors(); expect(declarationList.lateKeyword, isNotNull); expect(declarationList.keyword, isNull); expect(declarationList.type, isNotNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late_var() { var statement = parseStatement('late var a;') as VariableDeclarationStatement; var declarationList = statement.variables; assertNoErrors(); expect(declarationList.lateKeyword, isNotNull); expect(declarationList.keyword?.lexeme, 'var'); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_late_var_init() { var statement = parseStatement('late var a = 0;') as VariableDeclarationStatement; var declarationList = statement.variables; assertNoErrors(); expect(declarationList.lateKeyword, isNotNull); expect(declarationList.keyword?.lexeme, 'var'); expect(declarationList.type, isNull); expect(declarationList.variables, hasLength(1)); } void test_parseVariableDeclaration_noEquals() { VariableDeclaration declaration = parseVariableDeclaration('var a;'); expectNotNullIfNoErrors(declaration); assertNoErrors(); expect(declaration.name, isNotNull); expect(declaration.equals, isNull); expect(declaration.initializer, isNull); } void test_parseWithClause_multiple() { WithClause clause = parseWithClause('with A, B, C'); expectNotNullIfNoErrors(clause); assertNoErrors(); expect(clause.withKeyword, isNotNull); expect(clause.mixinTypes, hasLength(3)); } void test_parseWithClause_single() { WithClause clause = parseWithClause('with M'); expectNotNullIfNoErrors(clause); assertNoErrors(); expect(clause.withKeyword, isNotNull); expect(clause.mixinTypes, hasLength(1)); } void test_typeAlias_37733() { // https://github.com/dart-lang/sdk/issues/37733 var unit = parseCompilationUnit( r'typedef K=Function(<>($', errors: [ expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 1), expectedError(ParserErrorCode.EXPECTED_TOKEN, 22, 1), expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1), expectedError(ScannerErrorCode.EXPECTED_TOKEN, 23, 1), ], ); var typeAlias = unit.declarations[0] as GenericTypeAlias; expect(typeAlias.name.lexeme, 'K'); var functionType = typeAlias.functionType!; expect(functionType.parameters.parameters, hasLength(1)); var parameter = functionType.parameters.parameters[0]; expect(parameter.name, isNotNull); } void test_typeAlias_parameter_missingIdentifier_37733() { // https://github.com/dart-lang/sdk/issues/37733 var unit = parseCompilationUnit( r'typedef T=Function(());', errors: [ expectedError(CompileTimeErrorCode.INVALID_INLINE_FUNCTION_TYPE, 19, 1), expectedError(ParserErrorCode.MISSING_IDENTIFIER, 19, 1), ], ); var typeAlias = unit.declarations[0] as GenericTypeAlias; expect(typeAlias.name.lexeme, 'T'); var functionType = typeAlias.functionType!; expect(functionType.parameters.parameters, hasLength(1)); var parameter = functionType.parameters.parameters[0]; expect(parameter.name, isNotNull); } }