Skip to content

Commit a215513

Browse files
authored
prefer_const_constructors_in_immutables: simplify visitConstructorDeclaration override (#4254)
1 parent eb0ca50 commit a215513

File tree

5 files changed

+44
-72
lines changed

5 files changed

+44
-72
lines changed

lib/src/rules/prefer_const_constructors_in_immutables.dart

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,19 @@ class _Visitor extends SimpleAstVisitor<void> {
8282
@override
8383
void visitConstructorDeclaration(ConstructorDeclaration node) {
8484
var element = node.declaredElement;
85-
if (element == null) {
86-
return;
87-
}
85+
if (element == null) return;
86+
if (element.isConst) return;
87+
if (node.body is! EmptyFunctionBody) return;
88+
if (element.enclosingElement.mixins.isNotEmpty) return;
89+
if (!_hasImmutableAnnotation(element.enclosingElement)) return;
8890
var isRedirected =
8991
element.isFactory && element.redirectedConstructor != null;
90-
if (node.body is EmptyFunctionBody &&
91-
!element.isConst &&
92-
!_hasMixin(element.enclosingElement) &&
93-
_hasImmutableAnnotation(element.enclosingElement) &&
94-
(isRedirected && (element.redirectedConstructor?.isConst ?? false) ||
95-
(!isRedirected &&
96-
_hasConstConstructorInvocation(node) &&
97-
context.canBeConstConstructor(node)))) {
92+
if (isRedirected && (element.redirectedConstructor?.isConst ?? false)) {
93+
rule.reportLintForToken(node.firstTokenAfterCommentAndMetadata);
94+
}
95+
if (!isRedirected &&
96+
_hasConstConstructorInvocation(node) &&
97+
context.canBeConstConstructor(node)) {
9898
rule.reportLintForToken(node.firstTokenAfterCommentAndMetadata);
9999
}
100100
}
@@ -105,26 +105,27 @@ class _Visitor extends SimpleAstVisitor<void> {
105105
return false;
106106
}
107107
var clazz = declaredElement.enclosingElement;
108-
// construct with super
109-
var superInvocation = node.initializers
110-
.firstWhereOrNull((e) => e is SuperConstructorInvocation)
111-
as SuperConstructorInvocation?;
108+
// Constructor with super-initializer.
109+
var superInvocation =
110+
node.initializers.whereType<SuperConstructorInvocation>().firstOrNull;
112111
if (superInvocation != null) {
113112
return superInvocation.staticElement?.isConst ?? false;
114113
}
115-
// construct with this
114+
// Constructor with 'this' redirecting initializer.
116115
var redirectInvocation = node.initializers
117-
.firstWhereOrNull((e) => e is RedirectingConstructorInvocation)
118-
as RedirectingConstructorInvocation?;
116+
.whereType<RedirectingConstructorInvocation>()
117+
.firstOrNull;
119118
if (redirectInvocation != null) {
120119
return redirectInvocation.staticElement?.isConst ?? false;
121120
}
122-
// construct with implicit super()
121+
// Constructor with implicit `super()` call.
123122
var supertype = clazz.supertype;
124123
return supertype != null &&
125124
supertype.constructors.firstWhere((e) => e.name.isEmpty).isConst;
126125
}
127126

127+
/// Whether [clazz] or any of it's super-types are annotated with
128+
/// `@immutable`.
128129
bool _hasImmutableAnnotation(InterfaceElement clazz) {
129130
var selfAndInheritedClasses = _getSelfAndSuperClasses(clazz);
130131
for (var cls in selfAndInheritedClasses) {
@@ -133,8 +134,6 @@ class _Visitor extends SimpleAstVisitor<void> {
133134
return false;
134135
}
135136

136-
bool _hasMixin(InterfaceElement clazz) => clazz.mixins.isNotEmpty;
137-
138137
static List<InterfaceElement> _getSelfAndSuperClasses(InterfaceElement self) {
139138
InterfaceElement? current = self;
140139
var seenElements = <InterfaceElement>{};

test/integration/prefer_const_constructors_in_immutables.dart

Lines changed: 0 additions & 41 deletions
This file was deleted.

test/integration_test.dart

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import 'integration/avoid_web_libraries_in_flutter.dart'
1919
as avoid_web_libraries_in_flutter;
2020
import 'integration/close_sinks.dart' as close_sinks;
2121
import 'integration/exhaustive_cases.dart' as exhaustive_cases;
22-
import 'integration/prefer_const_constructors_in_immutables.dart'
23-
as prefer_const_constructors_in_immutables;
2422
import 'integration/public_member_api_docs.dart' as public_member_api_docs;
2523
import 'integration/sort_pub_dependencies.dart' as sort_pub_dependencies;
2624
import 'integration/use_build_context_synchronously.dart'
@@ -152,7 +150,6 @@ void ruleTests() {
152150
avoid_web_libraries_in_flutter.main();
153151
close_sinks.main();
154152
always_require_non_null_named_parameters.main();
155-
prefer_const_constructors_in_immutables.main();
156153
public_member_api_docs.main();
157154
sort_pub_dependencies.main();
158155
use_build_context_synchronously.main();

test/rules/prefer_const_constructors_in_immutables_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@ class PreferConstConstructorsInImmutablesTest extends LintRuleTest {
2020
@override
2121
bool get addMetaPackageDep => true;
2222

23+
test_assertInitializer_canBeConst() async {
24+
await assertDiagnostics(r'''
25+
import 'package:meta/meta.dart';
26+
27+
@immutable
28+
class C {
29+
C.named(a) : assert(a != null);
30+
}
31+
''', [
32+
lint(57, 1),
33+
]);
34+
}
35+
36+
test_assertInitializer_cannotBeConst() async {
37+
await assertNoDiagnostics(r'''
38+
import 'package:meta/meta.dart';
39+
40+
@immutable
41+
class C {
42+
C.named(a) : assert(a.toString() == 'string');
43+
}
44+
''');
45+
}
46+
2347
test_returnOfInvalidType() async {
2448
await assertDiagnostics(r'''
2549
import 'package:meta/meta.dart';

test_data/integration/prefer_const_constructors_in_immutables/lib.dart

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)