Skip to content

Commit fcb1e9d

Browse files
FMorschelCommit Queue
authored andcommitted
[DAS] Fixes Convert to use '??' for precedence with the outer expression
Fixes: #61507 Change-Id: Ifaab16a2ba087670d9695e8be1d2b02a542bad24 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449921 Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]> Auto-Submit: Felipe Morschel <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 9a86ae5 commit fcb1e9d

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ class ConvertToIfNull extends ResolvedCorrectionProducer {
4141
}
4242
}
4343

44+
bool _outerParenthesesNeeded(AstNode node) {
45+
if (node.parent case Expression expression
46+
when expression is! ParenthesizedExpression) {
47+
return expression.precedence >
48+
Precedence.forTokenType(TokenType.QUESTION_QUESTION);
49+
} else {
50+
return false;
51+
}
52+
}
53+
4454
Future<void> _preferIfNull(ChangeBuilder builder) async {
4555
var node = this.node;
4656
if (node is ConditionalExpression &&
@@ -62,21 +72,31 @@ class ConvertToIfNull extends ResolvedCorrectionProducer {
6272
return;
6373
}
6474

65-
var parentheses =
75+
var innerParentheses =
6676
defaultExpression.precedence <
6777
Precedence.forTokenType(TokenType.QUESTION_QUESTION);
6878

79+
// Should not be needed because the precedence for ConditionalExpression
80+
// is higher than for '??'. We still do it for consistency.
81+
var outerParentheses = _outerParenthesesNeeded(node);
82+
6983
await builder.addDartFileEdit(file, (builder) {
7084
builder.addReplacement(range.node(node), (builder) {
85+
if (outerParentheses) {
86+
builder.write('(');
87+
}
7188
builder.write(utils.getNodeText(nullableExpression));
7289

7390
if (defaultExpression is NullLiteral) return;
7491
builder.write(' ?? ');
75-
if (parentheses) {
92+
if (innerParentheses) {
7693
builder.write('(');
7794
}
7895
builder.write(utils.getNodeText(defaultExpression));
79-
if (parentheses) {
96+
if (innerParentheses) {
97+
builder.write(')');
98+
}
99+
if (outerParentheses) {
80100
builder.write(')');
81101
}
82102
});
@@ -101,15 +121,22 @@ class ConvertToIfNull extends ResolvedCorrectionProducer {
101121
} else {
102122
return;
103123
}
124+
var outerParentheses = _outerParenthesesNeeded(node);
104125
await builder.addDartFileEdit(file, (builder) {
105126
builder.addReplacement(range.node(node), (builder) {
127+
if (outerParentheses) {
128+
builder.write('(');
129+
}
106130
builder.write(utils.getNodeText(nullableExpression));
107131
builder.write(' ${TokenType.QUESTION_QUESTION.lexeme} ');
108132
if (node.operator.type == TokenType.EQ_EQ) {
109133
builder.write('false');
110134
} else {
111135
builder.write('true');
112136
}
137+
if (outerParentheses) {
138+
builder.write(')');
139+
}
113140
});
114141
});
115142
}

pkg/analysis_server/test/src/services/correction/fix/convert_to_if_null_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,19 @@ void f(bool? value) {
188188
void f(bool? value) {
189189
print(value ?? false);
190190
}
191+
''');
192+
}
193+
194+
Future<void> test_parensAround() async {
195+
await resolveTestCode('''
196+
void f(bool? value) {
197+
print(value != false && 1 == 2);
198+
}
199+
''');
200+
await assertHasFix('''
201+
void f(bool? value) {
202+
print((value ?? true) && 1 == 2);
203+
}
191204
''');
192205
}
193206
}

0 commit comments

Comments
 (0)