linter: move 3 rule tests:
* avoid_shadowing_type_parameters
* avoid_type_to_string
* avoid_types_as_parameter_names
Cq-Include-Trybots: luci.dart.try:flutter-analyze-try,analyzer-win-release-try,pkg-win-release-try
Change-Id: Id2ddef557475a76244cf4c75f5720c469b34cf3b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380142
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Auto-Submit: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Phil Quitslund <pquitslund@google.com>
diff --git a/pkg/linter/test/rules/avoid_shadowing_type_parameters_test.dart b/pkg/linter/test/rules/avoid_shadowing_type_parameters_test.dart
index 55b36ee..dcddc7a 100644
--- a/pkg/linter/test/rules/avoid_shadowing_type_parameters_test.dart
+++ b/pkg/linter/test/rules/avoid_shadowing_type_parameters_test.dart
@@ -2,6 +2,7 @@
// 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/analyzer_error_code.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../rule_test_support.dart';
@@ -15,9 +16,134 @@
@reflectiveTest
class AvoidShadowingTypeParametersTest extends LintRuleTest {
@override
+ List<AnalyzerErrorCode> get ignoredErrorCodes => [
+ WarningCode.UNUSED_ELEMENT,
+ WarningCode.UNUSED_LOCAL_VARIABLE,
+ ];
+
+ @override
String get lintRule => 'avoid_shadowing_type_parameters';
- test_enum() async {
+ test_enclosingElementsWithoutTypeParameters() async {
+ // Make sure we don't hit any null pointers when none of a function or
+ // method's ancestors have type parameters.
+ await assertNoDiagnostics(r'''
+class C {
+ void f() {
+ void g() {
+ void h<T>() {}
+ }
+ }
+ void i<T>() {}
+}
+''');
+ }
+
+ test_functionType_enclosingElementWithoutTypeParameters() async {
+ await assertNoDiagnostics(r'''
+typedef Fn5 = void Function<T>(T);
+''');
+ }
+
+ test_functionType_noShadowing() async {
+ await assertNoDiagnostics(r'''
+typedef Fn2<T> = void Function<U>(T);
+''');
+ }
+
+ test_functionType_shadowingTypedef() async {
+ await assertDiagnostics(r'''
+typedef Fn1<T> = void Function<T>(T);
+''', [
+ lint(31, 1),
+ ]);
+ }
+
+ @FailingTest(reason: '')
+ test_functionTypedParameter_shadowingFunction() async {
+ // TODO(srawlins): Report lint here.
+ await assertDiagnostics(r'''
+void fn2<T>(void Function<T>()) {}
+''', [
+ lint(26, 1),
+ ]);
+ }
+
+ test_localFunction_noShadowing() async {
+ await assertNoDiagnostics(r'''
+void f<T>() {
+ void g<U>() {}
+}
+''');
+ }
+
+ test_localFunction_shadowingClass() async {
+ await assertDiagnostics(r'''
+class C<T> {
+ void f() {
+ void g<T>() {}
+ }
+}
+''', [
+ lint(37, 1),
+ ]);
+ }
+
+ test_localFunction_shadowingFunction() async {
+ await assertDiagnostics(r'''
+void f<T>() {
+ void g<T>() {}
+}
+''', [
+ lint(23, 1),
+ ]);
+ }
+
+ test_localFunction_shadowingLocalFunction() async {
+ await assertDiagnostics(r'''
+class C {
+ void f() {
+ void g<T>() {
+ void h<T>() {}
+ }
+ }
+}
+''', [
+ lint(54, 1),
+ ]);
+ }
+
+ test_localFunction_shadowingMethod() async {
+ await assertDiagnostics(r'''
+class C<T> {
+ void fn1<U>() {
+ void fn3<U>() {}
+ }
+}
+''', [
+ lint(44, 1),
+ ]);
+ }
+
+ test_method_noShadowing() async {
+ await assertNoDiagnostics(r'''
+class C<T> {
+ void f<U>() {}
+}
+''');
+ }
+
+ test_method_shadowingClass() async {
+ await assertDiagnostics(r'''
+class C<T> {
+ void f<T>() {}
+}
+''', [
+ lint(22, 1),
+ ]);
+ }
+
+ test_method_shadowingEnum() async {
await assertDiagnostics(r'''
enum E<T> {
a, b, c;
@@ -28,7 +154,17 @@
]);
}
- test_extensionType() async {
+ test_method_shadowingExtension() async {
+ await assertDiagnostics(r'''
+extension E<T> on List<T> {
+ void f<T>() {}
+}
+''', [
+ lint(37, 1),
+ ]);
+ }
+
+ test_method_shadowingExtensionType() async {
await assertDiagnostics(r'''
extension type E<T>(int i) {
void m<T>() {}
@@ -38,6 +174,24 @@
]);
}
+ test_method_shadowingMixin() async {
+ await assertDiagnostics(r'''
+mixin M<T> {
+ void f<T>() {}
+}
+''', [
+ lint(22, 1),
+ ]);
+ }
+
+ test_staticMethod_shadowingClass() async {
+ await assertNoDiagnostics(r'''
+class A<T> {
+ static void f<T>() {}
+}
+''');
+ }
+
test_wildcards() async {
await assertNoDiagnostics(r'''
class A<_> {
diff --git a/pkg/linter/test/rules/avoid_type_to_string_test.dart b/pkg/linter/test/rules/avoid_type_to_string_test.dart
index fc481f7b..4700387 100644
--- a/pkg/linter/test/rules/avoid_type_to_string_test.dart
+++ b/pkg/linter/test/rules/avoid_type_to_string_test.dart
@@ -17,6 +17,18 @@
@override
String get lintRule => 'avoid_type_to_string';
+ test_extensionOnType_implicitThis() async {
+ await assertDiagnostics(r'''
+extension E on Type {
+ void f() {
+ toString();
+ }
+}
+''', [
+ lint(39, 8),
+ ]);
+ }
+
test_extensionType_implicitThis() async {
await assertDiagnostics(r'''
extension type E(int i) {
@@ -40,4 +52,142 @@
lint(55, 8),
]);
}
+
+ test_mixinOnType_explicitThis() async {
+ await assertDiagnostics(r'''
+mixin M on Type {
+ late var x = this.toString();
+}
+''', [
+ lint(38, 8),
+ ]);
+ }
+
+ test_mixinOnType_implicitThis() async {
+ await assertDiagnostics(r'''
+mixin M on Type {
+ late var x = toString();
+}
+''', [
+ lint(33, 8),
+ ]);
+ }
+
+ test_runtimeType() async {
+ await assertDiagnostics(r'''
+var x = 7.runtimeType.toString();
+''', [
+ lint(22, 8),
+ ]);
+ }
+
+ test_type_tearoff() async {
+ await assertDiagnostics(r'''
+void f() {
+ foo(7.runtimeType.toString);
+}
+void foo(String Function() p) {}
+''', [
+ lint(31, 8),
+ ]);
+ }
+
+ test_typeExtendingType_withToStringOverride() async {
+ await assertNoDiagnostics(r'''
+mixin M {
+ @override
+ String toString() => '';
+}
+class Type2 extends Type with M {
+ String get x => toString();
+}
+''');
+ }
+
+ test_typeThatExtendsType() async {
+ await assertDiagnostics(r'''
+var x = Type2().toString();
+class Type2 extends Type {}
+''', [
+ lint(16, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_explicitThis() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {
+ late var x = this.toString();
+}
+''', [
+ lint(47, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_implicitThis() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {
+ late var x = toString();
+}
+''', [
+ lint(42, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_super() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {
+ late var x = super.toString();
+}
+''', [
+ lint(48, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_tearoff() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {}
+void f(Type2 t) {
+ foo(t.toString);
+}
+void foo(String Function() p) {}
+''', [
+ lint(54, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_tearoff_explicitThis() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {
+ void f() {
+ foo(this.toString);
+ }
+ void foo(String Function() p) {}
+}
+''', [
+ lint(53, 8),
+ ]);
+ }
+
+ test_typeThatExtendsType_tearoff_implicitThis() async {
+ await assertDiagnostics(r'''
+class Type2 extends Type {
+ void f() {
+ foo(toString);
+ }
+ void foo(String Function() p) {}
+}
+''', [
+ lint(48, 8),
+ ]);
+ }
+
+ test_typeThatExtendsTypeThatExtendsType() async {
+ await assertDiagnostics(r'''
+var x = Type3().toString();
+class Type2 extends Type {}
+class Type3 extends Type2 {}
+''', [
+ lint(16, 8),
+ ]);
+ }
}
diff --git a/pkg/linter/test/rules/avoid_types_as_parameter_names_test.dart b/pkg/linter/test/rules/avoid_types_as_parameter_names_test.dart
index 2a602dd..82ec82b 100644
--- a/pkg/linter/test/rules/avoid_types_as_parameter_names_test.dart
+++ b/pkg/linter/test/rules/avoid_types_as_parameter_names_test.dart
@@ -17,6 +17,18 @@
@override
String get lintRule => 'avoid_types_as_parameter_names';
+ test_catchClauseParameter() async {
+ await assertDiagnostics(r'''
+class C {}
+
+void f() {
+ try {} catch (C) {}
+}
+''', [
+ lint(39, 1),
+ ]);
+ }
+
test_extensionType() async {
await assertDiagnostics(r'''
extension type E(int i) { }
@@ -27,6 +39,100 @@
]);
}
+ test_factoryParameter_shadowingTypeParameter() async {
+ await assertDiagnostics(r'''
+class C<X> {
+ factory C(X) => C.name();
+ C.name();
+}
+''', [
+ lint(25, 1),
+ ]);
+ }
+
+ test_fieldFormalParameter_missingType() async {
+ await assertNoDiagnostics(r'''
+class C {
+ final int num;
+ C(this.num);
+}
+''');
+ }
+
+ test_functionTypedParameter_missingName() async {
+ await assertDiagnostics(r'''
+void f(void g(int)) {}
+''', [
+ lint(14, 3),
+ ]);
+ }
+
+ test_functionTypedParameter_missingType_named() async {
+ await assertDiagnostics(r'''
+void f(void g({int})) {}
+''', [
+ lint(15, 3),
+ ]);
+ }
+
+ test_functionTypedParameter_missingType_optionalPositional() async {
+ await assertDiagnostics(r'''
+void f(void g([int])) {}
+''', [
+ lint(15, 3),
+ ]);
+ }
+
+ test_functionTypedParameter_noShadowing() async {
+ await assertNoDiagnostics(r'''
+void f(void g(int a)) {}
+''');
+ }
+
+ test_functionTypeParameter_missingName() async {
+ await assertNoDiagnostics(r'''
+void f(int Function(int) g) {}
+''');
+ }
+
+ test_functionTypeParameter_withParameter_noShadowing() async {
+ await assertNoDiagnostics(r'''
+class C<X> {
+ void m(void Function(X) g) {}
+}
+''');
+ }
+
+ test_functionTypeParameter_withParameter_shadowingTypeParameter() async {
+ await assertNoDiagnostics(r'''
+void f(int Function<T>(T) g) {}
+''');
+ }
+
+ test_parameter_shadowingTypeParameter() async {
+ await assertDiagnostics(r'''
+void f<X>(X) {}
+''', [
+ lint(10, 1),
+ ]);
+ }
+
+ test_parameterIsFunctionName() async {
+ await assertNoDiagnostics(r'''
+void f(g) {}
+void g() {}
+''');
+ }
+
+ test_parameterIsTypedefName() async {
+ await assertDiagnostics(r'''
+void f(T) {}
+typedef T = int;
+''', [
+ lint(7, 1),
+ ]);
+ }
+
test_super() async {
await assertDiagnostics(r'''
class A {
@@ -41,6 +147,48 @@
]);
}
+ test_typedefParameter_legacy_missingType() async {
+ await assertDiagnostics(r'''
+typedef void T(int);
+''', [
+ lint(15, 3),
+ ]);
+ }
+
+ test_typedefParameter_legacy_missingType_named() async {
+ await assertDiagnostics(r'''
+typedef void T({int});
+''', [
+ lint(16, 3),
+ ]);
+ }
+
+ test_typedefParameter_legacy_missingType_optionalPositional() async {
+ await assertDiagnostics(r'''
+typedef void f([int]);
+''', [
+ lint(16, 3),
+ ]);
+ }
+
+ test_typedefParameter_legacy_noShadowing() async {
+ await assertNoDiagnostics(r'''
+typedef void T(int a);
+''');
+ }
+
+ test_typedefParameter_legacy_undefinedName() async {
+ await assertNoDiagnostics(r'''
+typedef void f(Undefined);
+''');
+ }
+
+ test_typedefParameter_missingName() async {
+ await assertNoDiagnostics(r'''
+typedef T = int Function(int);
+''');
+ }
+
test_typeParameter_wildcard() async {
await assertDiagnostics(r'''
class C<_> {
diff --git a/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart b/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart
deleted file mode 100644
index 46f3cbab..0000000
--- a/pkg/linter/test_data/rules/avoid_shadowing_type_parameters.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2018, 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.
-
-void fn1<T>() {
- void fn2<T>() {} // LINT
- void fn3<U>() {} // OK
- void fn4() {} // OK
-}
-
-// TODO(srawlins): Lint on this stuff as well when the analyzer/language(?)
-// support it. Right now analyzer spits out a compile time error: "Analysis of
-// generic function typed parameters is not yet supported."
-// void fn2<T>(void Function<T>()) {} // NOT OK
-
-class A<T> {
- static void fn1<T>() {} // OK
-}
-
-extension Ext<T> on A<T> {
- void fn2<T>() {} // LINT
- void fn3<U>() {} // OK
- void fn4<V>() {} // OK
-}
-
-mixin M<T> {
- void fn1<T>() {} // LINT
- void fn2<U>() {} // OK
- void fn3<V>() {} // OK
-}
-
-class B<T> {
- void fn1<T>() {} // LINT
- void fn2<U>() {} // OK
- void fn3<V>() {} // OK
-}
-
-class C<T> {
- void fn1<U>() {
- void fn2<T>() {} // LINT
- void fn3<U>() {} // LINT
- void fn4<V>() {} // OK
- void fn5() {} // OK
- }
-}
-
-class D<T> {
- void fn1<U>() {
- void fn2<V>() {
- void fn3<T>() {} // LINT
- void fn4<U>() {} // LINT
- void fn5<V>() {} // LINT
- void fn6<W>() {} // OK
- void fn7() {} // OK
- }
- }
-}
-
-// Make sure we don't hit any null pointers when none of a function or method's
-// ancestors have type parameters.
-class E {
- void fn1() {
- void fn2() {
- void fn3<T>() {} // OK
- }
- }
-
- void fn4<T>() {} // OK
-}
-
-typedef Fn1<T> = void Function<T>(T); // LINT
-typedef Fn2<T> = void Function<U>(T); // OK
-typedef Fn3<T> = void Function<U>(U); // OK
-typedef Fn4<T> = void Function(T); // OK
-typedef Fn5 = void Function<T>(T); // OK
-
diff --git a/pkg/linter/test_data/rules/avoid_type_to_string.dart b/pkg/linter/test_data/rules/avoid_type_to_string.dart
deleted file mode 100644
index 9dbc9f2..0000000
--- a/pkg/linter/test_data/rules/avoid_type_to_string.dart
+++ /dev/null
@@ -1,151 +0,0 @@
-// 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.
-
-// SHARED
-
-class A {
- String toString() => '';
-}
-
-String takesFunction(Function f) => '';
-
-class TypeChildWithOverride extends Type {
- @override
- String toString() => '';
-}
-
-class TypeGrandChildWithOverride extends TypeChildWithOverride {}
-
-class TypeChildNoOverride extends Type {}
-
-class TypeGrandChildNoOverride extends TypeChildNoOverride {}
-
-mixin ToStringMixin {
- String toString() => '';
-}
-
-// BAD
-
-class Bad {
- void doBad(Function f) {
- A().runtimeType.toString(); // LINT
- TypeChildNoOverride().toString(); // LINT
- TypeGrandChildNoOverride().toString(); // LINT
- }
-}
-
-class BadWithType extends Type {
- Function passedFunction = (){};
-
- BadWithType(Function func) : this.withFunc(func);
- BadWithType.withoutFunc() {}
- BadWithType.withFunc(this.passedFunction) {}
- BadWithType.withSelf(BadWithType badWithType)
- : this.withFunc(badWithType.toString); // LINT
-
- void doBad() {
- toString(); // LINT
- this.toString(); // LINT
-
- print('${toString()}'); // LINT
- print('${this.toString()}'); // LINT
- print('${takesFunction(toString)}'); // LINT
- print('${takesFunction(this.toString)}'); // LINT
-
- takesFunction(toString); // LINT
- takesFunction(this.toString); // LINT
- takesFunction(BadWithType.withoutFunc().toString); // LINT
- Bad().doBad(toString); // LINT
- Bad().doBad(this.toString); // LINT
- Bad().doBad(BadWithType.withoutFunc().toString); // LINT
-
- BadWithType(toString); // LINT
- BadWithType.withFunc(this.toString); // LINT
-
- ((Function internal) => internal())(toString); // LINT
- }
-}
-
-class BadWithTypeChild extends BadWithType {
- BadWithTypeChild(BadWithType badWithType)
- : super(badWithType.toString); // LINT
- BadWithTypeChild.redirect(BadWithType badWithType)
- : super.withFunc(badWithType.toString); // LINT
-}
-
-mixin callToStringOnBadWithType on BadWithType {
- void mixedBad() {
- toString(); // LINT
- this.toString(); // LINT
- }
-}
-
-extension ExtensionOnBadWithType on BadWithType {
- void extendedBad() {
- toString(); // LINT
- this.toString(); // LINT
- }
-}
-
-// GOOD
-
-class Good {
- void doGood() {
- toString(); // OK
- A().toString(); // OK
- TypeChildWithOverride().toString(); // OK
- TypeGrandChildWithOverride().toString(); // OK
-
- final refToString = toString;
- refToString(); // OK?
- takesFunction(refToString); // OK
- }
-}
-
-class GoodWithType extends Type {
- Function passedFunction;
-
- GoodWithType.withFunc(this.passedFunction) {}
- GoodWithType.withSelf(GoodWithTypeAndMixin goodWithTypeAndMixin)
- : this.withFunc(goodWithTypeAndMixin.toString); // OK
- GoodWithType.withOther(Good good) : this.withFunc(good.toString); // OK
-
- void good() {
- String toString() => '';
- toString(); // OK
- }
-}
-
-class GoodWithTypeAndMixin extends Type with ToStringMixin {
- void doGood() {
- toString(); // OK
- this.toString(); // OK
-
- takesFunction(toString); // OK
- takesFunction(this.toString); // OK
- takesFunction(GoodWithTypeAndMixin().toString); // OK
- }
-}
-
-mixin CallToStringOnGoodWithType on GoodWithTypeAndMixin {
- void mixedGood() {
- toString(); // OK
- this.toString(); // OK
- }
-}
-
-extension ExtensionOnGoodWithTypeAndMixin on GoodWithTypeAndMixin {
- void extendedGood() {
- toString(); // OK
- this.toString(); // OK
- }
-}
-
-extension on int Function(int) {
- // ignore: unused_element
- void extendedGood() {
- toString(); // OK
- this.toString(); // OK
- }
-}
diff --git a/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart b/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart
deleted file mode 100644
index 3a89bec..0000000
--- a/pkg/linter/test_data/rules/avoid_types_as_parameter_names.dart
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2018, 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.
-
-class SomeType {}
-
-void f() {
- try {
- // ignore: avoid_catches_without_on_clauses
- } catch(SomeType) { //LINT
- // ...
- }
-}
-
-typedef void f1(); // OK
-typedef void f2(int a); // OK
-typedef void f3(int); // LINT
-typedef void f4(
- num a, // OK
- {
- int, // LINT
-});
-typedef void f5(
- double a, // OK
- [
- bool, // LINT
-]);
-typedef f6 = int Function(int); // OK
-typedef void f7(Undefined); // OK
-
-m1(f()) => null; // OK
-m2(f(int a)) => null; // OK
-m3(f(int)) => null; // LINT
-m4(f(num a, {int})) => null; // LINT
-m5(f(double a, [bool])) => null; // LINT
-m6(int Function(int) f)=> null; // OK
-m7(f(Undefined)) => null; // OK
-m8(f6) => null; // LINT
-m9(f7) => null; // LINT
-m10(m1) => null; // OK
-
-/// Naming the field `num` is significant - should be the name of a class.
-class FieldFormalParameter {
- final int num;
- FieldFormalParameter(this.num); // OK
-}
-
-void m11<X>(X) {} // LINT
-
-void m12(int Function<T>(T) g) {} // OK
-
-class C<X> {
- C.name();
- factory C(X) => C.name(); // LINT
- void m(void Function(X) h) {} // OK
-}