Skip to content

Commit cb3017c

Browse files
srawlinsCommit Queue
authored andcommitted
Revert two recent changes to no_literal_bool_comparisons:
* "[DAS] Broadens the scope of `no_literal_bool_comparisons`" commit 0541ad3. * "[DAS] Fixes broken cases for "Convert to boolean expression" fix" commit 0444838. The first commit may have lead to broken customer tests. See flutter/flutter#172087. Change-Id: Iba2c936a32ecf678318fa3aea929787dca046e09 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/440261 Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Samuel Rawlins <[email protected]>
1 parent 954aa12 commit cb3017c

File tree

5 files changed

+57
-730
lines changed

5 files changed

+57
-730
lines changed

pkg/analysis_server/lib/src/services/correction/dart/convert_to_boolean_expression.dart

Lines changed: 28 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import 'package:analysis_server/src/services/correction/fix.dart';
66
import 'package:analysis_server_plugin/edit/dart/correction_producer.dart';
77
import 'package:analyzer/dart/ast/ast.dart';
88
import 'package:analyzer/dart/ast/precedence.dart';
9-
import 'package:analyzer/dart/ast/token.dart';
10-
import 'package:analyzer/source/source_range.dart';
119
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
1210
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
1311
import 'package:analyzer_plugin/utilities/range_factory.dart';
@@ -29,223 +27,49 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
2927
Future<void> compute(ChangeBuilder builder) async {
3028
AstNode? node = this.node;
3129
if (node is BooleanLiteral) node = node.parent;
30+
if (node is! BinaryExpression) return;
3231

33-
if (node case BinaryExpression(
34-
:var rightOperand,
35-
:var leftOperand,
36-
operator: Token(type: var operator),
37-
)) {
38-
if (rightOperand is BooleanLiteral) {
39-
return await _processBinaryExp(
40-
builder,
41-
node,
42-
operator,
43-
rightOperand,
44-
leftOperand,
45-
currentIsLeft: false,
46-
);
47-
}
48-
if (leftOperand is BooleanLiteral) {
49-
return await _processBinaryExp(
50-
builder,
51-
node,
52-
operator,
53-
leftOperand,
54-
rightOperand,
55-
currentIsLeft: true,
56-
);
57-
}
58-
} else if (node
59-
case ConditionalExpression(
60-
:var condition,
61-
:var thenExpression,
62-
:var elseExpression,
63-
) &&
64-
var conditionalExp) {
65-
await (switch ((thenExpression, elseExpression)) {
66-
(BooleanLiteral then, BooleanLiteral elseExp) => () async {
67-
var equalValues = then.value == elseExp.value;
68-
var rangeStart =
69-
equalValues
70-
// keep `then`
71-
? range.startStart(condition, then)
72-
// keep `condition`
73-
: range.endEnd(condition, then);
74-
// remove ` : elseExp`
75-
var rangeEnd = range.endEnd(then, elseExp);
76-
await _addEdit(
77-
builder,
78-
parensRange: range.node(equalValues ? then : condition),
79-
deleteRanges: [rangeStart, rangeEnd],
80-
negated: !then.value && elseExp.value,
81-
needsParens: !equalValues && condition.needsParens(),
82-
bangBeforeParens: false,
83-
);
84-
}(),
85-
(BooleanLiteral then, Expression elseExp) => () async {
86-
var replaceRange = range.endStart(condition, elseExp);
87-
var operator = then.ifBarElseAmpersand;
88-
await _addEdit(
89-
builder,
90-
parensRange: range.node(conditionalExp.condition),
91-
deleteRanges: const <SourceRange>[],
92-
negated: !then.value,
93-
replace: (replaceRange, ' ${operator.lexeme} '),
94-
needsParens: conditionalExp.condition.needsParens(
95-
then.value ? operator : null,
96-
),
97-
bangBeforeParens: true,
98-
parensRange2:
99-
elseExp.needsParens(operator) ? range.node(elseExp) : null,
100-
);
101-
}(),
102-
(Expression then, BooleanLiteral elseExp) => () async {
103-
var rangeStart = range.endStart(condition, then);
104-
var rangeEnd = range.endEnd(then, elseExp);
105-
var operator = elseExp.ifBarElseAmpersand;
106-
await _addEdit(
107-
builder,
108-
parensRange: range.node(conditionalExp.condition),
109-
deleteRanges: [rangeEnd],
110-
negated: elseExp.value,
111-
replace: (rangeStart, ' ${operator.lexeme} '),
112-
needsParens: conditionalExp.condition.needsParens(
113-
elseExp.value ? null : operator,
114-
),
115-
bangBeforeParens: true,
116-
parensRange2: then.needsParens(operator) ? range.node(then) : null,
117-
);
118-
}(),
119-
(_, _) => null,
120-
});
32+
var rightOperand = node.rightOperand;
33+
var leftOperand = node.leftOperand;
34+
35+
Expression expression;
36+
BooleanLiteral literal;
37+
38+
var deleteRange = range.endEnd(leftOperand, rightOperand);
39+
40+
if (rightOperand is BooleanLiteral) {
41+
literal = rightOperand;
42+
expression = node.leftOperand;
43+
} else if (leftOperand is BooleanLiteral) {
44+
literal = leftOperand;
45+
expression = node.rightOperand;
46+
deleteRange = range.startStart(leftOperand, rightOperand);
47+
} else {
48+
return;
12149
}
122-
}
12350

124-
/// This correction producer can act on a variety of code, and various edits
125-
/// might be applied.
126-
///
127-
/// The [deleteRanges] are ranges that should be deleted from the code.
128-
///
129-
/// The [replace] will be normally used to replace part of the expression
130-
/// with a new operator.
131-
///
132-
/// The [parensRange] is related to [needsParens] and [bangBeforeParens]. The
133-
/// `bang` is added only if [negated] is true. It was meant for adding the
134-
/// parens when the `bang` or the new operator given by [replace] makes the
135-
/// precedence of the expression different than the original one.
136-
///
137-
/// The [parensRange2] is meant to be used when converting conditional
138-
/// expressions and should be non-`null` if the second expression needs
139-
/// parentheses considering the new operator added by the given [replace].
140-
Future<void> _addEdit(
141-
ChangeBuilder builder, {
142-
required SourceRange parensRange,
143-
required bool needsParens,
144-
required List<SourceRange> deleteRanges,
145-
required bool negated,
146-
required bool bangBeforeParens,
147-
(SourceRange, String)? replace,
148-
SourceRange? parensRange2,
149-
}) async {
51+
var negated = !isPositiveCase(node, literal);
15052
await builder.addDartFileEdit(file, (builder) {
151-
if (bangBeforeParens) {
152-
if (negated) {
153-
builder.addSimpleInsertion(parensRange.offset, TokenType.BANG.lexeme);
154-
}
155-
if (needsParens) {
156-
builder.addSimpleInsertion(parensRange.offset, '(');
157-
builder.addSimpleInsertion(parensRange.end, ')');
158-
}
159-
} else {
160-
if (needsParens) {
161-
builder.addSimpleInsertion(parensRange.offset, '(');
162-
}
163-
if (negated) {
164-
builder.addSimpleInsertion(parensRange.offset, TokenType.BANG.lexeme);
53+
if (negated) {
54+
builder.addSimpleInsertion(expression.offset, '!');
55+
if (expression.needsParens) {
56+
builder.addSimpleInsertion(expression.offset, '(');
57+
builder.addSimpleInsertion(expression.end, ')');
16558
}
166-
if (needsParens) {
167-
builder.addSimpleInsertion(parensRange.end, ')');
168-
}
169-
}
170-
if (replace != null) {
171-
builder.addSimpleReplacement(replace.$1, replace.$2);
172-
}
173-
if (parensRange2 != null) {
174-
builder.addSimpleInsertion(parensRange2.offset, '(');
175-
builder.addSimpleInsertion(parensRange2.end, ')');
176-
}
177-
for (var range in deleteRanges) {
178-
builder.addDeletion(range);
17959
}
60+
builder.addDeletion(deleteRange);
18061
});
18162
}
18263

183-
Future<void> _processBinaryExp(
184-
ChangeBuilder builder,
185-
BinaryExpression binaryExp,
186-
TokenType operator,
187-
BooleanLiteral current,
188-
Expression other, {
189-
required bool currentIsLeft,
190-
}) async {
191-
List<SourceRange> deleteRanges;
192-
SourceRange parensRange;
193-
bool needsParens;
194-
switch (operator) {
195-
case TokenType.BAR || TokenType.BAR_BAR when current.value:
196-
case TokenType.AMPERSAND || TokenType.AMPERSAND_AMPERSAND
197-
when !current.value:
198-
deleteRanges = [
199-
currentIsLeft
200-
? range.endEnd(current, other)
201-
: range.startStart(other, current),
202-
];
203-
parensRange = range.node(current);
204-
needsParens = current.needsParens();
205-
default:
206-
deleteRanges = [
207-
currentIsLeft
208-
? range.startStart(current, other)
209-
: range.endEnd(other, current),
210-
];
211-
parensRange = range.node(other);
212-
needsParens = other.needsParens();
213-
}
214-
await _addEdit(
215-
builder,
216-
negated: !isPositiveCase(binaryExp, current),
217-
parensRange: parensRange,
218-
deleteRanges: deleteRanges,
219-
needsParens: needsParens,
220-
bangBeforeParens: true,
221-
);
222-
}
223-
22464
static bool isPositiveCase(
22565
BinaryExpression expression,
22666
BooleanLiteral literal,
22767
) {
228-
return switch (expression.operator.type) {
229-
TokenType.BAR ||
230-
TokenType.BAR_BAR ||
231-
TokenType.AMPERSAND ||
232-
TokenType.AMPERSAND_AMPERSAND => true,
233-
TokenType.EQ_EQ => literal.value,
234-
TokenType.BANG_EQ || TokenType.CARET => !literal.value,
235-
_ => throw StateError('Unexpected operator ${expression.operator.type}'),
236-
};
68+
if (expression.operator.lexeme == '==') return literal.value;
69+
return !literal.value;
23770
}
23871
}
23972

240-
extension on BooleanLiteral {
241-
TokenType get ifBarElseAmpersand =>
242-
value ? TokenType.BAR_BAR : TokenType.AMPERSAND_AMPERSAND;
243-
}
244-
24573
extension on Expression {
246-
bool needsParens([TokenType? tokenType]) =>
247-
precedence <=
248-
(tokenType != null
249-
? Precedence.forTokenType(tokenType)
250-
: Precedence.prefix);
74+
bool get needsParens => precedence <= Precedence.prefix;
25175
}

pkg/analysis_server/test/abstract_single_unit.dart

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ import 'abstract_context.dart';
1818
class AbstractSingleUnitTest extends AbstractContextTest {
1919
bool verifyNoTestUnitErrors = true;
2020

21-
/// Whether the test code should parse carrets as position shorthands.
22-
///
23-
/// Set this to `true` when the test code is using the carret operator.
24-
bool keepCaret = false;
25-
2621
TestCode? _parsedTestCode;
2722
late ParsedUnitResult testParsedResult;
2823
late ResolvedLibraryResult? testLibraryResult;
@@ -43,10 +38,7 @@ class AbstractSingleUnitTest extends AbstractContextTest {
4338

4439
String get testCode => parsedTestCode.code;
4540
set testCode(String value) {
46-
parsedTestCode = TestCode.parse(
47-
normalizeSource(value),
48-
positionShorthand: !keepCaret,
49-
);
41+
parsedTestCode = TestCode.parse(normalizeSource(value));
5042
}
5143

5244
void addTestSource(String code) {

0 commit comments

Comments
 (0)