9cafa46290
Less internal, and more consistent to search for feature references. Change-Id: I9f74d12bc2e22317443f7ba5867369266334373f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355504 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Keerti Parthasarathy <keertip@google.com>
207 lines
7.1 KiB
Dart
207 lines
7.1 KiB
Dart
// 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/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: [
|
|
Feature.variance.enableString,
|
|
],
|
|
);
|
|
|
|
@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_OFF_BY_DEFAULT, 8, 2),
|
|
expectedError(
|
|
ParserErrorCode.EXPERIMENT_NOT_ENABLED_OFF_BY_DEFAULT, 14, 5),
|
|
expectedError(
|
|
ParserErrorCode.EXPERIMENT_NOT_ENABLED_OFF_BY_DEFAULT, 23, 3)
|
|
],
|
|
featureSet: _disabledFeatureSet);
|
|
}
|
|
|
|
void test_class_disabled_single() {
|
|
parseCompilationUnit('class A<out T> { }',
|
|
errors: [
|
|
expectedError(
|
|
ParserErrorCode.EXPERIMENT_NOT_ENABLED_OFF_BY_DEFAULT, 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.lexeme, 'A');
|
|
|
|
var typeParameters = classDecl.typeParameters!;
|
|
expect(typeParameters.typeParameters, hasLength(4));
|
|
expect(typeParameters.typeParameters[0].name.lexeme, 'T');
|
|
expect(typeParameters.typeParameters[1].name.lexeme, 'U');
|
|
expect(typeParameters.typeParameters[2].name.lexeme, 'V');
|
|
expect(typeParameters.typeParameters[3].name.lexeme, '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.lexeme, 'A');
|
|
|
|
var typeParameters = classDecl.typeParameters!;
|
|
expect(typeParameters.typeParameters, hasLength(1));
|
|
expect(typeParameters.typeParameters[0].name.lexeme, '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.lexeme, 'A');
|
|
|
|
var typeParameters = classDecl.typeParameters!;
|
|
expect(typeParameters.typeParameters, hasLength(1));
|
|
expect(typeParameters.typeParameters[0].name.lexeme, '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_OFF_BY_DEFAULT, 8, 5),
|
|
expectedError(
|
|
ParserErrorCode.EXPERIMENT_NOT_ENABLED_OFF_BY_DEFAULT, 17, 3),
|
|
],
|
|
featureSet: _disabledFeatureSet);
|
|
}
|
|
|
|
void test_mixin_disabled_single() {
|
|
parseCompilationUnit('mixin A<inout T> { }',
|
|
errors: [
|
|
expectedError(
|
|
ParserErrorCode.EXPERIMENT_NOT_ENABLED_OFF_BY_DEFAULT, 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.lexeme, 'A');
|
|
|
|
var typeParameters = mixinDecl.typeParameters!;
|
|
expect(typeParameters.typeParameters, hasLength(1));
|
|
expect(typeParameters.typeParameters[0].name.lexeme, '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),
|
|
]);
|
|
}
|
|
}
|