blob: 37c8af370901bd2fb51ed6136671f5b5fad30334 [file] [log] [blame]
// 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/analysis/experiments.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 {
final FeatureSet _disabledFeatureSet = FeatureSet.latestLanguageVersion();
final FeatureSet _enabledFeatureSet = FeatureSet.fromEnableFlags2(
sdkLanguageVersion: ExperimentStatus.currentVersion,
flags: [EnableString.variance],
);
@override
CompilationUnitImpl parseCompilationUnit(String content,
{List<ErrorCode>? codes,
List<ExpectedError>? errors,
FeatureSet? featureSet}) {
return super.parseCompilationUnit(
content,
codes: codes,
errors: errors,
featureSet: featureSet ?? _enabledFeatureSet,
);
}
void test_class_disabled_multiple() {
parseCompilationUnit('class A<in T, inout U, out V> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
],
featureSet: _disabledFeatureSet);
}
void test_class_disabled_single() {
parseCompilationUnit('class A<out T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
],
featureSet: _disabledFeatureSet);
}
void test_class_enabled_multiple() {
var unit = parseCompilationUnit('class A<in T, inout U, out V, W> { }');
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<in out inout T> { }', 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<in T> { }');
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: _disabledFeatureSet);
}
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<out String> stringList = [];',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
],
featureSet: _disabledFeatureSet);
}
void test_list_enabled() {
parseCompilationUnit('List<out String> stringList = [];', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
]);
}
void test_mixin_disabled_multiple() {
parseCompilationUnit('mixin A<inout T, out U> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
],
featureSet: _disabledFeatureSet);
}
void test_mixin_disabled_single() {
parseCompilationUnit('mixin A<inout T> { }',
errors: [
expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
],
featureSet: _disabledFeatureSet);
}
void test_mixin_enabled_single() {
var unit = parseCompilationUnit('mixin A<inout T> { }');
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<inout X> = X Function(X);',
errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
],
featureSet: _disabledFeatureSet);
}
void test_typedef_enabled() {
parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
]);
}
}