Skip to content

Commit

Permalink
lint rule: Remove the avoid_null_checks_in_equality_operators rule
Browse files Browse the repository at this point in the history
Fixes https://github.com/dart-lang/linter/issues/5063

Change-Id: I85a3c9e1a568d55ce1e21d0f1fee4ce1c83292f4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389300
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
  • Loading branch information
srawlins authored and Commit Queue committed Oct 14, 2024
1 parent 89f6622 commit 5572900
Show file tree
Hide file tree
Showing 10 changed files with 16 additions and 250 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import 'package:analyzer/src/error/codes.g.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:linter/src/lint_codes.dart';

class RemoveComparison extends ResolvedCorrectionProducer {
@override
Expand Down Expand Up @@ -51,8 +50,7 @@ class RemoveComparison extends ResolvedCorrectionProducer {
return errorCode == WarningCode.UNNECESSARY_NAN_COMPARISON_TRUE ||
errorCode == WarningCode.UNNECESSARY_NULL_COMPARISON_ALWAYS_NULL_TRUE ||
errorCode == WarningCode.UNNECESSARY_NULL_COMPARISON_NEVER_NULL_TRUE ||
errorCode == WarningCode.UNNECESSARY_TYPE_CHECK_TRUE ||
errorCode == LinterLintCode.avoid_null_checks_in_equality_operators;
errorCode == WarningCode.UNNECESSARY_TYPE_CHECK_TRUE;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1923,8 +1923,6 @@ LintCode.avoid_js_rounded_ints:
status: noFix
LintCode.avoid_multiple_declarations_per_line:
status: hasFix
LintCode.avoid_null_checks_in_equality_operators:
status: hasFix
LintCode.avoid_positional_boolean_parameters:
status: noFix
notes: |-
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,9 +313,6 @@ final _builtInLintProducers = <LintCode, List<ProducerGenerator>>{
LinterLintCode.avoid_multiple_declarations_per_line: [
SplitMultipleDeclarations.new,
],
LinterLintCode.avoid_null_checks_in_equality_operators: [
RemoveComparison.new,
],
LinterLintCode.avoid_print: [
MakeConditionalOnDebugMode.new,
RemovePrint.new,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import 'fix_processor.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(RemoveComparisonTest);
defineReflectiveTests(RemoveTypeCheckTest);
defineReflectiveTests(RemoveTypeCheckBulkTest);
defineReflectiveTests(RemoveNullCheckComparisonTest);
defineReflectiveTests(RemoveNullCheckComparisonBulkTest);
defineReflectiveTests(RemoveNullCheckComparisonTest);
defineReflectiveTests(RemoveTypeCheckBulkTest);
defineReflectiveTests(RemoveTypeCheckTest);
});
}

Expand Down Expand Up @@ -610,7 +610,7 @@ class Person {
final String name = '';
@override
operator ==(Object? other) =>
operator ==(Object other) =>
other != null &&
other is Person &&
name == other.name;
Expand All @@ -620,7 +620,7 @@ class Person2 {
final String name = '';
@override
operator ==(Object? other) =>
operator ==(Object other) =>
other != null &&
other is Person &&
name == other.name;
Expand All @@ -631,7 +631,7 @@ class Person {
final String name = '';
@override
operator ==(Object? other) =>
operator ==(Object other) =>
other is Person &&
name == other.name;
}
Expand All @@ -640,7 +640,7 @@ class Person2 {
final String name = '';
@override
operator ==(Object? other) =>
operator ==(Object other) =>
other is Person &&
name == other.name;
}
Expand Down
1 change: 0 additions & 1 deletion pkg/linter/example/all.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ linter:
- avoid_init_to_null
- avoid_js_rounded_ints
- avoid_multiple_declarations_per_line
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_print
- avoid_private_typedef_functions
Expand Down
7 changes: 0 additions & 7 deletions pkg/linter/lib/src/lint_codes.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,6 @@ class LinterLintCode extends LintCode {
"Try splitting the variable declarations into multiple lines.",
);

static const LintCode avoid_null_checks_in_equality_operators =
LinterLintCode(
LintNames.avoid_null_checks_in_equality_operators,
"Unnecessary null comparison in implementation of '=='.",
correctionMessage: "Try removing the comparison.",
);

static const LintCode avoid_positional_boolean_parameters = LinterLintCode(
LintNames.avoid_positional_boolean_parameters,
"'bool' parameters should be named parameters.",
Expand Down
104 changes: 5 additions & 99 deletions pkg/linter/lib/src/rules/avoid_null_checks_in_equality_operators.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,113 +2,19 @@
// 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/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:pub_semver/pub_semver.dart';

import '../analyzer.dart';
import '../extensions.dart';

const _desc = r"Don't check for `null` in custom `==` operators.";

bool _isComparingEquality(TokenType tokenType) =>
tokenType == TokenType.BANG_EQ || tokenType == TokenType.EQ_EQ;

bool _isComparingParameterWithNull(BinaryExpression node, Element? parameter) =>
_isComparingEquality(node.operator.type) &&
((node.leftOperand.isNullLiteral &&
_isParameter(node.rightOperand, parameter)) ||
(node.rightOperand.isNullLiteral &&
_isParameter(node.leftOperand, parameter)));

bool _isParameter(Expression expression, Element? parameter) =>
expression.canonicalElement == parameter;

bool _isParameterWithQuestionQuestion(
BinaryExpression node, Element? parameter) =>
node.operator.type == TokenType.QUESTION_QUESTION &&
_isParameter(node.leftOperand, parameter);

class AvoidNullChecksInEqualityOperators extends LintRule {
AvoidNullChecksInEqualityOperators()
: super(
name: LintNames.avoid_null_checks_in_equality_operators,
description: _desc,
);

@override
LintCode get lintCode =>
LinterLintCode.avoid_null_checks_in_equality_operators;

@override
void registerNodeProcessors(
NodeLintRegistry registry, LinterContext context) {
var visitor = _Visitor(this);
registry.addMethodDeclaration(this, visitor);
}
}

class _BodyVisitor extends RecursiveAstVisitor<void> {
final Element? parameter;
final LintRule rule;

_BodyVisitor(this.parameter, this.rule);

@override
visitBinaryExpression(BinaryExpression node) {
if (_isParameterWithQuestionQuestion(node, parameter) ||
_isComparingParameterWithNull(node, parameter)) {
rule.reportLint(node);
}
super.visitBinaryExpression(node);
}

@override
visitMethodInvocation(MethodInvocation node) {
if (node.operator?.type == TokenType.QUESTION_PERIOD &&
node.target.canonicalElement == parameter) {
rule.reportLint(node);
}
super.visitMethodInvocation(node);
}

@override
visitPropertyAccess(PropertyAccess node) {
if (node.operator.type == TokenType.QUESTION_PERIOD &&
node.target.canonicalElement == parameter) {
rule.reportLint(node);
}
super.visitPropertyAccess(node);
}
}

class _Visitor extends SimpleAstVisitor<void> {
final LintRule rule;

_Visitor(this.rule);
name: LintNames.avoid_null_checks_in_equality_operators,
description: _desc,
state: State.removed(since: Version(3, 7, 0)));

@override
void visitMethodDeclaration(MethodDeclaration node) {
var parameters = node.parameters?.parameters;
if (parameters == null) {
return;
}

if (node.name.type != TokenType.EQ_EQ || parameters.length != 1) {
return;
}

var parameter = parameters.first.declaredElement?.canonicalElement;

// Analyzer will produce UNNECESSARY_NULL_COMPARISON_FALSE|TRUE
// See: https://github.com/dart-lang/linter/issues/2864
if (parameter is VariableElement &&
parameter.type.nullabilitySuffix != NullabilitySuffix.question) {
return;
}

node.body.accept(_BodyVisitor(parameter, rule));
}
LintCode get lintCode => LinterLintCode.removed_lint;
}
3 changes: 3 additions & 0 deletions pkg/linter/messages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1455,6 +1455,7 @@ LintCode:
addedIn: "2.0"
categories: [style]
hasPublishedDocs: false
removedIn: "3.7"
deprecatedDetails: |-
**DON'T** check for `null` in custom `==` operators.
Expand Down Expand Up @@ -1482,6 +1483,8 @@ LintCode:
operator ==(Object? other) => other is Person && name == other.name;
}
```
This rule has been removed.
avoid_positional_boolean_parameters:
problemMessage: "'bool' parameters should be named parameters."
correctionMessage: "Try converting the parameter to a named parameter."
Expand Down
3 changes: 0 additions & 3 deletions pkg/linter/test/rules/all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ import 'avoid_init_to_null_test.dart' as avoid_init_to_null;
import 'avoid_js_rounded_ints_test.dart' as avoid_js_rounded_ints;
import 'avoid_multiple_declarations_per_line_test.dart'
as avoid_multiple_declarations_per_line;
import 'avoid_null_checks_in_equality_operators_test.dart'
as avoid_null_checks_in_equality_operators;
import 'avoid_positional_boolean_parameters_test.dart'
as avoid_positional_boolean_parameters;
import 'avoid_print_test.dart' as avoid_print;
Expand Down Expand Up @@ -346,7 +344,6 @@ void main() {
avoid_init_to_null.main();
avoid_js_rounded_ints.main();
avoid_multiple_declarations_per_line.main();
avoid_null_checks_in_equality_operators.main();
avoid_positional_boolean_parameters.main();
avoid_print.main();
avoid_private_typedef_functions.main();
Expand Down

This file was deleted.

0 comments on commit 5572900

Please sign in to comment.