Skip to content
This repository was archived by the owner on Nov 20, 2024. It is now read-only.

Commit fc290bd

Browse files
committed
Lint about comparing booleans to boolean literals
1 parent c30bfe1 commit fc290bd

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

example/all.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ linter:
9797
- no_duplicate_case_values
9898
- no_leading_underscores_for_library_prefixes
9999
- no_leading_underscores_for_local_identifiers
100+
- no_literal_bool_comparisons
100101
- no_logic_in_create_state
101102
- no_runtimeType_toString
102103
- non_constant_identifier_names

lib/src/rules.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ import 'rules/no_default_cases.dart';
100100
import 'rules/no_duplicate_case_values.dart';
101101
import 'rules/no_leading_underscores_for_library_prefixes.dart';
102102
import 'rules/no_leading_underscores_for_local_identifiers.dart';
103+
import 'rules/no_literal_bool_comparisons.dart';
103104
import 'rules/no_logic_in_create_state.dart';
104105
import 'rules/no_runtimeType_toString.dart';
105106
import 'rules/non_constant_identifier_names.dart';
@@ -321,6 +322,7 @@ void registerLintRules({bool inTestMode = false}) {
321322
..register(NoAdjacentStringsInList())
322323
..register(NoDefaultCases())
323324
..register(NoDuplicateCaseValues())
325+
..register(NoLiteralBoolComparisons())
324326
..register(NonConstantIdentifierNames())
325327
..register(NoLeadingUnderscoresForLibraryPrefixes())
326328
..register(NoLeadingUnderscoresForLocalIdentifiers())
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) 2023, 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/analysis/features.dart';
6+
import 'package:analyzer/dart/ast/ast.dart';
7+
import 'package:analyzer/dart/ast/visitor.dart';
8+
import 'package:analyzer/dart/element/type.dart';
9+
import 'package:linter/src/analyzer.dart';
10+
11+
const _desc = r"Don't compare booleans to boolean literals.";
12+
13+
const _details = r'''
14+
From [Effective Dart](https://dart.dev/guides/language/effective-dart/usage#dont-use-true-or-false-in-equality-operations):
15+
16+
**DON'T** use `true` or `false` in equality operations.
17+
18+
**BAD:**
19+
```dart
20+
if (someBool == true) {
21+
}
22+
while (someBool == false) {
23+
}
24+
```
25+
26+
**GOOD:**
27+
```dart
28+
if (someBool) {
29+
}
30+
while (!someBool) {
31+
}
32+
```
33+
''';
34+
35+
class NoLiteralBoolComparisons extends LintRule {
36+
NoLiteralBoolComparisons()
37+
: super(
38+
name: 'no_literal_bool_comparisons',
39+
description: _desc,
40+
details: _details,
41+
group: Group.style,
42+
);
43+
44+
@override
45+
void registerNodeProcessors(
46+
NodeLintRegistry registry, LinterContext context) {
47+
if (!context.isEnabled(Feature.non_nullable)) return;
48+
49+
var visitor = _Visitor(this, context);
50+
registry.addBinaryExpression(this, visitor);
51+
}
52+
}
53+
54+
class _Visitor extends SimpleAstVisitor<void> {
55+
final LintRule rule;
56+
final LinterContext context;
57+
58+
_Visitor(this.rule, this.context);
59+
60+
@override
61+
void visitBinaryExpression(BinaryExpression node) {
62+
var left = node.leftOperand;
63+
var right = node.rightOperand;
64+
if (right is BooleanLiteral && isBool(left.staticType)) {
65+
rule.reportLint(right);
66+
} else if (left is BooleanLiteral && isBool(right.staticType)) {
67+
rule.reportLint(left);
68+
}
69+
}
70+
71+
bool isBool(DartType? type) =>
72+
type != null &&
73+
type.isDartCoreBool &&
74+
context.typeSystem.isNonNullable(type);
75+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class TestClass {
2+
bool x = false;
3+
}
4+
5+
void foo() {
6+
var x = false;
7+
if (x == true) // LINT
8+
{
9+
print('oh');
10+
}
11+
var f = true;
12+
while (true == f) { // LINT
13+
print('oh');
14+
f = false;
15+
}
16+
17+
var c = TestClass();
18+
if (c.x == true) { // LINT
19+
print('oh');
20+
}
21+
}
22+
23+
void bar(bool x, bool? y) {
24+
print(x == true); // LINT
25+
print(y == true); // OK
26+
}

0 commit comments

Comments
 (0)