// 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/error/error.dart'; import 'package:analyzer/src/dart/ast/ast.dart'; import 'package:analyzer/src/dart/scanner/scanner.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(VarianceParserTest); }); } @reflectiveTest class VarianceParserTest extends FastaParserTestCase { @override CompilationUnitImpl parseCompilationUnit(String content, {List? codes, List? errors, FeatureSet? featureSet}) { return super.parseCompilationUnit(content, codes: codes, errors: errors, featureSet: featureSet ?? FeatureSet.forTesting( sdkVersion: '2.5.0', additionalFeatures: [Feature.variance], )); } void test_class_disabled_multiple() { parseCompilationUnit('class A { }', errors: [ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2), expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5), expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3) ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_class_disabled_single() { parseCompilationUnit('class A { }', errors: [ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_class_enabled_multiple() { var unit = parseCompilationUnit('class A { }'); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl.name.name, 'A'); var typeParameters = classDecl.typeParameters!; expect(typeParameters.typeParameters, hasLength(4)); expect(typeParameters.typeParameters[0].name.name, 'T'); expect(typeParameters.typeParameters[1].name.name, 'U'); expect(typeParameters.typeParameters[2].name.name, 'V'); expect(typeParameters.typeParameters[3].name.name, 'W'); var typeParameterImplList = typeParameters.typeParameters; expect((typeParameterImplList[0] as TypeParameterImpl).varianceKeyword, isNotNull); expect( (typeParameterImplList[0] as TypeParameterImpl).varianceKeyword!.lexeme, "in"); expect((typeParameterImplList[1] as TypeParameterImpl).varianceKeyword, isNotNull); expect( (typeParameterImplList[1] as TypeParameterImpl).varianceKeyword!.lexeme, "inout"); expect((typeParameterImplList[2] as TypeParameterImpl).varianceKeyword, isNotNull); expect( (typeParameterImplList[2] as TypeParameterImpl).varianceKeyword!.lexeme, "out"); expect((typeParameterImplList[3] as TypeParameterImpl).varianceKeyword, isNull); } void test_class_enabled_multipleVariances() { var unit = parseCompilationUnit('class A { }', errors: [ expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3), expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5) ]); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl.name.name, 'A'); var typeParameters = classDecl.typeParameters!; expect(typeParameters.typeParameters, hasLength(1)); expect(typeParameters.typeParameters[0].name.name, 'T'); } void test_class_enabled_single() { var unit = parseCompilationUnit('class A { }'); expect(unit.declarations, hasLength(1)); var classDecl = unit.declarations[0] as ClassDeclaration; expect(classDecl.name.name, 'A'); var typeParameters = classDecl.typeParameters!; expect(typeParameters.typeParameters, hasLength(1)); expect(typeParameters.typeParameters[0].name.name, 'T'); var typeParameterImpl = typeParameters.typeParameters[0] as TypeParameterImpl; expect(typeParameterImpl.varianceKeyword, isNotNull); expect(typeParameterImpl.varianceKeyword!.lexeme, "in"); } void test_function_disabled() { parseCompilationUnit('void A(in int value) {}', errors: [ expectedError( ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 2), expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_function_enabled() { parseCompilationUnit('void A(in int value) {}', errors: [ expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 2), expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3), ]); } void test_list_disabled() { parseCompilationUnit('List stringList = [];', errors: [ expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_list_enabled() { parseCompilationUnit('List stringList = [];', errors: [ expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6), ]); } void test_mixin_disabled_multiple() { parseCompilationUnit('mixin A { }', errors: [ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5), expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_mixin_disabled_single() { parseCompilationUnit('mixin A { }', errors: [ expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_mixin_enabled_single() { var unit = parseCompilationUnit('mixin A { }'); expect(unit.declarations, hasLength(1)); var mixinDecl = unit.declarations[0] as MixinDeclaration; expect(mixinDecl.name.name, 'A'); var typeParameters = mixinDecl.typeParameters!; expect(typeParameters.typeParameters, hasLength(1)); expect(typeParameters.typeParameters[0].name.name, 'T'); } void test_typedef_disabled() { parseCompilationUnit('typedef A = X Function(X);', errors: [ expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), ], featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0')); } void test_typedef_enabled() { parseCompilationUnit('typedef A = X Function(X);', errors: [ expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1), ]); } }