Report type_literal_in_constant_pattern more often. (#4358)
diff --git a/lib/src/rules/type_literal_in_constant_pattern.dart b/lib/src/rules/type_literal_in_constant_pattern.dart
index 223fe60..7376606 100644
--- a/lib/src/rules/type_literal_in_constant_pattern.dart
+++ b/lib/src/rules/type_literal_in_constant_pattern.dart
@@ -10,26 +10,30 @@
const _desc = r"Don't use constant patterns with type literals.";
const _details = r'''
-Use `== TypeName` or `TypeName _` instead of type literals in patterns.
+If you meant to test if the object has type `Foo`, instead write `Foo _`.
**BAD:**
```dart
-void f(Type x) {
- if (x case int) {
- print('int');
+void f(Object? x) {
+ if (x case num) {
+ print('int or double');
}
}
```
**GOOD:**
```dart
-void f(Type x) {
- if (x case == int) {
- print('int');
+void f(Object? x) {
+ if (x case num _) {
+ print('int or double');
}
}
```
+If you do mean to test that the matched value (which you expect to have the
+type `Type`) is equal to the type literal `Foo`, then this lint can be
+silenced using `const (Foo)`.
+
**BAD:**
```dart
void f(Object? x) {
@@ -42,12 +46,11 @@
**GOOD:**
```dart
void f(Object? x) {
- if (x case int _) {
+ if (x case const (int)) {
print('int');
}
}
```
-
''';
class TypeLiteralInConstantPattern extends LintRule {
@@ -86,18 +89,14 @@
@override
visitConstantPattern(ConstantPattern node) {
+ // `const (MyType)` is fine.
+ if (node.constKeyword != null) {
+ return;
+ }
+
var expressionType = node.expression.staticType;
if (expressionType != null && expressionType.isDartCoreType) {
- var matchedValueType = node.matchedValueType;
- if (matchedValueType != null) {
- var typeSystem = context.typeSystem;
- matchedValueType = typeSystem.resolveToBound(matchedValueType);
- if (!matchedValueType.isDartCoreType) {
- if (typeSystem.isSubtypeOf(expressionType, matchedValueType)) {
- rule.reportLint(node);
- }
- }
- }
+ rule.reportLint(node);
}
}
}
diff --git a/test/rules/type_literal_in_constant_pattern_test.dart b/test/rules/type_literal_in_constant_pattern_test.dart
index 5e399c6..849e2c8 100644
--- a/test/rules/type_literal_in_constant_pattern_test.dart
+++ b/test/rules/type_literal_in_constant_pattern_test.dart
@@ -46,16 +46,6 @@
]);
}
- test_constType_matchNum() async {
- await assertDiagnostics(r'''
-void f(num x) {
- if (x case int) {}
-}
-''', [
- error(WarningCode.CONSTANT_PATTERN_NEVER_MATCHES_VALUE_TYPE, 29, 3),
- ]);
- }
-
test_constType_matchObject() async {
await assertDiagnostics(r'''
void f(Object x) {
@@ -77,11 +67,13 @@
}
test_constType_matchType() async {
- await assertNoDiagnostics(r'''
+ await assertDiagnostics(r'''
void f(Type x) {
if (x case int) {}
}
-''');
+''', [
+ lint(30, 3),
+ ]);
}
test_constType_matchType_explicitConst() async {
@@ -93,7 +85,7 @@
}
test_constType_matchType_nested() async {
- await assertNoDiagnostics(r'''
+ await assertDiagnostics(r'''
void f(A x) {
if (x case A(type: int)) {}
}
@@ -102,7 +94,9 @@
final Type type;
A(this.type);
}
-''');
+''', [
+ lint(35, 3),
+ ]);
}
test_constType_matchTypeParameter_boundObjectNullable() async {
@@ -117,10 +111,12 @@
/// Nobody will write such code, but just in case.
test_constType_matchTypeParameter_boundType() async {
- await assertNoDiagnostics(r'''
+ await assertDiagnostics(r'''
void f<T extends Type>(T x) {
if (x case int) {}
}
-''');
+''', [
+ lint(43, 3),
+ ]);
}
}