@@ -39,7 +39,7 @@ mixin ErrorDetectionHelpers {
39
39
return ;
40
40
}
41
41
42
- checkForAssignableExpressionAtType (
42
+ _checkForAssignableExpressionAtType (
43
43
expression, actualStaticType, expectedStaticType, errorCode,
44
44
whyNotPromotedInfo: whyNotPromotedInfo);
45
45
}
@@ -81,33 +81,41 @@ mixin ErrorDetectionHelpers {
81
81
whyNotPromotedInfo);
82
82
}
83
83
84
- bool checkForAssignableExpressionAtType (
85
- Expression expression,
86
- DartType actualStaticType,
87
- DartType expectedStaticType,
88
- ErrorCode errorCode,
89
- {Map <DartType , NonPromotionReason > Function ()? whyNotPromotedInfo}) {
90
- if (! typeSystem.isAssignableTo (actualStaticType, expectedStaticType)) {
91
- AstNode getErrorNode (AstNode node) {
92
- if (node is CascadeExpression ) {
93
- return getErrorNode (node.target);
94
- }
95
- if (node is ParenthesizedExpression ) {
96
- return getErrorNode (node.expression);
97
- }
98
- return node;
99
- }
84
+ /// Verify that the given left hand side ([lhs] ) and right hand side ([rhs] )
85
+ /// represent a valid assignment.
86
+ ///
87
+ /// See [CompileTimeErrorCode.INVALID_ASSIGNMENT] .
88
+ void checkForInvalidAssignment (Expression ? lhs, Expression ? rhs) {
89
+ if (lhs == null || rhs == null ) {
90
+ return ;
91
+ }
100
92
101
- errorReporter.reportErrorForNode (
102
- errorCode,
103
- getErrorNode (expression),
104
- [actualStaticType, expectedStaticType],
105
- computeWhyNotPromotedMessages (
106
- expression, expression, whyNotPromotedInfo? .call ()),
107
- );
108
- return false ;
93
+ if (lhs is IndexExpression &&
94
+ identical (lhs.realTarget.staticType, NeverTypeImpl .instance) ||
95
+ lhs is PrefixedIdentifier &&
96
+ identical (lhs.prefix.staticType, NeverTypeImpl .instance) ||
97
+ lhs is PropertyAccess &&
98
+ identical (lhs.realTarget.staticType, NeverTypeImpl .instance)) {
99
+ return ;
109
100
}
110
- return true ;
101
+
102
+ DartType leftType;
103
+ var parent = lhs.parent;
104
+ if (parent is AssignmentExpression && parent.leftHandSide == lhs) {
105
+ leftType = parent.writeType! ;
106
+ } else {
107
+ var leftVariableElement = getVariableElement (lhs);
108
+ leftType = (leftVariableElement == null )
109
+ ? lhs.typeOrThrow
110
+ : leftVariableElement.type;
111
+ }
112
+
113
+ if (! leftType.isVoid && checkForUseOfVoidResult (rhs)) {
114
+ return ;
115
+ }
116
+
117
+ _checkForAssignableExpression (
118
+ rhs, leftType, CompileTimeErrorCode .INVALID_ASSIGNMENT );
111
119
}
112
120
113
121
/// Check for situations where the result of a method or function is used,
@@ -148,6 +156,18 @@ mixin ErrorDetectionHelpers {
148
156
SyntacticEntity errorEntity,
149
157
Map <DartType , NonPromotionReason >? whyNotPromoted);
150
158
159
+ /// Return the variable element represented by the given [expression] , or
160
+ /// `null` if there is no such element.
161
+ VariableElement ? getVariableElement (Expression ? expression) {
162
+ if (expression is Identifier ) {
163
+ var element = expression.staticElement;
164
+ if (element is VariableElement ) {
165
+ return element;
166
+ }
167
+ }
168
+ return null ;
169
+ }
170
+
151
171
/// Verify that the given [expression] can be assigned to its corresponding
152
172
/// parameters.
153
173
///
@@ -167,4 +187,40 @@ mixin ErrorDetectionHelpers {
167
187
expression, expectedStaticType, expression.typeOrThrow, errorCode,
168
188
whyNotPromotedInfo: whyNotPromotedInfo);
169
189
}
190
+
191
+ bool _checkForAssignableExpression (
192
+ Expression expression, DartType expectedStaticType, ErrorCode errorCode) {
193
+ DartType actualStaticType = expression.typeOrThrow;
194
+ return _checkForAssignableExpressionAtType (
195
+ expression, actualStaticType, expectedStaticType, errorCode);
196
+ }
197
+
198
+ bool _checkForAssignableExpressionAtType (
199
+ Expression expression,
200
+ DartType actualStaticType,
201
+ DartType expectedStaticType,
202
+ ErrorCode errorCode,
203
+ {Map <DartType , NonPromotionReason > Function ()? whyNotPromotedInfo}) {
204
+ if (! typeSystem.isAssignableTo (actualStaticType, expectedStaticType)) {
205
+ AstNode getErrorNode (AstNode node) {
206
+ if (node is CascadeExpression ) {
207
+ return getErrorNode (node.target);
208
+ }
209
+ if (node is ParenthesizedExpression ) {
210
+ return getErrorNode (node.expression);
211
+ }
212
+ return node;
213
+ }
214
+
215
+ errorReporter.reportErrorForNode (
216
+ errorCode,
217
+ getErrorNode (expression),
218
+ [actualStaticType, expectedStaticType],
219
+ computeWhyNotPromotedMessages (
220
+ expression, expression, whyNotPromotedInfo? .call ()),
221
+ );
222
+ return false ;
223
+ }
224
+ return true ;
225
+ }
170
226
}
0 commit comments