blob: f17c8a654d129f99800301a24ca5100c977cc8e7 [file] [log] [blame]
// Copyright (c) 2019, 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/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(StrictRawTypeTest);
});
}
@reflectiveTest
class StrictRawTypeTest extends PubPackageResolutionTest {
@override
void setUp() {
super.setUp();
writeTestPackageAnalysisOptionsFile(
AnalysisOptionsFileConfig(
experiments: experiments,
strictRawTypes: true,
),
);
}
test_asExpression() async {
await assertNoErrorsInCode(r'''
void f(dynamic x) {
print(x as List);
}
''');
}
test_asExpression_typeArgument() async {
await assertNoErrorsInCode(r'''
void f(dynamic x) {
print(x as List<List>);
}
''');
}
test_castPattern() async {
await assertNoErrorsInCode(r'''
void f([(Object, )? l]) {
var (_ as List, ) = l!;
}
''');
}
test_castPattern_typeArgument() async {
await assertNoErrorsInCode(r'''
void f([(Object, )? l]) {
var (_ as List<List>, ) = l!;
}
''');
}
test_constantPattern() async {
// This is not considered a "strict raw type" here, but a "strict inference"
// issue.
await assertNoErrorsInCode(r'''
void f(C<int> c) {
switch (c) {
case const C():
}
}
class C<T> {
const C();
}
''');
}
test_functionParts_optionalTypeArg() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
class C<T> {}
C f(int a) => C();
void g(C a) {}
''');
}
test_genericTypeArgument_extensionType_missingTypeArg() async {
await assertErrorsInCode(r'''
extension type E<T>(int i) {}
void f() {
<List<E>>[];
}
''', [
error(WarningCode.STRICT_RAW_TYPE, 50, 1),
]);
}
test_genericTypeArgument_extensionType_withTypeArg() async {
await assertNoErrorsInCode(r'''
extension type E<T>(int i) {}
void f() {
<List<E<int>>>[];
}
''');
}
test_genericTypeArgument_extensionTypeImplements_missingTypeArg() async {
await assertErrorsInCode(r'''
extension type E(List<int> i) implements Iterable {}
''', [
error(WarningCode.STRICT_RAW_TYPE, 41, 8),
]);
}
test_genericTypeArgument_extensionTypeImplementsExtensionType_missingTypeArg() async {
await assertErrorsInCode(r'''
extension type E<T>(Iterable<T> i) {}
extension type F(List<int> j) implements E {}
''', [
error(WarningCode.STRICT_RAW_TYPE, 81, 1),
]);
}
test_genericTypeArgument_extensionTypeRepresentationType_missingTypeArg() async {
await assertErrorsInCode(r'''
extension type E(List i) {}
''', [
error(WarningCode.STRICT_RAW_TYPE, 17, 4),
]);
}
test_genericTypeArgument_missingTypeArg() async {
await assertErrorsInCode(r'''
void f() {
var a = <List>[];
}
''', [
error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
error(WarningCode.STRICT_RAW_TYPE, 22, 4),
]);
}
test_genericTypeArgument_withTypeArg() async {
await assertErrorsInCode(r'''
void f() {
var a = <List<int>>[];
}
''', [
error(HintCode.UNUSED_LOCAL_VARIABLE, 17, 1),
]);
}
test_instanceCreation() async {
// This is not considered a "strict raw type" here, but a "strict inference"
// issue.
await assertNoErrorsInCode(r'''
var c = List.empty();
''');
}
test_isExpression() async {
await assertNoErrorsInCode(r'''
void f(dynamic x) {
print(x is List);
print(x is List<dynamic>);
print(x is List<List>);
}
''');
}
test_localVariable_extensionType_missingTypeArg() async {
await assertErrorsInCode(r'''
extension type E<T>(int i) {}
void f() {
E e = E(1);
}
''', [
error(WarningCode.STRICT_RAW_TYPE, 48, 1),
error(WarningCode.UNUSED_LOCAL_VARIABLE, 50, 1),
]);
}
test_localVariable_extensionType_withTypeArg() async {
await assertErrorsInCode(r'''
extension type E<T>(int i) {}
void f() {
E<int> e = E<int>(1);
}
''', [
error(WarningCode.UNUSED_LOCAL_VARIABLE, 55, 1),
]);
}
test_localVariable_missingTypeArg() async {
await assertErrorsInCode(r'''
void f() {
List a = [1, 2, 3];
}
''', [
error(WarningCode.STRICT_RAW_TYPE, 13, 4),
error(HintCode.UNUSED_LOCAL_VARIABLE, 18, 1),
]);
}
test_localVariable_withTypeArg() async {
await assertNoErrorsInCode(r'''
void f() {
List<Object> a = [1, 2, 3];
print(a);
}
''');
}
test_mixinApplication_missing() async {
await assertErrorsInCode(r'''
mixin class C<T> {}
class D = Object with C;
''', [
error(WarningCode.STRICT_RAW_TYPE, 42, 1),
]);
}
test_mixinApplication_withTypeArg() async {
await assertNoErrorsInCode(r'''
mixin class C<T> {}
class D = Object with C<int>;
''');
}
test_nonFunctionTypeAlias_explicitTypeArg() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode('''
typedef List2<T> = List<T>;
void f(List2<int> a) {}
''');
}
test_nonFunctionTypeAlias_missingTypeArg() async {
writeTestPackageConfigWithMeta();
await assertErrorsInCode('''
typedef List2<T> = List<T>;
void f(List2 a) {}
''', [
error(WarningCode.STRICT_RAW_TYPE, 35, 5),
]);
}
test_nonFunctionTypeAlias_optionalTypeArgs() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode('''
import 'package:meta/meta.dart';
@optionalTypeArgs
typedef List2<T> = List<T>;
void f(List2 a) {}
''');
}
test_objectPattern() async {
// This is not considered a "strict raw type" here, but a "strict inference"
// issue.
await assertNoErrorsInCode(r'''
void f(Object o) {
switch (o) {
case List():
}
}
''');
}
test_parameter_missingTypeArg() async {
await assertErrorsInCode(r'''
void f(List a) {}
''', [error(WarningCode.STRICT_RAW_TYPE, 7, 4)]);
}
test_returnType_missingTypeArg() async {
await assertErrorsInCode(r'''
List f(int a) => [1, 2, 3];
''', [error(WarningCode.STRICT_RAW_TYPE, 0, 4)]);
}
test_superclassWith_missingTypeArg() async {
await assertErrorsInCode(r'''
mixin class C<T> {}
class D extends Object with C {}
''', [
error(WarningCode.STRICT_RAW_TYPE, 48, 1),
]);
}
test_superclassWith_withTypeArg() async {
await assertNoErrorsInCode(r'''
mixin class C<T> {}
class D extends Object with C<int> {}
''');
}
test_topLevelField_missingTypeArg() async {
await assertErrorsInCode(r'''
List a = [];
''', [error(WarningCode.STRICT_RAW_TYPE, 0, 4)]);
}
test_topLevelField_optionalTypeArg() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
class C<T> {}
C a = C();
C get g => C();
void set s(C a) {}
''');
}
test_topLevelField_withTypeArg() async {
await assertNoErrorsInCode(r'''
List<int> a = [];
List<num> get g => [];
void set s(List<double> a) {}
''');
}
test_topLevelGetter_missingTypeArg() async {
await assertErrorsInCode(r'''
List get g => [];
''', [error(WarningCode.STRICT_RAW_TYPE, 0, 4)]);
}
test_topLevelSetter_missingTypeArg() async {
await assertErrorsInCode(r'''
void set s(List a) {}
''', [error(WarningCode.STRICT_RAW_TYPE, 11, 4)]);
}
test_typeAlias_classic_missingTypeArg() async {
await assertErrorsInCode(r'''
typedef T F1<T>(T _);
F1 func = (a) => a;
''', [error(WarningCode.STRICT_RAW_TYPE, 22, 2)]);
}
test_typeAlias_modern_missingTypeArg() async {
await assertErrorsInCode(r'''
typedef F1<T> = T Function(T);
F1 func = (a) => a;
''', [error(WarningCode.STRICT_RAW_TYPE, 31, 2)]);
}
test_typeAlias_modern_optionalTypeArgs() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
typedef T F1<T>(T _);
@optionalTypeArgs
typedef F2<T> = T Function(T);
F1 f1 = (a) => a;
F2 f2 = (a) => a;
''');
}
test_typeAlias_modern_withTypeArg() async {
await assertNoErrorsInCode(r'''
typedef T F1<T>(T _);
typedef F2<T> = T Function(T);
typedef F3 = T Function<T>(T);
F1<int> f1 = (a) => a;
F2<int> f2 = (a) => a;
F3 f3 = <T>(T a) => a;
''');
}
test_typeInClassDeclaration_optionalTypeArgs() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
mixin class C<T> {}
class D extends C {}
class E extends Object with C {}
class F = Object with C;
class G implements C {}
''');
}
test_typeInConstructorName() async {
await assertNoErrorsInCode(r'''
class C {
C();
C.named();
}
var c = C();
var d = C.named();
''');
}
test_typeInExtendedType_anonymous_missing() async {
await assertErrorsInCode(r'''
extension on List {}
''', [error(WarningCode.STRICT_RAW_TYPE, 13, 4)]);
}
test_typeInExtendedType_missing() async {
await assertErrorsInCode(r'''
extension E on List {}
''', [error(WarningCode.STRICT_RAW_TYPE, 15, 4)]);
}
test_typeInExtendedType_optionalTypeArgs() async {
writeTestPackageConfigWithMeta();
await assertNoErrorsInCode(r'''
import 'package:meta/meta.dart';
@optionalTypeArgs
class C<T> {}
extension E on C {}
extension on C {}
''');
}
test_typeInExtendedType_present() async {
await assertNoErrorsInCode(r'''
extension E<T> on List<T> {}
extension F on List<int> {}
''');
}
test_typeInInterface_missing() async {
await assertErrorsInCode(r'''
class C<T> {}
class D implements C {}
''', [error(WarningCode.STRICT_RAW_TYPE, 33, 1)]);
}
test_typeInInterface_withTypeArg() async {
await assertNoErrorsInCode(r'''
class C<T> {}
class D implements C<int> {}
''');
}
test_typeInSuperclass_missing() async {
await assertErrorsInCode(r'''
class C<T> {}
class D extends C {}
''', [error(WarningCode.STRICT_RAW_TYPE, 30, 1)]);
}
test_typeInSuperclass_withTypeArg() async {
await assertNoErrorsInCode(r'''
class C<T> {}
class D extends C<int> {}
''');
}
test_typeParameterBound_missingTypeArg() async {
await assertErrorsInCode(r'''
class C<T> {}
class D<T extends C> {}
''', [error(WarningCode.STRICT_RAW_TYPE, 32, 1)]);
}
test_typeParameterBound_withTypeArg() async {
await assertNoErrorsInCode(r'''
class C<T> {}
class D<S, T extends C<S>> {}
''');
}
}