@@ -7,7 +7,7 @@ import 'package:analysis_server/src/services/correction/dart/abstract_producer.d
7
7
import 'package:analysis_server/src/services/correction/fix.dart' ;
8
8
import 'package:analyzer/dart/ast/ast.dart' ;
9
9
import 'package:analyzer/dart/ast/token.dart' ;
10
- import 'package:analyzer/dart/element/element .dart' ;
10
+ import 'package:analyzer/source/source_range .dart' ;
11
11
import 'package:analyzer_plugin/utilities/assist/assist.dart' ;
12
12
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart' ;
13
13
import 'package:analyzer_plugin/utilities/fixes/fixes.dart' ;
@@ -43,29 +43,24 @@ class ConvertToNullAware extends ResolvedCorrectionProducer {
43
43
return ;
44
44
}
45
45
var condition = targetNode.condition.unParenthesized;
46
- SimpleIdentifier identifier ;
46
+ String conditionText ;
47
47
Expression nullExpression;
48
48
Expression nonNullExpression;
49
- int periodOffset;
50
49
51
50
if (condition is BinaryExpression ) {
52
51
//
53
52
// Identify the variable being compared to `null`, or return if the
54
- // condition isn't a simple comparison of `null` to a variable's value .
53
+ // condition isn't a simple comparison of `null` to another expression .
55
54
//
56
55
var leftOperand = condition.leftOperand;
57
56
var rightOperand = condition.rightOperand;
58
- if (leftOperand is NullLiteral && rightOperand is SimpleIdentifier ) {
59
- identifier = rightOperand;
60
- } else if (rightOperand is NullLiteral &&
61
- leftOperand is SimpleIdentifier ) {
62
- identifier = leftOperand;
57
+ if (leftOperand is NullLiteral && rightOperand is ! NullLiteral ) {
58
+ conditionText = rightOperand.toString ();
59
+ } else if (rightOperand is NullLiteral && leftOperand is ! NullLiteral ) {
60
+ conditionText = leftOperand.toString ();
63
61
} else {
64
62
return ;
65
63
}
66
- if (identifier.staticElement is ! LocalElement ) {
67
- return ;
68
- }
69
64
//
70
65
// Identify the expression executed when the variable is `null` and when
71
66
// it is non-`null`. Return if the `null` expression isn't a null literal
@@ -84,30 +79,51 @@ class ConvertToNullAware extends ResolvedCorrectionProducer {
84
79
if (nullExpression.unParenthesized is ! NullLiteral ) {
85
80
return ;
86
81
}
87
- var unwrappedExpression = nonNullExpression.unParenthesized;
88
- Expression ? target;
82
+ Expression ? resultExpression = nonNullExpression.unParenthesized;
89
83
Token ? operator ;
90
- if (unwrappedExpression is MethodInvocation ) {
91
- target = unwrappedExpression.target;
92
- operator = unwrappedExpression.operator ;
93
- } else if (unwrappedExpression is PrefixedIdentifier ) {
94
- target = unwrappedExpression.prefix;
95
- operator = unwrappedExpression.period;
96
- } else {
97
- return ;
84
+ while (true ) {
85
+ switch (resultExpression) {
86
+ case PrefixedIdentifier ():
87
+ operator = resultExpression.period;
88
+ resultExpression = resultExpression.prefix;
89
+ case MethodInvocation ():
90
+ operator = resultExpression.operator ;
91
+ resultExpression = resultExpression.target;
92
+ case PostfixExpression ()
93
+ when resultExpression.operator .type == TokenType .BANG :
94
+ // (Operator remains unaffected.)
95
+ resultExpression = resultExpression.operand;
96
+ case PropertyAccess ():
97
+ operator = resultExpression.operator ;
98
+ resultExpression = resultExpression.target;
99
+ default :
100
+ return ;
101
+ }
102
+ if (resultExpression.toString () == conditionText) {
103
+ break ;
104
+ }
98
105
}
99
- if (operator == null || operator .type != TokenType . PERIOD ) {
106
+ if (resultExpression == null ) {
100
107
return ;
101
108
}
102
- if (! (target is SimpleIdentifier &&
103
- target.staticElement == identifier.staticElement)) {
109
+
110
+ SourceRange operatorRange;
111
+ var optionalQuestionMark = '' ;
112
+ if (operator != null ) {
113
+ if (operator .type == TokenType .PERIOD ) {
114
+ optionalQuestionMark = '?' ;
115
+ }
116
+ operatorRange = range.endStart (resultExpression, operator );
117
+ } else if (resultExpression.parent is PostfixExpression ) {
118
+ // The case where the expression is just `foo!`.
119
+ operatorRange =
120
+ range.endEnd (resultExpression, resultExpression.parent! );
121
+ } else {
104
122
return ;
105
123
}
106
- periodOffset = operator .offset;
107
-
108
124
await builder.addDartFileEdit (file, (builder) {
109
125
builder.addDeletion (range.startStart (targetNode, nonNullExpression));
110
- builder.addSimpleInsertion (periodOffset, '?' );
126
+ builder.addSimpleReplacement (operatorRange, optionalQuestionMark );
111
127
builder.addDeletion (range.endEnd (nonNullExpression, targetNode));
112
128
});
113
129
}
0 commit comments