@@ -12,18 +12,6 @@ import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dar
1212import 'package:analyzer_plugin/utilities/fixes/fixes.dart' ;
1313import 'package:analyzer_plugin/utilities/range_factory.dart' ;
1414
15- /// This correction producer can act on a variety of code, and various edits
16- /// might be applied.
17- typedef _ParametersFixData =
18- ({
19- SourceRange parensRange,
20- List <SourceRange > deleteRanges,
21- bool negated,
22- bool needsParens,
23- (SourceRange , String )? replace,
24- bool bangBeforeParens,
25- });
26-
2715class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
2816 ConvertToBooleanExpression ({required super .context});
2917
@@ -41,31 +29,31 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
4129 Future <void > compute (ChangeBuilder builder) async {
4230 AstNode ? node = this .node;
4331 if (node is BooleanLiteral ) node = node.parent;
44- _ParametersFixData parameters;
4532
4633 if (node case BinaryExpression (
4734 : var rightOperand,
4835 : var leftOperand,
4936 operator : Token (type: var operator ),
5037 )) {
5138 if (rightOperand is BooleanLiteral ) {
52- parameters = _processBinaryExp (
39+ return await _processBinaryExp (
40+ builder,
5341 node,
5442 operator ,
5543 rightOperand,
5644 leftOperand,
5745 currentIsLeft: false ,
5846 );
59- } else if (leftOperand is BooleanLiteral ) {
60- parameters = _processBinaryExp (
47+ }
48+ if (leftOperand is BooleanLiteral ) {
49+ return await _processBinaryExp (
50+ builder,
6151 node,
6252 operator ,
6353 leftOperand,
6454 rightOperand,
6555 currentIsLeft: true ,
6656 );
67- } else {
68- return ;
6957 }
7058 } else if (node
7159 case ConditionalExpression (
@@ -74,8 +62,8 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
7462 : var elseExpression,
7563 ) &&
7664 var conditionalExp) {
77- _ParametersFixData ? result = (switch ((thenExpression, elseExpression)) {
78- (BooleanLiteral then, BooleanLiteral elseExp) => () {
65+ await (switch ((thenExpression, elseExpression)) {
66+ (BooleanLiteral then, BooleanLiteral elseExp) => () async {
7967 var equalValues = then.value == elseExp.value;
8068 var rangeStart =
8169 equalValues
@@ -85,76 +73,88 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
8573 : range.endEnd (condition, then);
8674 // remove ` : elseExp`
8775 var rangeEnd = range.endEnd (then, elseExp);
88- return (
76+ await _addEdit (
77+ builder,
8978 parensRange: range.node (equalValues ? then : condition),
9079 deleteRanges: [rangeStart, rangeEnd],
9180 negated: ! then.value && elseExp.value,
92- replace: null ,
93- needsParens: ! equalValues && condition.needsParens,
81+ needsParens: ! equalValues && condition.needsParens (),
9482 bangBeforeParens: false ,
9583 );
9684 }(),
97- (BooleanLiteral then, Expression elseExp) => () {
85+ (BooleanLiteral then, Expression elseExp) => () async {
9886 var replaceRange = range.endStart (condition, elseExp);
9987 var operator = then.ifBarElseAmpersand;
100- return (
101- parensRange: range.node (conditionalExp),
88+ await _addEdit (
89+ builder,
90+ parensRange: range.node (conditionalExp.condition),
10291 deleteRanges: const < SourceRange > [],
10392 negated: ! then.value,
10493 replace: (replaceRange, ' ${operator .lexeme } ' ),
105- // conditional expressions always need parens so there will
106- // be no need to add them
107- needsParens: false ,
108- bangBeforeParens: false ,
94+ needsParens: conditionalExp.condition.needsParens (
95+ then.value ? operator : null ,
96+ ),
97+ bangBeforeParens: true ,
98+ parensRange2:
99+ elseExp.needsParens (operator ) ? range.node (elseExp) : null ,
109100 );
110101 }(),
111- (Expression then, BooleanLiteral elseExp) => () {
102+ (Expression then, BooleanLiteral elseExp) => () async {
112103 var rangeStart = range.endStart (condition, then);
113104 var rangeEnd = range.endEnd (then, elseExp);
114105 var operator = elseExp.ifBarElseAmpersand;
115- return (
116- parensRange: range.node (conditionalExp),
106+ await _addEdit (
107+ builder,
108+ parensRange: range.node (conditionalExp.condition),
117109 deleteRanges: [rangeEnd],
118110 negated: elseExp.value,
119111 replace: (rangeStart, ' ${operator .lexeme } ' ),
120- // conditional expressions always need parens so there will
121- // be no need to add them
122- needsParens: false ,
123- bangBeforeParens: false ,
112+ needsParens: conditionalExp.condition.needsParens (
113+ elseExp.value ? null : operator ,
114+ ),
115+ bangBeforeParens: true ,
116+ parensRange2: then.needsParens (operator ) ? range.node (then) : null ,
124117 );
125118 }(),
126119 (_, _) => null ,
127120 });
128- if (result == null ) {
129- return ;
130- }
131- parameters = result;
132- } else {
133- return ;
134121 }
135- await _addEdit (builder, parameters);
136122 }
137123
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] .
138140 Future <void > _addEdit (
139- ChangeBuilder builder,
140- _ParametersFixData parameters,
141- ) async {
142- var (
143- : parensRange,
144- : deleteRanges,
145- : negated,
146- : replace,
147- : needsParens,
148- : bangBeforeParens,
149- ) = parameters;
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 {
150150 await builder.addDartFileEdit (file, (builder) {
151151 if (bangBeforeParens) {
152152 if (negated) {
153153 builder.addSimpleInsertion (parensRange.offset, TokenType .BANG .lexeme);
154- if (needsParens) {
155- builder. addSimpleInsertion (parensRange.offset, '(' );
156- builder.addSimpleInsertion (parensRange.end , ') ' );
157- }
154+ }
155+ if (needsParens) {
156+ builder.addSimpleInsertion (parensRange.offset , '( ' );
157+ builder. addSimpleInsertion (parensRange.end, ')' );
158158 }
159159 } else {
160160 if (needsParens) {
@@ -170,19 +170,24 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
170170 if (replace != null ) {
171171 builder.addSimpleReplacement (replace.$1, replace.$2);
172172 }
173+ if (parensRange2 != null ) {
174+ builder.addSimpleInsertion (parensRange2.offset, '(' );
175+ builder.addSimpleInsertion (parensRange2.end, ')' );
176+ }
173177 for (var range in deleteRanges) {
174178 builder.addDeletion (range);
175179 }
176180 });
177181 }
178182
179- _ParametersFixData _processBinaryExp (
183+ Future <void > _processBinaryExp (
184+ ChangeBuilder builder,
180185 BinaryExpression binaryExp,
181186 TokenType operator ,
182187 BooleanLiteral current,
183188 Expression other, {
184189 required bool currentIsLeft,
185- }) {
190+ }) async {
186191 List <SourceRange > deleteRanges;
187192 SourceRange parensRange;
188193 bool needsParens;
@@ -196,22 +201,22 @@ class ConvertToBooleanExpression extends ResolvedCorrectionProducer {
196201 : range.startStart (other, current),
197202 ];
198203 parensRange = range.node (current);
199- needsParens = current.needsParens;
204+ needsParens = current.needsParens () ;
200205 default :
201206 deleteRanges = [
202207 currentIsLeft
203208 ? range.startStart (current, other)
204209 : range.endEnd (other, current),
205210 ];
206211 parensRange = range.node (other);
207- needsParens = other.needsParens;
212+ needsParens = other.needsParens () ;
208213 }
209- return (
214+ await _addEdit (
215+ builder,
210216 negated: ! isPositiveCase (binaryExp, current),
211217 parensRange: parensRange,
212218 deleteRanges: deleteRanges,
213219 needsParens: needsParens,
214- replace: null ,
215220 bangBeforeParens: true ,
216221 );
217222 }
@@ -238,5 +243,9 @@ extension on BooleanLiteral {
238243}
239244
240245extension on Expression {
241- bool get needsParens => precedence <= Precedence .prefix;
246+ bool needsParens ([TokenType ? tokenType]) =>
247+ precedence <=
248+ (tokenType != null
249+ ? Precedence .forTokenType (tokenType)
250+ : Precedence .prefix);
242251}
0 commit comments