Skip to content

Commit e6f81df

Browse files
eernstgCommit Queue
authored andcommitted
Add new lints {omit_,specify_non}obvious_property_types
See https://github.com/dart-lang/linter/issues/5101 for some background information. Change-Id: I51b6988f08585b7b4863ae8858d44de831615177 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387960 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Erik Ernst <[email protected]>
1 parent d230290 commit e6f81df

16 files changed

+1486
-2
lines changed

pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2198,6 +2198,8 @@ LintCode.omit_local_variable_types:
21982198
status: hasFix
21992199
LintCode.omit_obvious_local_variable_types:
22002200
status: hasFix
2201+
LintCode.omit_obvious_property_types:
2202+
status: needsEvaluation
22012203
LintCode.one_member_abstracts:
22022204
status: noFix
22032205
notes: |-
@@ -2359,6 +2361,8 @@ LintCode.sort_unnamed_constructors_first:
23592361
status: hasFix
23602362
LintCode.specify_nonobvious_local_variable_types:
23612363
status: hasFix
2364+
LintCode.specify_nonobvious_property_types:
2365+
status: needsEvaluation
23622366
LintCode.test_types_in_equals:
23632367
status: noFix
23642368
LintCode.throw_in_finally:

pkg/linter/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# 3.7.0-wip
22

33
- deprecated lint: `package_api_docs`
4+
- new _(experimental)_ lint: `omit_obvious_property_types`
5+
- new _(experimental)_ lint: `specify_nonobvious_property_types`
46

57
# 3.6.0
68

pkg/linter/example/all.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ linter:
111111
- null_closures
112112
- omit_local_variable_types
113113
- omit_obvious_local_variable_types
114+
- omit_obvious_property_types
114115
- one_member_abstracts
115116
- only_throw_errors
116117
- overridden_fields
@@ -169,6 +170,7 @@ linter:
169170
- sort_pub_dependencies
170171
- sort_unnamed_constructors_first
171172
- specify_nonobvious_local_variable_types
173+
- specify_nonobvious_property_types
172174
- test_types_in_equals
173175
- throw_in_finally
174176
- tighten_type_of_initializing_formals

pkg/linter/lib/src/lint_codes.g.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,12 @@ class LinterLintCode extends LintCode {
986986
correctionMessage: "Try removing the type annotation.",
987987
);
988988

989+
static const LintCode omit_obvious_property_types = LinterLintCode(
990+
LintNames.omit_obvious_property_types,
991+
"The type annotation isn't needed because it is obvious.",
992+
correctionMessage: "Try removing the type annotation.",
993+
);
994+
989995
static const LintCode one_member_abstracts = LinterLintCode(
990996
LintNames.one_member_abstracts,
991997
"Unnecessary use of an abstract class.",
@@ -1481,6 +1487,12 @@ class LinterLintCode extends LintCode {
14811487
correctionMessage: "Try adding a type annotation.",
14821488
);
14831489

1490+
static const LintCode specify_nonobvious_property_types = LinterLintCode(
1491+
LintNames.specify_nonobvious_property_types,
1492+
"A type annotation is needed because it isn't obvious.",
1493+
correctionMessage: "Try adding a type annotation.",
1494+
);
1495+
14841496
static const LintCode test_types_in_equals = LinterLintCode(
14851497
LintNames.test_types_in_equals,
14861498
"Missing type test for '{0}' in '=='.",

pkg/linter/lib/src/lint_names.g.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ abstract final class LintNames {
307307
static const String omit_obvious_local_variable_types =
308308
'omit_obvious_local_variable_types';
309309

310+
static const String omit_obvious_property_types =
311+
'omit_obvious_property_types';
312+
310313
static const String one_member_abstracts = 'one_member_abstracts';
311314

312315
static const String only_throw_errors = 'only_throw_errors';
@@ -451,6 +454,9 @@ abstract final class LintNames {
451454
static const String specify_nonobvious_local_variable_types =
452455
'specify_nonobvious_local_variable_types';
453456

457+
static const String specify_nonobvious_property_types =
458+
'specify_nonobvious_property_types';
459+
454460
static const String super_goes_last = 'super_goes_last';
455461

456462
static const String test_types_in_equals = 'test_types_in_equals';

pkg/linter/lib/src/rules.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ import 'rules/null_check_on_nullable_type_parameter.dart';
122122
import 'rules/null_closures.dart';
123123
import 'rules/omit_local_variable_types.dart';
124124
import 'rules/omit_obvious_local_variable_types.dart';
125+
import 'rules/omit_obvious_property_types.dart';
125126
import 'rules/one_member_abstracts.dart';
126127
import 'rules/only_throw_errors.dart';
127128
import 'rules/overridden_fields.dart';
@@ -184,6 +185,7 @@ import 'rules/sort_child_properties_last.dart';
184185
import 'rules/sort_constructors_first.dart';
185186
import 'rules/sort_unnamed_constructors_first.dart';
186187
import 'rules/specify_nonobvious_local_variable_types.dart';
188+
import 'rules/specify_nonobvious_property_types.dart';
187189
import 'rules/super_goes_last.dart';
188190
import 'rules/test_types_in_equals.dart';
189191
import 'rules/throw_in_finally.dart';
@@ -366,6 +368,7 @@ void registerLintRules() {
366368
..register(NullClosures())
367369
..register(OmitLocalVariableTypes())
368370
..register(OmitObviousLocalVariableTypes())
371+
..register(OmitObviousPropertyTypes())
369372
..register(OneMemberAbstracts())
370373
..register(OnlyThrowErrors())
371374
..register(OverriddenFields())
@@ -428,6 +431,7 @@ void registerLintRules() {
428431
..register(SortUnnamedConstructorsFirst())
429432
..register(SuperGoesLast())
430433
..register(SpecifyNonObviousLocalVariableTypes())
434+
..register(SpecifyNonObviousPropertyTypes())
431435
..register(TestTypesInEquals())
432436
..register(ThrowInFinally())
433437
..register(TightenTypeOfInitializingFormals())

pkg/linter/lib/src/rules/always_specify_types.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AlwaysSpecifyTypes extends LintRule {
2626
LintNames.avoid_types_on_closure_parameters,
2727
LintNames.omit_local_variable_types,
2828
LintNames.omit_obvious_local_variable_types,
29+
LintNames.omit_obvious_property_types,
2930
];
3031

3132
@override

pkg/linter/lib/src/rules/omit_local_variable_types.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class OmitLocalVariableTypes extends LintRule {
2323
List<String> get incompatibleRules => const [
2424
LintNames.always_specify_types,
2525
LintNames.specify_nonobvious_local_variable_types,
26+
LintNames.specify_nonobvious_property_types,
2627
];
2728

2829
@override
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/dart/ast/ast.dart';
6+
import 'package:analyzer/dart/ast/visitor.dart';
7+
8+
import '../analyzer.dart';
9+
import '../util/obvious_types.dart';
10+
11+
const _desc =
12+
r'Omit obvious type annotations for top-level and static variables.';
13+
14+
class OmitObviousPropertyTypes extends LintRule {
15+
OmitObviousPropertyTypes()
16+
: super(
17+
name: 'omit_obvious_property_types',
18+
description: _desc,
19+
state: State.experimental(),
20+
);
21+
22+
@override
23+
List<String> get incompatibleRules => const ['always_specify_types'];
24+
25+
@override
26+
LintCode get lintCode => LinterLintCode.omit_obvious_property_types;
27+
28+
@override
29+
void registerNodeProcessors(
30+
NodeLintRegistry registry, LinterContext context) {
31+
var visitor = _Visitor(this);
32+
registry.addFieldDeclaration(this, visitor);
33+
registry.addTopLevelVariableDeclaration(this, visitor);
34+
}
35+
}
36+
37+
class _Visitor extends SimpleAstVisitor<void> {
38+
final LintRule rule;
39+
40+
_Visitor(this.rule);
41+
42+
@override
43+
void visitFieldDeclaration(FieldDeclaration node) =>
44+
_visitVariableDeclarationList(node.fields);
45+
46+
@override
47+
void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
48+
_visitVariableDeclarationList(node.variables);
49+
50+
void _visitVariableDeclarationList(VariableDeclarationList node) {
51+
var staticType = node.type?.type;
52+
if (staticType == null || staticType.isDartCoreNull) {
53+
return;
54+
}
55+
for (var child in node.variables) {
56+
var initializer = child.initializer;
57+
if (initializer != null && !initializer.hasObviousType) {
58+
return;
59+
}
60+
if (initializer?.staticType != staticType) {
61+
return;
62+
}
63+
}
64+
rule.reportLint(node.type);
65+
}
66+
}

pkg/linter/lib/src/rules/specify_nonobvious_local_variable_types.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class SpecifyNonObviousLocalVariableTypes extends LintRule {
3333
var visitor = _Visitor(this);
3434
registry.addForStatement(this, visitor);
3535
registry.addPatternVariableDeclarationStatement(this, visitor);
36+
registry.addSwitchExpression(this, visitor);
3637
registry.addSwitchStatement(this, visitor);
3738
registry.addVariableDeclarationStatement(this, visitor);
3839
}
@@ -87,7 +88,10 @@ class _Visitor extends SimpleAstVisitor<void> {
8788
}
8889

8990
@override
90-
void visitSwitchExpression(SwitchExpression node) {}
91+
void visitSwitchExpression(SwitchExpression node) {
92+
if (node.expression.hasObviousType) return;
93+
node.cases.forEach(_PatternVisitor(rule).visitSwitchExpressionCase);
94+
}
9195

9296
@override
9397
void visitSwitchStatement(SwitchStatement node) {

0 commit comments

Comments
 (0)