| // 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:analyzer/dart/analysis/features.dart'; | |
| import 'package:analyzer/dart/ast/ast.dart'; | |
| import 'package:analyzer/src/dart/error/syntactic_errors.dart'; | |
| import 'package:test/test.dart'; | |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; | |
| import 'parser_test_base.dart'; | |
| import 'test_support.dart'; | |
| main() { | |
| defineReflectiveSuite(() { | |
| defineReflectiveTests(GenericMetadataEnabledParserTest); | |
| defineReflectiveTests(GenericMetadataDisabledParserTest); | |
| }); | |
| } | |
| @reflectiveTest | |
| class GenericMetadataDisabledParserTest extends FastaParserTestCase | |
| with GenericMetadataParserTest { | |
| @override | |
| CompilationUnit _parseCompilationUnit(String content, | |
| {List<ExpectedError>? errors, required ExpectedError? disabledError}) { | |
| var combinedErrors = | |
| disabledError == null ? errors : [disabledError, ...?errors]; | |
| return parseCompilationUnit(content, | |
| errors: combinedErrors, | |
| featureSet: FeatureSet.forTesting(sdkVersion: '2.12')); | |
| } | |
| } | |
| @reflectiveTest | |
| class GenericMetadataEnabledParserTest extends FastaParserTestCase | |
| with GenericMetadataParserTest { | |
| @override | |
| CompilationUnit _parseCompilationUnit(String content, | |
| {List<ExpectedError>? errors, | |
| required ExpectedError? disabledError}) => | |
| parseCompilationUnit(content, | |
| errors: errors, | |
| featureSet: FeatureSet.forTesting( | |
| sdkVersion: '2.12', | |
| additionalFeatures: [Feature.generic_metadata])); | |
| } | |
| mixin GenericMetadataParserTest on FastaParserTestCase { | |
| void test_className_prefixed_constructorName_absent() { | |
| var compilationUnit = _parseCompilationUnit('@p.A<B>() class C {}', | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var className = annotation.name as PrefixedIdentifier; | |
| expect(className.prefix.name, 'p'); | |
| expect(className.identifier.name, 'A'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'B'); | |
| expect(annotation.constructorName, isNull); | |
| } | |
| void test_className_prefixed_constructorName_present() { | |
| var compilationUnit = _parseCompilationUnit('@p.A<B>.ctor() class C {}', | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var className = annotation.name as PrefixedIdentifier; | |
| expect(className.prefix.name, 'p'); | |
| expect(className.identifier.name, 'A'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'B'); | |
| expect(annotation.constructorName!.name, 'ctor'); | |
| } | |
| void test_className_unprefixed_constructorName_absent() { | |
| var compilationUnit = _parseCompilationUnit('@A<B>() class C {}', | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var className = annotation.name as SimpleIdentifier; | |
| expect(className.name, 'A'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'B'); | |
| expect(annotation.constructorName, isNull); | |
| } | |
| void test_className_unprefixed_constructorName_present() { | |
| var compilationUnit = _parseCompilationUnit('@A<B>.ctor() class C {}', | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var className = annotation.name as SimpleIdentifier; | |
| expect(className.name, 'A'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'B'); | |
| expect(annotation.constructorName!.name, 'ctor'); | |
| } | |
| void test_reference_prefixed() { | |
| var compilationUnit = _parseCompilationUnit('@p.x<A> class C {}', | |
| errors: [ | |
| expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED, | |
| 6, | |
| 1), | |
| ], | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 4, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var name = annotation.name as PrefixedIdentifier; | |
| expect(name.prefix.name, 'p'); | |
| expect(name.identifier.name, 'x'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'A'); | |
| expect(annotation.constructorName, isNull); | |
| } | |
| void test_reference_unprefixed() { | |
| var compilationUnit = _parseCompilationUnit('@x<A> class C {}', | |
| errors: [ | |
| expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED, | |
| 4, | |
| 1), | |
| ], | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1)); | |
| var classDeclaration = | |
| compilationUnit.declarations.single as ClassDeclaration; | |
| var annotation = classDeclaration.metadata.single; | |
| var name = annotation.name as SimpleIdentifier; | |
| expect(name.name, 'x'); | |
| var typeArgument = annotation.typeArguments!.arguments.single as TypeName; | |
| var typeArgumentName = typeArgument.name as SimpleIdentifier; | |
| expect(typeArgumentName.name, 'A'); | |
| expect(annotation.constructorName, isNull); | |
| } | |
| test_typeArguments_after_constructorName() { | |
| _parseCompilationUnit('@p.A.ctor<B>() class C {}', | |
| errors: [ | |
| expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 9, 1), | |
| expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 10, 1), | |
| expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1), | |
| expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 11, 1), | |
| expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 15, 5), | |
| ], | |
| disabledError: null); | |
| } | |
| test_typeArguments_after_prefix() { | |
| _parseCompilationUnit('@p<A>.B.ctor() class C {}', | |
| errors: [ | |
| expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS_UNINSTANTIATED, | |
| 6, | |
| 1), | |
| expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 7, 1), | |
| expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 15, 5), | |
| ], | |
| disabledError: expectedError( | |
| ParserErrorCode.ANNOTATION_WITH_TYPE_ARGUMENTS, 2, 1)); | |
| } | |
| CompilationUnit _parseCompilationUnit(String content, | |
| {List<ExpectedError>? errors, required ExpectedError? disabledError}); | |
| } |