OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/names.dart' show | 8 import '../common/names.dart' show Selectors; |
9 Selectors; | 9 import '../common/resolution.dart' show Feature; |
10 import '../common/resolution.dart' show | 10 import '../compiler.dart' show Compiler; |
11 Feature; | 11 import '../constants/constructors.dart' |
12 import '../compiler.dart' show | 12 show RedirectingFactoryConstantConstructor; |
13 Compiler; | |
14 import '../constants/constructors.dart' show | |
15 RedirectingFactoryConstantConstructor; | |
16 import '../constants/expressions.dart'; | 13 import '../constants/expressions.dart'; |
17 import '../constants/values.dart'; | 14 import '../constants/values.dart'; |
18 import '../core_types.dart'; | 15 import '../core_types.dart'; |
19 import '../dart_types.dart'; | 16 import '../dart_types.dart'; |
20 import '../elements/elements.dart'; | 17 import '../elements/elements.dart'; |
21 import '../elements/modelx.dart' show | 18 import '../elements/modelx.dart' |
22 ConstructorElementX, | 19 show |
23 ErroneousElementX, | 20 ConstructorElementX, |
24 FunctionElementX, | 21 ErroneousElementX, |
25 JumpTargetX, | 22 FunctionElementX, |
26 LocalFunctionElementX, | 23 JumpTargetX, |
27 LocalParameterElementX, | 24 LocalFunctionElementX, |
28 LocalVariableElementX, | 25 LocalParameterElementX, |
29 MethodElementX, | 26 LocalVariableElementX, |
30 ParameterElementX, | 27 MethodElementX, |
31 VariableElementX, | 28 ParameterElementX, |
32 VariableList; | 29 VariableElementX, |
33 import '../tokens/token.dart' show | 30 VariableList; |
34 isUserDefinableOperator; | 31 import '../tokens/token.dart' show isUserDefinableOperator; |
35 import '../tree/tree.dart'; | 32 import '../tree/tree.dart'; |
36 import '../util/util.dart' show | 33 import '../util/util.dart' show Link; |
37 Link; | 34 import '../universe/call_structure.dart' show CallStructure; |
38 import '../universe/call_structure.dart' show | 35 import '../universe/selector.dart' show Selector; |
39 CallStructure; | 36 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; |
40 import '../universe/selector.dart' show | |
41 Selector; | |
42 import '../universe/use.dart' show | |
43 DynamicUse, | |
44 StaticUse, | |
45 TypeUse; | |
46 | 37 |
47 import 'access_semantics.dart'; | 38 import 'access_semantics.dart'; |
48 import 'class_members.dart' show MembersCreator; | 39 import 'class_members.dart' show MembersCreator; |
49 import 'operators.dart'; | 40 import 'operators.dart'; |
50 import 'send_structure.dart'; | 41 import 'send_structure.dart'; |
51 | 42 |
52 import 'constructors.dart' show | 43 import 'constructors.dart' |
53 ConstructorResolver, | 44 show ConstructorResolver, ConstructorResult, ConstructorResultKind; |
54 ConstructorResult, | 45 import 'label_scope.dart' show StatementScope; |
55 ConstructorResultKind; | 46 import 'registry.dart' show ResolutionRegistry; |
56 import 'label_scope.dart' show | 47 import 'resolution.dart' show ResolverTask; |
57 StatementScope; | 48 import 'resolution_common.dart' show MappingVisitor; |
58 import 'registry.dart' show | |
59 ResolutionRegistry; | |
60 import 'resolution.dart' show | |
61 ResolverTask; | |
62 import 'resolution_common.dart' show | |
63 MappingVisitor; | |
64 import 'resolution_result.dart'; | 49 import 'resolution_result.dart'; |
65 import 'scope.dart' show | 50 import 'scope.dart' show BlockScope, MethodScope, Scope; |
66 BlockScope, | 51 import 'signatures.dart' show SignatureResolver; |
67 MethodScope, | 52 import 'variables.dart' show VariableDefinitionsVisitor; |
68 Scope; | |
69 import 'signatures.dart' show | |
70 SignatureResolver; | |
71 import 'variables.dart' show | |
72 VariableDefinitionsVisitor; | |
73 | 53 |
74 /// The state of constants in resolutions. | 54 /// The state of constants in resolutions. |
75 enum ConstantState { | 55 enum ConstantState { |
76 /// Expressions are not required to be constants. | 56 /// Expressions are not required to be constants. |
77 NON_CONSTANT, | 57 NON_CONSTANT, |
78 | 58 |
79 /// Expressions are required to be constants. | 59 /// Expressions are required to be constants. |
80 /// | 60 /// |
81 /// For instance the values of a constant list literal. | 61 /// For instance the values of a constant list literal. |
82 CONSTANT, | 62 CONSTANT, |
(...skipping 30 matching lines...) Expand all Loading... |
113 Scope scope; | 93 Scope scope; |
114 ClassElement currentClass; | 94 ClassElement currentClass; |
115 ExpressionStatement currentExpressionStatement; | 95 ExpressionStatement currentExpressionStatement; |
116 | 96 |
117 /// `true` if a [Send] or [SendSet] is visited as the prefix of member access. | 97 /// `true` if a [Send] or [SendSet] is visited as the prefix of member access. |
118 /// For instance `Class` in `Class.staticField` or `prefix.Class` in | 98 /// For instance `Class` in `Class.staticField` or `prefix.Class` in |
119 /// `prefix.Class.staticMethod()`. | 99 /// `prefix.Class.staticMethod()`. |
120 bool sendIsMemberAccess = false; | 100 bool sendIsMemberAccess = false; |
121 | 101 |
122 StatementScope statementScope; | 102 StatementScope statementScope; |
123 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 103 int allowedCategory = ElementCategory.VARIABLE | |
124 | ElementCategory.IMPLIES_TYPE; | 104 ElementCategory.FUNCTION | |
| 105 ElementCategory.IMPLIES_TYPE; |
125 | 106 |
126 /// When visiting the type declaration of the variable in a [ForIn] loop, | 107 /// When visiting the type declaration of the variable in a [ForIn] loop, |
127 /// the initializer of the variable is implicit and we should not emit an | 108 /// the initializer of the variable is implicit and we should not emit an |
128 /// error when verifying that all final variables are initialized. | 109 /// error when verifying that all final variables are initialized. |
129 bool inLoopVariable = false; | 110 bool inLoopVariable = false; |
130 | 111 |
131 /// The nodes for which variable access and mutation must be registered in | 112 /// The nodes for which variable access and mutation must be registered in |
132 /// order to determine when the static type of variables types is promoted. | 113 /// order to determine when the static type of variables types is promoted. |
133 Link<Node> promotionScope = const Link<Node>(); | 114 Link<Node> promotionScope = const Link<Node>(); |
134 | 115 |
135 bool isPotentiallyMutableTarget(Element target) { | 116 bool isPotentiallyMutableTarget(Element target) { |
136 if (target == null) return false; | 117 if (target == null) return false; |
137 return (target.isVariable || target.isParameter) && | 118 return (target.isVariable || target.isParameter) && |
138 !(target.isFinal || target.isConst); | 119 !(target.isFinal || target.isConst); |
139 } | 120 } |
140 | 121 |
141 // TODO(ahe): Find a way to share this with runtime implementation. | 122 // TODO(ahe): Find a way to share this with runtime implementation. |
142 static final RegExp symbolValidationPattern = | 123 static final RegExp symbolValidationPattern = |
143 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' | 124 new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' |
144 r'-|' | 125 r'-|' |
145 r'unary-|' | 126 r'unary-|' |
146 r'\[\]=|' | 127 r'\[\]=|' |
147 r'~|' | 128 r'~|' |
148 r'==|' | 129 r'==|' |
149 r'\[\]|' | 130 r'\[\]|' |
150 r'\*|' | 131 r'\*|' |
151 r'/|' | 132 r'/|' |
152 r'%|' | 133 r'%|' |
153 r'~/|' | 134 r'~/|' |
154 r'\+|' | 135 r'\+|' |
155 r'<<|' | 136 r'<<|' |
156 r'>>|' | 137 r'>>|' |
157 r'>=|' | 138 r'>=|' |
158 r'>|' | 139 r'>|' |
159 r'<=|' | 140 r'<=|' |
160 r'<|' | 141 r'<|' |
161 r'&|' | 142 r'&|' |
162 r'\^|' | 143 r'\^|' |
163 r'\|' | 144 r'\|' |
164 r')$'); | 145 r')$'); |
165 | 146 |
166 ResolverVisitor(Compiler compiler, | 147 ResolverVisitor( |
167 Element element, | 148 Compiler compiler, Element element, ResolutionRegistry registry, |
168 ResolutionRegistry registry, | 149 {bool useEnclosingScope: false}) |
169 {bool useEnclosingScope: false}) | 150 : this.enclosingElement = element, |
170 : this.enclosingElement = element, | 151 // When the element is a field, we are actually resolving its |
171 // When the element is a field, we are actually resolving its | 152 // initial value, which should not have access to instance |
172 // initial value, which should not have access to instance | 153 // fields. |
173 // fields. | 154 inInstanceContext = (element.isInstanceMember && !element.isField) || |
174 inInstanceContext = (element.isInstanceMember && !element.isField) | 155 element.isGenerativeConstructor, |
175 || element.isGenerativeConstructor, | 156 this.currentClass = |
176 this.currentClass = element.isClassMember ? element.enclosingClass | 157 element.isClassMember ? element.enclosingClass : null, |
177 : null, | 158 this.statementScope = new StatementScope(), |
178 this.statementScope = new StatementScope(), | 159 scope = useEnclosingScope |
179 scope = useEnclosingScope | 160 ? Scope.buildEnclosingScope(element) |
180 ? Scope.buildEnclosingScope(element) : element.buildScope(), | 161 : element.buildScope(), |
181 // The type annotations on a typedef do not imply type checks. | 162 // The type annotations on a typedef do not imply type checks. |
182 // TODO(karlklose): clean this up (dartbug.com/8870). | 163 // TODO(karlklose): clean this up (dartbug.com/8870). |
183 inCheckContext = compiler.options.enableTypeAssertions && | 164 inCheckContext = compiler.options.enableTypeAssertions && |
184 !element.isLibrary && | 165 !element.isLibrary && |
185 !element.isTypedef && | 166 !element.isTypedef && |
186 !element.enclosingElement.isTypedef, | 167 !element.enclosingElement.isTypedef, |
187 inCatchBlock = false, | 168 inCatchBlock = false, |
188 constantState = element.isConst | 169 constantState = element.isConst |
189 ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT, | 170 ? ConstantState.CONSTANT |
190 super(compiler, registry); | 171 : ConstantState.NON_CONSTANT, |
| 172 super(compiler, registry); |
191 | 173 |
192 CoreClasses get coreClasses => compiler.coreClasses; | 174 CoreClasses get coreClasses => compiler.coreClasses; |
193 | 175 |
194 CoreTypes get coreTypes => compiler.coreTypes; | 176 CoreTypes get coreTypes => compiler.coreTypes; |
195 | 177 |
196 AsyncMarker get currentAsyncMarker { | 178 AsyncMarker get currentAsyncMarker { |
197 if (enclosingElement is FunctionElement) { | 179 if (enclosingElement is FunctionElement) { |
198 FunctionElement function = enclosingElement; | 180 FunctionElement function = enclosingElement; |
199 return function.asyncMarker; | 181 return function.asyncMarker; |
200 } | 182 } |
201 return AsyncMarker.SYNC; | 183 return AsyncMarker.SYNC; |
202 } | 184 } |
203 | 185 |
204 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 186 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
205 if (!Elements.isUnresolved(result)) { | 187 if (!Elements.isUnresolved(result)) { |
206 if (!inInstanceContext && result.isInstanceMember) { | 188 if (!inInstanceContext && result.isInstanceMember) { |
207 reporter.reportErrorMessage( | 189 reporter.reportErrorMessage( |
208 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 190 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
209 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, | 191 return new ErroneousElementX(MessageKind.NO_INSTANCE_AVAILABLE, |
210 {'name': name}, | 192 {'name': name}, name, enclosingElement); |
211 name, enclosingElement); | |
212 } else if (result.isAmbiguous) { | 193 } else if (result.isAmbiguous) { |
213 AmbiguousElement ambiguous = result; | 194 AmbiguousElement ambiguous = result; |
214 return reportAndCreateErroneousElement( | 195 return reportAndCreateErroneousElement( |
215 node, | 196 node, name, ambiguous.messageKind, ambiguous.messageArguments, |
216 name, | 197 infos: ambiguous.computeInfos(enclosingElement, reporter), |
217 ambiguous.messageKind, | 198 isError: true); |
218 ambiguous.messageArguments, | |
219 infos: ambiguous.computeInfos(enclosingElement, reporter), | |
220 isError: true); | |
221 } | 199 } |
222 } | 200 } |
223 return result; | 201 return result; |
224 } | 202 } |
225 | 203 |
226 // Create, or reuse an already created, target element for a statement. | 204 // Create, or reuse an already created, target element for a statement. |
227 JumpTarget getOrDefineTarget(Node statement) { | 205 JumpTarget getOrDefineTarget(Node statement) { |
228 JumpTarget element = registry.getTargetDefinition(statement); | 206 JumpTarget element = registry.getTargetDefinition(statement); |
229 if (element == null) { | 207 if (element == null) { |
230 element = new JumpTargetX(statement, | 208 element = new JumpTargetX( |
231 statementScope.nestingLevel, | 209 statement, statementScope.nestingLevel, enclosingElement); |
232 enclosingElement); | |
233 registry.defineTarget(statement, element); | 210 registry.defineTarget(statement, element); |
234 } | 211 } |
235 return element; | 212 return element; |
236 } | 213 } |
237 | 214 |
238 doInPromotionScope(Node node, action()) { | 215 doInPromotionScope(Node node, action()) { |
239 promotionScope = promotionScope.prepend(node); | 216 promotionScope = promotionScope.prepend(node); |
240 var result = action(); | 217 var result = action(); |
241 promotionScope = promotionScope.tail; | 218 promotionScope = promotionScope.tail; |
242 return result; | 219 return result; |
243 } | 220 } |
244 | 221 |
245 inStaticContext(action(), | 222 inStaticContext(action(), {bool inConstantInitializer: false}) { |
246 {bool inConstantInitializer: false}) { | |
247 bool wasInstanceContext = inInstanceContext; | 223 bool wasInstanceContext = inInstanceContext; |
248 ConstantState oldConstantState = constantState; | 224 ConstantState oldConstantState = constantState; |
249 constantState = inConstantInitializer | 225 constantState = inConstantInitializer |
250 ? ConstantState.CONSTANT_INITIALIZER | 226 ? ConstantState.CONSTANT_INITIALIZER |
251 : constantState; | 227 : constantState; |
252 inInstanceContext = false; | 228 inInstanceContext = false; |
253 var result = action(); | 229 var result = action(); |
254 inInstanceContext = wasInstanceContext; | 230 inInstanceContext = wasInstanceContext; |
255 constantState = oldConstantState; | 231 constantState = oldConstantState; |
256 return result; | 232 return result; |
257 } | 233 } |
258 | 234 |
259 ResolutionResult visitInStaticContext(Node node, | 235 ResolutionResult visitInStaticContext(Node node, |
260 {bool inConstantInitializer: false}) { | 236 {bool inConstantInitializer: false}) { |
261 return inStaticContext( | 237 return inStaticContext(() => visit(node), |
262 () => visit(node), | |
263 inConstantInitializer: inConstantInitializer); | 238 inConstantInitializer: inConstantInitializer); |
264 } | 239 } |
265 | 240 |
266 /// Execute [action] where the constant state is `ConstantState.CONSTANT` if | 241 /// Execute [action] where the constant state is `ConstantState.CONSTANT` if |
267 /// not already `ConstantState.CONSTANT_INITIALIZER`. | 242 /// not already `ConstantState.CONSTANT_INITIALIZER`. |
268 inConstantContext(action()) { | 243 inConstantContext(action()) { |
269 ConstantState oldConstantState = constantState; | 244 ConstantState oldConstantState = constantState; |
270 if (constantState != ConstantState.CONSTANT_INITIALIZER) { | 245 if (constantState != ConstantState.CONSTANT_INITIALIZER) { |
271 constantState = ConstantState.CONSTANT; | 246 constantState = ConstantState.CONSTANT; |
272 } | 247 } |
273 var result = action(); | 248 var result = action(); |
274 constantState = oldConstantState; | 249 constantState = oldConstantState; |
275 return result; | 250 return result; |
276 } | 251 } |
277 | 252 |
278 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if | 253 /// Visit [node] where the constant state is `ConstantState.CONSTANT` if |
279 /// not already `ConstantState.CONSTANT_INITIALIZER`. | 254 /// not already `ConstantState.CONSTANT_INITIALIZER`. |
280 ResolutionResult visitInConstantContext(Node node) { | 255 ResolutionResult visitInConstantContext(Node node) { |
281 ResolutionResult result = inConstantContext(() => visit(node)); | 256 ResolutionResult result = inConstantContext(() => visit(node)); |
282 assert(invariant(node, result != null, | 257 assert(invariant(node, result != null, |
283 message: "No resolution result for $node.")); | 258 message: "No resolution result for $node.")); |
284 | 259 |
285 return result; | 260 return result; |
286 } | 261 } |
287 | 262 |
288 ErroneousElement reportAndCreateErroneousElement( | 263 ErroneousElement reportAndCreateErroneousElement( |
289 Node node, | 264 Node node, String name, MessageKind kind, Map arguments, |
290 String name, | |
291 MessageKind kind, | |
292 Map arguments, | |
293 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], | 265 {List<DiagnosticMessage> infos: const <DiagnosticMessage>[], |
294 bool isError: false}) { | 266 bool isError: false}) { |
295 if (isError) { | 267 if (isError) { |
296 reporter.reportError( | 268 reporter.reportError( |
297 reporter.createMessage(node, kind, arguments), infos); | 269 reporter.createMessage(node, kind, arguments), infos); |
298 } else { | 270 } else { |
299 reporter.reportWarning( | 271 reporter.reportWarning( |
300 reporter.createMessage(node, kind, arguments), infos); | 272 reporter.createMessage(node, kind, arguments), infos); |
301 } | 273 } |
302 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass | 274 // TODO(ahe): Use [allowedCategory] to synthesize a more precise subclass |
303 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], | 275 // of [ErroneousElementX]. For example, [ErroneousFieldElementX], |
304 // [ErroneousConstructorElementX], etc. | 276 // [ErroneousConstructorElementX], etc. |
305 return new ErroneousElementX(kind, arguments, name, enclosingElement); | 277 return new ErroneousElementX(kind, arguments, name, enclosingElement); |
306 } | 278 } |
307 | 279 |
308 /// Report a warning or error on an unresolved access in non-instance context. | 280 /// Report a warning or error on an unresolved access in non-instance context. |
309 /// | 281 /// |
310 /// The [ErroneousElement] corresponding to the message is returned. | 282 /// The [ErroneousElement] corresponding to the message is returned. |
311 ErroneousElement reportCannotResolve(Node node, String name) { | 283 ErroneousElement reportCannotResolve(Node node, String name) { |
312 assert(invariant(node, !inInstanceContext, | 284 assert(invariant(node, !inInstanceContext, |
313 message: "ResolverVisitor.reportCannotResolve must not be called in " | 285 message: "ResolverVisitor.reportCannotResolve must not be called in " |
314 "instance context.")); | 286 "instance context.")); |
315 | 287 |
316 // We report an error within initializers because `this` is implicitly | 288 // We report an error within initializers because `this` is implicitly |
317 // accessed when unqualified identifiers are not resolved. For | 289 // accessed when unqualified identifiers are not resolved. For |
318 // details, see section 16.14.3 of the spec (2nd edition): | 290 // details, see section 16.14.3 of the spec (2nd edition): |
319 // An unqualified invocation `i` of the form `id(a1, ...)` | 291 // An unqualified invocation `i` of the form `id(a1, ...)` |
320 // ... | 292 // ... |
321 // If `i` does not occur inside a top level or static function, `i` | 293 // If `i` does not occur inside a top level or static function, `i` |
322 // is equivalent to `this.id(a1 , ...)`. | 294 // is equivalent to `this.id(a1 , ...)`. |
323 bool inInitializer = | 295 bool inInitializer = enclosingElement.isGenerativeConstructor || |
324 enclosingElement.isGenerativeConstructor || | |
325 (enclosingElement.isInstanceMember && enclosingElement.isField); | 296 (enclosingElement.isInstanceMember && enclosingElement.isField); |
326 MessageKind kind; | 297 MessageKind kind; |
327 Map arguments = {'name': name}; | 298 Map arguments = {'name': name}; |
328 if (inInitializer) { | 299 if (inInitializer) { |
329 kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER; | 300 kind = MessageKind.CANNOT_RESOLVE_IN_INITIALIZER; |
330 } else if (name == 'await') { | 301 } else if (name == 'await') { |
331 var functionName = enclosingElement.name; | 302 var functionName = enclosingElement.name; |
332 if (functionName == '') { | 303 if (functionName == '') { |
333 kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE; | 304 kind = MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE; |
334 } else { | 305 } else { |
335 kind = MessageKind.CANNOT_RESOLVE_AWAIT; | 306 kind = MessageKind.CANNOT_RESOLVE_AWAIT; |
336 arguments['functionName'] = functionName; | 307 arguments['functionName'] = functionName; |
337 } | 308 } |
338 } else { | 309 } else { |
339 kind = MessageKind.CANNOT_RESOLVE; | 310 kind = MessageKind.CANNOT_RESOLVE; |
340 } | 311 } |
341 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 312 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
342 return reportAndCreateErroneousElement( | 313 return reportAndCreateErroneousElement(node, name, kind, arguments, |
343 node, name, kind, arguments, isError: inInitializer); | 314 isError: inInitializer); |
344 } | 315 } |
345 | 316 |
346 ResolutionResult visitIdentifier(Identifier node) { | 317 ResolutionResult visitIdentifier(Identifier node) { |
347 if (node.isThis()) { | 318 if (node.isThis()) { |
348 if (!inInstanceContext) { | 319 if (!inInstanceContext) { |
349 reporter.reportErrorMessage( | 320 reporter.reportErrorMessage( |
350 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 321 node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
351 } | 322 } |
352 return const NoneResult(); | 323 return const NoneResult(); |
353 } else if (node.isSuper()) { | 324 } else if (node.isSuper()) { |
354 if (!inInstanceContext) { | 325 if (!inInstanceContext) { |
355 reporter.reportErrorMessage( | 326 reporter.reportErrorMessage(node, MessageKind.NO_SUPER_IN_STATIC); |
356 node, MessageKind.NO_SUPER_IN_STATIC); | |
357 } | 327 } |
358 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 328 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
359 reporter.reportErrorMessage( | 329 reporter.reportErrorMessage(node, MessageKind.INVALID_USE_OF_SUPER); |
360 node, MessageKind.INVALID_USE_OF_SUPER); | |
361 } | 330 } |
362 return const NoneResult(); | 331 return const NoneResult(); |
363 } else { | 332 } else { |
364 String name = node.source; | 333 String name = node.source; |
365 Element element = lookupInScope(reporter, node, scope, name); | 334 Element element = lookupInScope(reporter, node, scope, name); |
366 if (Elements.isUnresolved(element) && name == 'dynamic') { | 335 if (Elements.isUnresolved(element) && name == 'dynamic') { |
367 // TODO(johnniwinther): Remove this hack when we can return more complex | 336 // TODO(johnniwinther): Remove this hack when we can return more complex |
368 // objects than [Element] from this method. | 337 // objects than [Element] from this method. |
369 element = coreClasses.typeClass; | 338 element = coreClasses.typeClass; |
370 // Set the type to be `dynamic` to mark that this is a type literal. | 339 // Set the type to be `dynamic` to mark that this is a type literal. |
371 registry.setType(node, const DynamicType()); | 340 registry.setType(node, const DynamicType()); |
372 } | 341 } |
373 element = reportLookupErrorIfAny(element, node, name); | 342 element = reportLookupErrorIfAny(element, node, name); |
374 if (element == null) { | 343 if (element == null) { |
375 if (!inInstanceContext) { | 344 if (!inInstanceContext) { |
376 element = reportCannotResolve(node, name); | 345 element = reportCannotResolve(node, name); |
377 } | 346 } |
378 } else if (element.isMalformed) { | 347 } else if (element.isMalformed) { |
379 // Use the malformed element. | 348 // Use the malformed element. |
380 } else { | 349 } else { |
381 if ((element.kind.category & allowedCategory) == 0) { | 350 if ((element.kind.category & allowedCategory) == 0) { |
382 element = reportAndCreateErroneousElement( | 351 element = |
383 node, name, MessageKind.GENERIC, | 352 reportAndCreateErroneousElement(node, name, MessageKind.GENERIC, |
384 // TODO(ahe): Improve error message. Need UX input. | 353 // TODO(ahe): Improve error message. Need UX input. |
385 {'text': "is not an expression $element"}); | 354 {'text': "is not an expression $element"}); |
386 } | 355 } |
387 } | 356 } |
388 if (!Elements.isUnresolved(element) && element.isClass) { | 357 if (!Elements.isUnresolved(element) && element.isClass) { |
389 ClassElement classElement = element; | 358 ClassElement classElement = element; |
390 classElement.ensureResolved(resolution); | 359 classElement.ensureResolved(resolution); |
391 } | 360 } |
392 if (element != null) { | 361 if (element != null) { |
393 registry.useElement(node, element); | 362 registry.useElement(node, element); |
394 if (element.isPrefix) { | 363 if (element.isPrefix) { |
395 return new PrefixResult(element, null); | 364 return new PrefixResult(element, null); |
(...skipping 27 matching lines...) Expand all Loading... |
423 | 392 |
424 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { | 393 FunctionElement resolveConstructorRedirection(FunctionElementX constructor) { |
425 FunctionExpression node = constructor.parseNode(resolution.parsing); | 394 FunctionExpression node = constructor.parseNode(resolution.parsing); |
426 | 395 |
427 // A synthetic constructor does not have a node. | 396 // A synthetic constructor does not have a node. |
428 if (node == null) return null; | 397 if (node == null) return null; |
429 if (node.initializers == null) return null; | 398 if (node.initializers == null) return null; |
430 Link<Node> initializers = node.initializers.nodes; | 399 Link<Node> initializers = node.initializers.nodes; |
431 if (!initializers.isEmpty && | 400 if (!initializers.isEmpty && |
432 Initializers.isConstructorRedirect(initializers.head)) { | 401 Initializers.isConstructorRedirect(initializers.head)) { |
433 Name name = | 402 Name name = getRedirectingThisOrSuperConstructorName(initializers.head); |
434 getRedirectingThisOrSuperConstructorName(initializers.head); | |
435 final ClassElement classElement = constructor.enclosingClass; | 403 final ClassElement classElement = constructor.enclosingClass; |
436 return classElement.lookupConstructor(name.text); | 404 return classElement.lookupConstructor(name.text); |
437 } | 405 } |
438 return null; | 406 return null; |
439 } | 407 } |
440 | 408 |
441 void setupFunction(FunctionExpression node, FunctionElement function) { | 409 void setupFunction(FunctionExpression node, FunctionElement function) { |
442 Element enclosingElement = function.enclosingElement; | 410 Element enclosingElement = function.enclosingElement; |
443 if (node.modifiers.isStatic && | 411 if (node.modifiers.isStatic && enclosingElement.kind != ElementKind.CLASS) { |
444 enclosingElement.kind != ElementKind.CLASS) { | |
445 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); | 412 reporter.reportErrorMessage(node, MessageKind.ILLEGAL_STATIC); |
446 } | 413 } |
447 | 414 |
448 scope = new MethodScope(scope, function); | 415 scope = new MethodScope(scope, function); |
449 // Put the parameters in scope. | 416 // Put the parameters in scope. |
450 FunctionSignature functionParameters = function.functionSignature; | 417 FunctionSignature functionParameters = function.functionSignature; |
451 Link<Node> parameterNodes = (node.parameters == null) | 418 Link<Node> parameterNodes = |
452 ? const Link<Node>() : node.parameters.nodes; | 419 (node.parameters == null) ? const Link<Node>() : node.parameters.nodes; |
453 functionParameters.forEachParameter((ParameterElementX element) { | 420 functionParameters.forEachParameter((ParameterElementX element) { |
454 // TODO(karlklose): should be a list of [FormalElement]s, but the actual | 421 // TODO(karlklose): should be a list of [FormalElement]s, but the actual |
455 // implementation uses [Element]. | 422 // implementation uses [Element]. |
456 List<Element> optionals = functionParameters.optionalParameters; | 423 List<Element> optionals = functionParameters.optionalParameters; |
457 if (!optionals.isEmpty && element == optionals.first) { | 424 if (!optionals.isEmpty && element == optionals.first) { |
458 NodeList nodes = parameterNodes.head; | 425 NodeList nodes = parameterNodes.head; |
459 parameterNodes = nodes.nodes; | 426 parameterNodes = nodes.nodes; |
460 } | 427 } |
461 if (element.isOptional) { | 428 if (element.isOptional) { |
462 if (element.initializer != null) { | 429 if (element.initializer != null) { |
(...skipping 12 matching lines...) Expand all Loading... |
475 if (element.isInitializingFormal) { | 442 if (element.isInitializingFormal) { |
476 registry.useElement(parameterNode, element); | 443 registry.useElement(parameterNode, element); |
477 } else { | 444 } else { |
478 LocalParameterElementX parameterElement = element; | 445 LocalParameterElementX parameterElement = element; |
479 defineLocalVariable(parameterNode, parameterElement); | 446 defineLocalVariable(parameterNode, parameterElement); |
480 addToScope(parameterElement); | 447 addToScope(parameterElement); |
481 } | 448 } |
482 parameterNodes = parameterNodes.tail; | 449 parameterNodes = parameterNodes.tail; |
483 }); | 450 }); |
484 addDeferredAction(enclosingElement, () { | 451 addDeferredAction(enclosingElement, () { |
485 functionParameters.forEachOptionalParameter( | 452 functionParameters |
486 (ParameterElementX parameter) { | 453 .forEachOptionalParameter((ParameterElementX parameter) { |
487 parameter.constant = | 454 parameter.constant = |
488 compiler.resolver.constantCompiler.compileConstant(parameter); | 455 compiler.resolver.constantCompiler.compileConstant(parameter); |
489 }); | 456 }); |
490 }); | 457 }); |
491 if (inCheckContext) { | 458 if (inCheckContext) { |
492 functionParameters.forEachParameter((ParameterElement element) { | 459 functionParameters.forEachParameter((ParameterElement element) { |
493 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); | 460 registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type)); |
494 }); | 461 }); |
495 } | 462 } |
496 } | 463 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 visitLoopBodyIn(node, node.body, blockScope); | 541 visitLoopBodyIn(node, node.body, blockScope); |
575 return const NoneResult(); | 542 return const NoneResult(); |
576 } | 543 } |
577 | 544 |
578 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { | 545 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { |
579 assert(node.function.name != null); | 546 assert(node.function.name != null); |
580 visitFunctionExpression(node.function, inFunctionDeclaration: true); | 547 visitFunctionExpression(node.function, inFunctionDeclaration: true); |
581 return const NoneResult(); | 548 return const NoneResult(); |
582 } | 549 } |
583 | 550 |
584 | |
585 /// Process a local function declaration or an anonymous function expression. | 551 /// Process a local function declaration or an anonymous function expression. |
586 /// | 552 /// |
587 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 553 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
588 /// child of a function declaration. | 554 /// child of a function declaration. |
589 /// | 555 /// |
590 /// This is used to distinguish local function declarations from anonymous | 556 /// This is used to distinguish local function declarations from anonymous |
591 /// function expressions. | 557 /// function expressions. |
592 ResolutionResult visitFunctionExpression( | 558 ResolutionResult visitFunctionExpression(FunctionExpression node, |
593 FunctionExpression node, | |
594 {bool inFunctionDeclaration: false}) { | 559 {bool inFunctionDeclaration: false}) { |
595 bool doAddToScope = inFunctionDeclaration; | 560 bool doAddToScope = inFunctionDeclaration; |
596 if (!inFunctionDeclaration && node.name != null) { | 561 if (!inFunctionDeclaration && node.name != null) { |
597 reporter.reportErrorMessage( | 562 reporter.reportErrorMessage(node.name, |
598 node.name, | 563 MessageKind.NAMED_FUNCTION_EXPRESSION, {'name': node.name}); |
599 MessageKind.NAMED_FUNCTION_EXPRESSION, | |
600 {'name': node.name}); | |
601 } | 564 } |
602 visit(node.returnType); | 565 visit(node.returnType); |
603 String name; | 566 String name; |
604 if (node.name == null) { | 567 if (node.name == null) { |
605 name = ""; | 568 name = ""; |
606 } else { | 569 } else { |
607 name = node.name.asIdentifier().source; | 570 name = node.name.asIdentifier().source; |
608 } | 571 } |
609 LocalFunctionElementX function = new LocalFunctionElementX( | 572 LocalFunctionElementX function = new LocalFunctionElementX( |
610 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, | 573 name, node, ElementKind.FUNCTION, Modifiers.EMPTY, enclosingElement); |
611 enclosingElement); | |
612 ResolverTask.processAsyncMarker(compiler, function, registry); | 574 ResolverTask.processAsyncMarker(compiler, function, registry); |
613 function.functionSignature = SignatureResolver.analyze( | 575 function.functionSignature = SignatureResolver.analyze( |
614 compiler, | 576 compiler, node.parameters, node.returnType, function, registry, |
615 node.parameters, | |
616 node.returnType, | |
617 function, | |
618 registry, | |
619 createRealParameters: true, | 577 createRealParameters: true, |
620 isFunctionExpression: !inFunctionDeclaration); | 578 isFunctionExpression: !inFunctionDeclaration); |
621 checkLocalDefinitionName(node, function); | 579 checkLocalDefinitionName(node, function); |
622 registry.defineFunction(node, function); | 580 registry.defineFunction(node, function); |
623 if (doAddToScope) { | 581 if (doAddToScope) { |
624 addToScope(function); | 582 addToScope(function); |
625 } | 583 } |
626 Scope oldScope = scope; // The scope is modified by [setupFunction]. | 584 Scope oldScope = scope; // The scope is modified by [setupFunction]. |
627 setupFunction(node, function); | 585 setupFunction(node, function); |
628 | 586 |
629 Element previousEnclosingElement = enclosingElement; | 587 Element previousEnclosingElement = enclosingElement; |
630 enclosingElement = function; | 588 enclosingElement = function; |
631 // Run the body in a fresh statement scope. | 589 // Run the body in a fresh statement scope. |
632 StatementScope oldStatementScope = statementScope; | 590 StatementScope oldStatementScope = statementScope; |
633 statementScope = new StatementScope(); | 591 statementScope = new StatementScope(); |
634 visit(node.body); | 592 visit(node.body); |
635 statementScope = oldStatementScope; | 593 statementScope = oldStatementScope; |
636 | 594 |
637 scope = oldScope; | 595 scope = oldScope; |
638 enclosingElement = previousEnclosingElement; | 596 enclosingElement = previousEnclosingElement; |
639 | 597 |
640 registry.registerStaticUse(new StaticUse.closure(function)); | 598 registry.registerStaticUse(new StaticUse.closure(function)); |
641 return const NoneResult(); | 599 return const NoneResult(); |
642 } | 600 } |
643 | 601 |
644 ResolutionResult visitIf(If node) { | 602 ResolutionResult visitIf(If node) { |
645 doInPromotionScope(node.condition.expression, () => visit(node.condition)); | 603 doInPromotionScope(node.condition.expression, () => visit(node.condition)); |
646 doInPromotionScope(node.thenPart, | 604 doInPromotionScope( |
647 () => visitIn(node.thenPart, new BlockScope(scope))); | 605 node.thenPart, () => visitIn(node.thenPart, new BlockScope(scope))); |
648 visitIn(node.elsePart, new BlockScope(scope)); | 606 visitIn(node.elsePart, new BlockScope(scope)); |
649 return const NoneResult(); | 607 return const NoneResult(); |
650 } | 608 } |
651 | 609 |
652 static Selector computeSendSelector(Send node, | 610 static Selector computeSendSelector( |
653 LibraryElement library, | 611 Send node, LibraryElement library, Element element) { |
654 Element element) { | |
655 // First determine if this is part of an assignment. | 612 // First determine if this is part of an assignment. |
656 bool isSet = node.asSendSet() != null; | 613 bool isSet = node.asSendSet() != null; |
657 | 614 |
658 if (node.isIndex) { | 615 if (node.isIndex) { |
659 return isSet ? new Selector.indexSet() : new Selector.index(); | 616 return isSet ? new Selector.indexSet() : new Selector.index(); |
660 } | 617 } |
661 | 618 |
662 if (node.isOperator) { | 619 if (node.isOperator) { |
663 String source = node.selector.asOperator().source; | 620 String source = node.selector.asOperator().source; |
664 String string = source; | 621 String string = source; |
665 if (identical(string, '!') || | 622 if (identical(string, '!') || |
666 identical(string, '&&') || identical(string, '||') || | 623 identical(string, '&&') || |
667 identical(string, 'is') || identical(string, 'as') || | 624 identical(string, '||') || |
668 identical(string, '?') || identical(string, '??')) { | 625 identical(string, 'is') || |
| 626 identical(string, 'as') || |
| 627 identical(string, '?') || |
| 628 identical(string, '??')) { |
669 return null; | 629 return null; |
670 } | 630 } |
671 String op = source; | 631 String op = source; |
672 if (!isUserDefinableOperator(source)) { | 632 if (!isUserDefinableOperator(source)) { |
673 op = Elements.mapToUserOperatorOrNull(source); | 633 op = Elements.mapToUserOperatorOrNull(source); |
674 } | 634 } |
675 if (op == null) { | 635 if (op == null) { |
676 // Unsupported operator. An error has been reported during parsing. | 636 // Unsupported operator. An error has been reported during parsing. |
677 return new Selector.call( | 637 return new Selector.call(new Name(source, library), |
678 new Name(source, library), | |
679 new CallStructure.unnamed(node.argumentsNode.slowLength())); | 638 new CallStructure.unnamed(node.argumentsNode.slowLength())); |
680 } | 639 } |
681 return node.arguments.isEmpty | 640 return node.arguments.isEmpty |
682 ? new Selector.unaryOperator(op) | 641 ? new Selector.unaryOperator(op) |
683 : new Selector.binaryOperator(op); | 642 : new Selector.binaryOperator(op); |
684 } | 643 } |
685 | 644 |
686 Identifier identifier = node.selector.asIdentifier(); | 645 Identifier identifier = node.selector.asIdentifier(); |
687 if (node.isPropertyAccess) { | 646 if (node.isPropertyAccess) { |
688 assert(!isSet); | 647 assert(!isSet); |
689 return new Selector.getter( | 648 return new Selector.getter(new Name(identifier.source, library)); |
690 new Name(identifier.source, library)); | |
691 } else if (isSet) { | 649 } else if (isSet) { |
692 return new Selector.setter( | 650 return new Selector.setter( |
693 new Name(identifier.source, library, isSetter: true)); | 651 new Name(identifier.source, library, isSetter: true)); |
694 } | 652 } |
695 | 653 |
696 // Compute the arity and the list of named arguments. | 654 // Compute the arity and the list of named arguments. |
697 int arity = 0; | 655 int arity = 0; |
698 List<String> named = <String>[]; | 656 List<String> named = <String>[]; |
699 for (Link<Node> link = node.argumentsNode.nodes; | 657 for (Link<Node> link = node.argumentsNode.nodes; |
700 !link.isEmpty; | 658 !link.isEmpty; |
701 link = link.tail) { | 659 link = link.tail) { |
702 Expression argument = link.head; | 660 Expression argument = link.head; |
703 NamedArgument namedArgument = argument.asNamedArgument(); | 661 NamedArgument namedArgument = argument.asNamedArgument(); |
704 if (namedArgument != null) { | 662 if (namedArgument != null) { |
705 named.add(namedArgument.name.source); | 663 named.add(namedArgument.name.source); |
706 } | 664 } |
707 arity++; | 665 arity++; |
708 } | 666 } |
709 | 667 |
710 if (element != null && element.isConstructor) { | 668 if (element != null && element.isConstructor) { |
711 return new Selector.callConstructor( | 669 return new Selector.callConstructor( |
712 new Name(element.name, library), arity, named); | 670 new Name(element.name, library), arity, named); |
713 } | 671 } |
714 | 672 |
715 // If we're invoking a closure, we do not have an identifier. | 673 // If we're invoking a closure, we do not have an identifier. |
716 return (identifier == null) | 674 return (identifier == null) |
717 ? new Selector.callClosure(arity, named) | 675 ? new Selector.callClosure(arity, named) |
718 : new Selector.call(new Name(identifier.source, library), | 676 : new Selector.call(new Name(identifier.source, library), |
719 new CallStructure(arity, named)); | 677 new CallStructure(arity, named)); |
720 } | 678 } |
721 | 679 |
722 Selector resolveSelector(Send node, Element element) { | 680 Selector resolveSelector(Send node, Element element) { |
723 LibraryElement library = enclosingElement.library; | 681 LibraryElement library = enclosingElement.library; |
724 Selector selector = computeSendSelector(node, library, element); | 682 Selector selector = computeSendSelector(node, library, element); |
725 if (selector != null) registry.setSelector(node, selector); | 683 if (selector != null) registry.setSelector(node, selector); |
726 return selector; | 684 return selector; |
727 } | 685 } |
728 | 686 |
729 ArgumentsResult resolveArguments(NodeList list) { | 687 ArgumentsResult resolveArguments(NodeList list) { |
(...skipping 12 matching lines...) Expand all Loading... |
742 isValidAsConstant = false; | 700 isValidAsConstant = false; |
743 } | 701 } |
744 argumentResults.add(result); | 702 argumentResults.add(result); |
745 | 703 |
746 NamedArgument namedArgument = argument.asNamedArgument(); | 704 NamedArgument namedArgument = argument.asNamedArgument(); |
747 if (namedArgument != null) { | 705 if (namedArgument != null) { |
748 String source = namedArgument.name.source; | 706 String source = namedArgument.name.source; |
749 namedArguments.add(source); | 707 namedArguments.add(source); |
750 if (seenNamedArguments.containsKey(source)) { | 708 if (seenNamedArguments.containsKey(source)) { |
751 reportDuplicateDefinition( | 709 reportDuplicateDefinition( |
752 source, | 710 source, argument, seenNamedArguments[source]); |
753 argument, | |
754 seenNamedArguments[source]); | |
755 isValidAsConstant = false; | 711 isValidAsConstant = false; |
756 } else { | 712 } else { |
757 seenNamedArguments[source] = namedArgument; | 713 seenNamedArguments[source] = namedArgument; |
758 } | 714 } |
759 } else if (!seenNamedArguments.isEmpty) { | 715 } else if (!seenNamedArguments.isEmpty) { |
760 reporter.reportErrorMessage( | 716 reporter.reportErrorMessage( |
761 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 717 argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
762 isValidAsConstant = false; | 718 isValidAsConstant = false; |
763 } | 719 } |
764 argumentCount++; | 720 argumentCount++; |
765 } | 721 } |
766 sendIsMemberAccess = oldSendIsMemberAccess; | 722 sendIsMemberAccess = oldSendIsMemberAccess; |
767 return new ArgumentsResult( | 723 return new ArgumentsResult( |
768 new CallStructure(argumentCount, namedArguments), | 724 new CallStructure(argumentCount, namedArguments), argumentResults, |
769 argumentResults, | |
770 isValidAsConstant: isValidAsConstant); | 725 isValidAsConstant: isValidAsConstant); |
771 } | 726 } |
772 | 727 |
773 /// Check that access to `super` is currently allowed. Returns an | 728 /// Check that access to `super` is currently allowed. Returns an |
774 /// [AccessSemantics] in case of an error, `null` otherwise. | 729 /// [AccessSemantics] in case of an error, `null` otherwise. |
775 AccessSemantics checkSuperAccess(Send node) { | 730 AccessSemantics checkSuperAccess(Send node) { |
776 if (!inInstanceContext) { | 731 if (!inInstanceContext) { |
777 ErroneousElement error = reportAndCreateErroneousElement( | 732 ErroneousElement error = reportAndCreateErroneousElement( |
778 node, 'super', | 733 node, 'super', MessageKind.NO_SUPER_IN_STATIC, {}, |
779 MessageKind.NO_SUPER_IN_STATIC, {}, | |
780 isError: true); | 734 isError: true); |
781 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 735 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
782 return new StaticAccess.invalid(error); | 736 return new StaticAccess.invalid(error); |
783 } | 737 } |
784 if (node.isConditional) { | 738 if (node.isConditional) { |
785 // `super?.foo` is not allowed. | 739 // `super?.foo` is not allowed. |
786 ErroneousElement error = reportAndCreateErroneousElement( | 740 ErroneousElement error = reportAndCreateErroneousElement( |
787 node, 'super', | 741 node, 'super', MessageKind.INVALID_USE_OF_SUPER, {}, |
788 MessageKind.INVALID_USE_OF_SUPER, {}, | |
789 isError: true); | 742 isError: true); |
790 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 743 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
791 return new StaticAccess.invalid(error); | 744 return new StaticAccess.invalid(error); |
792 } | 745 } |
793 if (currentClass.supertype == null) { | 746 if (currentClass.supertype == null) { |
794 // This is just to guard against internal errors, so no need | 747 // This is just to guard against internal errors, so no need |
795 // for a real error message. | 748 // for a real error message. |
796 ErroneousElement error = reportAndCreateErroneousElement( | 749 ErroneousElement error = reportAndCreateErroneousElement(node, 'super', |
797 node, 'super', | 750 MessageKind.GENERIC, {'text': "Object has no superclass"}, |
798 MessageKind.GENERIC, | |
799 {'text': "Object has no superclass"}, | |
800 isError: true); | 751 isError: true); |
801 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 752 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
802 return new StaticAccess.invalid(error); | 753 return new StaticAccess.invalid(error); |
803 } | 754 } |
804 registry.registerSuperUse(reporter.spanFromSpannable(node)); | 755 registry.registerSuperUse(reporter.spanFromSpannable(node)); |
805 return null; | 756 return null; |
806 } | 757 } |
807 | 758 |
808 /// Check that access to `this` is currently allowed. Returns an | 759 /// Check that access to `this` is currently allowed. Returns an |
809 /// [AccessSemantics] in case of an error, `null` otherwise. | 760 /// [AccessSemantics] in case of an error, `null` otherwise. |
810 AccessSemantics checkThisAccess(Send node) { | 761 AccessSemantics checkThisAccess(Send node) { |
811 if (!inInstanceContext) { | 762 if (!inInstanceContext) { |
812 ErroneousElement error = reportAndCreateErroneousElement( | 763 ErroneousElement error = reportAndCreateErroneousElement( |
813 node, 'this', | 764 node, 'this', MessageKind.NO_THIS_AVAILABLE, const {}, |
814 MessageKind.NO_THIS_AVAILABLE, const {}, | |
815 isError: true); | 765 isError: true); |
816 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 766 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
817 return new StaticAccess.invalid(error); | 767 return new StaticAccess.invalid(error); |
818 } | 768 } |
819 return null; | 769 return null; |
820 } | 770 } |
821 | 771 |
822 /// Compute the [AccessSemantics] corresponding to a super access of [target]. | 772 /// Compute the [AccessSemantics] corresponding to a super access of [target]. |
823 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { | 773 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { |
824 if (target.isMalformed) { | 774 if (target.isMalformed) { |
(...skipping 11 matching lines...) Expand all Loading... |
836 } else { | 786 } else { |
837 assert(invariant(node, target.isFunction, | 787 assert(invariant(node, target.isFunction, |
838 message: "Unexpected super target '$target'.")); | 788 message: "Unexpected super target '$target'.")); |
839 return new StaticAccess.superMethod(target); | 789 return new StaticAccess.superMethod(target); |
840 } | 790 } |
841 } | 791 } |
842 | 792 |
843 /// Compute the [AccessSemantics] corresponding to a compound super access | 793 /// Compute the [AccessSemantics] corresponding to a compound super access |
844 /// reading from [getter] and writing to [setter]. | 794 /// reading from [getter] and writing to [setter]. |
845 AccessSemantics computeCompoundSuperAccessSemantics( | 795 AccessSemantics computeCompoundSuperAccessSemantics( |
846 Spannable node, | 796 Spannable node, Element getter, Element setter, |
847 Element getter, | |
848 Element setter, | |
849 {bool isIndex: false}) { | 797 {bool isIndex: false}) { |
850 if (getter.isMalformed) { | 798 if (getter.isMalformed) { |
851 if (setter.isMalformed) { | 799 if (setter.isMalformed) { |
852 return new StaticAccess.unresolvedSuper(getter); | 800 return new StaticAccess.unresolvedSuper(getter); |
853 } else if (setter.isFunction) { | 801 } else if (setter.isFunction) { |
854 assert(invariant(node, setter.name == '[]=', | 802 assert(invariant(node, setter.name == '[]=', |
855 message: "Unexpected super setter '$setter'.")); | 803 message: "Unexpected super setter '$setter'.")); |
856 return new CompoundAccessSemantics( | 804 return new CompoundAccessSemantics( |
857 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 805 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
858 } else { | 806 } else { |
859 assert(invariant(node, setter.isSetter, | 807 assert(invariant(node, setter.isSetter, |
860 message: "Unexpected super setter '$setter'.")); | 808 message: "Unexpected super setter '$setter'.")); |
861 return new CompoundAccessSemantics( | 809 return new CompoundAccessSemantics( |
862 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); | 810 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, setter); |
863 } | 811 } |
864 } else if (getter.isField) { | 812 } else if (getter.isField) { |
865 if (setter.isMalformed) { | 813 if (setter.isMalformed) { |
866 assert(invariant(node, getter.isFinal, | 814 assert(invariant(node, getter.isFinal, |
867 message: "Unexpected super setter '$setter' for getter '$getter.")); | 815 message: "Unexpected super setter '$setter' for getter '$getter.")); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); | 852 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, setter); |
905 } else { | 853 } else { |
906 return new StaticAccess.superMethod(getter); | 854 return new StaticAccess.superMethod(getter); |
907 } | 855 } |
908 } else if (setter.isFunction) { | 856 } else if (setter.isFunction) { |
909 assert(invariant(node, setter.name == '[]=', | 857 assert(invariant(node, setter.name == '[]=', |
910 message: "Unexpected super setter '$setter'.")); | 858 message: "Unexpected super setter '$setter'.")); |
911 assert(invariant(node, getter.name == '[]', | 859 assert(invariant(node, getter.name == '[]', |
912 message: "Unexpected super getter '$getter'.")); | 860 message: "Unexpected super getter '$getter'.")); |
913 return new CompoundAccessSemantics( | 861 return new CompoundAccessSemantics( |
914 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); | 862 CompoundAccessKind.SUPER_GETTER_SETTER, getter, setter); |
915 } else { | 863 } else { |
916 assert(invariant(node, setter.isSetter, | 864 assert(invariant(node, setter.isSetter, |
917 message: "Unexpected super setter '$setter'.")); | 865 message: "Unexpected super setter '$setter'.")); |
918 return new CompoundAccessSemantics( | 866 return new CompoundAccessSemantics( |
919 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); | 867 CompoundAccessKind.SUPER_METHOD_SETTER, getter, setter); |
920 } | 868 } |
921 } | 869 } |
922 } | 870 } |
923 | 871 |
924 /// Compute the [AccessSemantics] corresponding to a local access of [target]. | 872 /// Compute the [AccessSemantics] corresponding to a local access of [target]. |
925 AccessSemantics computeLocalAccessSemantics(Spannable node, | 873 AccessSemantics computeLocalAccessSemantics( |
926 LocalElement target) { | 874 Spannable node, LocalElement target) { |
927 if (target.isParameter) { | 875 if (target.isParameter) { |
928 if (target.isFinal || target.isConst) { | 876 if (target.isFinal || target.isConst) { |
929 return new StaticAccess.finalParameter(target); | 877 return new StaticAccess.finalParameter(target); |
930 } else { | 878 } else { |
931 return new StaticAccess.parameter(target); | 879 return new StaticAccess.parameter(target); |
932 } | 880 } |
933 } else if (target.isVariable) { | 881 } else if (target.isVariable) { |
934 if (target.isFinal || target.isConst) { | 882 if (target.isFinal || target.isConst) { |
935 return new StaticAccess.finalLocalVariable(target); | 883 return new StaticAccess.finalLocalVariable(target); |
936 } else { | 884 } else { |
937 return new StaticAccess.localVariable(target); | 885 return new StaticAccess.localVariable(target); |
938 } | 886 } |
939 } else { | 887 } else { |
940 assert(invariant(node, target.isFunction, | 888 assert(invariant(node, target.isFunction, |
941 message: "Unexpected local target '$target'.")); | 889 message: "Unexpected local target '$target'.")); |
942 return new StaticAccess.localFunction(target); | 890 return new StaticAccess.localFunction(target); |
943 } | 891 } |
944 } | 892 } |
945 | 893 |
946 /// Compute the [AccessSemantics] corresponding to a static or toplevel access | 894 /// Compute the [AccessSemantics] corresponding to a static or toplevel access |
947 /// of [target]. | 895 /// of [target]. |
948 AccessSemantics computeStaticOrTopLevelAccessSemantics( | 896 AccessSemantics computeStaticOrTopLevelAccessSemantics( |
949 Spannable node, | 897 Spannable node, Element target) { |
950 Element target) { | |
951 | |
952 target = target.declaration; | 898 target = target.declaration; |
953 if (target.isMalformed) { | 899 if (target.isMalformed) { |
954 // This handles elements with parser errors. | 900 // This handles elements with parser errors. |
955 return new StaticAccess.unresolved(target); | 901 return new StaticAccess.unresolved(target); |
956 } | 902 } |
957 if (target.isStatic) { | 903 if (target.isStatic) { |
958 if (target.isGetter) { | 904 if (target.isGetter) { |
959 return new StaticAccess.staticGetter(target); | 905 return new StaticAccess.staticGetter(target); |
960 } else if (target.isSetter) { | 906 } else if (target.isSetter) { |
961 return new StaticAccess.staticSetter(target); | 907 return new StaticAccess.staticSetter(target); |
962 } else if (target.isField) { | 908 } else if (target.isField) { |
963 if (target.isFinal || target.isConst) { | 909 if (target.isFinal || target.isConst) { |
964 return new StaticAccess.finalStaticField(target); | 910 return new StaticAccess.finalStaticField(target); |
965 } else { | 911 } else { |
966 return new StaticAccess.staticField(target); | 912 return new StaticAccess.staticField(target); |
967 } | 913 } |
968 } else { | 914 } else { |
969 assert(invariant(node, target.isFunction, | 915 assert(invariant(node, target.isFunction, |
970 message: "Unexpected static target '$target'.")); | 916 message: "Unexpected static target '$target'.")); |
971 return new StaticAccess.staticMethod(target); | 917 return new StaticAccess.staticMethod(target); |
972 } | 918 } |
973 } else { | 919 } else { |
974 assert(invariant(node, target.isTopLevel, | 920 assert(invariant(node, target.isTopLevel, |
975 message: "Unexpected statically resolved target '$target'.")); | 921 message: "Unexpected statically resolved target '$target'.")); |
976 if (target.isGetter) { | 922 if (target.isGetter) { |
977 return new StaticAccess.topLevelGetter(target); | 923 return new StaticAccess.topLevelGetter(target); |
978 } else if (target.isSetter) { | 924 } else if (target.isSetter) { |
979 return new StaticAccess.topLevelSetter(target); | 925 return new StaticAccess.topLevelSetter(target); |
980 } else if (target.isField) { | 926 } else if (target.isField) { |
981 if (target.isFinal) { | 927 if (target.isFinal) { |
982 return new StaticAccess.finalTopLevelField(target); | 928 return new StaticAccess.finalTopLevelField(target); |
983 } else { | 929 } else { |
984 return new StaticAccess.topLevelField(target); | 930 return new StaticAccess.topLevelField(target); |
985 } | 931 } |
986 } else { | 932 } else { |
987 assert(invariant(node, target.isFunction, | 933 assert(invariant(node, target.isFunction, |
988 message: "Unexpected top level target '$target'.")); | 934 message: "Unexpected top level target '$target'.")); |
989 return new StaticAccess.topLevelMethod(target); | 935 return new StaticAccess.topLevelMethod(target); |
990 } | 936 } |
991 } | 937 } |
992 } | 938 } |
993 | 939 |
994 /// Compute the [AccessSemantics] for accessing the name of [selector] on the | 940 /// Compute the [AccessSemantics] for accessing the name of [selector] on the |
995 /// super class. | 941 /// super class. |
996 /// | 942 /// |
997 /// If no matching super member is found and error is reported and | 943 /// If no matching super member is found and error is reported and |
998 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] | 944 /// `noSuchMethod` on `super` is registered. Furthermore, if [alternateName] |
999 /// is provided, the [AccessSemantics] corresponding to the alternate name is | 945 /// is provided, the [AccessSemantics] corresponding to the alternate name is |
1000 /// returned. For instance, the access of a super setter for an unresolved | 946 /// returned. For instance, the access of a super setter for an unresolved |
1001 /// getter: | 947 /// getter: |
1002 /// | 948 /// |
1003 /// class Super { | 949 /// class Super { |
1004 /// set name(_) {} | 950 /// set name(_) {} |
1005 /// } | 951 /// } |
1006 /// class Sub extends Super { | 952 /// class Sub extends Super { |
1007 /// foo => super.name; // Access to the setter. | 953 /// foo => super.name; // Access to the setter. |
1008 /// } | 954 /// } |
1009 /// | 955 /// |
1010 AccessSemantics computeSuperAccessSemanticsForSelector( | 956 AccessSemantics computeSuperAccessSemanticsForSelector( |
1011 Spannable node, | 957 Spannable node, Selector selector, |
1012 Selector selector, | |
1013 {Name alternateName}) { | 958 {Name alternateName}) { |
1014 | |
1015 Name name = selector.memberName; | 959 Name name = selector.memberName; |
1016 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 960 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
1017 // patch. | 961 // patch. |
1018 Element target = currentClass.lookupSuperByName(name); | 962 Element target = currentClass.lookupSuperByName(name); |
1019 // [target] may be null which means invoking noSuchMethod on super. | 963 // [target] may be null which means invoking noSuchMethod on super. |
1020 if (target == null) { | 964 if (target == null) { |
1021 if (alternateName != null) { | 965 if (alternateName != null) { |
1022 target = currentClass.lookupSuperByName(alternateName); | 966 target = currentClass.lookupSuperByName(alternateName); |
1023 } | 967 } |
1024 Element error; | 968 Element error; |
1025 if (selector.isSetter) { | 969 if (selector.isSetter) { |
1026 error = reportAndCreateErroneousElement( | 970 error = reportAndCreateErroneousElement( |
1027 node, name.text, MessageKind.UNDEFINED_SUPER_SETTER, | 971 node, |
1028 {'className': currentClass.name, 'memberName': name}); | 972 name.text, |
| 973 MessageKind.UNDEFINED_SUPER_SETTER, |
| 974 {'className': currentClass.name, 'memberName': name}); |
1029 } else { | 975 } else { |
1030 error = reportAndCreateErroneousElement( | 976 error = reportAndCreateErroneousElement( |
1031 node, name.text, MessageKind.NO_SUCH_SUPER_MEMBER, | 977 node, |
1032 {'className': currentClass.name, 'memberName': name}); | 978 name.text, |
| 979 MessageKind.NO_SUCH_SUPER_MEMBER, |
| 980 {'className': currentClass.name, 'memberName': name}); |
1033 } | 981 } |
1034 if (target == null) { | 982 if (target == null) { |
1035 // If a setter wasn't resolved, use the [ErroneousElement]. | 983 // If a setter wasn't resolved, use the [ErroneousElement]. |
1036 target = error; | 984 target = error; |
1037 } | 985 } |
1038 // We still need to register the invocation, because we might | 986 // We still need to register the invocation, because we might |
1039 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 987 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
1040 registry.registerDynamicUse(new DynamicUse(selector, null)); | 988 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1041 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 989 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
1042 } | 990 } |
(...skipping 10 matching lines...) Expand all Loading... |
1053 /// getter: | 1001 /// getter: |
1054 /// | 1002 /// |
1055 /// class Super { | 1003 /// class Super { |
1056 /// set name(_) {} | 1004 /// set name(_) {} |
1057 /// } | 1005 /// } |
1058 /// class Sub extends Super { | 1006 /// class Sub extends Super { |
1059 /// foo => super.name; // Access to the setter. | 1007 /// foo => super.name; // Access to the setter. |
1060 /// } | 1008 /// } |
1061 /// | 1009 /// |
1062 AccessSemantics computeSuperAccessSemanticsForSelectors( | 1010 AccessSemantics computeSuperAccessSemanticsForSelectors( |
1063 Spannable node, | 1011 Spannable node, Selector getterSelector, Selector setterSelector, |
1064 Selector getterSelector, | |
1065 Selector setterSelector, | |
1066 {bool isIndex: false}) { | 1012 {bool isIndex: false}) { |
1067 bool getterError = false; | 1013 bool getterError = false; |
1068 bool setterError = false; | 1014 bool setterError = false; |
1069 | 1015 |
1070 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 1016 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
1071 // patch. | 1017 // patch. |
1072 Element getter = currentClass.lookupSuperByName(getterSelector.memberName); | 1018 Element getter = currentClass.lookupSuperByName(getterSelector.memberName); |
1073 // [target] may be null which means invoking noSuchMethod on super. | 1019 // [target] may be null which means invoking noSuchMethod on super. |
1074 if (getter == null) { | 1020 if (getter == null) { |
1075 getter = reportAndCreateErroneousElement( | 1021 getter = reportAndCreateErroneousElement( |
1076 node, getterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER, | 1022 node, |
| 1023 getterSelector.name, |
| 1024 MessageKind.NO_SUCH_SUPER_MEMBER, |
1077 {'className': currentClass.name, 'memberName': getterSelector.name}); | 1025 {'className': currentClass.name, 'memberName': getterSelector.name}); |
1078 getterError = true; | 1026 getterError = true; |
1079 } | 1027 } |
1080 Element setter = currentClass.lookupSuperByName(setterSelector.memberName); | 1028 Element setter = currentClass.lookupSuperByName(setterSelector.memberName); |
1081 // [target] may be null which means invoking noSuchMethod on super. | 1029 // [target] may be null which means invoking noSuchMethod on super. |
1082 if (setter == null) { | 1030 if (setter == null) { |
1083 setter = reportAndCreateErroneousElement( | 1031 setter = reportAndCreateErroneousElement( |
1084 node, setterSelector.name, MessageKind.NO_SUCH_SUPER_MEMBER, | 1032 node, |
| 1033 setterSelector.name, |
| 1034 MessageKind.NO_SUCH_SUPER_MEMBER, |
1085 {'className': currentClass.name, 'memberName': setterSelector.name}); | 1035 {'className': currentClass.name, 'memberName': setterSelector.name}); |
1086 setterError = true; | 1036 setterError = true; |
1087 } else if (getter == setter) { | 1037 } else if (getter == setter) { |
1088 if (setter.isFunction) { | 1038 if (setter.isFunction) { |
1089 setter = reportAndCreateErroneousElement( | 1039 setter = reportAndCreateErroneousElement( |
1090 node, setterSelector.name, | 1040 node, setterSelector.name, MessageKind.ASSIGNING_METHOD_IN_SUPER, { |
1091 MessageKind.ASSIGNING_METHOD_IN_SUPER, | 1041 'superclassName': setter.enclosingClass.name, |
1092 {'superclassName': setter.enclosingClass.name, | 1042 'name': setterSelector.name |
1093 'name': setterSelector.name}); | 1043 }); |
1094 setterError = true; | 1044 setterError = true; |
1095 } else if (setter.isField && setter.isFinal) { | 1045 } else if (setter.isField && setter.isFinal) { |
1096 setter = reportAndCreateErroneousElement( | 1046 setter = reportAndCreateErroneousElement(node, setterSelector.name, |
1097 node, setterSelector.name, | 1047 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, { |
1098 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 1048 'superclassName': setter.enclosingClass.name, |
1099 {'superclassName': setter.enclosingClass.name, | 1049 'name': setterSelector.name |
1100 'name': setterSelector.name}); | 1050 }); |
1101 setterError = true; | 1051 setterError = true; |
1102 } | 1052 } |
1103 } | 1053 } |
1104 if (getterError) { | 1054 if (getterError) { |
1105 // We still need to register the invocation, because we might | 1055 // We still need to register the invocation, because we might |
1106 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 1056 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
1107 registry.registerDynamicUse( | 1057 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
1108 new DynamicUse(getterSelector, null)); | |
1109 } | 1058 } |
1110 if (setterError) { | 1059 if (setterError) { |
1111 // We still need to register the invocation, because we might | 1060 // We still need to register the invocation, because we might |
1112 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. | 1061 // call [:super.noSuchMethod:] which calls [JSInvocationMirror._invokeOn]. |
1113 registry.registerDynamicUse( | 1062 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
1114 new DynamicUse(setterSelector, null)); | |
1115 } | 1063 } |
1116 if (getterError || setterError) { | 1064 if (getterError || setterError) { |
1117 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 1065 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
1118 } | 1066 } |
1119 return computeCompoundSuperAccessSemantics( | 1067 return computeCompoundSuperAccessSemantics(node, getter, setter, |
1120 node, getter, setter, isIndex: isIndex); | 1068 isIndex: isIndex); |
1121 } | 1069 } |
1122 | 1070 |
1123 /// Resolve [node] as a subexpression that is _not_ the prefix of a member | 1071 /// Resolve [node] as a subexpression that is _not_ the prefix of a member |
1124 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. | 1072 /// access. For instance `a` in `a + b`, as opposed to `a` in `a.b`. |
1125 ResolutionResult visitExpression(Node node) { | 1073 ResolutionResult visitExpression(Node node) { |
1126 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1074 bool oldSendIsMemberAccess = sendIsMemberAccess; |
1127 sendIsMemberAccess = false; | 1075 sendIsMemberAccess = false; |
1128 ResolutionResult result = visit(node); | 1076 ResolutionResult result = visit(node); |
1129 sendIsMemberAccess = oldSendIsMemberAccess; | 1077 sendIsMemberAccess = oldSendIsMemberAccess; |
1130 return result; | 1078 return result; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 registry.setSelector(node, selector); | 1155 registry.setSelector(node, selector); |
1208 | 1156 |
1209 AccessSemantics semantics; | 1157 AccessSemantics semantics; |
1210 if (node.isSuperCall) { | 1158 if (node.isSuperCall) { |
1211 semantics = checkSuperAccess(node); | 1159 semantics = checkSuperAccess(node); |
1212 if (semantics == null) { | 1160 if (semantics == null) { |
1213 semantics = computeSuperAccessSemanticsForSelector(node, selector); | 1161 semantics = computeSuperAccessSemanticsForSelector(node, selector); |
1214 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1162 // TODO(johnniwinther): Add information to [AccessSemantics] about |
1215 // whether it is erroneous. | 1163 // whether it is erroneous. |
1216 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1164 if (semantics.kind == AccessKind.SUPER_METHOD) { |
1217 registry.registerStaticUse( | 1165 registry.registerStaticUse(new StaticUse.superInvoke( |
1218 new StaticUse.superInvoke( | 1166 semantics.element.declaration, selector.callStructure)); |
1219 semantics.element.declaration, | |
1220 selector.callStructure)); | |
1221 } | 1167 } |
1222 // TODO(23998): Remove this when all information goes through | 1168 // TODO(23998): Remove this when all information goes through |
1223 // the [SendStructure]. | 1169 // the [SendStructure]. |
1224 registry.useElement(node, semantics.element); | 1170 registry.useElement(node, semantics.element); |
1225 } | 1171 } |
1226 } else { | 1172 } else { |
1227 ResolutionResult expressionResult = visitExpression(expression); | 1173 ResolutionResult expressionResult = visitExpression(expression); |
1228 semantics = const DynamicAccess.expression(); | 1174 semantics = const DynamicAccess.expression(); |
1229 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1175 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1230 | 1176 |
1231 if (expressionResult.isConstant) { | 1177 if (expressionResult.isConstant) { |
1232 bool isValidConstant; | 1178 bool isValidConstant; |
1233 ConstantExpression expressionConstant = expressionResult.constant; | 1179 ConstantExpression expressionConstant = expressionResult.constant; |
1234 DartType knownExpressionType = | 1180 DartType knownExpressionType = |
1235 expressionConstant.getKnownType(coreTypes); | 1181 expressionConstant.getKnownType(coreTypes); |
1236 switch (operator.kind) { | 1182 switch (operator.kind) { |
1237 case UnaryOperatorKind.COMPLEMENT: | 1183 case UnaryOperatorKind.COMPLEMENT: |
1238 isValidConstant = | 1184 isValidConstant = knownExpressionType == coreTypes.intType; |
1239 knownExpressionType == coreTypes.intType; | |
1240 break; | 1185 break; |
1241 case UnaryOperatorKind.NEGATE: | 1186 case UnaryOperatorKind.NEGATE: |
1242 isValidConstant = | 1187 isValidConstant = knownExpressionType == coreTypes.intType || |
1243 knownExpressionType == coreTypes.intType || | |
1244 knownExpressionType == coreTypes.doubleType; | 1188 knownExpressionType == coreTypes.doubleType; |
1245 break; | 1189 break; |
1246 case UnaryOperatorKind.NOT: | 1190 case UnaryOperatorKind.NOT: |
1247 reporter.internalError(node, | 1191 reporter.internalError( |
1248 "Unexpected user definable unary operator: $operator"); | 1192 node, "Unexpected user definable unary operator: $operator"); |
1249 } | 1193 } |
1250 if (isValidConstant) { | 1194 if (isValidConstant) { |
1251 // TODO(johnniwinther): Handle potentially invalid constant | 1195 // TODO(johnniwinther): Handle potentially invalid constant |
1252 // expressions. | 1196 // expressions. |
1253 ConstantExpression constant = | 1197 ConstantExpression constant = |
1254 new UnaryConstantExpression(operator, expressionConstant); | 1198 new UnaryConstantExpression(operator, expressionConstant); |
1255 registry.setConstant(node, constant); | 1199 registry.setConstant(node, constant); |
1256 result = new ConstantResult(node, constant); | 1200 result = new ConstantResult(node, constant); |
1257 } | 1201 } |
1258 } | 1202 } |
1259 } | 1203 } |
1260 if (semantics != null) { | 1204 if (semantics != null) { |
1261 registry.registerSendStructure(node, | 1205 registry.registerSendStructure( |
1262 new UnaryStructure(semantics, operator)); | 1206 node, new UnaryStructure(semantics, operator)); |
1263 } | 1207 } |
1264 return result; | 1208 return result; |
1265 } | 1209 } |
1266 | 1210 |
1267 /// Handle a not expression, like `!a`. | 1211 /// Handle a not expression, like `!a`. |
1268 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1212 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
1269 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1213 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); |
1270 | 1214 |
1271 Node expression = node.receiver; | 1215 Node expression = node.receiver; |
1272 ResolutionResult result = visitExpression(expression); | 1216 ResolutionResult result = visitExpression(expression); |
(...skipping 23 matching lines...) Expand all Loading... |
1296 doInPromotionScope(right, () => visitExpression(right)); | 1240 doInPromotionScope(right, () => visitExpression(right)); |
1297 registry.registerSendStructure(node, const LogicalAndStructure()); | 1241 registry.registerSendStructure(node, const LogicalAndStructure()); |
1298 | 1242 |
1299 if (leftResult.isConstant && rightResult.isConstant) { | 1243 if (leftResult.isConstant && rightResult.isConstant) { |
1300 ConstantExpression leftConstant = leftResult.constant; | 1244 ConstantExpression leftConstant = leftResult.constant; |
1301 ConstantExpression rightConstant = rightResult.constant; | 1245 ConstantExpression rightConstant = rightResult.constant; |
1302 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && | 1246 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
1303 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { | 1247 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
1304 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1248 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
1305 ConstantExpression constant = new BinaryConstantExpression( | 1249 ConstantExpression constant = new BinaryConstantExpression( |
1306 leftConstant, | 1250 leftConstant, BinaryOperator.LOGICAL_AND, rightConstant); |
1307 BinaryOperator.LOGICAL_AND, | |
1308 rightConstant); | |
1309 registry.setConstant(node, constant); | 1251 registry.setConstant(node, constant); |
1310 return new ConstantResult(node, constant); | 1252 return new ConstantResult(node, constant); |
1311 } | 1253 } |
1312 } | 1254 } |
1313 | 1255 |
1314 return const NoneResult(); | 1256 return const NoneResult(); |
1315 } | 1257 } |
1316 | 1258 |
1317 /// Handle a logical or expression, like `a || b`. | 1259 /// Handle a logical or expression, like `a || b`. |
1318 ResolutionResult handleLogicalOr(Send node) { | 1260 ResolutionResult handleLogicalOr(Send node) { |
1319 Node left = node.receiver; | 1261 Node left = node.receiver; |
1320 Node right = node.arguments.head; | 1262 Node right = node.arguments.head; |
1321 ResolutionResult leftResult = visitExpression(left); | 1263 ResolutionResult leftResult = visitExpression(left); |
1322 ResolutionResult rightResult = visitExpression(right); | 1264 ResolutionResult rightResult = visitExpression(right); |
1323 registry.registerSendStructure(node, const LogicalOrStructure()); | 1265 registry.registerSendStructure(node, const LogicalOrStructure()); |
1324 | 1266 |
1325 if (leftResult.isConstant && rightResult.isConstant) { | 1267 if (leftResult.isConstant && rightResult.isConstant) { |
1326 ConstantExpression leftConstant = leftResult.constant; | 1268 ConstantExpression leftConstant = leftResult.constant; |
1327 ConstantExpression rightConstant = rightResult.constant; | 1269 ConstantExpression rightConstant = rightResult.constant; |
1328 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && | 1270 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
1329 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { | 1271 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
1330 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1272 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
1331 ConstantExpression constant = new BinaryConstantExpression( | 1273 ConstantExpression constant = new BinaryConstantExpression( |
1332 leftConstant, | 1274 leftConstant, BinaryOperator.LOGICAL_OR, rightConstant); |
1333 BinaryOperator.LOGICAL_OR, | |
1334 rightConstant); | |
1335 registry.setConstant(node, constant); | 1275 registry.setConstant(node, constant); |
1336 return new ConstantResult(node, constant); | 1276 return new ConstantResult(node, constant); |
1337 } | 1277 } |
1338 } | 1278 } |
1339 return const NoneResult(); | 1279 return const NoneResult(); |
1340 } | 1280 } |
1341 | 1281 |
1342 /// Handle an if-null expression, like `a ?? b`. | 1282 /// Handle an if-null expression, like `a ?? b`. |
1343 ResolutionResult handleIfNull(Send node) { | 1283 ResolutionResult handleIfNull(Send node) { |
1344 Node left = node.receiver; | 1284 Node left = node.receiver; |
(...skipping 14 matching lines...) Expand all Loading... |
1359 } else { | 1299 } else { |
1360 visitExpression(left); | 1300 visitExpression(left); |
1361 } | 1301 } |
1362 visitExpression(right); | 1302 visitExpression(right); |
1363 registry.registerSendStructure(node, const InvalidBinaryStructure()); | 1303 registry.registerSendStructure(node, const InvalidBinaryStructure()); |
1364 return const NoneResult(); | 1304 return const NoneResult(); |
1365 } | 1305 } |
1366 | 1306 |
1367 /// Handle the binary expression of a user definable binary [operator], like | 1307 /// Handle the binary expression of a user definable binary [operator], like |
1368 /// `a + b`, `super + b`, `a == b` and `a != b`. | 1308 /// `a + b`, `super + b`, `a == b` and `a != b`. |
1369 ResolutionResult handleUserDefinableBinary(Send node, | 1309 ResolutionResult handleUserDefinableBinary( |
1370 BinaryOperator operator) { | 1310 Send node, BinaryOperator operator) { |
1371 ResolutionResult result = const NoneResult(); | 1311 ResolutionResult result = const NoneResult(); |
1372 Node left = node.receiver; | 1312 Node left = node.receiver; |
1373 Node right = node.arguments.head; | 1313 Node right = node.arguments.head; |
1374 AccessSemantics semantics; | 1314 AccessSemantics semantics; |
1375 Selector selector; | 1315 Selector selector; |
1376 if (operator.kind == BinaryOperatorKind.INDEX) { | 1316 if (operator.kind == BinaryOperatorKind.INDEX) { |
1377 selector = new Selector.index(); | 1317 selector = new Selector.index(); |
1378 } else { | 1318 } else { |
1379 selector = new Selector.binaryOperator(operator.selectorName); | 1319 selector = new Selector.binaryOperator(operator.selectorName); |
1380 } | 1320 } |
1381 // TODO(23998): Remove this when all information goes through the | 1321 // TODO(23998): Remove this when all information goes through the |
1382 // [SendStructure]. | 1322 // [SendStructure]. |
1383 registry.setSelector(node, selector); | 1323 registry.setSelector(node, selector); |
1384 | 1324 |
1385 if (node.isSuperCall) { | 1325 if (node.isSuperCall) { |
1386 semantics = checkSuperAccess(node); | 1326 semantics = checkSuperAccess(node); |
1387 if (semantics == null) { | 1327 if (semantics == null) { |
1388 semantics = computeSuperAccessSemanticsForSelector(node, selector); | 1328 semantics = computeSuperAccessSemanticsForSelector(node, selector); |
1389 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1329 // TODO(johnniwinther): Add information to [AccessSemantics] about |
1390 // whether it is erroneous. | 1330 // whether it is erroneous. |
1391 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1331 if (semantics.kind == AccessKind.SUPER_METHOD) { |
1392 registry.registerStaticUse( | 1332 registry.registerStaticUse(new StaticUse.superInvoke( |
1393 new StaticUse.superInvoke( | 1333 semantics.element.declaration, selector.callStructure)); |
1394 semantics.element.declaration, | |
1395 selector.callStructure)); | |
1396 } | 1334 } |
1397 // TODO(23998): Remove this when all information goes through | 1335 // TODO(23998): Remove this when all information goes through |
1398 // the [SendStructure]. | 1336 // the [SendStructure]. |
1399 registry.useElement(node, semantics.element); | 1337 registry.useElement(node, semantics.element); |
1400 } | 1338 } |
1401 visitExpression(right); | 1339 visitExpression(right); |
1402 } else { | 1340 } else { |
1403 ResolutionResult leftResult = visitExpression(left); | 1341 ResolutionResult leftResult = visitExpression(left); |
1404 ResolutionResult rightResult = visitExpression(right); | 1342 ResolutionResult rightResult = visitExpression(right); |
1405 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1343 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1406 semantics = const DynamicAccess.expression(); | 1344 semantics = const DynamicAccess.expression(); |
1407 | 1345 |
1408 if (leftResult.isConstant && rightResult.isConstant) { | 1346 if (leftResult.isConstant && rightResult.isConstant) { |
1409 bool isValidConstant; | 1347 bool isValidConstant; |
1410 ConstantExpression leftConstant = leftResult.constant; | 1348 ConstantExpression leftConstant = leftResult.constant; |
1411 ConstantExpression rightConstant = rightResult.constant; | 1349 ConstantExpression rightConstant = rightResult.constant; |
1412 DartType knownLeftType = leftConstant.getKnownType(coreTypes); | 1350 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
1413 DartType knownRightType = rightConstant.getKnownType(coreTypes); | 1351 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
1414 switch (operator.kind) { | 1352 switch (operator.kind) { |
1415 case BinaryOperatorKind.EQ: | 1353 case BinaryOperatorKind.EQ: |
1416 case BinaryOperatorKind.NOT_EQ: | 1354 case BinaryOperatorKind.NOT_EQ: |
1417 isValidConstant = | 1355 isValidConstant = (knownLeftType == coreTypes.intType || |
1418 (knownLeftType == coreTypes.intType || | 1356 knownLeftType == coreTypes.doubleType || |
1419 knownLeftType == coreTypes.doubleType || | 1357 knownLeftType == coreTypes.stringType || |
1420 knownLeftType == coreTypes.stringType || | 1358 knownLeftType == coreTypes.boolType || |
1421 knownLeftType == coreTypes.boolType || | 1359 knownLeftType == coreTypes.nullType) && |
1422 knownLeftType == coreTypes.nullType) && | |
1423 (knownRightType == coreTypes.intType || | 1360 (knownRightType == coreTypes.intType || |
1424 knownRightType == coreTypes.doubleType || | 1361 knownRightType == coreTypes.doubleType || |
1425 knownRightType == coreTypes.stringType || | 1362 knownRightType == coreTypes.stringType || |
1426 knownRightType == coreTypes.boolType || | 1363 knownRightType == coreTypes.boolType || |
1427 knownRightType == coreTypes.nullType); | 1364 knownRightType == coreTypes.nullType); |
1428 break; | 1365 break; |
1429 case BinaryOperatorKind.ADD: | 1366 case BinaryOperatorKind.ADD: |
1430 isValidConstant = | 1367 isValidConstant = (knownLeftType == coreTypes.intType || |
1431 (knownLeftType == coreTypes.intType || | 1368 knownLeftType == coreTypes.doubleType || |
1432 knownLeftType == coreTypes.doubleType || | 1369 knownLeftType == coreTypes.stringType) && |
1433 knownLeftType == coreTypes.stringType) && | |
1434 (knownRightType == coreTypes.intType || | 1370 (knownRightType == coreTypes.intType || |
1435 knownRightType == coreTypes.doubleType || | 1371 knownRightType == coreTypes.doubleType || |
1436 knownRightType == coreTypes.stringType); | 1372 knownRightType == coreTypes.stringType); |
1437 break; | 1373 break; |
1438 case BinaryOperatorKind.SUB: | 1374 case BinaryOperatorKind.SUB: |
1439 case BinaryOperatorKind.MUL: | 1375 case BinaryOperatorKind.MUL: |
1440 case BinaryOperatorKind.DIV: | 1376 case BinaryOperatorKind.DIV: |
1441 case BinaryOperatorKind.IDIV: | 1377 case BinaryOperatorKind.IDIV: |
1442 case BinaryOperatorKind.MOD: | 1378 case BinaryOperatorKind.MOD: |
1443 case BinaryOperatorKind.GTEQ: | 1379 case BinaryOperatorKind.GTEQ: |
1444 case BinaryOperatorKind.GT: | 1380 case BinaryOperatorKind.GT: |
1445 case BinaryOperatorKind.LTEQ: | 1381 case BinaryOperatorKind.LTEQ: |
1446 case BinaryOperatorKind.LT: | 1382 case BinaryOperatorKind.LT: |
1447 isValidConstant = | 1383 isValidConstant = (knownLeftType == coreTypes.intType || |
1448 (knownLeftType == coreTypes.intType || | 1384 knownLeftType == coreTypes.doubleType) && |
1449 knownLeftType == coreTypes.doubleType) && | |
1450 (knownRightType == coreTypes.intType || | 1385 (knownRightType == coreTypes.intType || |
1451 knownRightType == coreTypes.doubleType); | 1386 knownRightType == coreTypes.doubleType); |
1452 break; | 1387 break; |
1453 case BinaryOperatorKind.SHL: | 1388 case BinaryOperatorKind.SHL: |
1454 case BinaryOperatorKind.SHR: | 1389 case BinaryOperatorKind.SHR: |
1455 case BinaryOperatorKind.AND: | 1390 case BinaryOperatorKind.AND: |
1456 case BinaryOperatorKind.OR: | 1391 case BinaryOperatorKind.OR: |
1457 case BinaryOperatorKind.XOR: | 1392 case BinaryOperatorKind.XOR: |
1458 isValidConstant = | 1393 isValidConstant = knownLeftType == coreTypes.intType && |
1459 knownLeftType == coreTypes.intType && | |
1460 knownRightType == coreTypes.intType; | 1394 knownRightType == coreTypes.intType; |
1461 break; | 1395 break; |
1462 case BinaryOperatorKind.INDEX: | 1396 case BinaryOperatorKind.INDEX: |
1463 isValidConstant = false; | 1397 isValidConstant = false; |
1464 break; | 1398 break; |
1465 case BinaryOperatorKind.LOGICAL_AND: | 1399 case BinaryOperatorKind.LOGICAL_AND: |
1466 case BinaryOperatorKind.LOGICAL_OR: | 1400 case BinaryOperatorKind.LOGICAL_OR: |
1467 case BinaryOperatorKind.IF_NULL: | 1401 case BinaryOperatorKind.IF_NULL: |
1468 reporter.internalError( | 1402 reporter.internalError( |
1469 node, "Unexpected binary operator '${operator}'."); | 1403 node, "Unexpected binary operator '${operator}'."); |
1470 break; | 1404 break; |
1471 } | 1405 } |
1472 if (isValidConstant) { | 1406 if (isValidConstant) { |
1473 // TODO(johnniwinther): Handle potentially invalid constant | 1407 // TODO(johnniwinther): Handle potentially invalid constant |
1474 // expressions. | 1408 // expressions. |
1475 ConstantExpression constant = new BinaryConstantExpression( | 1409 ConstantExpression constant = new BinaryConstantExpression( |
1476 leftResult.constant, | 1410 leftResult.constant, operator, rightResult.constant); |
1477 operator, | |
1478 rightResult.constant); | |
1479 registry.setConstant(node, constant); | 1411 registry.setConstant(node, constant); |
1480 result = new ConstantResult(node, constant); | 1412 result = new ConstantResult(node, constant); |
1481 } | 1413 } |
1482 } | 1414 } |
1483 } | 1415 } |
1484 | 1416 |
1485 if (semantics != null) { | 1417 if (semantics != null) { |
1486 // TODO(johnniwinther): Support invalid super access as an | 1418 // TODO(johnniwinther): Support invalid super access as an |
1487 // [AccessSemantics]. | 1419 // [AccessSemantics]. |
1488 SendStructure sendStructure; | 1420 SendStructure sendStructure; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 node, "Unexpected binary operator '${operator}'."); | 1452 node, "Unexpected binary operator '${operator}'."); |
1521 break; | 1453 break; |
1522 } | 1454 } |
1523 registry.registerSendStructure(node, sendStructure); | 1455 registry.registerSendStructure(node, sendStructure); |
1524 } | 1456 } |
1525 return result; | 1457 return result; |
1526 } | 1458 } |
1527 | 1459 |
1528 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1460 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
1529 ResolutionResult handleExpressionInvoke(Send node) { | 1461 ResolutionResult handleExpressionInvoke(Send node) { |
1530 assert(invariant(node, node.isCall, | 1462 assert( |
1531 message: "Unexpected expression: $node")); | 1463 invariant(node, node.isCall, message: "Unexpected expression: $node")); |
1532 Node expression = node.selector; | 1464 Node expression = node.selector; |
1533 visitExpression(expression); | 1465 visitExpression(expression); |
1534 CallStructure callStructure = | 1466 CallStructure callStructure = |
1535 resolveArguments(node.argumentsNode).callStructure; | 1467 resolveArguments(node.argumentsNode).callStructure; |
1536 Selector selector = callStructure.callSelector; | 1468 Selector selector = callStructure.callSelector; |
1537 // TODO(23998): Remove this when all information goes through the | 1469 // TODO(23998): Remove this when all information goes through the |
1538 // [SendStructure]. | 1470 // [SendStructure]. |
1539 registry.setSelector(node, selector); | 1471 registry.setSelector(node, selector); |
1540 registry.registerDynamicUse(new DynamicUse(selector, null)); | 1472 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1541 registry.registerSendStructure(node, | 1473 registry.registerSendStructure( |
1542 new InvokeStructure(const DynamicAccess.expression(), selector)); | 1474 node, new InvokeStructure(const DynamicAccess.expression(), selector)); |
1543 return const NoneResult(); | 1475 return const NoneResult(); |
1544 } | 1476 } |
1545 | 1477 |
1546 /// Handle access of a property of [name] on `this`, like `this.name` and | 1478 /// Handle access of a property of [name] on `this`, like `this.name` and |
1547 /// `this.name()`, or `name` and `name()` in instance context. | 1479 /// `this.name()`, or `name` and `name()` in instance context. |
1548 ResolutionResult handleThisPropertyAccess(Send node, Name name) { | 1480 ResolutionResult handleThisPropertyAccess(Send node, Name name) { |
1549 AccessSemantics semantics = new DynamicAccess.thisProperty(name); | 1481 AccessSemantics semantics = new DynamicAccess.thisProperty(name); |
1550 return handleDynamicAccessSemantics(node, name, semantics); | 1482 return handleDynamicAccessSemantics(node, name, semantics); |
1551 } | 1483 } |
1552 | 1484 |
(...skipping 10 matching lines...) Expand all Loading... |
1563 ResolutionResult handleThisAccess(Send node) { | 1495 ResolutionResult handleThisAccess(Send node) { |
1564 if (node.isCall) { | 1496 if (node.isCall) { |
1565 CallStructure callStructure = | 1497 CallStructure callStructure = |
1566 resolveArguments(node.argumentsNode).callStructure; | 1498 resolveArguments(node.argumentsNode).callStructure; |
1567 Selector selector = callStructure.callSelector; | 1499 Selector selector = callStructure.callSelector; |
1568 // TODO(johnniwinther): Handle invalid this access as an | 1500 // TODO(johnniwinther): Handle invalid this access as an |
1569 // [AccessSemantics]. | 1501 // [AccessSemantics]. |
1570 AccessSemantics accessSemantics = checkThisAccess(node); | 1502 AccessSemantics accessSemantics = checkThisAccess(node); |
1571 if (accessSemantics == null) { | 1503 if (accessSemantics == null) { |
1572 accessSemantics = const DynamicAccess.thisAccess(); | 1504 accessSemantics = const DynamicAccess.thisAccess(); |
1573 registry.registerDynamicUse( | 1505 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1574 new DynamicUse(selector, null)); | |
1575 } | 1506 } |
1576 registry.registerSendStructure(node, | 1507 registry.registerSendStructure( |
1577 new InvokeStructure(accessSemantics, selector)); | 1508 node, new InvokeStructure(accessSemantics, selector)); |
1578 // TODO(23998): Remove this when all information goes through | 1509 // TODO(23998): Remove this when all information goes through |
1579 // the [SendStructure]. | 1510 // the [SendStructure]. |
1580 registry.setSelector(node, selector); | 1511 registry.setSelector(node, selector); |
1581 return const NoneResult(); | 1512 return const NoneResult(); |
1582 } else { | 1513 } else { |
1583 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1514 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
1584 reporter.internalError( | 1515 reporter.internalError(node, "Unexpected node '$node'."); |
1585 node, "Unexpected node '$node'."); | |
1586 } | 1516 } |
1587 return const NoneResult(); | 1517 return const NoneResult(); |
1588 } | 1518 } |
1589 | 1519 |
1590 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1520 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
1591 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1521 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
1592 Element target; | 1522 Element target; |
1593 Selector selector; | 1523 Selector selector; |
1594 CallStructure callStructure; | 1524 CallStructure callStructure; |
1595 if (node.isCall) { | 1525 if (node.isCall) { |
1596 callStructure = resolveArguments(node.argumentsNode).callStructure; | 1526 callStructure = resolveArguments(node.argumentsNode).callStructure; |
1597 selector = new Selector.call(name, callStructure); | 1527 selector = new Selector.call(name, callStructure); |
1598 } else { | 1528 } else { |
1599 selector = new Selector.getter(name); | 1529 selector = new Selector.getter(name); |
1600 } | 1530 } |
1601 AccessSemantics semantics = checkSuperAccess(node); | 1531 AccessSemantics semantics = checkSuperAccess(node); |
1602 if (semantics == null) { | 1532 if (semantics == null) { |
1603 semantics = computeSuperAccessSemanticsForSelector( | 1533 semantics = computeSuperAccessSemanticsForSelector(node, selector, |
1604 node, selector, alternateName: name.setter); | 1534 alternateName: name.setter); |
1605 } | 1535 } |
1606 if (node.isCall) { | 1536 if (node.isCall) { |
1607 bool isIncompatibleInvoke = false; | 1537 bool isIncompatibleInvoke = false; |
1608 switch (semantics.kind) { | 1538 switch (semantics.kind) { |
1609 case AccessKind.SUPER_METHOD: | 1539 case AccessKind.SUPER_METHOD: |
1610 MethodElementX superMethod = semantics.element; | 1540 MethodElementX superMethod = semantics.element; |
1611 superMethod.computeType(resolution); | 1541 superMethod.computeType(resolution); |
1612 if (!callStructure.signatureApplies( | 1542 if (!callStructure.signatureApplies(superMethod.functionSignature)) { |
1613 superMethod.functionSignature)) { | |
1614 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1543 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1615 registry.registerDynamicUse( | 1544 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1616 new DynamicUse(selector, null)); | |
1617 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 1545 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
1618 isIncompatibleInvoke = true; | 1546 isIncompatibleInvoke = true; |
1619 } else { | 1547 } else { |
1620 registry.registerStaticUse( | 1548 registry.registerStaticUse( |
1621 new StaticUse.superInvoke(semantics.element, callStructure)); | 1549 new StaticUse.superInvoke(semantics.element, callStructure)); |
1622 } | 1550 } |
1623 break; | 1551 break; |
1624 case AccessKind.SUPER_FIELD: | 1552 case AccessKind.SUPER_FIELD: |
1625 case AccessKind.SUPER_FINAL_FIELD: | 1553 case AccessKind.SUPER_FINAL_FIELD: |
1626 case AccessKind.SUPER_GETTER: | 1554 case AccessKind.SUPER_GETTER: |
1627 registry.registerStaticUse( | 1555 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
1628 new StaticUse.superGet(semantics.element)); | |
1629 selector = callStructure.callSelector; | 1556 selector = callStructure.callSelector; |
1630 registry.registerDynamicUse( | 1557 registry.registerDynamicUse(new DynamicUse(selector, null)); |
1631 new DynamicUse(selector, null)); | |
1632 break; | 1558 break; |
1633 case AccessKind.SUPER_SETTER: | 1559 case AccessKind.SUPER_SETTER: |
1634 case AccessKind.UNRESOLVED_SUPER: | 1560 case AccessKind.UNRESOLVED_SUPER: |
1635 // NoSuchMethod registered in [computeSuperSemantics]. | 1561 // NoSuchMethod registered in [computeSuperSemantics]. |
1636 break; | 1562 break; |
1637 case AccessKind.INVALID: | 1563 case AccessKind.INVALID: |
1638 // 'super' is not allowed. | 1564 // 'super' is not allowed. |
1639 break; | 1565 break; |
1640 default: | 1566 default: |
1641 reporter.internalError( | 1567 reporter.internalError( |
1642 node, "Unexpected super property access $semantics."); | 1568 node, "Unexpected super property access $semantics."); |
1643 break; | 1569 break; |
1644 } | 1570 } |
1645 registry.registerSendStructure(node, | 1571 registry.registerSendStructure( |
| 1572 node, |
1646 isIncompatibleInvoke | 1573 isIncompatibleInvoke |
1647 ? new IncompatibleInvokeStructure(semantics, selector) | 1574 ? new IncompatibleInvokeStructure(semantics, selector) |
1648 : new InvokeStructure(semantics, selector)); | 1575 : new InvokeStructure(semantics, selector)); |
1649 } else { | 1576 } else { |
1650 switch (semantics.kind) { | 1577 switch (semantics.kind) { |
1651 case AccessKind.SUPER_METHOD: | 1578 case AccessKind.SUPER_METHOD: |
1652 // TODO(johnniwinther): Method this should be registered as a | 1579 // TODO(johnniwinther): Method this should be registered as a |
1653 // closurization. | 1580 // closurization. |
1654 registry.registerStaticUse( | 1581 registry |
1655 new StaticUse.superTearOff(semantics.element)); | 1582 .registerStaticUse(new StaticUse.superTearOff(semantics.element)); |
1656 break; | 1583 break; |
1657 case AccessKind.SUPER_FIELD: | 1584 case AccessKind.SUPER_FIELD: |
1658 case AccessKind.SUPER_FINAL_FIELD: | 1585 case AccessKind.SUPER_FINAL_FIELD: |
1659 case AccessKind.SUPER_GETTER: | 1586 case AccessKind.SUPER_GETTER: |
1660 registry.registerStaticUse( | 1587 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
1661 new StaticUse.superGet(semantics.element)); | |
1662 break; | 1588 break; |
1663 case AccessKind.SUPER_SETTER: | 1589 case AccessKind.SUPER_SETTER: |
1664 case AccessKind.UNRESOLVED_SUPER: | 1590 case AccessKind.UNRESOLVED_SUPER: |
1665 // NoSuchMethod registered in [computeSuperSemantics]. | 1591 // NoSuchMethod registered in [computeSuperSemantics]. |
1666 break; | 1592 break; |
1667 case AccessKind.INVALID: | 1593 case AccessKind.INVALID: |
1668 // 'super' is not allowed. | 1594 // 'super' is not allowed. |
1669 break; | 1595 break; |
1670 default: | 1596 default: |
1671 reporter.internalError( | 1597 reporter.internalError( |
(...skipping 10 matching lines...) Expand all Loading... |
1682 registry.setSelector(node, selector); | 1608 registry.setSelector(node, selector); |
1683 return const NoneResult(); | 1609 return const NoneResult(); |
1684 } | 1610 } |
1685 | 1611 |
1686 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, | 1612 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, |
1687 /// `a + b`, and `~a`. | 1613 /// `a + b`, and `~a`. |
1688 ResolutionResult handleOperatorSend(Send node) { | 1614 ResolutionResult handleOperatorSend(Send node) { |
1689 String operatorText = node.selector.asOperator().source; | 1615 String operatorText = node.selector.asOperator().source; |
1690 if (operatorText == 'is') { | 1616 if (operatorText == 'is') { |
1691 return handleIs(node); | 1617 return handleIs(node); |
1692 } else if (operatorText == 'as') { | 1618 } else if (operatorText == 'as') { |
1693 return handleAs(node); | 1619 return handleAs(node); |
1694 } else if (node.arguments.isEmpty) { | 1620 } else if (node.arguments.isEmpty) { |
1695 UnaryOperator operator = UnaryOperator.parse(operatorText); | 1621 UnaryOperator operator = UnaryOperator.parse(operatorText); |
1696 if (operator == null) { | 1622 if (operator == null) { |
1697 return handleUnresolvedUnary(node, operatorText); | 1623 return handleUnresolvedUnary(node, operatorText); |
1698 } else { | 1624 } else { |
1699 switch (operator.kind) { | 1625 switch (operator.kind) { |
1700 case UnaryOperatorKind.NOT: | 1626 case UnaryOperatorKind.NOT: |
1701 return handleNot(node, operator); | 1627 return handleNot(node, operator); |
1702 case UnaryOperatorKind.COMPLEMENT: | 1628 case UnaryOperatorKind.COMPLEMENT: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1753 // a constructor. | 1679 // a constructor. |
1754 | 1680 |
1755 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1681 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
1756 // try to resolve injected elements if [currentClass] is in the patch | 1682 // try to resolve injected elements if [currentClass] is in the patch |
1757 // library of [receiverClass]. | 1683 // library of [receiverClass]. |
1758 | 1684 |
1759 // TODO(karlklose): this should be reported by the caller of | 1685 // TODO(karlklose): this should be reported by the caller of |
1760 // [resolveSend] to select better warning messages for getters and | 1686 // [resolveSend] to select better warning messages for getters and |
1761 // setters. | 1687 // setters. |
1762 ErroneousElement error = reportAndCreateErroneousElement( | 1688 ErroneousElement error = reportAndCreateErroneousElement( |
1763 node, name.text, MessageKind.UNDEFINED_GETTER, | 1689 node, |
| 1690 name.text, |
| 1691 MessageKind.UNDEFINED_GETTER, |
1764 {'className': receiverClass.name, 'memberName': name.text}); | 1692 {'className': receiverClass.name, 'memberName': name.text}); |
1765 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1693 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
1766 // member access. | 1694 // member access. |
1767 return handleErroneousAccess( | 1695 return handleErroneousAccess( |
1768 node, name, new StaticAccess.unresolved(error)); | 1696 node, name, new StaticAccess.unresolved(error)); |
1769 } | 1697 } |
1770 | 1698 |
1771 /// Handle qualified update to an unresolved static class member, like | 1699 /// Handle qualified update to an unresolved static class member, like |
1772 /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved. | 1700 /// `a.b = c` or `a.b++` where `a` is a class and `b` is unresolved. |
1773 ResolutionResult handleUnresolvedStaticMemberUpdate( | 1701 ResolutionResult handleUnresolvedStaticMemberUpdate( |
1774 SendSet node, Name name, ClassElement receiverClass) { | 1702 SendSet node, Name name, ClassElement receiverClass) { |
1775 // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate] | 1703 // TODO(johnniwinther): Share code with [handleStaticInstanceMemberUpdate] |
1776 // and [handlePrivateStaticMemberUpdate]. | 1704 // and [handlePrivateStaticMemberUpdate]. |
1777 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1705 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1778 // TODO(johnniwinther): Produce a different error if [name] is resolves to | 1706 // TODO(johnniwinther): Produce a different error if [name] is resolves to |
1779 // a constructor. | 1707 // a constructor. |
1780 | 1708 |
1781 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1709 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
1782 // try to resolve injected elements if [currentClass] is in the patch | 1710 // try to resolve injected elements if [currentClass] is in the patch |
1783 // library of [receiverClass]. | 1711 // library of [receiverClass]. |
1784 | 1712 |
1785 // TODO(johnniwinther): Produce a different error for complex update. | 1713 // TODO(johnniwinther): Produce a different error for complex update. |
1786 ErroneousElement error = reportAndCreateErroneousElement( | 1714 ErroneousElement error = reportAndCreateErroneousElement( |
1787 node, name.text, MessageKind.UNDEFINED_GETTER, | 1715 node, |
| 1716 name.text, |
| 1717 MessageKind.UNDEFINED_GETTER, |
1788 {'className': receiverClass.name, 'memberName': name.text}); | 1718 {'className': receiverClass.name, 'memberName': name.text}); |
1789 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1719 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
1790 // member access. | 1720 // member access. |
1791 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1721 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
1792 } | 1722 } |
1793 | 1723 |
1794 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where | 1724 /// Handle qualified access of an instance member, like `a.b` or `a.b()` where |
1795 /// `a` is a class and `b` is a non-static member. | 1725 /// `a` is a class and `b` is a non-static member. |
1796 ResolutionResult handleStaticInstanceMemberAccess( | 1726 ResolutionResult handleStaticInstanceMemberAccess( |
1797 Send node, Name name, ClassElement receiverClass, Element member) { | 1727 Send node, Name name, ClassElement receiverClass, Element member) { |
1798 | |
1799 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1728 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1800 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1729 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
1801 // try to resolve injected elements if [currentClass] is in the patch | 1730 // try to resolve injected elements if [currentClass] is in the patch |
1802 // library of [receiverClass]. | 1731 // library of [receiverClass]. |
1803 | 1732 |
1804 // TODO(karlklose): this should be reported by the caller of | 1733 // TODO(karlklose): this should be reported by the caller of |
1805 // [resolveSend] to select better warning messages for getters and | 1734 // [resolveSend] to select better warning messages for getters and |
1806 // setters. | 1735 // setters. |
1807 ErroneousElement error = reportAndCreateErroneousElement( | 1736 ErroneousElement error = reportAndCreateErroneousElement( |
1808 node, name.text, MessageKind.MEMBER_NOT_STATIC, | 1737 node, |
| 1738 name.text, |
| 1739 MessageKind.MEMBER_NOT_STATIC, |
1809 {'className': receiverClass.name, 'memberName': name}); | 1740 {'className': receiverClass.name, 'memberName': name}); |
1810 | 1741 |
1811 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed | 1742 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed |
1812 // instance members. | 1743 // instance members. |
1813 return handleErroneousAccess( | 1744 return handleErroneousAccess( |
1814 node, name, new StaticAccess.unresolved(error)); | 1745 node, name, new StaticAccess.unresolved(error)); |
1815 } | 1746 } |
1816 | 1747 |
1817 /// Handle qualified update of an instance member, like `a.b = c` or `a.b++` | 1748 /// Handle qualified update of an instance member, like `a.b = c` or `a.b++` |
1818 /// where `a` is a class and `b` is a non-static member. | 1749 /// where `a` is a class and `b` is a non-static member. |
1819 ResolutionResult handleStaticInstanceMemberUpdate( | 1750 ResolutionResult handleStaticInstanceMemberUpdate( |
1820 SendSet node, Name name, ClassElement receiverClass, Element member) { | 1751 SendSet node, Name name, ClassElement receiverClass, Element member) { |
1821 | |
1822 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1752 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1823 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 1753 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
1824 // try to resolve injected elements if [currentClass] is in the patch | 1754 // try to resolve injected elements if [currentClass] is in the patch |
1825 // library of [receiverClass]. | 1755 // library of [receiverClass]. |
1826 | 1756 |
1827 // TODO(johnniwinther): Produce a different error for complex update. | 1757 // TODO(johnniwinther): Produce a different error for complex update. |
1828 ErroneousElement error = reportAndCreateErroneousElement( | 1758 ErroneousElement error = reportAndCreateErroneousElement( |
1829 node, name.text, MessageKind.MEMBER_NOT_STATIC, | 1759 node, |
| 1760 name.text, |
| 1761 MessageKind.MEMBER_NOT_STATIC, |
1830 {'className': receiverClass.name, 'memberName': name}); | 1762 {'className': receiverClass.name, 'memberName': name}); |
1831 | 1763 |
1832 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed | 1764 // TODO(johnniwinther): Add an [AccessSemantics] for statically accessed |
1833 // instance members. | 1765 // instance members. |
1834 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1766 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
1835 } | 1767 } |
1836 | 1768 |
1837 /// Handle qualified access of an inaccessible private static class member, | 1769 /// Handle qualified access of an inaccessible private static class member, |
1838 /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a` | 1770 /// like `a._b` or `a._b()` where `a` is class, `_b` is static member of `a` |
1839 /// but `a` is not defined in the current library. | 1771 /// but `a` is not defined in the current library. |
1840 ResolutionResult handlePrivateStaticMemberAccess( | 1772 ResolutionResult handlePrivateStaticMemberAccess( |
1841 Send node, Name name, ClassElement receiverClass, Element member) { | 1773 Send node, Name name, ClassElement receiverClass, Element member) { |
1842 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1774 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1843 ErroneousElement error = reportAndCreateErroneousElement( | 1775 ErroneousElement error = reportAndCreateErroneousElement( |
1844 node, name.text, MessageKind.PRIVATE_ACCESS, | 1776 node, |
1845 {'libraryName': member.library.libraryOrScriptName, | 1777 name.text, |
1846 'name': name}); | 1778 MessageKind.PRIVATE_ACCESS, |
| 1779 {'libraryName': member.library.libraryOrScriptName, 'name': name}); |
1847 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1780 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
1848 // member access. | 1781 // member access. |
1849 return handleErroneousAccess( | 1782 return handleErroneousAccess( |
1850 node, name, new StaticAccess.unresolved(error)); | 1783 node, name, new StaticAccess.unresolved(error)); |
1851 } | 1784 } |
1852 | 1785 |
1853 /// Handle qualified update of an inaccessible private static class member, | 1786 /// Handle qualified update of an inaccessible private static class member, |
1854 /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of | 1787 /// like `a._b = c` or `a._b++` where `a` is class, `_b` is static member of |
1855 /// `a` but `a` is not defined in the current library. | 1788 /// `a` but `a` is not defined in the current library. |
1856 ResolutionResult handlePrivateStaticMemberUpdate( | 1789 ResolutionResult handlePrivateStaticMemberUpdate( |
1857 SendSet node, Name name, ClassElement receiverClass, Element member) { | 1790 SendSet node, Name name, ClassElement receiverClass, Element member) { |
1858 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1791 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
1859 ErroneousElement error = reportAndCreateErroneousElement( | 1792 ErroneousElement error = reportAndCreateErroneousElement( |
1860 node, name.text, MessageKind.PRIVATE_ACCESS, | 1793 node, |
1861 {'libraryName': member.library.libraryOrScriptName, | 1794 name.text, |
1862 'name': name}); | 1795 MessageKind.PRIVATE_ACCESS, |
| 1796 {'libraryName': member.library.libraryOrScriptName, 'name': name}); |
1863 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static | 1797 // TODO(johnniwinther): Add an [AccessSemantics] for unresolved static |
1864 // member access. | 1798 // member access. |
1865 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 1799 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
1866 } | 1800 } |
1867 | 1801 |
1868 /// Handle qualified access to a static member, like `a.b` or `a.b()` where | 1802 /// Handle qualified access to a static member, like `a.b` or `a.b()` where |
1869 /// `a` is a class and `b` is a static member of `a`. | 1803 /// `a` is a class and `b` is a static member of `a`. |
1870 ResolutionResult handleStaticMemberAccess( | 1804 ResolutionResult handleStaticMemberAccess( |
1871 Send node, Name memberName, ClassElement receiverClass) { | 1805 Send node, Name memberName, ClassElement receiverClass) { |
1872 String name = memberName.text; | 1806 String name = memberName.text; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1924 } | 1858 } |
1925 } | 1859 } |
1926 | 1860 |
1927 /// Handle access to a type literal of type variable [element]. Like `T` or | 1861 /// Handle access to a type literal of type variable [element]. Like `T` or |
1928 /// `T()` where 'T' is type variable. | 1862 /// `T()` where 'T' is type variable. |
1929 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1863 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
1930 // the [GetStructure]. | 1864 // the [GetStructure]. |
1931 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1865 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
1932 // evaluating constants. | 1866 // evaluating constants. |
1933 ResolutionResult handleTypeVariableTypeLiteralAccess( | 1867 ResolutionResult handleTypeVariableTypeLiteralAccess( |
1934 Send node, | 1868 Send node, Name name, TypeVariableElement element) { |
1935 Name name, | |
1936 TypeVariableElement element) { | |
1937 AccessSemantics semantics; | 1869 AccessSemantics semantics; |
1938 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1870 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { |
1939 // TODO(johnniwinther): Add another access semantics for this. | 1871 // TODO(johnniwinther): Add another access semantics for this. |
1940 ErroneousElement error = reportAndCreateErroneousElement( | 1872 ErroneousElement error = reportAndCreateErroneousElement( |
1941 node, name.text, | 1873 node, |
| 1874 name.text, |
1942 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1875 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
1943 {'typeVariableName': name}, | 1876 {'typeVariableName': name}, |
1944 isError: true); | 1877 isError: true); |
1945 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1878 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
1946 semantics = new StaticAccess.invalid(error); | 1879 semantics = new StaticAccess.invalid(error); |
1947 // TODO(johnniwinther): Clean up registration of elements and selectors | 1880 // TODO(johnniwinther): Clean up registration of elements and selectors |
1948 // for this case. | 1881 // for this case. |
1949 } else { | 1882 } else { |
1950 semantics = new StaticAccess.typeParameterTypeLiteral(element); | 1883 semantics = new StaticAccess.typeParameterTypeLiteral(element); |
1951 } | 1884 } |
1952 | 1885 |
1953 registry.useElement(node, element); | 1886 registry.useElement(node, element); |
1954 registry.registerTypeLiteral(node, element.type); | 1887 registry.registerTypeLiteral(node, element.type); |
1955 | 1888 |
1956 if (node.isCall) { | 1889 if (node.isCall) { |
1957 CallStructure callStructure = | 1890 CallStructure callStructure = |
1958 resolveArguments(node.argumentsNode).callStructure; | 1891 resolveArguments(node.argumentsNode).callStructure; |
1959 Selector selector = callStructure.callSelector; | 1892 Selector selector = callStructure.callSelector; |
1960 // TODO(23998): Remove this when all information goes through | 1893 // TODO(23998): Remove this when all information goes through |
1961 // the [SendStructure]. | 1894 // the [SendStructure]. |
1962 registry.setSelector(node, selector); | 1895 registry.setSelector(node, selector); |
1963 | 1896 |
1964 registry.registerSendStructure(node, | 1897 registry.registerSendStructure( |
1965 new InvokeStructure(semantics, selector)); | 1898 node, new InvokeStructure(semantics, selector)); |
1966 } else { | 1899 } else { |
1967 // TODO(johnniwinther): Avoid the need for a [Selector] here. | 1900 // TODO(johnniwinther): Avoid the need for a [Selector] here. |
1968 registry.registerSendStructure(node, new GetStructure(semantics)); | 1901 registry.registerSendStructure(node, new GetStructure(semantics)); |
1969 } | 1902 } |
1970 return const NoneResult(); | 1903 return const NoneResult(); |
1971 } | 1904 } |
1972 | 1905 |
1973 /// Handle access to a type literal of type variable [element]. Like `T = b`, | 1906 /// Handle access to a type literal of type variable [element]. Like `T = b`, |
1974 /// `T++` or `T += b` where 'T' is type variable. | 1907 /// `T++` or `T += b` where 'T' is type variable. |
1975 ResolutionResult handleTypeVariableTypeLiteralUpdate( | 1908 ResolutionResult handleTypeVariableTypeLiteralUpdate( |
1976 SendSet node, | 1909 SendSet node, Name name, TypeVariableElement element) { |
1977 Name name, | |
1978 TypeVariableElement element) { | |
1979 AccessSemantics semantics; | 1910 AccessSemantics semantics; |
1980 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { | 1911 if (!Elements.hasAccessToTypeVariables(enclosingElement)) { |
1981 // TODO(johnniwinther): Add another access semantics for this. | 1912 // TODO(johnniwinther): Add another access semantics for this. |
1982 ErroneousElement error = reportAndCreateErroneousElement( | 1913 ErroneousElement error = reportAndCreateErroneousElement( |
1983 node, name.text, | 1914 node, |
| 1915 name.text, |
1984 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, | 1916 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER, |
1985 {'typeVariableName': name}, | 1917 {'typeVariableName': name}, |
1986 isError: true); | 1918 isError: true); |
1987 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 1919 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
1988 semantics = new StaticAccess.invalid(error); | 1920 semantics = new StaticAccess.invalid(error); |
1989 } else { | 1921 } else { |
1990 ErroneousElement error; | 1922 ErroneousElement error; |
1991 if (node.isIfNullAssignment) { | 1923 if (node.isIfNullAssignment) { |
1992 error = reportAndCreateErroneousElement( | 1924 error = reportAndCreateErroneousElement(node.selector, name.text, |
1993 node.selector, name.text, | |
1994 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); | 1925 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); |
1995 // TODO(23998): Remove these when all information goes through | 1926 // TODO(23998): Remove these when all information goes through |
1996 // the [SendStructure]. | 1927 // the [SendStructure]. |
1997 registry.useElement(node.selector, element); | 1928 registry.useElement(node.selector, element); |
1998 } else { | 1929 } else { |
1999 error = reportAndCreateErroneousElement( | 1930 error = reportAndCreateErroneousElement( |
2000 node.selector, name.text, | 1931 node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {}); |
2001 MessageKind.ASSIGNING_TYPE, const {}); | |
2002 } | 1932 } |
2003 | 1933 |
2004 // TODO(23998): Remove this when all information goes through | 1934 // TODO(23998): Remove this when all information goes through |
2005 // the [SendStructure]. | 1935 // the [SendStructure]. |
2006 registry.useElement(node, error); | 1936 registry.useElement(node, error); |
2007 // TODO(johnniwinther): Register only on read? | 1937 // TODO(johnniwinther): Register only on read? |
2008 registry.registerTypeLiteral(node, element.type); | 1938 registry.registerTypeLiteral(node, element.type); |
2009 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 1939 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2010 semantics = new StaticAccess.typeParameterTypeLiteral(element); | 1940 semantics = new StaticAccess.typeParameterTypeLiteral(element); |
2011 } | 1941 } |
2012 return handleUpdate(node, name, semantics); | 1942 return handleUpdate(node, name, semantics); |
2013 } | 1943 } |
2014 | 1944 |
2015 /// Handle access to a constant type literal of [type]. | 1945 /// Handle access to a constant type literal of [type]. |
2016 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1946 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
2017 // the [GetStructure]. | 1947 // the [GetStructure]. |
2018 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1948 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
2019 // evaluating constants. | 1949 // evaluating constants. |
2020 ResolutionResult handleConstantTypeLiteralAccess( | 1950 ResolutionResult handleConstantTypeLiteralAccess(Send node, Name name, |
2021 Send node, | 1951 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { |
2022 Name name, | |
2023 TypeDeclarationElement element, | |
2024 DartType type, | |
2025 ConstantAccess semantics) { | |
2026 registry.useElement(node, element); | 1952 registry.useElement(node, element); |
2027 registry.registerTypeLiteral(node, type); | 1953 registry.registerTypeLiteral(node, type); |
2028 | 1954 |
2029 if (node.isCall) { | 1955 if (node.isCall) { |
2030 CallStructure callStructure = | 1956 CallStructure callStructure = |
2031 resolveArguments(node.argumentsNode).callStructure; | 1957 resolveArguments(node.argumentsNode).callStructure; |
2032 Selector selector = callStructure.callSelector; | 1958 Selector selector = callStructure.callSelector; |
2033 // TODO(23998): Remove this when all information goes through | 1959 // TODO(23998): Remove this when all information goes through |
2034 // the [SendStructure]. | 1960 // the [SendStructure]. |
2035 registry.setSelector(node, selector); | 1961 registry.setSelector(node, selector); |
2036 | 1962 |
2037 // The node itself is not a constant but we register the selector (the | 1963 // The node itself is not a constant but we register the selector (the |
2038 // identifier that refers to the class/typedef) as a constant. | 1964 // identifier that refers to the class/typedef) as a constant. |
2039 registry.useElement(node.selector, element); | 1965 registry.useElement(node.selector, element); |
2040 analyzeConstantDeferred(node.selector, enforceConst: false); | 1966 analyzeConstantDeferred(node.selector, enforceConst: false); |
2041 | 1967 |
2042 registry.registerSendStructure(node, | 1968 registry.registerSendStructure( |
2043 new InvokeStructure(semantics, selector)); | 1969 node, new InvokeStructure(semantics, selector)); |
2044 return const NoneResult(); | 1970 return const NoneResult(); |
2045 } else { | 1971 } else { |
2046 analyzeConstantDeferred(node, enforceConst: false); | 1972 analyzeConstantDeferred(node, enforceConst: false); |
2047 | 1973 |
2048 registry.setConstant(node, semantics.constant); | 1974 registry.setConstant(node, semantics.constant); |
2049 registry.registerSendStructure(node, new GetStructure(semantics)); | 1975 registry.registerSendStructure(node, new GetStructure(semantics)); |
2050 return new ConstantResult(node, semantics.constant); | 1976 return new ConstantResult(node, semantics.constant); |
2051 } | 1977 } |
2052 } | 1978 } |
2053 | 1979 |
2054 /// Handle access to a constant type literal of [type]. | 1980 /// Handle access to a constant type literal of [type]. |
2055 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the | 1981 // TODO(johnniwinther): Remove [name] when [Selector] is not required for the |
2056 // the [GetStructure]. | 1982 // the [GetStructure]. |
2057 // TODO(johnniwinther): Remove [element] when it is no longer needed for | 1983 // TODO(johnniwinther): Remove [element] when it is no longer needed for |
2058 // evaluating constants. | 1984 // evaluating constants. |
2059 ResolutionResult handleConstantTypeLiteralUpdate( | 1985 ResolutionResult handleConstantTypeLiteralUpdate(SendSet node, Name name, |
2060 SendSet node, | 1986 TypeDeclarationElement element, DartType type, ConstantAccess semantics) { |
2061 Name name, | |
2062 TypeDeclarationElement element, | |
2063 DartType type, | |
2064 ConstantAccess semantics) { | |
2065 | |
2066 // TODO(johnniwinther): Remove this when all constants are evaluated. | 1987 // TODO(johnniwinther): Remove this when all constants are evaluated. |
2067 compiler.resolver.constantCompiler.evaluate(semantics.constant); | 1988 compiler.resolver.constantCompiler.evaluate(semantics.constant); |
2068 | 1989 |
2069 ErroneousElement error; | 1990 ErroneousElement error; |
2070 if (node.isIfNullAssignment) { | 1991 if (node.isIfNullAssignment) { |
2071 error = reportAndCreateErroneousElement( | 1992 error = reportAndCreateErroneousElement(node.selector, name.text, |
2072 node.selector, name.text, | |
2073 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); | 1993 MessageKind.IF_NULL_ASSIGNING_TYPE, const {}); |
2074 // TODO(23998): Remove these when all information goes through | 1994 // TODO(23998): Remove these when all information goes through |
2075 // the [SendStructure]. | 1995 // the [SendStructure]. |
2076 registry.setConstant(node.selector, semantics.constant); | 1996 registry.setConstant(node.selector, semantics.constant); |
2077 registry.useElement(node.selector, element); | 1997 registry.useElement(node.selector, element); |
2078 } else { | 1998 } else { |
2079 error = reportAndCreateErroneousElement( | 1999 error = reportAndCreateErroneousElement( |
2080 node.selector, name.text, | 2000 node.selector, name.text, MessageKind.ASSIGNING_TYPE, const {}); |
2081 MessageKind.ASSIGNING_TYPE, const {}); | |
2082 } | 2001 } |
2083 | 2002 |
2084 // TODO(23998): Remove this when all information goes through | 2003 // TODO(23998): Remove this when all information goes through |
2085 // the [SendStructure]. | 2004 // the [SendStructure]. |
2086 registry.useElement(node, error); | 2005 registry.useElement(node, error); |
2087 registry.registerTypeLiteral(node, type); | 2006 registry.registerTypeLiteral(node, type); |
2088 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2007 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2089 | 2008 |
2090 return handleUpdate(node, name, semantics); | 2009 return handleUpdate(node, name, semantics); |
2091 } | 2010 } |
2092 | 2011 |
2093 /// Handle access to a type literal of a typedef. Like `F` or | 2012 /// Handle access to a type literal of a typedef. Like `F` or |
2094 /// `F()` where 'F' is typedef. | 2013 /// `F()` where 'F' is typedef. |
2095 ResolutionResult handleTypedefTypeLiteralAccess( | 2014 ResolutionResult handleTypedefTypeLiteralAccess( |
2096 Send node, | 2015 Send node, Name name, TypedefElement typdef) { |
2097 Name name, | |
2098 TypedefElement typdef) { | |
2099 typdef.ensureResolved(resolution); | 2016 typdef.ensureResolved(resolution); |
2100 DartType type = typdef.rawType; | 2017 DartType type = typdef.rawType; |
2101 ConstantExpression constant = new TypeConstantExpression(type); | 2018 ConstantExpression constant = new TypeConstantExpression(type); |
2102 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2019 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
2103 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); | 2020 return handleConstantTypeLiteralAccess(node, name, typdef, type, semantics); |
2104 } | 2021 } |
2105 | 2022 |
2106 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or | 2023 /// Handle access to a type literal of a typedef. Like `F = b`, `F++` or |
2107 /// `F += b` where 'F' is typedef. | 2024 /// `F += b` where 'F' is typedef. |
2108 ResolutionResult handleTypedefTypeLiteralUpdate( | 2025 ResolutionResult handleTypedefTypeLiteralUpdate( |
2109 SendSet node, | 2026 SendSet node, Name name, TypedefElement typdef) { |
2110 Name name, | |
2111 TypedefElement typdef) { | |
2112 typdef.ensureResolved(resolution); | 2027 typdef.ensureResolved(resolution); |
2113 DartType type = typdef.rawType; | 2028 DartType type = typdef.rawType; |
2114 ConstantExpression constant = new TypeConstantExpression(type); | 2029 ConstantExpression constant = new TypeConstantExpression(type); |
2115 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); | 2030 AccessSemantics semantics = new ConstantAccess.typedefTypeLiteral(constant); |
2116 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); | 2031 return handleConstantTypeLiteralUpdate(node, name, typdef, type, semantics); |
2117 } | 2032 } |
2118 | 2033 |
2119 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or | 2034 /// Handle access to a type literal of the type 'dynamic'. Like `dynamic` or |
2120 /// `dynamic()`. | 2035 /// `dynamic()`. |
2121 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { | 2036 ResolutionResult handleDynamicTypeLiteralAccess(Send node) { |
2122 DartType type = const DynamicType(); | 2037 DartType type = const DynamicType(); |
2123 ConstantExpression constant = new TypeConstantExpression( | 2038 ConstantExpression constant = new TypeConstantExpression( |
2124 // TODO(johnniwinther): Use [type] when evaluation of constants is done | 2039 // TODO(johnniwinther): Use [type] when evaluation of constants is done |
2125 // directly on the constant expressions. | 2040 // directly on the constant expressions. |
2126 node.isCall ? coreTypes.typeType : type); | 2041 node.isCall ? coreTypes.typeType : type); |
2127 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); | 2042 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
2128 return handleConstantTypeLiteralAccess( | 2043 return handleConstantTypeLiteralAccess(node, const PublicName('dynamic'), |
2129 node, const PublicName('dynamic'), | |
2130 coreClasses.typeClass, type, semantics); | 2044 coreClasses.typeClass, type, semantics); |
2131 } | 2045 } |
2132 | 2046 |
2133 /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or | 2047 /// Handle update to a type literal of the type 'dynamic'. Like `dynamic++` or |
2134 /// `dynamic = 0`. | 2048 /// `dynamic = 0`. |
2135 ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) { | 2049 ResolutionResult handleDynamicTypeLiteralUpdate(SendSet node) { |
2136 DartType type = const DynamicType(); | 2050 DartType type = const DynamicType(); |
2137 ConstantExpression constant = | 2051 ConstantExpression constant = |
2138 new TypeConstantExpression(const DynamicType()); | 2052 new TypeConstantExpression(const DynamicType()); |
2139 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); | 2053 AccessSemantics semantics = new ConstantAccess.dynamicTypeLiteral(constant); |
2140 return handleConstantTypeLiteralUpdate( | 2054 return handleConstantTypeLiteralUpdate(node, const PublicName('dynamic'), |
2141 node, const PublicName('dynamic'), | |
2142 coreClasses.typeClass, type, semantics); | 2055 coreClasses.typeClass, type, semantics); |
2143 } | 2056 } |
2144 | 2057 |
2145 /// Handle access to a type literal of a class. Like `C` or | 2058 /// Handle access to a type literal of a class. Like `C` or |
2146 /// `C()` where 'C' is class. | 2059 /// `C()` where 'C' is class. |
2147 ResolutionResult handleClassTypeLiteralAccess( | 2060 ResolutionResult handleClassTypeLiteralAccess( |
2148 Send node, | 2061 Send node, Name name, ClassElement cls) { |
2149 Name name, | |
2150 ClassElement cls) { | |
2151 cls.ensureResolved(resolution); | 2062 cls.ensureResolved(resolution); |
2152 DartType type = cls.rawType; | 2063 DartType type = cls.rawType; |
2153 ConstantExpression constant = new TypeConstantExpression(type); | 2064 ConstantExpression constant = new TypeConstantExpression(type); |
2154 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2065 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
2155 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); | 2066 return handleConstantTypeLiteralAccess(node, name, cls, type, semantics); |
2156 } | 2067 } |
2157 | 2068 |
2158 /// Handle access to a type literal of a class. Like `C = b`, `C++` or | 2069 /// Handle access to a type literal of a class. Like `C = b`, `C++` or |
2159 /// `C += b` where 'C' is class. | 2070 /// `C += b` where 'C' is class. |
2160 ResolutionResult handleClassTypeLiteralUpdate( | 2071 ResolutionResult handleClassTypeLiteralUpdate( |
2161 SendSet node, | 2072 SendSet node, Name name, ClassElement cls) { |
2162 Name name, | |
2163 ClassElement cls) { | |
2164 cls.ensureResolved(resolution); | 2073 cls.ensureResolved(resolution); |
2165 DartType type = cls.rawType; | 2074 DartType type = cls.rawType; |
2166 ConstantExpression constant = new TypeConstantExpression(type); | 2075 ConstantExpression constant = new TypeConstantExpression(type); |
2167 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); | 2076 AccessSemantics semantics = new ConstantAccess.classTypeLiteral(constant); |
2168 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); | 2077 return handleConstantTypeLiteralUpdate(node, name, cls, type, semantics); |
2169 } | 2078 } |
2170 | 2079 |
2171 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 2080 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
2172 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 2081 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
2173 /// error. | 2082 /// error. |
2174 ResolutionResult handleClassSend( | 2083 ResolutionResult handleClassSend(Send node, Name name, ClassElement cls) { |
2175 Send node, | |
2176 Name name, | |
2177 ClassElement cls) { | |
2178 cls.ensureResolved(resolution); | 2084 cls.ensureResolved(resolution); |
2179 if (sendIsMemberAccess) { | 2085 if (sendIsMemberAccess) { |
2180 registry.useElement(node, cls); | 2086 registry.useElement(node, cls); |
2181 return new PrefixResult(null, cls); | 2087 return new PrefixResult(null, cls); |
2182 } else { | 2088 } else { |
2183 // `C` or `C()` where 'C' is a class. | 2089 // `C` or `C()` where 'C' is a class. |
2184 return handleClassTypeLiteralAccess(node, name, cls); | 2090 return handleClassTypeLiteralAccess(node, name, cls); |
2185 } | 2091 } |
2186 } | 2092 } |
2187 | 2093 |
2188 /// Compute a [DeferredPrefixStructure] for [node]. | 2094 /// Compute a [DeferredPrefixStructure] for [node]. |
2189 ResolutionResult handleDeferredAccess( | 2095 ResolutionResult handleDeferredAccess( |
2190 Send node, | 2096 Send node, PrefixElement prefix, ResolutionResult result) { |
2191 PrefixElement prefix, | |
2192 ResolutionResult result) { | |
2193 assert(invariant(node, prefix.isDeferred, | 2097 assert(invariant(node, prefix.isDeferred, |
2194 message: "Prefix $prefix is not deferred.")); | 2098 message: "Prefix $prefix is not deferred.")); |
2195 SendStructure sendStructure = registry.getSendStructure(node); | 2099 SendStructure sendStructure = registry.getSendStructure(node); |
2196 assert(invariant(node, sendStructure != null, | 2100 assert(invariant(node, sendStructure != null, |
2197 message: "No SendStructure for $node.")); | 2101 message: "No SendStructure for $node.")); |
2198 registry.registerSendStructure(node, | 2102 registry.registerSendStructure( |
2199 new DeferredPrefixStructure(prefix, sendStructure)); | 2103 node, new DeferredPrefixStructure(prefix, sendStructure)); |
2200 if (result.isConstant) { | 2104 if (result.isConstant) { |
2201 ConstantExpression constant = | 2105 ConstantExpression constant = |
2202 new DeferredConstantExpression(result.constant, prefix); | 2106 new DeferredConstantExpression(result.constant, prefix); |
2203 registry.setConstant(node, constant); | 2107 registry.setConstant(node, constant); |
2204 result = new ConstantResult(node, constant); | 2108 result = new ConstantResult(node, constant); |
2205 } | 2109 } |
2206 return result; | 2110 return result; |
2207 } | 2111 } |
2208 | 2112 |
2209 /// Handle qualified [Send] where the receiver resolves to a [prefix], | 2113 /// Handle qualified [Send] where the receiver resolves to a [prefix], |
2210 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where | 2114 /// like `prefix.toplevelFunction()` or `prefix.Class.staticField` where |
2211 /// `prefix` is a library prefix. | 2115 /// `prefix` is a library prefix. |
2212 ResolutionResult handleLibraryPrefixSend( | 2116 ResolutionResult handleLibraryPrefixSend( |
2213 Send node, Name name, PrefixElement prefix) { | 2117 Send node, Name name, PrefixElement prefix) { |
2214 ResolutionResult result; | 2118 ResolutionResult result; |
2215 Element member = prefix.lookupLocalMember(name.text); | 2119 Element member = prefix.lookupLocalMember(name.text); |
2216 if (member == null) { | 2120 if (member == null) { |
2217 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2121 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2218 Element error = reportAndCreateErroneousElement( | 2122 Element error = reportAndCreateErroneousElement( |
2219 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 2123 node, |
| 2124 name.text, |
| 2125 MessageKind.NO_SUCH_LIBRARY_MEMBER, |
2220 {'libraryName': prefix.name, 'memberName': name}); | 2126 {'libraryName': prefix.name, 'memberName': name}); |
2221 result = handleUnresolvedAccess(node, name, error); | 2127 result = handleUnresolvedAccess(node, name, error); |
2222 } else { | 2128 } else { |
2223 result = handleResolvedSend(node, name, member); | 2129 result = handleResolvedSend(node, name, member); |
2224 } | 2130 } |
2225 if (result.kind == ResultKind.PREFIX) { | 2131 if (result.kind == ResultKind.PREFIX) { |
2226 // [member] is a class prefix of a static access like `prefix.Class` of | 2132 // [member] is a class prefix of a static access like `prefix.Class` of |
2227 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will | 2133 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will |
2228 // called on the parent `prefix.Class.foo` node. | 2134 // called on the parent `prefix.Class.foo` node. |
2229 result = new PrefixResult(prefix, result.element); | 2135 result = new PrefixResult(prefix, result.element); |
2230 } else if (prefix.isDeferred && | 2136 } else if (prefix.isDeferred && |
2231 (member == null || !member.isDeferredLoaderGetter)) { | 2137 (member == null || !member.isDeferredLoaderGetter)) { |
2232 result = handleDeferredAccess(node, prefix, result); | 2138 result = handleDeferredAccess(node, prefix, result); |
2233 } | 2139 } |
2234 return result; | 2140 return result; |
2235 } | 2141 } |
2236 | 2142 |
2237 /// Handle qualified [SendSet] where the receiver resolves to a [prefix], | 2143 /// Handle qualified [SendSet] where the receiver resolves to a [prefix], |
2238 /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where | 2144 /// like `prefix.toplevelField = b` or `prefix.Class.staticField++` where |
2239 /// `prefix` is a library prefix. | 2145 /// `prefix` is a library prefix. |
2240 ResolutionResult handleLibraryPrefixSendSet( | 2146 ResolutionResult handleLibraryPrefixSendSet( |
2241 SendSet node, Name name, PrefixElement prefix) { | 2147 SendSet node, Name name, PrefixElement prefix) { |
2242 ResolutionResult result; | 2148 ResolutionResult result; |
2243 Element member = prefix.lookupLocalMember(name.text); | 2149 Element member = prefix.lookupLocalMember(name.text); |
2244 if (member == null) { | 2150 if (member == null) { |
2245 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2151 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2246 Element error = reportAndCreateErroneousElement( | 2152 Element error = reportAndCreateErroneousElement( |
2247 node, name.text, MessageKind.NO_SUCH_LIBRARY_MEMBER, | 2153 node, |
| 2154 name.text, |
| 2155 MessageKind.NO_SUCH_LIBRARY_MEMBER, |
2248 {'libraryName': prefix.name, 'memberName': name}); | 2156 {'libraryName': prefix.name, 'memberName': name}); |
2249 return handleUpdate(node, name, new StaticAccess.unresolved(error)); | 2157 return handleUpdate(node, name, new StaticAccess.unresolved(error)); |
2250 } else { | 2158 } else { |
2251 result = handleResolvedSendSet(node, name, member); | 2159 result = handleResolvedSendSet(node, name, member); |
2252 } | 2160 } |
2253 if (result.kind == ResultKind.PREFIX) { | 2161 if (result.kind == ResultKind.PREFIX) { |
2254 // [member] is a class prefix of a static access like `prefix.Class` of | 2162 // [member] is a class prefix of a static access like `prefix.Class` of |
2255 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will | 2163 // `prefix.Class.foo`. No need to call [handleDeferredAccess]; it will |
2256 // called on the parent `prefix.Class.foo` node. | 2164 // called on the parent `prefix.Class.foo` node. |
2257 result = new PrefixResult(prefix, result.element); | 2165 result = new PrefixResult(prefix, result.element); |
2258 } else if (prefix.isDeferred && | 2166 } else if (prefix.isDeferred && |
2259 (member == null || !member.isDeferredLoaderGetter)) { | 2167 (member == null || !member.isDeferredLoaderGetter)) { |
2260 result = handleDeferredAccess(node, prefix, result); | 2168 result = handleDeferredAccess(node, prefix, result); |
2261 } | 2169 } |
2262 return result; | 2170 return result; |
2263 } | 2171 } |
2264 | 2172 |
2265 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in | 2173 /// Handle a [Send] that resolves to a [prefix]. Like `prefix` in |
2266 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time | 2174 /// `prefix.Class` or `prefix` in `prefix()`, the latter being a compile time |
2267 /// error. | 2175 /// error. |
2268 ResolutionResult handleLibraryPrefix( | 2176 ResolutionResult handleLibraryPrefix( |
2269 Send node, | 2177 Send node, Name name, PrefixElement prefix) { |
2270 Name name, | |
2271 PrefixElement prefix) { | |
2272 if ((ElementCategory.PREFIX & allowedCategory) == 0) { | 2178 if ((ElementCategory.PREFIX & allowedCategory) == 0) { |
2273 ErroneousElement error = reportAndCreateErroneousElement( | 2179 ErroneousElement error = reportAndCreateErroneousElement( |
2274 node, | 2180 node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name}, |
2275 name.text, | |
2276 MessageKind.PREFIX_AS_EXPRESSION, | |
2277 {'prefix': name}, | |
2278 isError: true); | 2181 isError: true); |
2279 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2182 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
2280 return handleErroneousAccess( | 2183 return handleErroneousAccess(node, name, new StaticAccess.invalid(error)); |
2281 node, name, new StaticAccess.invalid(error)); | |
2282 } | 2184 } |
2283 if (prefix.isDeferred) { | 2185 if (prefix.isDeferred) { |
2284 // TODO(23998): Remove this when deferred access is detected | 2186 // TODO(23998): Remove this when deferred access is detected |
2285 // through a [SendStructure]. | 2187 // through a [SendStructure]. |
2286 registry.useElement(node.selector, prefix); | 2188 registry.useElement(node.selector, prefix); |
2287 } | 2189 } |
2288 registry.useElement(node, prefix); | 2190 registry.useElement(node, prefix); |
2289 return new PrefixResult(prefix, null); | 2191 return new PrefixResult(prefix, null); |
2290 } | 2192 } |
2291 | 2193 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2333 | 2235 |
2334 /// Handle dynamic access of [semantics]. | 2236 /// Handle dynamic access of [semantics]. |
2335 ResolutionResult handleDynamicAccessSemantics( | 2237 ResolutionResult handleDynamicAccessSemantics( |
2336 Send node, Name name, AccessSemantics semantics) { | 2238 Send node, Name name, AccessSemantics semantics) { |
2337 SendStructure sendStructure; | 2239 SendStructure sendStructure; |
2338 Selector selector; | 2240 Selector selector; |
2339 if (node.isCall) { | 2241 if (node.isCall) { |
2340 CallStructure callStructure = | 2242 CallStructure callStructure = |
2341 resolveArguments(node.argumentsNode).callStructure; | 2243 resolveArguments(node.argumentsNode).callStructure; |
2342 selector = new Selector.call(name, callStructure); | 2244 selector = new Selector.call(name, callStructure); |
2343 registry.registerDynamicUse( | 2245 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2344 new DynamicUse(selector, null)); | |
2345 sendStructure = new InvokeStructure(semantics, selector); | 2246 sendStructure = new InvokeStructure(semantics, selector); |
2346 } else { | 2247 } else { |
2347 assert(invariant(node, node.isPropertyAccess)); | 2248 assert(invariant(node, node.isPropertyAccess)); |
2348 selector = new Selector.getter(name); | 2249 selector = new Selector.getter(name); |
2349 registry.registerDynamicUse( | 2250 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2350 new DynamicUse(selector, null)); | |
2351 sendStructure = new GetStructure(semantics); | 2251 sendStructure = new GetStructure(semantics); |
2352 } | 2252 } |
2353 registry.registerSendStructure(node, sendStructure); | 2253 registry.registerSendStructure(node, sendStructure); |
2354 // TODO(23998): Remove this when all information goes through | 2254 // TODO(23998): Remove this when all information goes through |
2355 // the [SendStructure]. | 2255 // the [SendStructure]. |
2356 registry.setSelector(node, selector); | 2256 registry.setSelector(node, selector); |
2357 return const NoneResult(); | 2257 return const NoneResult(); |
2358 } | 2258 } |
2359 | 2259 |
2360 /// Handle dynamic update of [semantics]. | 2260 /// Handle dynamic update of [semantics]. |
2361 ResolutionResult handleDynamicUpdateSemantics( | 2261 ResolutionResult handleDynamicUpdateSemantics( |
2362 SendSet node, Name name, Element element, AccessSemantics semantics) { | 2262 SendSet node, Name name, Element element, AccessSemantics semantics) { |
2363 Selector getterSelector = new Selector.getter(name); | 2263 Selector getterSelector = new Selector.getter(name); |
2364 Selector setterSelector = new Selector.setter(name.setter); | 2264 Selector setterSelector = new Selector.setter(name.setter); |
2365 registry.registerDynamicUse( | 2265 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
2366 new DynamicUse(setterSelector, null)); | |
2367 if (node.isComplex) { | 2266 if (node.isComplex) { |
2368 registry.registerDynamicUse( | 2267 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
2369 new DynamicUse(getterSelector, null)); | |
2370 } | 2268 } |
2371 | 2269 |
2372 // TODO(23998): Remove these when elements are only accessed through the | 2270 // TODO(23998): Remove these when elements are only accessed through the |
2373 // send structure. | 2271 // send structure. |
2374 Element getter = element; | 2272 Element getter = element; |
2375 Element setter = element; | 2273 Element setter = element; |
2376 if (element != null && element.isAbstractField) { | 2274 if (element != null && element.isAbstractField) { |
2377 AbstractFieldElement abstractField = element; | 2275 AbstractFieldElement abstractField = element; |
2378 getter = abstractField.getter; | 2276 getter = abstractField.getter; |
2379 setter = abstractField.setter; | 2277 setter = abstractField.setter; |
2380 } | 2278 } |
2381 if (setter != null) { | 2279 if (setter != null) { |
2382 registry.useElement(node, setter); | 2280 registry.useElement(node, setter); |
2383 if (getter != null && node.isComplex) { | 2281 if (getter != null && node.isComplex) { |
2384 registry.useElement(node.selector, getter); | 2282 registry.useElement(node.selector, getter); |
2385 } | 2283 } |
2386 } | 2284 } |
2387 | 2285 |
2388 return handleUpdate(node, name, semantics); | 2286 return handleUpdate(node, name, semantics); |
2389 } | 2287 } |
2390 | 2288 |
2391 /// Handle `this` as a qualified property, like `a.this`. | 2289 /// Handle `this` as a qualified property, like `a.this`. |
2392 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { | 2290 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { |
2393 ErroneousElement error = reportAndCreateErroneousElement( | 2291 ErroneousElement error = reportAndCreateErroneousElement( |
2394 node.selector, | 2292 node.selector, name.text, MessageKind.THIS_PROPERTY, {}, |
2395 name.text, | |
2396 MessageKind.THIS_PROPERTY, {}, | |
2397 isError: true); | 2293 isError: true); |
2398 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2294 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
2399 AccessSemantics accessSemantics = new StaticAccess.invalid(error); | 2295 AccessSemantics accessSemantics = new StaticAccess.invalid(error); |
2400 return handleErroneousAccess(node, name, accessSemantics); | 2296 return handleErroneousAccess(node, name, accessSemantics); |
2401 } | 2297 } |
2402 | 2298 |
2403 /// Handle a qualified [Send], that is where the receiver is non-null, like | 2299 /// Handle a qualified [Send], that is where the receiver is non-null, like |
2404 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. | 2300 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. |
2405 ResolutionResult handleQualifiedSend(Send node) { | 2301 ResolutionResult handleQualifiedSend(Send node) { |
2406 Identifier selector = node.selector.asIdentifier(); | 2302 Identifier selector = node.selector.asIdentifier(); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2463 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` | 2359 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` |
2464 // where `a` is not a prefix or class. | 2360 // where `a` is not a prefix or class. |
2465 // TODO(johnniwinther): Use the `element` of [result]. | 2361 // TODO(johnniwinther): Use the `element` of [result]. |
2466 return handleDynamicUpdateSemantics( | 2362 return handleDynamicUpdateSemantics( |
2467 node, name, null, new DynamicAccess.dynamicProperty(name)); | 2363 node, name, null, new DynamicAccess.dynamicProperty(name)); |
2468 } | 2364 } |
2469 } | 2365 } |
2470 | 2366 |
2471 /// Handle access unresolved access to [name] in a non-instance context. | 2367 /// Handle access unresolved access to [name] in a non-instance context. |
2472 ResolutionResult handleUnresolvedAccess( | 2368 ResolutionResult handleUnresolvedAccess( |
2473 Send node, Name name, Element element) { | 2369 Send node, Name name, Element element) { |
2474 // TODO(johnniwinther): Support unresolved top level access as an | 2370 // TODO(johnniwinther): Support unresolved top level access as an |
2475 // [AccessSemantics]. | 2371 // [AccessSemantics]. |
2476 AccessSemantics semantics = new StaticAccess.unresolved(element); | 2372 AccessSemantics semantics = new StaticAccess.unresolved(element); |
2477 return handleErroneousAccess(node, name, semantics); | 2373 return handleErroneousAccess(node, name, semantics); |
2478 } | 2374 } |
2479 | 2375 |
2480 /// Handle erroneous access of [element] of the given [semantics]. | 2376 /// Handle erroneous access of [element] of the given [semantics]. |
2481 ResolutionResult handleErroneousAccess( | 2377 ResolutionResult handleErroneousAccess( |
2482 Send node, Name name, AccessSemantics semantics) { | 2378 Send node, Name name, AccessSemantics semantics) { |
2483 SendStructure sendStructure; | 2379 SendStructure sendStructure; |
(...skipping 13 matching lines...) Expand all Loading... |
2497 // TODO(23998): Remove this when all information goes through | 2393 // TODO(23998): Remove this when all information goes through |
2498 // the [SendStructure]. | 2394 // the [SendStructure]. |
2499 registry.setSelector(node, selector); | 2395 registry.setSelector(node, selector); |
2500 registry.useElement(node, semantics.element); | 2396 registry.useElement(node, semantics.element); |
2501 registry.registerSendStructure(node, sendStructure); | 2397 registry.registerSendStructure(node, sendStructure); |
2502 return const NoneResult(); | 2398 return const NoneResult(); |
2503 } | 2399 } |
2504 | 2400 |
2505 /// Handle access to an ambiguous element, that is, a name imported twice. | 2401 /// Handle access to an ambiguous element, that is, a name imported twice. |
2506 ResolutionResult handleAmbiguousSend( | 2402 ResolutionResult handleAmbiguousSend( |
2507 Send node, | 2403 Send node, Name name, AmbiguousElement element) { |
2508 Name name, | |
2509 AmbiguousElement element) { | |
2510 | |
2511 ErroneousElement error = reportAndCreateErroneousElement( | 2404 ErroneousElement error = reportAndCreateErroneousElement( |
2512 node, | 2405 node, name.text, element.messageKind, element.messageArguments, |
2513 name.text, | |
2514 element.messageKind, | |
2515 element.messageArguments, | |
2516 infos: element.computeInfos(enclosingElement, reporter)); | 2406 infos: element.computeInfos(enclosingElement, reporter)); |
2517 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2407 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2518 | 2408 |
2519 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2409 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2520 AccessSemantics semantics = new StaticAccess.unresolved(error); | 2410 AccessSemantics semantics = new StaticAccess.unresolved(error); |
2521 return handleErroneousAccess(node, name, semantics); | 2411 return handleErroneousAccess(node, name, semantics); |
2522 } | 2412 } |
2523 | 2413 |
2524 /// Handle update to an ambiguous element, that is, a name imported twice. | 2414 /// Handle update to an ambiguous element, that is, a name imported twice. |
2525 ResolutionResult handleAmbiguousUpdate( | 2415 ResolutionResult handleAmbiguousUpdate( |
2526 SendSet node, | 2416 SendSet node, Name name, AmbiguousElement element) { |
2527 Name name, | |
2528 AmbiguousElement element) { | |
2529 | |
2530 ErroneousElement error = reportAndCreateErroneousElement( | 2417 ErroneousElement error = reportAndCreateErroneousElement( |
2531 node, | 2418 node, name.text, element.messageKind, element.messageArguments, |
2532 name.text, | |
2533 element.messageKind, | |
2534 element.messageArguments, | |
2535 infos: element.computeInfos(enclosingElement, reporter)); | 2419 infos: element.computeInfos(enclosingElement, reporter)); |
2536 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2420 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2537 | 2421 |
2538 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. | 2422 // TODO(johnniwinther): Support ambiguous access as an [AccessSemantics]. |
2539 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); | 2423 AccessSemantics accessSemantics = new StaticAccess.unresolved(error); |
2540 return handleUpdate(node, name, accessSemantics); | 2424 return handleUpdate(node, name, accessSemantics); |
2541 } | 2425 } |
2542 | 2426 |
2543 /// Report access of an instance [member] from a non-instance context. | 2427 /// Report access of an instance [member] from a non-instance context. |
2544 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { | 2428 AccessSemantics reportStaticInstanceAccess(Send node, Name name) { |
2545 ErroneousElement error = reportAndCreateErroneousElement( | 2429 ErroneousElement error = reportAndCreateErroneousElement( |
2546 node, name.text, | 2430 node, name.text, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}, |
2547 MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}, | |
2548 isError: true); | 2431 isError: true); |
2549 // TODO(johnniwinther): Support static instance access as an | 2432 // TODO(johnniwinther): Support static instance access as an |
2550 // [AccessSemantics]. | 2433 // [AccessSemantics]. |
2551 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2434 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
2552 return new StaticAccess.invalid(error); | 2435 return new StaticAccess.invalid(error); |
2553 } | 2436 } |
2554 | 2437 |
2555 /// Handle access of a parameter, local variable or local function. | 2438 /// Handle access of a parameter, local variable or local function. |
2556 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { | 2439 ResolutionResult handleLocalAccess(Send node, Name name, Element element) { |
2557 ResolutionResult result = const NoneResult(); | 2440 ResolutionResult result = const NoneResult(); |
2558 AccessSemantics semantics = computeLocalAccessSemantics(node, element); | 2441 AccessSemantics semantics = computeLocalAccessSemantics(node, element); |
2559 Selector selector; | 2442 Selector selector; |
2560 if (node.isCall) { | 2443 if (node.isCall) { |
2561 CallStructure callStructure = | 2444 CallStructure callStructure = |
2562 resolveArguments(node.argumentsNode).callStructure; | 2445 resolveArguments(node.argumentsNode).callStructure; |
2563 selector = new Selector.call(name, callStructure); | 2446 selector = new Selector.call(name, callStructure); |
2564 bool isIncompatibleInvoke = false; | 2447 bool isIncompatibleInvoke = false; |
2565 switch (semantics.kind) { | 2448 switch (semantics.kind) { |
2566 case AccessKind.LOCAL_FUNCTION: | 2449 case AccessKind.LOCAL_FUNCTION: |
2567 LocalFunctionElementX function = semantics.element; | 2450 LocalFunctionElementX function = semantics.element; |
2568 function.computeType(resolution); | 2451 function.computeType(resolution); |
2569 if (!callStructure.signatureApplies(function.functionSignature)) { | 2452 if (!callStructure.signatureApplies(function.functionSignature)) { |
2570 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2453 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2571 registry.registerDynamicUse( | 2454 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2572 new DynamicUse(selector, null)); | |
2573 isIncompatibleInvoke = true; | 2455 isIncompatibleInvoke = true; |
2574 } | 2456 } |
2575 break; | 2457 break; |
2576 case AccessKind.PARAMETER: | 2458 case AccessKind.PARAMETER: |
2577 case AccessKind.FINAL_PARAMETER: | 2459 case AccessKind.FINAL_PARAMETER: |
2578 case AccessKind.LOCAL_VARIABLE: | 2460 case AccessKind.LOCAL_VARIABLE: |
2579 case AccessKind.FINAL_LOCAL_VARIABLE: | 2461 case AccessKind.FINAL_LOCAL_VARIABLE: |
2580 selector = callStructure.callSelector; | 2462 selector = callStructure.callSelector; |
2581 registry.registerDynamicUse( | 2463 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2582 new DynamicUse(selector, null)); | |
2583 break; | 2464 break; |
2584 default: | 2465 default: |
2585 reporter.internalError(node, | 2466 reporter.internalError(node, "Unexpected local access $semantics."); |
2586 "Unexpected local access $semantics."); | |
2587 break; | 2467 break; |
2588 } | 2468 } |
2589 registry.registerSendStructure(node, | 2469 registry.registerSendStructure( |
| 2470 node, |
2590 isIncompatibleInvoke | 2471 isIncompatibleInvoke |
2591 ? new IncompatibleInvokeStructure(semantics, selector) | 2472 ? new IncompatibleInvokeStructure(semantics, selector) |
2592 : new InvokeStructure(semantics, selector)); | 2473 : new InvokeStructure(semantics, selector)); |
2593 } else { | 2474 } else { |
2594 switch (semantics.kind) { | 2475 switch (semantics.kind) { |
2595 case AccessKind.LOCAL_VARIABLE: | 2476 case AccessKind.LOCAL_VARIABLE: |
2596 case AccessKind.LOCAL_FUNCTION: | 2477 case AccessKind.LOCAL_FUNCTION: |
2597 result = new ElementResult(element); | 2478 result = new ElementResult(element); |
2598 break; | 2479 break; |
2599 case AccessKind.PARAMETER: | 2480 case AccessKind.PARAMETER: |
2600 case AccessKind.FINAL_PARAMETER: | 2481 case AccessKind.FINAL_PARAMETER: |
2601 if (constantState == ConstantState.CONSTANT_INITIALIZER) { | 2482 if (constantState == ConstantState.CONSTANT_INITIALIZER) { |
2602 ParameterElement parameter = element; | 2483 ParameterElement parameter = element; |
2603 if (parameter.isNamed) { | 2484 if (parameter.isNamed) { |
2604 result = new ConstantResult( | 2485 result = new ConstantResult( |
2605 node, | 2486 node, new NamedArgumentReference(parameter.name), |
2606 new NamedArgumentReference(parameter.name), | |
2607 element: element); | 2487 element: element); |
2608 } else { | 2488 } else { |
2609 result = new ConstantResult( | 2489 result = new ConstantResult( |
2610 node, | 2490 node, |
2611 new PositionalArgumentReference( | 2491 new PositionalArgumentReference(parameter |
2612 parameter.functionDeclaration.parameters.indexOf( | 2492 .functionDeclaration.parameters |
2613 parameter)), | 2493 .indexOf(parameter)), |
2614 element: element); | 2494 element: element); |
2615 } | 2495 } |
2616 } else { | 2496 } else { |
2617 result = new ElementResult(element); | 2497 result = new ElementResult(element); |
2618 } | 2498 } |
2619 break; | 2499 break; |
2620 case AccessKind.FINAL_LOCAL_VARIABLE: | 2500 case AccessKind.FINAL_LOCAL_VARIABLE: |
2621 if (element.isConst) { | 2501 if (element.isConst) { |
2622 result = new ConstantResult( | 2502 result = new ConstantResult( |
2623 node, | 2503 node, new VariableConstantExpression(element), |
2624 new VariableConstantExpression(element), | |
2625 element: element); | 2504 element: element); |
2626 } else { | 2505 } else { |
2627 result = new ElementResult(element); | 2506 result = new ElementResult(element); |
2628 } | 2507 } |
2629 break; | 2508 break; |
2630 default: | 2509 default: |
2631 reporter.internalError(node, | 2510 reporter.internalError(node, "Unexpected local access $semantics."); |
2632 "Unexpected local access $semantics."); | |
2633 break; | 2511 break; |
2634 } | 2512 } |
2635 selector = new Selector.getter(name); | 2513 selector = new Selector.getter(name); |
2636 registry.registerSendStructure(node, new GetStructure(semantics)); | 2514 registry.registerSendStructure(node, new GetStructure(semantics)); |
2637 } | 2515 } |
2638 | 2516 |
2639 // TODO(23998): Remove these when all information goes through | 2517 // TODO(23998): Remove these when all information goes through |
2640 // the [SendStructure]. | 2518 // the [SendStructure]. |
2641 registry.useElement(node, element); | 2519 registry.useElement(node, element); |
2642 registry.setSelector(node, selector); | 2520 registry.setSelector(node, selector); |
2643 | 2521 |
2644 registerPotentialAccessInClosure(node, element); | 2522 registerPotentialAccessInClosure(node, element); |
2645 | 2523 |
2646 return result; | 2524 return result; |
2647 } | 2525 } |
2648 | 2526 |
2649 /// Handle update of a parameter, local variable or local function. | 2527 /// Handle update of a parameter, local variable or local function. |
2650 ResolutionResult handleLocalUpdate(Send node, Name name, Element element) { | 2528 ResolutionResult handleLocalUpdate(Send node, Name name, Element element) { |
2651 AccessSemantics semantics; | 2529 AccessSemantics semantics; |
2652 ErroneousElement error; | 2530 ErroneousElement error; |
2653 if (element.isParameter) { | 2531 if (element.isParameter) { |
2654 if (element.isFinal) { | 2532 if (element.isFinal) { |
2655 error = reportAndCreateErroneousElement( | 2533 error = reportAndCreateErroneousElement(node.selector, name.text, |
2656 node.selector, name.text, | 2534 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
2657 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | |
2658 {'name': name}); | |
2659 semantics = new StaticAccess.finalParameter(element); | 2535 semantics = new StaticAccess.finalParameter(element); |
2660 } else { | 2536 } else { |
2661 semantics = new StaticAccess.parameter(element); | 2537 semantics = new StaticAccess.parameter(element); |
2662 } | 2538 } |
2663 } else if (element.isVariable) { | 2539 } else if (element.isVariable) { |
2664 if (element.isFinal || element.isConst) { | 2540 if (element.isFinal || element.isConst) { |
2665 error = reportAndCreateErroneousElement( | 2541 error = reportAndCreateErroneousElement(node.selector, name.text, |
2666 node.selector, name.text, | 2542 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, {'name': name}); |
2667 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | |
2668 {'name': name}); | |
2669 semantics = new StaticAccess.finalLocalVariable(element); | 2543 semantics = new StaticAccess.finalLocalVariable(element); |
2670 } else { | 2544 } else { |
2671 semantics = new StaticAccess.localVariable(element); | 2545 semantics = new StaticAccess.localVariable(element); |
2672 } | 2546 } |
2673 } else { | 2547 } else { |
2674 assert(invariant(node, element.isFunction, | 2548 assert(invariant(node, element.isFunction, |
2675 message: "Unexpected local $element.")); | 2549 message: "Unexpected local $element.")); |
2676 error = reportAndCreateErroneousElement( | 2550 error = reportAndCreateErroneousElement( |
2677 node.selector, name.text, | 2551 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); |
2678 MessageKind.ASSIGNING_METHOD, const {}); | |
2679 semantics = new StaticAccess.localFunction(element); | 2552 semantics = new StaticAccess.localFunction(element); |
2680 } | 2553 } |
2681 if (isPotentiallyMutableTarget(element)) { | 2554 if (isPotentiallyMutableTarget(element)) { |
2682 registry.registerPotentialMutation(element, node); | 2555 registry.registerPotentialMutation(element, node); |
2683 if (enclosingElement != element.enclosingElement) { | 2556 if (enclosingElement != element.enclosingElement) { |
2684 registry.registerPotentialMutationInClosure(element, node); | 2557 registry.registerPotentialMutationInClosure(element, node); |
2685 } | 2558 } |
2686 for (Node scope in promotionScope) { | 2559 for (Node scope in promotionScope) { |
2687 registry.registerPotentialMutationIn(scope, element, node); | 2560 registry.registerPotentialMutationIn(scope, element, node); |
2688 } | 2561 } |
2689 } | 2562 } |
2690 | 2563 |
2691 ResolutionResult result = handleUpdate(node, name, semantics); | 2564 ResolutionResult result = handleUpdate(node, name, semantics); |
2692 if (error != null) { | 2565 if (error != null) { |
2693 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2566 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2694 // TODO(23998): Remove this when all information goes through | 2567 // TODO(23998): Remove this when all information goes through |
2695 // the [SendStructure]. | 2568 // the [SendStructure]. |
2696 registry.useElement(node, error); | 2569 registry.useElement(node, error); |
2697 } | 2570 } |
2698 return result; | 2571 return result; |
2699 } | 2572 } |
2700 | 2573 |
2701 /// Handle access of a static or top level [element]. | 2574 /// Handle access of a static or top level [element]. |
2702 ResolutionResult handleStaticOrTopLevelAccess( | 2575 ResolutionResult handleStaticOrTopLevelAccess( |
2703 Send node, Name name, Element element) { | 2576 Send node, Name name, Element element) { |
2704 ResolutionResult result = const NoneResult(); | 2577 ResolutionResult result = const NoneResult(); |
2705 MemberElement member; | 2578 MemberElement member; |
2706 if (element.isAbstractField) { | 2579 if (element.isAbstractField) { |
2707 AbstractFieldElement abstractField = element; | 2580 AbstractFieldElement abstractField = element; |
2708 if (abstractField.getter != null) { | 2581 if (abstractField.getter != null) { |
2709 member = abstractField.getter; | 2582 member = abstractField.getter; |
2710 } else { | 2583 } else { |
2711 member = abstractField.setter; | 2584 member = abstractField.setter; |
2712 } | 2585 } |
2713 } else { | 2586 } else { |
2714 member = element; | 2587 member = element; |
2715 } | 2588 } |
2716 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2589 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2717 // of parse errors to make [element] erroneous. Fix this! | 2590 // of parse errors to make [element] erroneous. Fix this! |
2718 member.computeType(resolution); | 2591 member.computeType(resolution); |
2719 | 2592 |
2720 | |
2721 if (member == compiler.mirrorSystemGetNameFunction && | 2593 if (member == compiler.mirrorSystemGetNameFunction && |
2722 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 2594 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
2723 reporter.reportHintMessage( | 2595 reporter |
2724 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 2596 .reportHintMessage(node.selector, MessageKind.STATIC_FUNCTION_BLOAT, { |
2725 {'class': compiler.mirrorSystemClass.name, | 2597 'class': compiler.mirrorSystemClass.name, |
2726 'name': compiler.mirrorSystemGetNameFunction.name}); | 2598 'name': compiler.mirrorSystemGetNameFunction.name |
| 2599 }); |
2727 } | 2600 } |
2728 | 2601 |
2729 Selector selector; | 2602 Selector selector; |
2730 AccessSemantics semantics = | 2603 AccessSemantics semantics = |
2731 computeStaticOrTopLevelAccessSemantics(node, member); | 2604 computeStaticOrTopLevelAccessSemantics(node, member); |
2732 if (node.isCall) { | 2605 if (node.isCall) { |
2733 ArgumentsResult argumentsResult = | 2606 ArgumentsResult argumentsResult = resolveArguments(node.argumentsNode); |
2734 resolveArguments(node.argumentsNode); | |
2735 CallStructure callStructure = argumentsResult.callStructure; | 2607 CallStructure callStructure = argumentsResult.callStructure; |
2736 selector = new Selector.call(name, callStructure); | 2608 selector = new Selector.call(name, callStructure); |
2737 | 2609 |
2738 bool isIncompatibleInvoke = false; | 2610 bool isIncompatibleInvoke = false; |
2739 switch (semantics.kind) { | 2611 switch (semantics.kind) { |
2740 case AccessKind.STATIC_METHOD: | 2612 case AccessKind.STATIC_METHOD: |
2741 case AccessKind.TOPLEVEL_METHOD: | 2613 case AccessKind.TOPLEVEL_METHOD: |
2742 MethodElement method = semantics.element; | 2614 MethodElement method = semantics.element; |
2743 method.computeType(resolution); | 2615 method.computeType(resolution); |
2744 if (!callStructure.signatureApplies(method.functionSignature)) { | 2616 if (!callStructure.signatureApplies(method.functionSignature)) { |
2745 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2617 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2746 registry.registerDynamicUse( | 2618 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2747 new DynamicUse(selector, null)); | |
2748 isIncompatibleInvoke = true; | 2619 isIncompatibleInvoke = true; |
2749 } else { | 2620 } else { |
2750 registry.registerStaticUse( | 2621 registry.registerStaticUse( |
2751 new StaticUse.staticInvoke(semantics.element, callStructure)); | 2622 new StaticUse.staticInvoke(semantics.element, callStructure)); |
2752 handleForeignCall(node, semantics.element, callStructure); | 2623 handleForeignCall(node, semantics.element, callStructure); |
2753 if (method == compiler.identicalFunction && | 2624 if (method == compiler.identicalFunction && |
2754 argumentsResult.isValidAsConstant) { | 2625 argumentsResult.isValidAsConstant) { |
2755 result = new ConstantResult(node, | 2626 result = new ConstantResult( |
| 2627 node, |
2756 new IdenticalConstantExpression( | 2628 new IdenticalConstantExpression( |
2757 argumentsResult.argumentResults[0].constant, | 2629 argumentsResult.argumentResults[0].constant, |
2758 argumentsResult.argumentResults[1].constant)); | 2630 argumentsResult.argumentResults[1].constant)); |
2759 } | 2631 } |
2760 } | 2632 } |
2761 break; | 2633 break; |
2762 case AccessKind.STATIC_FIELD: | 2634 case AccessKind.STATIC_FIELD: |
2763 case AccessKind.FINAL_STATIC_FIELD: | 2635 case AccessKind.FINAL_STATIC_FIELD: |
2764 case AccessKind.STATIC_GETTER: | 2636 case AccessKind.STATIC_GETTER: |
2765 case AccessKind.TOPLEVEL_FIELD: | 2637 case AccessKind.TOPLEVEL_FIELD: |
2766 case AccessKind.FINAL_TOPLEVEL_FIELD: | 2638 case AccessKind.FINAL_TOPLEVEL_FIELD: |
2767 case AccessKind.TOPLEVEL_GETTER: | 2639 case AccessKind.TOPLEVEL_GETTER: |
2768 registry.registerStaticUse( | 2640 registry |
2769 new StaticUse.staticGet(semantics.element)); | 2641 .registerStaticUse(new StaticUse.staticGet(semantics.element)); |
2770 selector = callStructure.callSelector; | 2642 selector = callStructure.callSelector; |
2771 registry.registerDynamicUse( | 2643 registry.registerDynamicUse(new DynamicUse(selector, null)); |
2772 new DynamicUse(selector, null)); | |
2773 break; | 2644 break; |
2774 case AccessKind.STATIC_SETTER: | 2645 case AccessKind.STATIC_SETTER: |
2775 case AccessKind.TOPLEVEL_SETTER: | 2646 case AccessKind.TOPLEVEL_SETTER: |
2776 case AccessKind.UNRESOLVED: | 2647 case AccessKind.UNRESOLVED: |
2777 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2648 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2778 member = reportAndCreateErroneousElement( | 2649 member = reportAndCreateErroneousElement(node.selector, name.text, |
2779 node.selector, name.text, | 2650 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name}); |
2780 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | |
2781 {'name': name}); | |
2782 break; | 2651 break; |
2783 default: | 2652 default: |
2784 reporter.internalError(node, | 2653 reporter.internalError( |
2785 "Unexpected statically resolved access $semantics."); | 2654 node, "Unexpected statically resolved access $semantics."); |
2786 break; | 2655 break; |
2787 } | 2656 } |
2788 registry.registerSendStructure(node, | 2657 registry.registerSendStructure( |
| 2658 node, |
2789 isIncompatibleInvoke | 2659 isIncompatibleInvoke |
2790 ? new IncompatibleInvokeStructure(semantics, selector) | 2660 ? new IncompatibleInvokeStructure(semantics, selector) |
2791 : new InvokeStructure(semantics, selector)); | 2661 : new InvokeStructure(semantics, selector)); |
2792 } else { | 2662 } else { |
2793 selector = new Selector.getter(name); | 2663 selector = new Selector.getter(name); |
2794 switch (semantics.kind) { | 2664 switch (semantics.kind) { |
2795 case AccessKind.STATIC_METHOD: | 2665 case AccessKind.STATIC_METHOD: |
2796 case AccessKind.TOPLEVEL_METHOD: | 2666 case AccessKind.TOPLEVEL_METHOD: |
2797 registry.registerStaticUse( | 2667 registry.registerStaticUse( |
2798 new StaticUse.staticTearOff(semantics.element)); | 2668 new StaticUse.staticTearOff(semantics.element)); |
2799 break; | 2669 break; |
2800 case AccessKind.STATIC_FIELD: | 2670 case AccessKind.STATIC_FIELD: |
2801 case AccessKind.FINAL_STATIC_FIELD: | 2671 case AccessKind.FINAL_STATIC_FIELD: |
2802 case AccessKind.STATIC_GETTER: | 2672 case AccessKind.STATIC_GETTER: |
2803 case AccessKind.TOPLEVEL_FIELD: | 2673 case AccessKind.TOPLEVEL_FIELD: |
2804 case AccessKind.FINAL_TOPLEVEL_FIELD: | 2674 case AccessKind.FINAL_TOPLEVEL_FIELD: |
2805 case AccessKind.TOPLEVEL_GETTER: | 2675 case AccessKind.TOPLEVEL_GETTER: |
2806 registry.registerStaticUse( | 2676 registry |
2807 new StaticUse.staticGet(semantics.element)); | 2677 .registerStaticUse(new StaticUse.staticGet(semantics.element)); |
2808 break; | 2678 break; |
2809 case AccessKind.STATIC_SETTER: | 2679 case AccessKind.STATIC_SETTER: |
2810 case AccessKind.TOPLEVEL_SETTER: | 2680 case AccessKind.TOPLEVEL_SETTER: |
2811 case AccessKind.UNRESOLVED: | 2681 case AccessKind.UNRESOLVED: |
2812 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2682 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2813 member = reportAndCreateErroneousElement( | 2683 member = reportAndCreateErroneousElement(node.selector, name.text, |
2814 node.selector, name.text, | 2684 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, {'name': name}); |
2815 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | |
2816 {'name': name}); | |
2817 break; | 2685 break; |
2818 default: | 2686 default: |
2819 reporter.internalError(node, | 2687 reporter.internalError( |
2820 "Unexpected statically resolved access $semantics."); | 2688 node, "Unexpected statically resolved access $semantics."); |
2821 break; | 2689 break; |
2822 } | 2690 } |
2823 registry.registerSendStructure(node, new GetStructure(semantics)); | 2691 registry.registerSendStructure(node, new GetStructure(semantics)); |
2824 if (member.isConst) { | 2692 if (member.isConst) { |
2825 FieldElement field = member; | 2693 FieldElement field = member; |
2826 result = new ConstantResult( | 2694 result = new ConstantResult(node, new VariableConstantExpression(field), |
2827 node, new VariableConstantExpression(field), element: field); | 2695 element: field); |
2828 } else { | 2696 } else { |
2829 result = new ElementResult(member); | 2697 result = new ElementResult(member); |
2830 } | 2698 } |
2831 } | 2699 } |
2832 | 2700 |
2833 // TODO(23998): Remove these when all information goes through | 2701 // TODO(23998): Remove these when all information goes through |
2834 // the [SendStructure]. | 2702 // the [SendStructure]. |
2835 registry.useElement(node, member); | 2703 registry.useElement(node, member); |
2836 registry.setSelector(node, selector); | 2704 registry.setSelector(node, selector); |
2837 | 2705 |
2838 return result; | 2706 return result; |
2839 } | 2707 } |
2840 | 2708 |
2841 /// Handle update of a static or top level [element]. | 2709 /// Handle update of a static or top level [element]. |
2842 ResolutionResult handleStaticOrTopLevelUpdate( | 2710 ResolutionResult handleStaticOrTopLevelUpdate( |
2843 SendSet node, Name name, Element element) { | 2711 SendSet node, Name name, Element element) { |
2844 AccessSemantics semantics; | 2712 AccessSemantics semantics; |
2845 if (element.isAbstractField) { | 2713 if (element.isAbstractField) { |
2846 AbstractFieldElement abstractField = element; | 2714 AbstractFieldElement abstractField = element; |
2847 if (abstractField.setter == null) { | 2715 if (abstractField.setter == null) { |
2848 ErroneousElement error = reportAndCreateErroneousElement( | 2716 ErroneousElement error = reportAndCreateErroneousElement( |
2849 node.selector, name.text, | 2717 node.selector, |
| 2718 name.text, |
2850 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | 2719 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, |
2851 {'name': name}); | 2720 {'name': name}); |
2852 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2721 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2853 | 2722 |
2854 if (node.isComplex) { | 2723 if (node.isComplex) { |
2855 // `a++` or `a += b` where `a` has no setter. | 2724 // `a++` or `a += b` where `a` has no setter. |
2856 semantics = new CompoundAccessSemantics( | 2725 semantics = new CompoundAccessSemantics( |
2857 element.isTopLevel | 2726 element.isTopLevel |
2858 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER | 2727 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER |
2859 : CompoundAccessKind.UNRESOLVED_STATIC_SETTER, | 2728 : CompoundAccessKind.UNRESOLVED_STATIC_SETTER, |
2860 abstractField.getter, | 2729 abstractField.getter, |
2861 error); | 2730 error); |
2862 } else { | 2731 } else { |
2863 // `a = b` where `a` has no setter. | 2732 // `a = b` where `a` has no setter. |
2864 semantics = element.isTopLevel | 2733 semantics = element.isTopLevel |
2865 ? new StaticAccess.topLevelGetter(abstractField.getter) | 2734 ? new StaticAccess.topLevelGetter(abstractField.getter) |
2866 : new StaticAccess.staticGetter(abstractField.getter); | 2735 : new StaticAccess.staticGetter(abstractField.getter); |
2867 } | 2736 } |
2868 registry.registerStaticUse( | 2737 registry |
2869 new StaticUse.staticGet(abstractField.getter)); | 2738 .registerStaticUse(new StaticUse.staticGet(abstractField.getter)); |
2870 } else if (node.isComplex) { | 2739 } else if (node.isComplex) { |
2871 if (abstractField.getter == null) { | 2740 if (abstractField.getter == null) { |
2872 ErroneousElement error = reportAndCreateErroneousElement( | 2741 ErroneousElement error = reportAndCreateErroneousElement( |
2873 node.selector, name.text, | 2742 node.selector, |
| 2743 name.text, |
2874 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, | 2744 MessageKind.UNDEFINED_STATIC_GETTER_BUT_SETTER, |
2875 {'name': name}); | 2745 {'name': name}); |
2876 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2746 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2877 // `a++` or `a += b` where `a` has no getter. | 2747 // `a++` or `a += b` where `a` has no getter. |
2878 semantics = new CompoundAccessSemantics( | 2748 semantics = new CompoundAccessSemantics( |
2879 element.isTopLevel | 2749 element.isTopLevel |
2880 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER | 2750 ? CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER |
2881 : CompoundAccessKind.UNRESOLVED_STATIC_GETTER, | 2751 : CompoundAccessKind.UNRESOLVED_STATIC_GETTER, |
2882 error, | 2752 error, |
2883 abstractField.setter); | 2753 abstractField.setter); |
2884 registry.registerStaticUse( | 2754 registry |
2885 new StaticUse.staticSet(abstractField.setter)); | 2755 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
2886 } else { | 2756 } else { |
2887 // `a++` or `a += b` where `a` has both a getter and a setter. | 2757 // `a++` or `a += b` where `a` has both a getter and a setter. |
2888 semantics = new CompoundAccessSemantics( | 2758 semantics = new CompoundAccessSemantics( |
2889 element.isTopLevel | 2759 element.isTopLevel |
2890 ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER | 2760 ? CompoundAccessKind.TOPLEVEL_GETTER_SETTER |
2891 : CompoundAccessKind.STATIC_GETTER_SETTER, | 2761 : CompoundAccessKind.STATIC_GETTER_SETTER, |
2892 abstractField.getter, | 2762 abstractField.getter, |
2893 abstractField.setter); | 2763 abstractField.setter); |
2894 registry.registerStaticUse( | 2764 registry |
2895 new StaticUse.staticGet(abstractField.getter)); | 2765 .registerStaticUse(new StaticUse.staticGet(abstractField.getter)); |
2896 registry.registerStaticUse( | 2766 registry |
2897 new StaticUse.staticSet(abstractField.setter)); | 2767 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
2898 } | 2768 } |
2899 } else { | 2769 } else { |
2900 // `a = b` where `a` has a setter. | 2770 // `a = b` where `a` has a setter. |
2901 semantics = element.isTopLevel | 2771 semantics = element.isTopLevel |
2902 ? new StaticAccess.topLevelSetter(abstractField.setter) | 2772 ? new StaticAccess.topLevelSetter(abstractField.setter) |
2903 : new StaticAccess.staticSetter(abstractField.setter); | 2773 : new StaticAccess.staticSetter(abstractField.setter); |
2904 registry.registerStaticUse( | 2774 registry |
2905 new StaticUse.staticSet(abstractField.setter)); | 2775 .registerStaticUse(new StaticUse.staticSet(abstractField.setter)); |
2906 } | 2776 } |
2907 } else { | 2777 } else { |
2908 MemberElement member = element; | 2778 MemberElement member = element; |
2909 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery | 2779 // TODO(johnniwinther): Needed to provoke a parsing and with it discovery |
2910 // of parse errors to make [element] erroneous. Fix this! | 2780 // of parse errors to make [element] erroneous. Fix this! |
2911 member.computeType(resolution); | 2781 member.computeType(resolution); |
2912 if (member.isMalformed) { | 2782 if (member.isMalformed) { |
2913 // [member] has parse errors. | 2783 // [member] has parse errors. |
2914 semantics = new StaticAccess.unresolved(member); | 2784 semantics = new StaticAccess.unresolved(member); |
2915 } else if (member.isFunction) { | 2785 } else if (member.isFunction) { |
2916 // `a = b`, `a++` or `a += b` where `a` is a function. | 2786 // `a = b`, `a++` or `a += b` where `a` is a function. |
2917 ErroneousElement error = reportAndCreateErroneousElement( | 2787 ErroneousElement error = reportAndCreateErroneousElement( |
2918 node.selector, name.text, | 2788 node.selector, name.text, MessageKind.ASSIGNING_METHOD, const {}); |
2919 MessageKind.ASSIGNING_METHOD, const {}); | |
2920 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2789 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2921 if (node.isComplex) { | 2790 if (node.isComplex) { |
2922 // `a++` or `a += b` where `a` is a function. | 2791 // `a++` or `a += b` where `a` is a function. |
2923 registry.registerStaticUse( | 2792 registry.registerStaticUse(new StaticUse.staticTearOff(element)); |
2924 new StaticUse.staticTearOff(element)); | |
2925 } | 2793 } |
2926 semantics = member.isTopLevel | 2794 semantics = member.isTopLevel |
2927 ? new StaticAccess.topLevelMethod(member) | 2795 ? new StaticAccess.topLevelMethod(member) |
2928 : new StaticAccess.staticMethod(member); | 2796 : new StaticAccess.staticMethod(member); |
2929 } else { | 2797 } else { |
2930 // `a = b`, `a++` or `a += b` where `a` is a field. | 2798 // `a = b`, `a++` or `a += b` where `a` is a field. |
2931 assert(invariant(node, member.isField, | 2799 assert(invariant(node, member.isField, |
2932 message: "Unexpected element: $member.")); | 2800 message: "Unexpected element: $member.")); |
2933 if (node.isComplex) { | 2801 if (node.isComplex) { |
2934 // `a++` or `a += b` where `a` is a field. | 2802 // `a++` or `a += b` where `a` is a field. |
2935 registry.registerStaticUse(new StaticUse.staticGet(member)); | 2803 registry.registerStaticUse(new StaticUse.staticGet(member)); |
2936 } | 2804 } |
2937 if (member.isFinal || member.isConst) { | 2805 if (member.isFinal || member.isConst) { |
2938 ErroneousElement error = reportAndCreateErroneousElement( | 2806 ErroneousElement error = reportAndCreateErroneousElement( |
2939 node.selector, name.text, | 2807 node.selector, |
2940 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, | 2808 name.text, |
2941 {'name': name}); | 2809 MessageKind.UNDEFINED_STATIC_SETTER_BUT_GETTER, |
| 2810 {'name': name}); |
2942 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 2811 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
2943 semantics = member.isTopLevel | 2812 semantics = member.isTopLevel |
2944 ? new StaticAccess.finalTopLevelField(member) | 2813 ? new StaticAccess.finalTopLevelField(member) |
2945 : new StaticAccess.finalStaticField(member); | 2814 : new StaticAccess.finalStaticField(member); |
2946 } else { | 2815 } else { |
2947 registry.registerStaticUse(new StaticUse.staticSet(member)); | 2816 registry.registerStaticUse(new StaticUse.staticSet(member)); |
2948 semantics = member.isTopLevel | 2817 semantics = member.isTopLevel |
2949 ? new StaticAccess.topLevelField(member) | 2818 ? new StaticAccess.topLevelField(member) |
2950 : new StaticAccess.staticField(member); | 2819 : new StaticAccess.staticField(member); |
2951 } | 2820 } |
2952 } | 2821 } |
2953 } | 2822 } |
2954 return handleUpdate(node, name, semantics); | 2823 return handleUpdate(node, name, semantics); |
2955 } | 2824 } |
2956 | 2825 |
2957 /// Handle access to resolved [element]. | 2826 /// Handle access to resolved [element]. |
2958 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { | 2827 ResolutionResult handleResolvedSend(Send node, Name name, Element element) { |
2959 if (element.isAmbiguous) { | 2828 if (element.isAmbiguous) { |
2960 return handleAmbiguousSend(node, name, element); | 2829 return handleAmbiguousSend(node, name, element); |
2961 } | 2830 } |
2962 if (element.isMalformed) { | 2831 if (element.isMalformed) { |
2963 // This handles elements with parser errors. | 2832 // This handles elements with parser errors. |
2964 assert(invariant(node, element is! ErroneousElement, | 2833 assert(invariant(node, element is! ErroneousElement, |
2965 message: "Unexpected erroneous element $element.")); | 2834 message: "Unexpected erroneous element $element.")); |
2966 return handleErroneousAccess(node, name, | 2835 return handleErroneousAccess( |
2967 new StaticAccess.unresolved(element)); | 2836 node, name, new StaticAccess.unresolved(element)); |
2968 } | 2837 } |
2969 if (element.isInstanceMember) { | 2838 if (element.isInstanceMember) { |
2970 if (inInstanceContext) { | 2839 if (inInstanceContext) { |
2971 // TODO(johnniwinther): Maybe use the found [element]. | 2840 // TODO(johnniwinther): Maybe use the found [element]. |
2972 return handleThisPropertyAccess(node, name); | 2841 return handleThisPropertyAccess(node, name); |
2973 } else { | 2842 } else { |
2974 return handleErroneousAccess( | 2843 return handleErroneousAccess( |
2975 node, name, reportStaticInstanceAccess(node, name)); | 2844 node, name, reportStaticInstanceAccess(node, name)); |
2976 } | 2845 } |
2977 } | 2846 } |
(...skipping 18 matching lines...) Expand all Loading... |
2996 /// Handle update to resolved [element]. | 2865 /// Handle update to resolved [element]. |
2997 ResolutionResult handleResolvedSendSet( | 2866 ResolutionResult handleResolvedSendSet( |
2998 SendSet node, Name name, Element element) { | 2867 SendSet node, Name name, Element element) { |
2999 if (element.isAmbiguous) { | 2868 if (element.isAmbiguous) { |
3000 return handleAmbiguousUpdate(node, name, element); | 2869 return handleAmbiguousUpdate(node, name, element); |
3001 } | 2870 } |
3002 if (element.isMalformed) { | 2871 if (element.isMalformed) { |
3003 // This handles elements with parser errors.. | 2872 // This handles elements with parser errors.. |
3004 assert(invariant(node, element is! ErroneousElement, | 2873 assert(invariant(node, element is! ErroneousElement, |
3005 message: "Unexpected erroneous element $element.")); | 2874 message: "Unexpected erroneous element $element.")); |
3006 return handleUpdate(node, name,new StaticAccess.unresolved(element)); | 2875 return handleUpdate(node, name, new StaticAccess.unresolved(element)); |
3007 } | 2876 } |
3008 if (element.isInstanceMember) { | 2877 if (element.isInstanceMember) { |
3009 if (inInstanceContext) { | 2878 if (inInstanceContext) { |
3010 return handleThisPropertyUpdate(node, name, element); | 2879 return handleThisPropertyUpdate(node, name, element); |
3011 } else { | 2880 } else { |
3012 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); | 2881 return handleUpdate(node, name, reportStaticInstanceAccess(node, name)); |
3013 } | 2882 } |
3014 } | 2883 } |
3015 if (element.isClass) { | 2884 if (element.isClass) { |
3016 // `C = b`, `C++`, or 'C += b` where 'C' is a class. | 2885 // `C = b`, `C++`, or 'C += b` where 'C' is a class. |
3017 return handleClassTypeLiteralUpdate(node, name, element); | 2886 return handleClassTypeLiteralUpdate(node, name, element); |
3018 } else if (element.isTypedef) { | 2887 } else if (element.isTypedef) { |
3019 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. | 2888 // `C = b`, `C++`, or 'C += b` where 'F' is a typedef. |
3020 return handleTypedefTypeLiteralUpdate(node, name, element); | 2889 return handleTypedefTypeLiteralUpdate(node, name, element); |
3021 } else if (element.isTypeVariable) { | 2890 } else if (element.isTypeVariable) { |
3022 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. | 2891 // `T = b`, `T++`, or 'T += b` where 'T' is a type variable. |
3023 return handleTypeVariableTypeLiteralUpdate(node, name, element); | 2892 return handleTypeVariableTypeLiteralUpdate(node, name, element); |
3024 } else if (element.isPrefix) { | 2893 } else if (element.isPrefix) { |
3025 // `p = b` where `p` is a prefix. | 2894 // `p = b` where `p` is a prefix. |
3026 ErroneousElement error = reportAndCreateErroneousElement( | 2895 ErroneousElement error = reportAndCreateErroneousElement( |
3027 node, | 2896 node, name.text, MessageKind.PREFIX_AS_EXPRESSION, {'prefix': name}, |
3028 name.text, | 2897 isError: true); |
3029 MessageKind.PREFIX_AS_EXPRESSION, | |
3030 {'prefix': name}, | |
3031 isError: true); | |
3032 registry.registerFeature(Feature.COMPILE_TIME_ERROR); | 2898 registry.registerFeature(Feature.COMPILE_TIME_ERROR); |
3033 return handleUpdate( | 2899 return handleUpdate(node, name, new StaticAccess.invalid(error)); |
3034 node, name, new StaticAccess.invalid(error)); | |
3035 } else if (element.isLocal) { | 2900 } else if (element.isLocal) { |
3036 return handleLocalUpdate(node, name, element); | 2901 return handleLocalUpdate(node, name, element); |
3037 } else if (element.isStatic || element.isTopLevel) { | 2902 } else if (element.isStatic || element.isTopLevel) { |
3038 return handleStaticOrTopLevelUpdate(node, name, element); | 2903 return handleStaticOrTopLevelUpdate(node, name, element); |
3039 } | 2904 } |
3040 return reporter.internalError(node, "Unexpected resolved send: $element"); | 2905 return reporter.internalError(node, "Unexpected resolved send: $element"); |
3041 } | 2906 } |
3042 | 2907 |
3043 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 2908 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
3044 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 2909 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3117 if (isPotentiallyMutableTarget(target)) { | 2982 if (isPotentiallyMutableTarget(target)) { |
3118 if (enclosingElement != target.enclosingElement) { | 2983 if (enclosingElement != target.enclosingElement) { |
3119 for (Node scope in promotionScope) { | 2984 for (Node scope in promotionScope) { |
3120 registry.setAccessedByClosureIn(scope, target, node); | 2985 registry.setAccessedByClosureIn(scope, target, node); |
3121 } | 2986 } |
3122 } | 2987 } |
3123 } | 2988 } |
3124 } | 2989 } |
3125 | 2990 |
3126 // TODO(johnniwinther): Move this to the backend resolution callbacks. | 2991 // TODO(johnniwinther): Move this to the backend resolution callbacks. |
3127 void handleForeignCall(Send node, | 2992 void handleForeignCall( |
3128 Element target, | 2993 Send node, Element target, CallStructure callStructure) { |
3129 CallStructure callStructure) { | |
3130 if (target != null && compiler.backend.isForeign(target)) { | 2994 if (target != null && compiler.backend.isForeign(target)) { |
3131 registry.registerForeignCall(node, target, callStructure, this); | 2995 registry.registerForeignCall(node, target, callStructure, this); |
3132 } | 2996 } |
3133 } | 2997 } |
3134 | 2998 |
3135 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 2999 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
3136 DartType resolveTypeFromString(Node node, String typeName) { | 3000 DartType resolveTypeFromString(Node node, String typeName) { |
3137 Element element = lookupInScope(reporter, node, scope, typeName); | 3001 Element element = lookupInScope(reporter, node, scope, typeName); |
3138 if (element == null) return null; | 3002 if (element == null) return null; |
3139 if (element is! ClassElement) return null; | 3003 if (element is! ClassElement) return null; |
(...skipping 17 matching lines...) Expand all Loading... |
3157 Selector setterSelector = new Selector.indexSet(); | 3021 Selector setterSelector = new Selector.indexSet(); |
3158 Selector operatorSelector = | 3022 Selector operatorSelector = |
3159 new Selector.binaryOperator(operator.selectorName); | 3023 new Selector.binaryOperator(operator.selectorName); |
3160 | 3024 |
3161 // TODO(23998): Remove these when selectors are only accessed | 3025 // TODO(23998): Remove these when selectors are only accessed |
3162 // through the send structure. | 3026 // through the send structure. |
3163 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3027 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3164 registry.setSelector(node, setterSelector); | 3028 registry.setSelector(node, setterSelector); |
3165 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3029 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3166 | 3030 |
3167 registry.registerDynamicUse( | 3031 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
3168 new DynamicUse(getterSelector, null)); | 3032 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
3169 registry.registerDynamicUse( | 3033 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3170 new DynamicUse(setterSelector, null)); | |
3171 registry.registerDynamicUse( | |
3172 new DynamicUse(operatorSelector, null)); | |
3173 | 3034 |
3174 SendStructure sendStructure = node.isPrefix | 3035 SendStructure sendStructure = node.isPrefix |
3175 ? new IndexPrefixStructure(semantics, operator) | 3036 ? new IndexPrefixStructure(semantics, operator) |
3176 : new IndexPostfixStructure(semantics, operator); | 3037 : new IndexPostfixStructure(semantics, operator); |
3177 registry.registerSendStructure(node, sendStructure); | 3038 registry.registerSendStructure(node, sendStructure); |
3178 return const NoneResult(); | 3039 return const NoneResult(); |
3179 } else { | 3040 } else { |
3180 Node rhs = node.arguments.tail.head; | 3041 Node rhs = node.arguments.tail.head; |
3181 visitExpression(rhs); | 3042 visitExpression(rhs); |
3182 | 3043 |
3183 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3044 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
3184 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3045 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
3185 // `a[b] = c`. | 3046 // `a[b] = c`. |
3186 Selector setterSelector = new Selector.indexSet(); | 3047 Selector setterSelector = new Selector.indexSet(); |
3187 | 3048 |
3188 // TODO(23998): Remove this when selectors are only accessed | 3049 // TODO(23998): Remove this when selectors are only accessed |
3189 // through the send structure. | 3050 // through the send structure. |
3190 registry.setSelector(node, setterSelector); | 3051 registry.setSelector(node, setterSelector); |
3191 registry.registerDynamicUse( | 3052 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
3192 new DynamicUse(setterSelector, null)); | |
3193 | 3053 |
3194 SendStructure sendStructure = new IndexSetStructure(semantics); | 3054 SendStructure sendStructure = new IndexSetStructure(semantics); |
3195 registry.registerSendStructure(node, sendStructure); | 3055 registry.registerSendStructure(node, sendStructure); |
3196 return const NoneResult(); | 3056 return const NoneResult(); |
3197 } else { | 3057 } else { |
3198 // `a[b] += c`. | 3058 // `a[b] += c`. |
3199 Selector getterSelector = new Selector.index(); | 3059 Selector getterSelector = new Selector.index(); |
3200 Selector setterSelector = new Selector.indexSet(); | 3060 Selector setterSelector = new Selector.indexSet(); |
3201 Selector operatorSelector = | 3061 Selector operatorSelector = |
3202 new Selector.binaryOperator(operator.selectorName); | 3062 new Selector.binaryOperator(operator.selectorName); |
3203 | 3063 |
3204 // TODO(23998): Remove these when selectors are only accessed | 3064 // TODO(23998): Remove these when selectors are only accessed |
3205 // through the send structure. | 3065 // through the send structure. |
3206 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3066 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3207 registry.setSelector(node, setterSelector); | 3067 registry.setSelector(node, setterSelector); |
3208 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3068 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3209 | 3069 |
3210 registry.registerDynamicUse( | 3070 registry.registerDynamicUse(new DynamicUse(getterSelector, null)); |
3211 new DynamicUse(getterSelector, null)); | 3071 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
3212 registry.registerDynamicUse( | 3072 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3213 new DynamicUse(setterSelector, null)); | |
3214 registry.registerDynamicUse( | |
3215 new DynamicUse(operatorSelector, null)); | |
3216 | 3073 |
3217 SendStructure sendStructure; | 3074 SendStructure sendStructure; |
3218 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3075 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
3219 sendStructure = new IndexSetIfNullStructure(semantics); | 3076 sendStructure = new IndexSetIfNullStructure(semantics); |
3220 } else { | 3077 } else { |
3221 sendStructure = new CompoundIndexSetStructure(semantics, operator); | 3078 sendStructure = new CompoundIndexSetStructure(semantics, operator); |
3222 } | 3079 } |
3223 registry.registerSendStructure(node, sendStructure); | 3080 registry.registerSendStructure(node, sendStructure); |
3224 return const NoneResult(); | 3081 return const NoneResult(); |
3225 } | 3082 } |
(...skipping 18 matching lines...) Expand all Loading... |
3244 new Selector.binaryOperator(operator.selectorName); | 3101 new Selector.binaryOperator(operator.selectorName); |
3245 | 3102 |
3246 // TODO(23998): Remove these when selectors are only accessed | 3103 // TODO(23998): Remove these when selectors are only accessed |
3247 // through the send structure. | 3104 // through the send structure. |
3248 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3105 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3249 registry.setSelector(node, setterSelector); | 3106 registry.setSelector(node, setterSelector); |
3250 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3107 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3251 | 3108 |
3252 if (semantics == null) { | 3109 if (semantics == null) { |
3253 semantics = computeSuperAccessSemanticsForSelectors( | 3110 semantics = computeSuperAccessSemanticsForSelectors( |
3254 node, getterSelector, setterSelector, isIndex: true); | 3111 node, getterSelector, setterSelector, |
| 3112 isIndex: true); |
3255 | 3113 |
3256 if (!semantics.getter.isError) { | 3114 if (!semantics.getter.isError) { |
3257 registry.registerStaticUse( | 3115 registry.registerStaticUse(new StaticUse.superInvoke( |
3258 new StaticUse.superInvoke( | 3116 semantics.getter, getterSelector.callStructure)); |
3259 semantics.getter, getterSelector.callStructure)); | |
3260 } | 3117 } |
3261 if (!semantics.setter.isError) { | 3118 if (!semantics.setter.isError) { |
3262 registry.registerStaticUse( | 3119 registry.registerStaticUse(new StaticUse.superInvoke( |
3263 new StaticUse.superInvoke( | 3120 semantics.setter, setterSelector.callStructure)); |
3264 semantics.setter, setterSelector.callStructure)); | |
3265 } | 3121 } |
3266 | 3122 |
3267 // TODO(23998): Remove these when elements are only accessed | 3123 // TODO(23998): Remove these when elements are only accessed |
3268 // through the send structure. | 3124 // through the send structure. |
3269 registry.useElement(node, semantics.setter); | 3125 registry.useElement(node, semantics.setter); |
3270 registry.useElement(node.selector, semantics.getter); | 3126 registry.useElement(node.selector, semantics.getter); |
3271 } | 3127 } |
3272 registry.registerDynamicUse( | 3128 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3273 new DynamicUse(operatorSelector, null)); | |
3274 | 3129 |
3275 SendStructure sendStructure = node.isPrefix | 3130 SendStructure sendStructure = node.isPrefix |
3276 ? new IndexPrefixStructure(semantics, operator) | 3131 ? new IndexPrefixStructure(semantics, operator) |
3277 : new IndexPostfixStructure(semantics, operator); | 3132 : new IndexPostfixStructure(semantics, operator); |
3278 registry.registerSendStructure(node, sendStructure); | 3133 registry.registerSendStructure(node, sendStructure); |
3279 return const NoneResult(); | 3134 return const NoneResult(); |
3280 } else { | 3135 } else { |
3281 Node rhs = node.arguments.tail.head; | 3136 Node rhs = node.arguments.tail.head; |
3282 visitExpression(rhs); | 3137 visitExpression(rhs); |
3283 | 3138 |
3284 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3139 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
3285 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3140 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
3286 // `super[a] = b`. | 3141 // `super[a] = b`. |
3287 Selector setterSelector = new Selector.indexSet(); | 3142 Selector setterSelector = new Selector.indexSet(); |
3288 if (semantics == null) { | 3143 if (semantics == null) { |
3289 semantics = | 3144 semantics = |
3290 computeSuperAccessSemanticsForSelector(node, setterSelector); | 3145 computeSuperAccessSemanticsForSelector(node, setterSelector); |
3291 | 3146 |
3292 // TODO(23998): Remove these when elements are only accessed | 3147 // TODO(23998): Remove these when elements are only accessed |
3293 // through the send structure. | 3148 // through the send structure. |
3294 registry.useElement(node, semantics.setter); | 3149 registry.useElement(node, semantics.setter); |
3295 } | 3150 } |
3296 | 3151 |
3297 // TODO(23998): Remove this when selectors are only accessed | 3152 // TODO(23998): Remove this when selectors are only accessed |
3298 // through the send structure. | 3153 // through the send structure. |
3299 registry.setSelector(node, setterSelector); | 3154 registry.setSelector(node, setterSelector); |
3300 if (!semantics.setter.isError) { | 3155 if (!semantics.setter.isError) { |
3301 registry.registerStaticUse( | 3156 registry.registerStaticUse(new StaticUse.superInvoke( |
3302 new StaticUse.superInvoke( | 3157 semantics.setter, setterSelector.callStructure)); |
3303 semantics.setter, setterSelector.callStructure)); | |
3304 } | 3158 } |
3305 | 3159 |
3306 SendStructure sendStructure = new IndexSetStructure(semantics); | 3160 SendStructure sendStructure = new IndexSetStructure(semantics); |
3307 registry.registerSendStructure(node, sendStructure); | 3161 registry.registerSendStructure(node, sendStructure); |
3308 return const NoneResult(); | 3162 return const NoneResult(); |
3309 } else { | 3163 } else { |
3310 // `super[a] += b`. | 3164 // `super[a] += b`. |
3311 Selector getterSelector = new Selector.index(); | 3165 Selector getterSelector = new Selector.index(); |
3312 Selector setterSelector = new Selector.indexSet(); | 3166 Selector setterSelector = new Selector.indexSet(); |
3313 Selector operatorSelector = | 3167 Selector operatorSelector = |
3314 new Selector.binaryOperator(operator.selectorName); | 3168 new Selector.binaryOperator(operator.selectorName); |
3315 if (semantics == null) { | 3169 if (semantics == null) { |
3316 semantics = computeSuperAccessSemanticsForSelectors( | 3170 semantics = computeSuperAccessSemanticsForSelectors( |
3317 node, getterSelector, setterSelector, isIndex: true); | 3171 node, getterSelector, setterSelector, |
| 3172 isIndex: true); |
3318 | 3173 |
3319 if (!semantics.getter.isError) { | 3174 if (!semantics.getter.isError) { |
3320 registry.registerStaticUse( | 3175 registry.registerStaticUse(new StaticUse.superInvoke( |
3321 new StaticUse.superInvoke( | 3176 semantics.getter, getterSelector.callStructure)); |
3322 semantics.getter, getterSelector.callStructure)); | |
3323 } | 3177 } |
3324 if (!semantics.setter.isError) { | 3178 if (!semantics.setter.isError) { |
3325 registry.registerStaticUse( | 3179 registry.registerStaticUse(new StaticUse.superInvoke( |
3326 new StaticUse.superInvoke( | 3180 semantics.setter, setterSelector.callStructure)); |
3327 semantics.setter, setterSelector.callStructure)); | |
3328 } | 3181 } |
3329 | 3182 |
3330 // TODO(23998): Remove these when elements are only accessed | 3183 // TODO(23998): Remove these when elements are only accessed |
3331 // through the send structure. | 3184 // through the send structure. |
3332 registry.useElement(node, semantics.setter); | 3185 registry.useElement(node, semantics.setter); |
3333 registry.useElement(node.selector, semantics.getter); | 3186 registry.useElement(node.selector, semantics.getter); |
3334 } | 3187 } |
3335 | 3188 |
3336 // TODO(23998): Remove these when selectors are only accessed | 3189 // TODO(23998): Remove these when selectors are only accessed |
3337 // through the send structure. | 3190 // through the send structure. |
3338 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3191 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3339 registry.setSelector(node, setterSelector); | 3192 registry.setSelector(node, setterSelector); |
3340 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3193 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3341 | 3194 |
3342 registry.registerDynamicUse( | 3195 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3343 new DynamicUse(operatorSelector, null)); | |
3344 | 3196 |
3345 SendStructure sendStructure; | 3197 SendStructure sendStructure; |
3346 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3198 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
3347 sendStructure = new IndexSetIfNullStructure(semantics); | 3199 sendStructure = new IndexSetIfNullStructure(semantics); |
3348 } else { | 3200 } else { |
3349 sendStructure = new CompoundIndexSetStructure(semantics, operator); | 3201 sendStructure = new CompoundIndexSetStructure(semantics, operator); |
3350 } | 3202 } |
3351 registry.registerSendStructure(node, sendStructure); | 3203 registry.registerSendStructure(node, sendStructure); |
3352 return const NoneResult(); | 3204 return const NoneResult(); |
3353 } | 3205 } |
3354 } | 3206 } |
3355 } | 3207 } |
3356 | 3208 |
3357 /// Handle super index operations like `super.a = b`, `super.a += b`, and | 3209 /// Handle super index operations like `super.a = b`, `super.a += b`, and |
3358 /// `super.a++`. | 3210 /// `super.a++`. |
3359 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. | 3211 // TODO(johnniwinther): Share code with [handleSuperIndexSendSet]. |
3360 ResolutionResult handleSuperSendSet(SendSet node) { | 3212 ResolutionResult handleSuperSendSet(SendSet node) { |
3361 Identifier selector = node.selector.asIdentifier(); | 3213 Identifier selector = node.selector.asIdentifier(); |
3362 String text = selector.source; | 3214 String text = selector.source; |
3363 Name name = new Name(text, enclosingElement.library); | 3215 Name name = new Name(text, enclosingElement.library); |
3364 String operatorText = node.assignmentOperator.source; | 3216 String operatorText = node.assignmentOperator.source; |
3365 Selector getterSelector = new Selector.getter(name); | 3217 Selector getterSelector = new Selector.getter(name); |
3366 Selector setterSelector = new Selector.setter(name); | 3218 Selector setterSelector = new Selector.setter(name); |
3367 | 3219 |
3368 void registerStaticUses(AccessSemantics semantics) { | 3220 void registerStaticUses(AccessSemantics semantics) { |
3369 switch (semantics.kind) { | 3221 switch (semantics.kind) { |
3370 case AccessKind.SUPER_METHOD: | 3222 case AccessKind.SUPER_METHOD: |
3371 registry.registerStaticUse( | 3223 registry |
3372 new StaticUse.superTearOff(semantics.element)); | 3224 .registerStaticUse(new StaticUse.superTearOff(semantics.element)); |
3373 break; | 3225 break; |
3374 case AccessKind.SUPER_GETTER: | 3226 case AccessKind.SUPER_GETTER: |
3375 registry.registerStaticUse(new StaticUse.superGet(semantics.getter)); | 3227 registry.registerStaticUse(new StaticUse.superGet(semantics.getter)); |
3376 break; | 3228 break; |
3377 case AccessKind.SUPER_SETTER: | 3229 case AccessKind.SUPER_SETTER: |
3378 registry.registerStaticUse( | 3230 registry.registerStaticUse( |
3379 new StaticUse.superSetterSet(semantics.setter)); | 3231 new StaticUse.superSetterSet(semantics.setter)); |
3380 break; | 3232 break; |
3381 case AccessKind.SUPER_FIELD: | 3233 case AccessKind.SUPER_FIELD: |
3382 registry.registerStaticUse( | 3234 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
3383 new StaticUse.superGet(semantics.element)); | |
3384 registry.registerStaticUse( | 3235 registry.registerStaticUse( |
3385 new StaticUse.superFieldSet(semantics.element)); | 3236 new StaticUse.superFieldSet(semantics.element)); |
3386 break; | 3237 break; |
3387 case AccessKind.SUPER_FINAL_FIELD: | 3238 case AccessKind.SUPER_FINAL_FIELD: |
3388 registry.registerStaticUse( | 3239 registry.registerStaticUse(new StaticUse.superGet(semantics.element)); |
3389 new StaticUse.superGet(semantics.element)); | |
3390 break; | 3240 break; |
3391 case AccessKind.COMPOUND: | 3241 case AccessKind.COMPOUND: |
3392 CompoundAccessSemantics compoundSemantics = semantics; | 3242 CompoundAccessSemantics compoundSemantics = semantics; |
3393 switch (compoundSemantics.compoundAccessKind) { | 3243 switch (compoundSemantics.compoundAccessKind) { |
3394 case CompoundAccessKind.SUPER_GETTER_FIELD: | 3244 case CompoundAccessKind.SUPER_GETTER_FIELD: |
3395 case CompoundAccessKind.SUPER_FIELD_FIELD: | 3245 case CompoundAccessKind.SUPER_FIELD_FIELD: |
3396 registry.registerStaticUse( | 3246 registry |
3397 new StaticUse.superGet(semantics.getter)); | 3247 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
3398 registry.registerStaticUse( | 3248 registry.registerStaticUse( |
3399 new StaticUse.superFieldSet(semantics.setter)); | 3249 new StaticUse.superFieldSet(semantics.setter)); |
3400 break; | 3250 break; |
3401 case CompoundAccessKind.SUPER_FIELD_SETTER: | 3251 case CompoundAccessKind.SUPER_FIELD_SETTER: |
3402 case CompoundAccessKind.SUPER_GETTER_SETTER: | 3252 case CompoundAccessKind.SUPER_GETTER_SETTER: |
3403 registry.registerStaticUse( | 3253 registry |
3404 new StaticUse.superGet(semantics.getter)); | 3254 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
3405 registry.registerStaticUse( | 3255 registry.registerStaticUse( |
3406 new StaticUse.superSetterSet(semantics.setter)); | 3256 new StaticUse.superSetterSet(semantics.setter)); |
3407 break; | 3257 break; |
3408 case CompoundAccessKind.SUPER_METHOD_SETTER: | 3258 case CompoundAccessKind.SUPER_METHOD_SETTER: |
3409 registry.registerStaticUse( | 3259 registry.registerStaticUse( |
3410 new StaticUse.superSetterSet(semantics.setter)); | 3260 new StaticUse.superSetterSet(semantics.setter)); |
3411 break; | 3261 break; |
3412 case CompoundAccessKind.UNRESOLVED_SUPER_GETTER: | 3262 case CompoundAccessKind.UNRESOLVED_SUPER_GETTER: |
3413 registry.registerStaticUse( | 3263 registry.registerStaticUse( |
3414 new StaticUse.superSetterSet(semantics.setter)); | 3264 new StaticUse.superSetterSet(semantics.setter)); |
3415 break; | 3265 break; |
3416 case CompoundAccessKind.UNRESOLVED_SUPER_SETTER: | 3266 case CompoundAccessKind.UNRESOLVED_SUPER_SETTER: |
3417 registry.registerStaticUse( | 3267 registry |
3418 new StaticUse.superGet(semantics.getter)); | 3268 .registerStaticUse(new StaticUse.superGet(semantics.getter)); |
3419 break; | 3269 break; |
3420 default: | 3270 default: |
3421 break; | 3271 break; |
3422 } | 3272 } |
3423 break; | 3273 break; |
3424 default: | 3274 default: |
3425 break; | 3275 break; |
3426 } | 3276 } |
3427 } | 3277 } |
3428 | 3278 |
3429 AccessSemantics semantics = checkSuperAccess(node); | 3279 AccessSemantics semantics = checkSuperAccess(node); |
3430 if (node.isPrefix || node.isPostfix) { | 3280 if (node.isPrefix || node.isPostfix) { |
3431 // `super.a++` or `++super.a`. | 3281 // `super.a++` or `++super.a`. |
3432 if (semantics == null) { | 3282 if (semantics == null) { |
3433 semantics = computeSuperAccessSemanticsForSelectors( | 3283 semantics = computeSuperAccessSemanticsForSelectors( |
3434 node, getterSelector, setterSelector); | 3284 node, getterSelector, setterSelector); |
3435 registerStaticUses(semantics); | 3285 registerStaticUses(semantics); |
3436 } | 3286 } |
3437 return handleUpdate(node, name, semantics); | 3287 return handleUpdate(node, name, semantics); |
3438 } else { | 3288 } else { |
3439 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 3289 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
3440 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 3290 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
3441 // `super.a = b`. | 3291 // `super.a = b`. |
3442 if (semantics == null) { | 3292 if (semantics == null) { |
3443 semantics = | 3293 semantics = computeSuperAccessSemanticsForSelector( |
3444 computeSuperAccessSemanticsForSelector( | 3294 node, setterSelector, |
3445 node, setterSelector, alternateName: name); | 3295 alternateName: name); |
3446 switch (semantics.kind) { | 3296 switch (semantics.kind) { |
3447 case AccessKind.SUPER_FINAL_FIELD: | 3297 case AccessKind.SUPER_FINAL_FIELD: |
3448 reporter.reportWarningMessage( | 3298 reporter.reportWarningMessage( |
3449 node, | 3299 node, MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, { |
3450 MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER, | 3300 'name': name, |
3451 {'name': name, | 3301 'superclassName': semantics.setter.enclosingClass.name |
3452 'superclassName': semantics.setter.enclosingClass.name}); | 3302 }); |
3453 // TODO(johnniwinther): This shouldn't be needed. | 3303 // TODO(johnniwinther): This shouldn't be needed. |
3454 registry.registerDynamicUse( | 3304 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
3455 new DynamicUse(setterSelector, null)); | |
3456 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 3305 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
3457 break; | 3306 break; |
3458 case AccessKind.SUPER_METHOD: | 3307 case AccessKind.SUPER_METHOD: |
3459 reporter.reportWarningMessage( | 3308 reporter.reportWarningMessage( |
3460 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, | 3309 node, MessageKind.ASSIGNING_METHOD_IN_SUPER, { |
3461 {'name': name, | 3310 'name': name, |
3462 'superclassName': semantics.setter.enclosingClass.name}); | 3311 'superclassName': semantics.setter.enclosingClass.name |
| 3312 }); |
3463 // TODO(johnniwinther): This shouldn't be needed. | 3313 // TODO(johnniwinther): This shouldn't be needed. |
3464 registry.registerDynamicUse( | 3314 registry.registerDynamicUse(new DynamicUse(setterSelector, null)); |
3465 new DynamicUse(setterSelector, null)); | |
3466 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); | 3315 registry.registerFeature(Feature.SUPER_NO_SUCH_METHOD); |
3467 break; | 3316 break; |
3468 case AccessKind.SUPER_FIELD: | 3317 case AccessKind.SUPER_FIELD: |
3469 registry.registerStaticUse( | 3318 registry.registerStaticUse( |
3470 new StaticUse.superFieldSet(semantics.setter)); | 3319 new StaticUse.superFieldSet(semantics.setter)); |
3471 break; | 3320 break; |
3472 case AccessKind.SUPER_SETTER: | 3321 case AccessKind.SUPER_SETTER: |
3473 registry.registerStaticUse( | 3322 registry.registerStaticUse( |
3474 new StaticUse.superSetterSet(semantics.setter)); | 3323 new StaticUse.superSetterSet(semantics.setter)); |
3475 break; | 3324 break; |
(...skipping 10 matching lines...) Expand all Loading... |
3486 registerStaticUses(semantics); | 3335 registerStaticUses(semantics); |
3487 } | 3336 } |
3488 return handleUpdate(node, name, semantics); | 3337 return handleUpdate(node, name, semantics); |
3489 } | 3338 } |
3490 } | 3339 } |
3491 } | 3340 } |
3492 | 3341 |
3493 /// Handle update of an entity defined by [semantics]. For instance `a = b`, | 3342 /// Handle update of an entity defined by [semantics]. For instance `a = b`, |
3494 /// `a++` or `a += b` where [semantics] describe `a`. | 3343 /// `a++` or `a += b` where [semantics] describe `a`. |
3495 ResolutionResult handleUpdate( | 3344 ResolutionResult handleUpdate( |
3496 SendSet node, | 3345 SendSet node, Name name, AccessSemantics semantics) { |
3497 Name name, | |
3498 AccessSemantics semantics) { | |
3499 SendStructure sendStructure; | 3346 SendStructure sendStructure; |
3500 String operatorText = node.assignmentOperator.source; | 3347 String operatorText = node.assignmentOperator.source; |
3501 Selector getterSelector = new Selector.getter(name); | 3348 Selector getterSelector = new Selector.getter(name); |
3502 Selector setterSelector = new Selector.setter(name); | 3349 Selector setterSelector = new Selector.setter(name); |
3503 if (node.isPrefix || node.isPostfix) { | 3350 if (node.isPrefix || node.isPostfix) { |
3504 // `e++` or `++e`. | 3351 // `e++` or `++e`. |
3505 IncDecOperator operator = IncDecOperator.parse(operatorText); | 3352 IncDecOperator operator = IncDecOperator.parse(operatorText); |
3506 Selector operatorSelector = | 3353 Selector operatorSelector = |
3507 new Selector.binaryOperator(operator.selectorName); | 3354 new Selector.binaryOperator(operator.selectorName); |
3508 | 3355 |
3509 // TODO(23998): Remove these when selectors are only accessed | 3356 // TODO(23998): Remove these when selectors are only accessed |
3510 // through the send structure. | 3357 // through the send structure. |
3511 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3358 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3512 registry.setSelector(node, setterSelector); | 3359 registry.setSelector(node, setterSelector); |
3513 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3360 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3514 | 3361 |
3515 // TODO(23998): Remove these when elements are only accessed | 3362 // TODO(23998): Remove these when elements are only accessed |
3516 // through the send structure. | 3363 // through the send structure. |
3517 registry.useElement(node, semantics.setter); | 3364 registry.useElement(node, semantics.setter); |
3518 registry.useElement(node.selector, semantics.getter); | 3365 registry.useElement(node.selector, semantics.getter); |
3519 | 3366 |
3520 registry.registerDynamicUse( | 3367 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3521 new DynamicUse(operatorSelector, null)); | |
3522 | 3368 |
3523 SendStructure sendStructure = node.isPrefix | 3369 SendStructure sendStructure = node.isPrefix |
3524 ? new PrefixStructure(semantics, operator) | 3370 ? new PrefixStructure(semantics, operator) |
3525 : new PostfixStructure(semantics, operator); | 3371 : new PostfixStructure(semantics, operator); |
3526 registry.registerSendStructure(node, sendStructure); | 3372 registry.registerSendStructure(node, sendStructure); |
3527 registry.registerFeature(Feature.INC_DEC_OPERATION); | 3373 registry.registerFeature(Feature.INC_DEC_OPERATION); |
3528 } else { | 3374 } else { |
3529 Node rhs = node.arguments.head; | 3375 Node rhs = node.arguments.head; |
3530 visitExpression(rhs); | 3376 visitExpression(rhs); |
3531 | 3377 |
(...skipping 20 matching lines...) Expand all Loading... |
3552 // through the send structure. | 3398 // through the send structure. |
3553 registry.useElement(node, semantics.setter); | 3399 registry.useElement(node, semantics.setter); |
3554 registry.useElement(node.selector, semantics.getter); | 3400 registry.useElement(node.selector, semantics.getter); |
3555 | 3401 |
3556 // TODO(23998): Remove these when selectors are only accessed | 3402 // TODO(23998): Remove these when selectors are only accessed |
3557 // through the send structure. | 3403 // through the send structure. |
3558 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 3404 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
3559 registry.setSelector(node, setterSelector); | 3405 registry.setSelector(node, setterSelector); |
3560 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 3406 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
3561 | 3407 |
3562 registry.registerDynamicUse( | 3408 registry.registerDynamicUse(new DynamicUse(operatorSelector, null)); |
3563 new DynamicUse(operatorSelector, null)); | |
3564 | 3409 |
3565 SendStructure sendStructure; | 3410 SendStructure sendStructure; |
3566 if (operator.kind == AssignmentOperatorKind.IF_NULL) { | 3411 if (operator.kind == AssignmentOperatorKind.IF_NULL) { |
3567 sendStructure = new SetIfNullStructure(semantics); | 3412 sendStructure = new SetIfNullStructure(semantics); |
3568 } else { | 3413 } else { |
3569 sendStructure = new CompoundStructure(semantics, operator); | 3414 sendStructure = new CompoundStructure(semantics, operator); |
3570 } | 3415 } |
3571 registry.registerSendStructure(node, sendStructure); | 3416 registry.registerSendStructure(node, sendStructure); |
3572 } | 3417 } |
3573 } | 3418 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3634 registry.setConstant(node, constant); | 3479 registry.setConstant(node, constant); |
3635 return new ConstantResult(node, constant); | 3480 return new ConstantResult(node, constant); |
3636 } | 3481 } |
3637 | 3482 |
3638 ConstantResult visitLiteralSymbol(LiteralSymbol node) { | 3483 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
3639 String name = node.slowNameString; | 3484 String name = node.slowNameString; |
3640 // TODO(johnniwinther): Use [registerConstantLiteral] instead. | 3485 // TODO(johnniwinther): Use [registerConstantLiteral] instead. |
3641 registry.registerConstSymbol(name); | 3486 registry.registerConstSymbol(name); |
3642 if (!validateSymbol(node, name, reportError: false)) { | 3487 if (!validateSymbol(node, name, reportError: false)) { |
3643 reporter.reportErrorMessage( | 3488 reporter.reportErrorMessage( |
3644 node, | 3489 node, MessageKind.UNSUPPORTED_LITERAL_SYMBOL, {'value': name}); |
3645 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | |
3646 {'value': name}); | |
3647 } | 3490 } |
3648 analyzeConstantDeferred(node); | 3491 analyzeConstantDeferred(node); |
3649 ConstantExpression constant = new SymbolConstantExpression(name); | 3492 ConstantExpression constant = new SymbolConstantExpression(name); |
3650 registry.setConstant(node, constant); | 3493 registry.setConstant(node, constant); |
3651 return new ConstantResult(node, constant); | 3494 return new ConstantResult(node, constant); |
3652 } | 3495 } |
3653 | 3496 |
3654 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { | 3497 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { |
3655 registry.registerFeature(Feature.STRING_JUXTAPOSITION); | 3498 registry.registerFeature(Feature.STRING_JUXTAPOSITION); |
3656 ResolutionResult first = visit(node.first); | 3499 ResolutionResult first = visit(node.first); |
3657 ResolutionResult second = visit(node.second); | 3500 ResolutionResult second = visit(node.second); |
3658 if (first.isConstant && second.isConstant) { | 3501 if (first.isConstant && second.isConstant) { |
3659 ConstantExpression constant = new ConcatenateConstantExpression( | 3502 ConstantExpression constant = new ConcatenateConstantExpression( |
3660 <ConstantExpression>[first.constant, second.constant]); | 3503 <ConstantExpression>[first.constant, second.constant]); |
3661 registry.setConstant(node, constant); | 3504 registry.setConstant(node, constant); |
3662 return new ConstantResult(node, constant); | 3505 return new ConstantResult(node, constant); |
3663 } | 3506 } |
3664 return const NoneResult(); | 3507 return const NoneResult(); |
3665 } | 3508 } |
3666 | 3509 |
3667 ResolutionResult visitNodeList(NodeList node) { | 3510 ResolutionResult visitNodeList(NodeList node) { |
3668 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 3511 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
3669 visit(link.head); | 3512 visit(link.head); |
3670 } | 3513 } |
3671 return const NoneResult(); | 3514 return const NoneResult(); |
3672 } | 3515 } |
3673 | 3516 |
3674 ResolutionResult visitRethrow(Rethrow node) { | 3517 ResolutionResult visitRethrow(Rethrow node) { |
3675 if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') { | 3518 if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') { |
3676 reporter.reportErrorMessage( | 3519 reporter.reportErrorMessage(node, MessageKind.RETHROW_OUTSIDE_CATCH); |
3677 node, MessageKind.RETHROW_OUTSIDE_CATCH); | |
3678 } | 3520 } |
3679 return const NoneResult(); | 3521 return const NoneResult(); |
3680 } | 3522 } |
3681 | 3523 |
3682 ResolutionResult visitReturn(Return node) { | 3524 ResolutionResult visitReturn(Return node) { |
3683 Node expression = node.expression; | 3525 Node expression = node.expression; |
3684 if (expression != null) { | 3526 if (expression != null) { |
3685 if (enclosingElement.isGenerativeConstructor) { | 3527 if (enclosingElement.isGenerativeConstructor) { |
3686 // It is a compile-time error if a return statement of the form | 3528 // It is a compile-time error if a return statement of the form |
3687 // `return e;` appears in a generative constructor. (Dart Language | 3529 // `return e;` appears in a generative constructor. (Dart Language |
3688 // Specification 13.12.) | 3530 // Specification 13.12.) |
3689 reporter.reportErrorMessage( | 3531 reporter.reportErrorMessage( |
3690 expression, | 3532 expression, MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR); |
3691 MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR); | |
3692 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 3533 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
3693 reporter.reportErrorMessage( | 3534 reporter.reportErrorMessage(node, MessageKind.RETURN_IN_GENERATOR, |
3694 node, | |
3695 MessageKind.RETURN_IN_GENERATOR, | |
3696 {'modifier': currentAsyncMarker}); | 3535 {'modifier': currentAsyncMarker}); |
3697 } | 3536 } |
3698 } | 3537 } |
3699 visit(node.expression); | 3538 visit(node.expression); |
3700 return const NoneResult(); | 3539 return const NoneResult(); |
3701 } | 3540 } |
3702 | 3541 |
3703 ResolutionResult visitYield(Yield node) { | 3542 ResolutionResult visitYield(Yield node) { |
3704 if (!currentAsyncMarker.isYielding) { | 3543 if (!currentAsyncMarker.isYielding) { |
3705 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); | 3544 reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD); |
(...skipping 11 matching lines...) Expand all Loading... |
3717 if (!enclosingElement.isFactoryConstructor) { | 3556 if (!enclosingElement.isFactoryConstructor) { |
3718 reporter.reportErrorMessage( | 3557 reporter.reportErrorMessage( |
3719 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 3558 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
3720 reporter.reportHintMessage( | 3559 reporter.reportHintMessage( |
3721 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 3560 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
3722 } | 3561 } |
3723 | 3562 |
3724 ConstructorElementX constructor = enclosingElement; | 3563 ConstructorElementX constructor = enclosingElement; |
3725 bool isConstConstructor = constructor.isConst; | 3564 bool isConstConstructor = constructor.isConst; |
3726 bool isValidAsConstant = isConstConstructor; | 3565 bool isValidAsConstant = isConstConstructor; |
3727 ConstructorResult result = resolveRedirectingFactory( | 3566 ConstructorResult result = |
3728 node, inConstContext: isConstConstructor); | 3567 resolveRedirectingFactory(node, inConstContext: isConstConstructor); |
3729 ConstructorElement redirectionTarget = result.element; | 3568 ConstructorElement redirectionTarget = result.element; |
3730 constructor.immediateRedirectionTarget = redirectionTarget; | 3569 constructor.immediateRedirectionTarget = redirectionTarget; |
3731 | 3570 |
3732 Node constructorReference = node.constructorReference; | 3571 Node constructorReference = node.constructorReference; |
3733 if (result.isDeferred) { | 3572 if (result.isDeferred) { |
3734 constructor.redirectionDeferredPrefix = result.prefix; | 3573 constructor.redirectionDeferredPrefix = result.prefix; |
3735 } | 3574 } |
3736 | 3575 |
3737 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 3576 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
3738 switch (result.kind) { | 3577 switch (result.kind) { |
3739 case ConstructorResultKind.GENERATIVE: | 3578 case ConstructorResultKind.GENERATIVE: |
3740 case ConstructorResultKind.FACTORY: | 3579 case ConstructorResultKind.FACTORY: |
3741 // Register a post process to check for cycles in the redirection chain | 3580 // Register a post process to check for cycles in the redirection chain |
3742 // and set the actual generative constructor at the end of the chain. | 3581 // and set the actual generative constructor at the end of the chain. |
3743 addDeferredAction(constructor, () { | 3582 addDeferredAction(constructor, () { |
3744 compiler.resolver.resolveRedirectionChain(constructor, node); | 3583 compiler.resolver.resolveRedirectionChain(constructor, node); |
3745 }); | 3584 }); |
3746 break; | 3585 break; |
3747 case ConstructorResultKind.ABSTRACT: | 3586 case ConstructorResultKind.ABSTRACT: |
3748 case ConstructorResultKind.INVALID_TYPE: | 3587 case ConstructorResultKind.INVALID_TYPE: |
3749 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: | 3588 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: |
3750 case ConstructorResultKind.NON_CONSTANT: | 3589 case ConstructorResultKind.NON_CONSTANT: |
3751 isValidAsConstant = false; | 3590 isValidAsConstant = false; |
3752 constructor.setEffectiveTarget( | 3591 constructor.setEffectiveTarget(result.element, result.type, |
3753 result.element, result.type, isMalformed: true); | 3592 isMalformed: true); |
3754 break; | 3593 break; |
3755 } | 3594 } |
3756 if (Elements.isUnresolved(redirectionTarget)) { | 3595 if (Elements.isUnresolved(redirectionTarget)) { |
3757 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 3596 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
3758 return const NoneResult(); | 3597 return const NoneResult(); |
3759 } else { | 3598 } else { |
3760 if (isConstConstructor && | 3599 if (isConstConstructor && !redirectionTarget.isConst) { |
3761 !redirectionTarget.isConst) { | 3600 reporter.reportErrorMessage(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
3762 reporter.reportErrorMessage( | |
3763 node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | |
3764 isValidAsConstant = false; | 3601 isValidAsConstant = false; |
3765 } | 3602 } |
3766 if (redirectionTarget == constructor) { | 3603 if (redirectionTarget == constructor) { |
3767 reporter.reportErrorMessage( | 3604 reporter.reportErrorMessage( |
3768 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 3605 node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
3769 // TODO(johnniwinther): Create constant constructor for this case and | 3606 // TODO(johnniwinther): Create constant constructor for this case and |
3770 // let evaluation detect the cyclicity. | 3607 // let evaluation detect the cyclicity. |
3771 isValidAsConstant = false; | 3608 isValidAsConstant = false; |
3772 } | 3609 } |
3773 } | 3610 } |
3774 | 3611 |
3775 // Check that the target constructor is type compatible with the | 3612 // Check that the target constructor is type compatible with the |
3776 // redirecting constructor. | 3613 // redirecting constructor. |
3777 ClassElement targetClass = redirectionTarget.enclosingClass; | 3614 ClassElement targetClass = redirectionTarget.enclosingClass; |
3778 InterfaceType type = registry.getType(node); | 3615 InterfaceType type = registry.getType(node); |
3779 FunctionType targetConstructorType = | 3616 FunctionType targetConstructorType = redirectionTarget |
3780 redirectionTarget.computeType(resolution) | 3617 .computeType(resolution) |
3781 .subst(type.typeArguments, targetClass.typeVariables); | 3618 .subst(type.typeArguments, targetClass.typeVariables); |
3782 FunctionType constructorType = constructor.computeType(resolution); | 3619 FunctionType constructorType = constructor.computeType(resolution); |
3783 bool isSubtype = compiler.types.isSubtype( | 3620 bool isSubtype = |
3784 targetConstructorType, constructorType); | 3621 compiler.types.isSubtype(targetConstructorType, constructorType); |
3785 if (!isSubtype) { | 3622 if (!isSubtype) { |
3786 reporter.reportWarningMessage( | 3623 reporter.reportWarningMessage(node, MessageKind.NOT_ASSIGNABLE, |
3787 node, | |
3788 MessageKind.NOT_ASSIGNABLE, | |
3789 {'fromType': targetConstructorType, 'toType': constructorType}); | 3624 {'fromType': targetConstructorType, 'toType': constructorType}); |
3790 // TODO(johnniwinther): Handle this (potentially) erroneous case. | 3625 // TODO(johnniwinther): Handle this (potentially) erroneous case. |
3791 isValidAsConstant = false; | 3626 isValidAsConstant = false; |
3792 } | 3627 } |
3793 | 3628 |
3794 redirectionTarget.computeType(resolution); | 3629 redirectionTarget.computeType(resolution); |
3795 FunctionSignature targetSignature = redirectionTarget.functionSignature; | 3630 FunctionSignature targetSignature = redirectionTarget.functionSignature; |
3796 constructor.computeType(resolution); | 3631 constructor.computeType(resolution); |
3797 FunctionSignature constructorSignature = constructor.functionSignature; | 3632 FunctionSignature constructorSignature = constructor.functionSignature; |
3798 if (!targetSignature.isCompatibleWith(constructorSignature)) { | 3633 if (!targetSignature.isCompatibleWith(constructorSignature)) { |
3799 assert(!isSubtype); | 3634 assert(!isSubtype); |
3800 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); | 3635 registry.registerFeature(Feature.THROW_NO_SUCH_METHOD); |
3801 isValidAsConstant = false; | 3636 isValidAsConstant = false; |
3802 } | 3637 } |
3803 | 3638 |
3804 registry.registerStaticUse( | 3639 registry.registerStaticUse( |
3805 new StaticUse.constructorRedirect(redirectionTarget)); | 3640 new StaticUse.constructorRedirect(redirectionTarget)); |
3806 // TODO(johnniwinther): Register the effective target type as part of the | 3641 // TODO(johnniwinther): Register the effective target type as part of the |
3807 // static use instead. | 3642 // static use instead. |
3808 registry.registerTypeUse(new TypeUse.instantiation( | 3643 registry.registerTypeUse(new TypeUse.instantiation(redirectionTarget |
3809 redirectionTarget.enclosingClass.thisType | 3644 .enclosingClass.thisType |
3810 .subst(type.typeArguments, targetClass.typeVariables))); | 3645 .subst(type.typeArguments, targetClass.typeVariables))); |
3811 if (enclosingElement == compiler.symbolConstructor) { | 3646 if (enclosingElement == compiler.symbolConstructor) { |
3812 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); | 3647 registry.registerFeature(Feature.SYMBOL_CONSTRUCTOR); |
3813 } | 3648 } |
3814 if (isValidAsConstant) { | 3649 if (isValidAsConstant) { |
3815 List<String> names = <String>[]; | 3650 List<String> names = <String>[]; |
3816 List<ConstantExpression> arguments = <ConstantExpression>[]; | 3651 List<ConstantExpression> arguments = <ConstantExpression>[]; |
3817 int index = 0; | 3652 int index = 0; |
3818 constructorSignature.forEachParameter((ParameterElement parameter) { | 3653 constructorSignature.forEachParameter((ParameterElement parameter) { |
3819 if (parameter.isNamed) { | 3654 if (parameter.isNamed) { |
3820 String name = parameter.name; | 3655 String name = parameter.name; |
3821 names.add(name); | 3656 names.add(name); |
3822 arguments.add(new NamedArgumentReference(name)); | 3657 arguments.add(new NamedArgumentReference(name)); |
3823 } else { | 3658 } else { |
3824 arguments.add(new PositionalArgumentReference(index)); | 3659 arguments.add(new PositionalArgumentReference(index)); |
3825 } | 3660 } |
3826 index++; | 3661 index++; |
3827 }); | 3662 }); |
3828 CallStructure callStructure = | 3663 CallStructure callStructure = |
3829 new CallStructure(constructorSignature.parameterCount, names); | 3664 new CallStructure(constructorSignature.parameterCount, names); |
3830 constructor.constantConstructor = | 3665 constructor.constantConstructor = |
3831 new RedirectingFactoryConstantConstructor( | 3666 new RedirectingFactoryConstantConstructor( |
3832 new ConstructedConstantExpression( | 3667 new ConstructedConstantExpression( |
3833 type, | 3668 type, redirectionTarget, callStructure, arguments)); |
3834 redirectionTarget, | |
3835 callStructure, | |
3836 arguments)); | |
3837 } | 3669 } |
3838 return const NoneResult(); | 3670 return const NoneResult(); |
3839 } | 3671 } |
3840 | 3672 |
3841 ResolutionResult visitThrow(Throw node) { | 3673 ResolutionResult visitThrow(Throw node) { |
3842 registry.registerFeature(Feature.THROW_EXPRESSION); | 3674 registry.registerFeature(Feature.THROW_EXPRESSION); |
3843 visit(node.expression); | 3675 visit(node.expression); |
3844 return const NoneResult(); | 3676 return const NoneResult(); |
3845 } | 3677 } |
3846 | 3678 |
(...skipping 14 matching lines...) Expand all Loading... |
3861 type = const DynamicType(); | 3693 type = const DynamicType(); |
3862 } | 3694 } |
3863 VariableList variables = new VariableList.node(node, type); | 3695 VariableList variables = new VariableList.node(node, type); |
3864 VariableDefinitionsVisitor visitor = | 3696 VariableDefinitionsVisitor visitor = |
3865 new VariableDefinitionsVisitor(compiler, node, this, variables); | 3697 new VariableDefinitionsVisitor(compiler, node, this, variables); |
3866 | 3698 |
3867 Modifiers modifiers = node.modifiers; | 3699 Modifiers modifiers = node.modifiers; |
3868 void reportExtraModifier(String modifier) { | 3700 void reportExtraModifier(String modifier) { |
3869 Node modifierNode; | 3701 Node modifierNode; |
3870 for (Link<Node> nodes = modifiers.nodes.nodes; | 3702 for (Link<Node> nodes = modifiers.nodes.nodes; |
3871 !nodes.isEmpty; | 3703 !nodes.isEmpty; |
3872 nodes = nodes.tail) { | 3704 nodes = nodes.tail) { |
3873 if (modifier == nodes.head.asIdentifier().source) { | 3705 if (modifier == nodes.head.asIdentifier().source) { |
3874 modifierNode = nodes.head; | 3706 modifierNode = nodes.head; |
3875 break; | 3707 break; |
3876 } | 3708 } |
3877 } | 3709 } |
3878 assert(modifierNode != null); | 3710 assert(modifierNode != null); |
3879 reporter.reportErrorMessage( | 3711 reporter.reportErrorMessage(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, |
3880 modifierNode, MessageKind.EXTRANEOUS_MODIFIER, | |
3881 {'modifier': modifier}); | 3712 {'modifier': modifier}); |
3882 } | 3713 } |
3883 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { | 3714 if (modifiers.isFinal && (modifiers.isConst || modifiers.isVar)) { |
3884 reportExtraModifier('final'); | 3715 reportExtraModifier('final'); |
3885 } | 3716 } |
3886 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { | 3717 if (modifiers.isVar && (modifiers.isConst || node.type != null)) { |
3887 reportExtraModifier('var'); | 3718 reportExtraModifier('var'); |
3888 } | 3719 } |
3889 if (enclosingElement.isFunction || enclosingElement.isConstructor) { | 3720 if (enclosingElement.isFunction || enclosingElement.isConstructor) { |
3890 if (modifiers.isAbstract) { | 3721 if (modifiers.isAbstract) { |
(...skipping 14 matching lines...) Expand all Loading... |
3905 ResolutionResult visitWhile(While node) { | 3736 ResolutionResult visitWhile(While node) { |
3906 visit(node.condition); | 3737 visit(node.condition); |
3907 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 3738 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
3908 return const NoneResult(); | 3739 return const NoneResult(); |
3909 } | 3740 } |
3910 | 3741 |
3911 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { | 3742 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { |
3912 bool oldSendIsMemberAccess = sendIsMemberAccess; | 3743 bool oldSendIsMemberAccess = sendIsMemberAccess; |
3913 sendIsMemberAccess = false; | 3744 sendIsMemberAccess = false; |
3914 var oldCategory = allowedCategory; | 3745 var oldCategory = allowedCategory; |
3915 allowedCategory = | 3746 allowedCategory = ElementCategory.VARIABLE | |
3916 ElementCategory.VARIABLE | | |
3917 ElementCategory.FUNCTION | | 3747 ElementCategory.FUNCTION | |
3918 ElementCategory.IMPLIES_TYPE; | 3748 ElementCategory.IMPLIES_TYPE; |
3919 ResolutionResult result = visit(node.expression); | 3749 ResolutionResult result = visit(node.expression); |
3920 allowedCategory = oldCategory; | 3750 allowedCategory = oldCategory; |
3921 sendIsMemberAccess = oldSendIsMemberAccess; | 3751 sendIsMemberAccess = oldSendIsMemberAccess; |
3922 if (result.kind == ResultKind.CONSTANT) { | 3752 if (result.kind == ResultKind.CONSTANT) { |
3923 return result; | 3753 return result; |
3924 } | 3754 } |
3925 return const NoneResult(); | 3755 return const NoneResult(); |
3926 } | 3756 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3976 case ConstructorResultKind.ABSTRACT: | 3806 case ConstructorResultKind.ABSTRACT: |
3977 isInvalid = true; | 3807 isInvalid = true; |
3978 kind = ConstructorAccessKind.ABSTRACT; | 3808 kind = ConstructorAccessKind.ABSTRACT; |
3979 break; | 3809 break; |
3980 case ConstructorResultKind.INVALID_TYPE: | 3810 case ConstructorResultKind.INVALID_TYPE: |
3981 isInvalid = true; | 3811 isInvalid = true; |
3982 kind = ConstructorAccessKind.UNRESOLVED_TYPE; | 3812 kind = ConstructorAccessKind.UNRESOLVED_TYPE; |
3983 break; | 3813 break; |
3984 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: | 3814 case ConstructorResultKind.UNRESOLVED_CONSTRUCTOR: |
3985 // TODO(johnniwinther): Unify codepaths to only have one return. | 3815 // TODO(johnniwinther): Unify codepaths to only have one return. |
3986 registry.registerNewStructure(node, | 3816 registry.registerNewStructure( |
| 3817 node, |
3987 new NewInvokeStructure( | 3818 new NewInvokeStructure( |
3988 new ConstructorAccessSemantics( | 3819 new ConstructorAccessSemantics( |
3989 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, | 3820 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, |
3990 constructor, | 3821 constructor, |
3991 type), | 3822 type), |
3992 selector)); | 3823 selector)); |
3993 return new ResolutionResult.forElement(constructor); | 3824 return new ResolutionResult.forElement(constructor); |
3994 case ConstructorResultKind.NON_CONSTANT: | 3825 case ConstructorResultKind.NON_CONSTANT: |
3995 registry.registerNewStructure(node, | 3826 registry.registerNewStructure( |
| 3827 node, |
3996 new NewInvokeStructure( | 3828 new NewInvokeStructure( |
3997 new ConstructorAccessSemantics( | 3829 new ConstructorAccessSemantics( |
3998 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, | 3830 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, |
3999 constructor, | 3831 constructor, |
4000 type), | 3832 type), |
4001 selector)); | 3833 selector)); |
4002 return new ResolutionResult.forElement(constructor); | 3834 return new ResolutionResult.forElement(constructor); |
4003 } | 3835 } |
4004 | 3836 |
4005 if (!isInvalid) { | 3837 if (!isInvalid) { |
4006 // [constructor] might be the implementation element | 3838 // [constructor] might be the implementation element |
4007 // and only declaration elements may be registered. | 3839 // and only declaration elements may be registered. |
4008 registry.registerStaticUse( | 3840 registry.registerStaticUse(new StaticUse.constructorInvoke( |
4009 new StaticUse.constructorInvoke( | 3841 constructor.declaration, callStructure)); |
4010 constructor.declaration, callStructure)); | |
4011 // TODO(johniwinther): Avoid registration of `type` in face of redirecting | 3842 // TODO(johniwinther): Avoid registration of `type` in face of redirecting |
4012 // factory constructors. | 3843 // factory constructors. |
4013 registry.registerTypeUse(new TypeUse.instantiation(type)); | 3844 registry.registerTypeUse(new TypeUse.instantiation(type)); |
4014 } | 3845 } |
4015 | 3846 |
4016 if (node.isConst) { | 3847 if (node.isConst) { |
4017 bool isValidAsConstant = !isInvalid && constructor.isConst; | 3848 bool isValidAsConstant = !isInvalid && constructor.isConst; |
4018 | 3849 |
4019 if (constructor == compiler.symbolConstructor) { | 3850 if (constructor == compiler.symbolConstructor) { |
4020 Node argumentNode = node.send.arguments.head; | 3851 Node argumentNode = node.send.arguments.head; |
4021 ConstantExpression constant = | 3852 ConstantExpression constant = compiler.resolver.constantCompiler |
4022 compiler.resolver.constantCompiler.compileNode( | 3853 .compileNode(argumentNode, registry.mapping); |
4023 argumentNode, registry.mapping); | |
4024 ConstantValue name = compiler.constants.getConstantValue(constant); | 3854 ConstantValue name = compiler.constants.getConstantValue(constant); |
4025 if (!name.isString) { | 3855 if (!name.isString) { |
4026 DartType type = name.getType(coreTypes); | 3856 DartType type = name.getType(coreTypes); |
4027 reporter.reportErrorMessage( | 3857 reporter.reportErrorMessage( |
4028 argumentNode, | 3858 argumentNode, MessageKind.STRING_EXPECTED, {'type': type}); |
4029 MessageKind.STRING_EXPECTED, | |
4030 {'type': type}); | |
4031 } else { | 3859 } else { |
4032 StringConstantValue stringConstant = name; | 3860 StringConstantValue stringConstant = name; |
4033 String nameString = stringConstant.toDartString().slowToString(); | 3861 String nameString = stringConstant.toDartString().slowToString(); |
4034 if (validateSymbol(argumentNode, nameString)) { | 3862 if (validateSymbol(argumentNode, nameString)) { |
4035 registry.registerConstSymbol(nameString); | 3863 registry.registerConstSymbol(nameString); |
4036 } | 3864 } |
4037 } | 3865 } |
4038 } else if (constructor == compiler.mirrorsUsedConstructor) { | 3866 } else if (constructor == compiler.mirrorsUsedConstructor) { |
4039 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 3867 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
4040 } | 3868 } |
4041 | 3869 |
4042 analyzeConstantDeferred(node); | 3870 analyzeConstantDeferred(node); |
4043 | 3871 |
4044 if (type.containsTypeVariables) { | 3872 if (type.containsTypeVariables) { |
4045 reporter.reportErrorMessage( | 3873 reporter.reportErrorMessage( |
4046 node.send.selector, | 3874 node.send.selector, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4047 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
4048 isValidAsConstant = false; | 3875 isValidAsConstant = false; |
4049 isInvalid = true; | 3876 isInvalid = true; |
4050 } | 3877 } |
4051 | 3878 |
4052 if (result.isDeferred) { | 3879 if (result.isDeferred) { |
4053 isValidAsConstant = false; | 3880 isValidAsConstant = false; |
4054 } | 3881 } |
4055 | 3882 |
4056 if (isValidAsConstant && | 3883 if (isValidAsConstant && |
4057 argumentsResult.isValidAsConstant && | 3884 argumentsResult.isValidAsConstant && |
4058 // TODO(johnniwinther): Remove this when all constants are computed | 3885 // TODO(johnniwinther): Remove this when all constants are computed |
4059 // in resolution. | 3886 // in resolution. |
4060 !constructor.isFromEnvironmentConstructor) { | 3887 !constructor.isFromEnvironmentConstructor) { |
4061 CallStructure callStructure = argumentsResult.callStructure; | 3888 CallStructure callStructure = argumentsResult.callStructure; |
4062 List<ConstantExpression> arguments = argumentsResult.constantArguments; | 3889 List<ConstantExpression> arguments = argumentsResult.constantArguments; |
4063 | 3890 |
4064 ConstructedConstantExpression constant = | 3891 ConstructedConstantExpression constant = |
4065 new ConstructedConstantExpression( | 3892 new ConstructedConstantExpression( |
4066 type, | 3893 type, constructor, callStructure, arguments); |
4067 constructor, | |
4068 callStructure, | |
4069 arguments); | |
4070 registry.registerNewStructure(node, | 3894 registry.registerNewStructure(node, |
4071 new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant)); | 3895 new ConstInvokeStructure(ConstantInvokeKind.CONSTRUCTED, constant)); |
4072 return new ConstantResult(node, constant); | 3896 return new ConstantResult(node, constant); |
4073 } else if (isInvalid) { | 3897 } else if (isInvalid) { |
4074 // Known to be non-constant. | 3898 // Known to be non-constant. |
4075 kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR; | 3899 kind == ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR; |
4076 registry.registerNewStructure(node, | 3900 registry.registerNewStructure( |
| 3901 node, |
4077 new NewInvokeStructure( | 3902 new NewInvokeStructure( |
4078 new ConstructorAccessSemantics(kind, constructor, type), | 3903 new ConstructorAccessSemantics(kind, constructor, type), |
4079 selector)); | 3904 selector)); |
4080 } else { | 3905 } else { |
4081 // Might be valid but we don't know for sure. The compile-time constant | 3906 // Might be valid but we don't know for sure. The compile-time constant |
4082 // evaluator will compute the actual constant as a deferred action. | 3907 // evaluator will compute the actual constant as a deferred action. |
4083 registry.registerNewStructure(node, | 3908 registry.registerNewStructure( |
4084 new LateConstInvokeStructure(registry.mapping)); | 3909 node, new LateConstInvokeStructure(registry.mapping)); |
4085 } | 3910 } |
4086 | |
4087 } else { | 3911 } else { |
4088 // Not constant. | 3912 // Not constant. |
4089 if (constructor == compiler.symbolConstructor && | 3913 if (constructor == compiler.symbolConstructor && |
4090 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 3914 !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
4091 reporter.reportHintMessage( | 3915 reporter.reportHintMessage(node.newToken, MessageKind.NON_CONST_BLOAT, |
4092 node.newToken, MessageKind.NON_CONST_BLOAT, | 3916 {'name': coreClasses.symbolClass.name}); |
4093 {'name': coreClasses.symbolClass.name}); | |
4094 } | 3917 } |
4095 registry.registerNewStructure(node, | 3918 registry.registerNewStructure( |
| 3919 node, |
4096 new NewInvokeStructure( | 3920 new NewInvokeStructure( |
4097 new ConstructorAccessSemantics(kind, constructor, type), | 3921 new ConstructorAccessSemantics(kind, constructor, type), |
4098 selector)); | 3922 selector)); |
4099 } | 3923 } |
4100 | 3924 |
4101 return const NoneResult(); | 3925 return const NoneResult(); |
4102 } | 3926 } |
4103 | 3927 |
4104 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 3928 void checkConstMapKeysDontOverrideEquals( |
4105 MapConstantValue map) { | 3929 Spannable spannable, MapConstantValue map) { |
4106 for (ConstantValue key in map.keys) { | 3930 for (ConstantValue key in map.keys) { |
4107 if (!key.isObject) continue; | 3931 if (!key.isObject) continue; |
4108 ObjectConstantValue objectConstant = key; | 3932 ObjectConstantValue objectConstant = key; |
4109 DartType keyType = objectConstant.type; | 3933 DartType keyType = objectConstant.type; |
4110 ClassElement cls = keyType.element; | 3934 ClassElement cls = keyType.element; |
4111 if (cls == coreClasses.stringClass) continue; | 3935 if (cls == coreClasses.stringClass) continue; |
4112 Element equals = cls.lookupMember('=='); | 3936 Element equals = cls.lookupMember('=='); |
4113 if (equals.enclosingClass != coreClasses.objectClass) { | 3937 if (equals.enclosingClass != coreClasses.objectClass) { |
4114 reporter.reportErrorMessage( | 3938 reporter.reportErrorMessage(spannable, |
4115 spannable, | 3939 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, {'type': keyType}); |
4116 MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS, | |
4117 {'type': keyType}); | |
4118 } | 3940 } |
4119 } | 3941 } |
4120 } | 3942 } |
4121 | 3943 |
4122 void analyzeConstant(Node node, {enforceConst: true}) { | 3944 void analyzeConstant(Node node, {enforceConst: true}) { |
4123 ConstantExpression constant = | 3945 ConstantExpression constant = compiler.resolver.constantCompiler |
4124 compiler.resolver.constantCompiler.compileNode( | 3946 .compileNode(node, registry.mapping, enforceConst: enforceConst); |
4125 node, registry.mapping, enforceConst: enforceConst); | |
4126 | 3947 |
4127 if (constant == null) { | 3948 if (constant == null) { |
4128 assert(invariant(node, compiler.compilationFailed)); | 3949 assert(invariant(node, compiler.compilationFailed)); |
4129 return; | 3950 return; |
4130 } | 3951 } |
4131 | 3952 |
4132 ConstantValue value = compiler.constants.getConstantValue(constant); | 3953 ConstantValue value = compiler.constants.getConstantValue(constant); |
4133 if (value.isMap) { | 3954 if (value.isMap) { |
4134 checkConstMapKeysDontOverrideEquals(node, value); | 3955 checkConstMapKeysDontOverrideEquals(node, value); |
4135 } | 3956 } |
(...skipping 23 matching lines...) Expand all Loading... |
4159 } | 3980 } |
4160 return true; | 3981 return true; |
4161 } | 3982 } |
4162 | 3983 |
4163 /** | 3984 /** |
4164 * Try to resolve the constructor that is referred to by [node]. | 3985 * Try to resolve the constructor that is referred to by [node]. |
4165 * Note: this function may return an ErroneousFunctionElement instead of | 3986 * Note: this function may return an ErroneousFunctionElement instead of |
4166 * [:null:], if there is no corresponding constructor, class or library. | 3987 * [:null:], if there is no corresponding constructor, class or library. |
4167 */ | 3988 */ |
4168 ConstructorResult resolveConstructor(NewExpression node) { | 3989 ConstructorResult resolveConstructor(NewExpression node) { |
4169 return node.accept(new ConstructorResolver( | 3990 return node.accept( |
4170 compiler, this, inConstContext: node.isConst)); | 3991 new ConstructorResolver(compiler, this, inConstContext: node.isConst)); |
4171 } | 3992 } |
4172 | 3993 |
4173 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, | 3994 ConstructorResult resolveRedirectingFactory(RedirectingFactoryBody node, |
4174 {bool inConstContext: false}) { | 3995 {bool inConstContext: false}) { |
4175 return node.accept(new ConstructorResolver( | 3996 return node.accept(new ConstructorResolver(compiler, this, |
4176 compiler, this, inConstContext: inConstContext)); | 3997 inConstContext: inConstContext)); |
4177 } | 3998 } |
4178 | 3999 |
4179 DartType resolveTypeAnnotation(TypeAnnotation node, | 4000 DartType resolveTypeAnnotation(TypeAnnotation node, |
4180 {bool malformedIsError: false, | 4001 {bool malformedIsError: false, bool deferredIsMalformed: true}) { |
4181 bool deferredIsMalformed: true}) { | 4002 DartType type = typeResolver.resolveTypeAnnotation(this, node, |
4182 DartType type = typeResolver.resolveTypeAnnotation( | 4003 malformedIsError: malformedIsError, |
4183 this, node, malformedIsError: malformedIsError, | |
4184 deferredIsMalformed: deferredIsMalformed); | 4004 deferredIsMalformed: deferredIsMalformed); |
4185 if (inCheckContext) { | 4005 if (inCheckContext) { |
4186 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); | 4006 registry.registerTypeUse(new TypeUse.checkedModeCheck(type)); |
4187 } | 4007 } |
4188 return type; | 4008 return type; |
4189 } | 4009 } |
4190 | 4010 |
4191 ResolutionResult visitLiteralList(LiteralList node) { | 4011 ResolutionResult visitLiteralList(LiteralList node) { |
4192 bool isValidAsConstant = true; | 4012 bool isValidAsConstant = true; |
4193 sendIsMemberAccess = false; | 4013 sendIsMemberAccess = false; |
(...skipping 13 matching lines...) Expand all Loading... |
4207 reporter.reportWarningMessage( | 4027 reporter.reportWarningMessage( |
4208 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 4028 nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
4209 resolveTypeAnnotation(nodes.head); | 4029 resolveTypeAnnotation(nodes.head); |
4210 } | 4030 } |
4211 } | 4031 } |
4212 } | 4032 } |
4213 DartType listType; | 4033 DartType listType; |
4214 if (typeArgument != null) { | 4034 if (typeArgument != null) { |
4215 if (node.isConst && typeArgument.containsTypeVariables) { | 4035 if (node.isConst && typeArgument.containsTypeVariables) { |
4216 reporter.reportErrorMessage( | 4036 reporter.reportErrorMessage( |
4217 arguments.nodes.head, | 4037 arguments.nodes.head, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4218 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
4219 isValidAsConstant = false; | 4038 isValidAsConstant = false; |
4220 } | 4039 } |
4221 listType = coreTypes.listType(typeArgument); | 4040 listType = coreTypes.listType(typeArgument); |
4222 } else { | 4041 } else { |
4223 listType = coreTypes.listType(); | 4042 listType = coreTypes.listType(); |
4224 } | 4043 } |
4225 registry.registerLiteralList( | 4044 registry.registerLiteralList(node, listType, |
4226 node, | 4045 isConstant: node.isConst, isEmpty: node.elements.isEmpty); |
4227 listType, | |
4228 isConstant: node.isConst, | |
4229 isEmpty: node.elements.isEmpty); | |
4230 if (node.isConst) { | 4046 if (node.isConst) { |
4231 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; | 4047 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; |
4232 inConstantContext(() { | 4048 inConstantContext(() { |
4233 for (Node element in node.elements) { | 4049 for (Node element in node.elements) { |
4234 ResolutionResult elementResult = visit(element); | 4050 ResolutionResult elementResult = visit(element); |
4235 if (isValidAsConstant && elementResult.isConstant) { | 4051 if (isValidAsConstant && elementResult.isConstant) { |
4236 constantExpressions.add(elementResult.constant); | 4052 constantExpressions.add(elementResult.constant); |
4237 } else { | 4053 } else { |
4238 isValidAsConstant = false; | 4054 isValidAsConstant = false; |
4239 } | 4055 } |
4240 } | 4056 } |
4241 }); | 4057 }); |
4242 analyzeConstantDeferred(node); | 4058 analyzeConstantDeferred(node); |
4243 sendIsMemberAccess = false; | 4059 sendIsMemberAccess = false; |
4244 if (isValidAsConstant) { | 4060 if (isValidAsConstant) { |
4245 ConstantExpression constant = | 4061 ConstantExpression constant = |
4246 new ListConstantExpression(listType, constantExpressions); | 4062 new ListConstantExpression(listType, constantExpressions); |
4247 registry.setConstant(node, constant); | 4063 registry.setConstant(node, constant); |
4248 return new ConstantResult(node, constant); | 4064 return new ConstantResult(node, constant); |
4249 } | 4065 } |
4250 } else { | 4066 } else { |
4251 visit(node.elements); | 4067 visit(node.elements); |
4252 sendIsMemberAccess = false; | 4068 sendIsMemberAccess = false; |
4253 } | 4069 } |
4254 return const NoneResult(); | 4070 return const NoneResult(); |
4255 | |
4256 } | 4071 } |
4257 | 4072 |
4258 ResolutionResult visitConditional(Conditional node) { | 4073 ResolutionResult visitConditional(Conditional node) { |
4259 ResolutionResult conditionResult = | 4074 ResolutionResult conditionResult = |
4260 doInPromotionScope(node.condition, () => visit(node.condition)); | 4075 doInPromotionScope(node.condition, () => visit(node.condition)); |
4261 ResolutionResult thenResult = | 4076 ResolutionResult thenResult = doInPromotionScope( |
4262 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)
); | 4077 node.thenExpression, () => visit(node.thenExpression)); |
4263 ResolutionResult elseResult = visit(node.elseExpression); | 4078 ResolutionResult elseResult = visit(node.elseExpression); |
4264 if (conditionResult.isConstant && | 4079 if (conditionResult.isConstant && |
4265 thenResult.isConstant && | 4080 thenResult.isConstant && |
4266 elseResult.isConstant) { | 4081 elseResult.isConstant) { |
4267 ConstantExpression constant = new ConditionalConstantExpression( | 4082 ConstantExpression constant = new ConditionalConstantExpression( |
4268 conditionResult.constant, | 4083 conditionResult.constant, thenResult.constant, elseResult.constant); |
4269 thenResult.constant, | |
4270 elseResult.constant); | |
4271 registry.setConstant(node, constant); | 4084 registry.setConstant(node, constant); |
4272 return new ConstantResult(node, constant); | 4085 return new ConstantResult(node, constant); |
4273 } | 4086 } |
4274 return const NoneResult(); | 4087 return const NoneResult(); |
4275 } | 4088 } |
4276 | 4089 |
4277 ResolutionResult visitStringInterpolation(StringInterpolation node) { | 4090 ResolutionResult visitStringInterpolation(StringInterpolation node) { |
4278 // TODO(johnniwinther): This should be a consequence of the registration | 4091 // TODO(johnniwinther): This should be a consequence of the registration |
4279 // of [registerStringInterpolation]. | 4092 // of [registerStringInterpolation]. |
4280 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType)); | 4093 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType)); |
(...skipping 24 matching lines...) Expand all Loading... |
4305 return new ConstantResult(node, constant); | 4118 return new ConstantResult(node, constant); |
4306 } | 4119 } |
4307 return const NoneResult(); | 4120 return const NoneResult(); |
4308 } | 4121 } |
4309 | 4122 |
4310 ResolutionResult visitBreakStatement(BreakStatement node) { | 4123 ResolutionResult visitBreakStatement(BreakStatement node) { |
4311 JumpTarget target; | 4124 JumpTarget target; |
4312 if (node.target == null) { | 4125 if (node.target == null) { |
4313 target = statementScope.currentBreakTarget(); | 4126 target = statementScope.currentBreakTarget(); |
4314 if (target == null) { | 4127 if (target == null) { |
4315 reporter.reportErrorMessage( | 4128 reporter.reportErrorMessage(node, MessageKind.NO_BREAK_TARGET); |
4316 node, MessageKind.NO_BREAK_TARGET); | |
4317 return const NoneResult(); | 4129 return const NoneResult(); |
4318 } | 4130 } |
4319 target.isBreakTarget = true; | 4131 target.isBreakTarget = true; |
4320 } else { | 4132 } else { |
4321 String labelName = node.target.source; | 4133 String labelName = node.target.source; |
4322 LabelDefinition label = statementScope.lookupLabel(labelName); | 4134 LabelDefinition label = statementScope.lookupLabel(labelName); |
4323 if (label == null) { | 4135 if (label == null) { |
4324 reporter.reportErrorMessage( | 4136 reporter.reportErrorMessage( |
4325 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4137 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4326 return const NoneResult(); | 4138 return const NoneResult(); |
4327 } | 4139 } |
4328 target = label.target; | 4140 target = label.target; |
4329 if (!target.statement.isValidBreakTarget()) { | 4141 if (!target.statement.isValidBreakTarget()) { |
4330 reporter.reportErrorMessage( | 4142 reporter.reportErrorMessage(node.target, MessageKind.INVALID_BREAK); |
4331 node.target, MessageKind.INVALID_BREAK); | |
4332 return const NoneResult(); | 4143 return const NoneResult(); |
4333 } | 4144 } |
4334 label.setBreakTarget(); | 4145 label.setBreakTarget(); |
4335 registry.useLabel(node, label); | 4146 registry.useLabel(node, label); |
4336 } | 4147 } |
4337 registry.registerTargetOf(node, target); | 4148 registry.registerTargetOf(node, target); |
4338 return const NoneResult(); | 4149 return const NoneResult(); |
4339 } | 4150 } |
4340 | 4151 |
4341 ResolutionResult visitContinueStatement(ContinueStatement node) { | 4152 ResolutionResult visitContinueStatement(ContinueStatement node) { |
4342 JumpTarget target; | 4153 JumpTarget target; |
4343 if (node.target == null) { | 4154 if (node.target == null) { |
4344 target = statementScope.currentContinueTarget(); | 4155 target = statementScope.currentContinueTarget(); |
4345 if (target == null) { | 4156 if (target == null) { |
4346 reporter.reportErrorMessage( | 4157 reporter.reportErrorMessage(node, MessageKind.NO_CONTINUE_TARGET); |
4347 node, MessageKind.NO_CONTINUE_TARGET); | |
4348 return const NoneResult(); | 4158 return const NoneResult(); |
4349 } | 4159 } |
4350 target.isContinueTarget = true; | 4160 target.isContinueTarget = true; |
4351 } else { | 4161 } else { |
4352 String labelName = node.target.source; | 4162 String labelName = node.target.source; |
4353 LabelDefinition label = statementScope.lookupLabel(labelName); | 4163 LabelDefinition label = statementScope.lookupLabel(labelName); |
4354 if (label == null) { | 4164 if (label == null) { |
4355 reporter.reportErrorMessage( | 4165 reporter.reportErrorMessage( |
4356 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 4166 node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
4357 return const NoneResult(); | 4167 return const NoneResult(); |
4358 } | 4168 } |
4359 target = label.target; | 4169 target = label.target; |
4360 if (!target.statement.isValidContinueTarget()) { | 4170 if (!target.statement.isValidContinueTarget()) { |
4361 reporter.reportErrorMessage( | 4171 reporter.reportErrorMessage(node.target, MessageKind.INVALID_CONTINUE); |
4362 node.target, MessageKind.INVALID_CONTINUE); | |
4363 } | 4172 } |
4364 label.setContinueTarget(); | 4173 label.setContinueTarget(); |
4365 registry.useLabel(node, label); | 4174 registry.useLabel(node, label); |
4366 } | 4175 } |
4367 registry.registerTargetOf(node, target); | 4176 registry.registerTargetOf(node, target); |
4368 return const NoneResult(); | 4177 return const NoneResult(); |
4369 } | 4178 } |
4370 | 4179 |
4371 registerImplicitInvocation(Selector selector) { | 4180 registerImplicitInvocation(Selector selector) { |
4372 registry.registerDynamicUse(new DynamicUse(selector, null)); | 4181 registry.registerDynamicUse(new DynamicUse(selector, null)); |
4373 } | 4182 } |
4374 | 4183 |
4375 ResolutionResult visitAsyncForIn(AsyncForIn node) { | 4184 ResolutionResult visitAsyncForIn(AsyncForIn node) { |
4376 if (!currentAsyncMarker.isAsync) { | 4185 if (!currentAsyncMarker.isAsync) { |
4377 reporter.reportErrorMessage( | 4186 reporter.reportErrorMessage( |
4378 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); | 4187 node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN); |
4379 } | 4188 } |
4380 registry.registerFeature(Feature.ASYNC_FOR_IN); | 4189 registry.registerFeature(Feature.ASYNC_FOR_IN); |
4381 registry.registerDynamicUse( | 4190 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); |
4382 new DynamicUse(Selectors.current, null)); | 4191 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); |
4383 registry.registerDynamicUse( | |
4384 new DynamicUse(Selectors.moveNext, null)); | |
4385 | 4192 |
4386 visit(node.expression); | 4193 visit(node.expression); |
4387 | 4194 |
4388 Scope blockScope = new BlockScope(scope); | 4195 Scope blockScope = new BlockScope(scope); |
4389 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 4196 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
4390 visitLoopBodyIn(node, node.body, blockScope); | 4197 visitLoopBodyIn(node, node.body, blockScope); |
4391 return const NoneResult(); | 4198 return const NoneResult(); |
4392 } | 4199 } |
4393 | 4200 |
4394 ResolutionResult visitSyncForIn(SyncForIn node) { | 4201 ResolutionResult visitSyncForIn(SyncForIn node) { |
4395 registry.registerFeature(Feature.SYNC_FOR_IN); | 4202 registry.registerFeature(Feature.SYNC_FOR_IN); |
4396 registry.registerDynamicUse( | 4203 registry.registerDynamicUse(new DynamicUse(Selectors.iterator, null)); |
4397 new DynamicUse(Selectors.iterator, null)); | 4204 registry.registerDynamicUse(new DynamicUse(Selectors.current, null)); |
4398 registry.registerDynamicUse( | 4205 registry.registerDynamicUse(new DynamicUse(Selectors.moveNext, null)); |
4399 new DynamicUse(Selectors.current, null)); | |
4400 registry.registerDynamicUse( | |
4401 new DynamicUse(Selectors.moveNext, null)); | |
4402 | 4206 |
4403 visit(node.expression); | 4207 visit(node.expression); |
4404 | 4208 |
4405 Scope blockScope = new BlockScope(scope); | 4209 Scope blockScope = new BlockScope(scope); |
4406 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 4210 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
4407 visitLoopBodyIn(node, node.body, blockScope); | 4211 visitLoopBodyIn(node, node.body, blockScope); |
4408 return const NoneResult(); | 4212 return const NoneResult(); |
4409 } | 4213 } |
4410 | 4214 |
4411 void visitForInDeclaredIdentifierIn( | 4215 void visitForInDeclaredIdentifierIn( |
4412 Node declaration, | 4216 Node declaration, ForIn node, Scope blockScope) { |
4413 ForIn node, | |
4414 Scope blockScope) { | |
4415 LibraryElement library = enclosingElement.library; | 4217 LibraryElement library = enclosingElement.library; |
4416 | 4218 |
4417 bool oldAllowFinalWithoutInitializer = inLoopVariable; | 4219 bool oldAllowFinalWithoutInitializer = inLoopVariable; |
4418 inLoopVariable = true; | 4220 inLoopVariable = true; |
4419 visitIn(declaration, blockScope); | 4221 visitIn(declaration, blockScope); |
4420 inLoopVariable = oldAllowFinalWithoutInitializer; | 4222 inLoopVariable = oldAllowFinalWithoutInitializer; |
4421 | 4223 |
4422 Send send = declaration.asSend(); | 4224 Send send = declaration.asSend(); |
4423 VariableDefinitions variableDefinitions = | 4225 VariableDefinitions variableDefinitions = |
4424 declaration.asVariableDefinitions(); | 4226 declaration.asVariableDefinitions(); |
4425 Element loopVariable; | 4227 Element loopVariable; |
4426 Selector loopVariableSelector; | 4228 Selector loopVariableSelector; |
4427 if (send != null) { | 4229 if (send != null) { |
4428 loopVariable = registry.getDefinition(send); | 4230 loopVariable = registry.getDefinition(send); |
4429 Identifier identifier = send.selector.asIdentifier(); | 4231 Identifier identifier = send.selector.asIdentifier(); |
4430 if (identifier == null) { | 4232 if (identifier == null) { |
4431 reporter.reportErrorMessage( | 4233 reporter.reportErrorMessage(send.selector, MessageKind.INVALID_FOR_IN); |
4432 send.selector, MessageKind.INVALID_FOR_IN); | |
4433 } else { | 4234 } else { |
4434 loopVariableSelector = new Selector.setter( | 4235 loopVariableSelector = |
4435 new Name(identifier.source, library)); | 4236 new Selector.setter(new Name(identifier.source, library)); |
4436 } | 4237 } |
4437 if (send.receiver != null) { | 4238 if (send.receiver != null) { |
4438 reporter.reportErrorMessage( | 4239 reporter.reportErrorMessage(send.receiver, MessageKind.INVALID_FOR_IN); |
4439 send.receiver, MessageKind.INVALID_FOR_IN); | |
4440 } | 4240 } |
4441 } else if (variableDefinitions != null) { | 4241 } else if (variableDefinitions != null) { |
4442 Link<Node> nodes = variableDefinitions.definitions.nodes; | 4242 Link<Node> nodes = variableDefinitions.definitions.nodes; |
4443 if (!nodes.tail.isEmpty) { | 4243 if (!nodes.tail.isEmpty) { |
4444 reporter.reportErrorMessage( | 4244 reporter.reportErrorMessage( |
4445 nodes.tail.head, MessageKind.INVALID_FOR_IN); | 4245 nodes.tail.head, MessageKind.INVALID_FOR_IN); |
4446 } | 4246 } |
4447 Node first = nodes.head; | 4247 Node first = nodes.head; |
4448 Identifier identifier = first.asIdentifier(); | 4248 Identifier identifier = first.asIdentifier(); |
4449 if (identifier == null) { | 4249 if (identifier == null) { |
4450 reporter.reportErrorMessage( | 4250 reporter.reportErrorMessage(first, MessageKind.INVALID_FOR_IN); |
4451 first, MessageKind.INVALID_FOR_IN); | |
4452 } else { | 4251 } else { |
4453 loopVariableSelector = new Selector.setter( | 4252 loopVariableSelector = |
4454 new Name(identifier.source, library)); | 4253 new Selector.setter(new Name(identifier.source, library)); |
4455 loopVariable = registry.getDefinition(identifier); | 4254 loopVariable = registry.getDefinition(identifier); |
4456 } | 4255 } |
4457 } else { | 4256 } else { |
4458 reporter.reportErrorMessage( | 4257 reporter.reportErrorMessage(declaration, MessageKind.INVALID_FOR_IN); |
4459 declaration, MessageKind.INVALID_FOR_IN); | |
4460 } | 4258 } |
4461 if (loopVariableSelector != null) { | 4259 if (loopVariableSelector != null) { |
4462 registry.setSelector(declaration, loopVariableSelector); | 4260 registry.setSelector(declaration, loopVariableSelector); |
4463 if (loopVariable == null || loopVariable.isInstanceMember) { | 4261 if (loopVariable == null || loopVariable.isInstanceMember) { |
4464 registry.registerDynamicUse( | 4262 registry.registerDynamicUse(new DynamicUse(loopVariableSelector, null)); |
4465 new DynamicUse(loopVariableSelector, null)); | |
4466 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { | 4263 } else if (loopVariable.isStatic || loopVariable.isTopLevel) { |
4467 registry.registerStaticUse( | 4264 registry.registerStaticUse( |
4468 new StaticUse.staticSet(loopVariable.declaration)); | 4265 new StaticUse.staticSet(loopVariable.declaration)); |
4469 } | 4266 } |
4470 } else { | 4267 } else { |
4471 // The selector may only be null if we reported an error. | 4268 // The selector may only be null if we reported an error. |
4472 assert(invariant(declaration, compiler.compilationFailed)); | 4269 assert(invariant(declaration, compiler.compilationFailed)); |
4473 } | 4270 } |
4474 if (loopVariable != null) { | 4271 if (loopVariable != null) { |
4475 // loopVariable may be null if it could not be resolved. | 4272 // loopVariable may be null if it could not be resolved. |
(...skipping 16 matching lines...) Expand all Loading... |
4492 labelElements[labelName] = element; | 4289 labelElements[labelName] = element; |
4493 } | 4290 } |
4494 statementScope.enterLabelScope(labelElements); | 4291 statementScope.enterLabelScope(labelElements); |
4495 visit(node.statement); | 4292 visit(node.statement); |
4496 statementScope.exitLabelScope(); | 4293 statementScope.exitLabelScope(); |
4497 labelElements.forEach((String labelName, LabelDefinition element) { | 4294 labelElements.forEach((String labelName, LabelDefinition element) { |
4498 if (element.isTarget) { | 4295 if (element.isTarget) { |
4499 registry.defineLabel(element.label, element); | 4296 registry.defineLabel(element.label, element); |
4500 } else { | 4297 } else { |
4501 reporter.reportWarningMessage( | 4298 reporter.reportWarningMessage( |
4502 element.label, | 4299 element.label, MessageKind.UNUSED_LABEL, {'labelName': labelName}); |
4503 MessageKind.UNUSED_LABEL, | |
4504 {'labelName': labelName}); | |
4505 } | 4300 } |
4506 }); | 4301 }); |
4507 if (!targetElement.isTarget) { | 4302 if (!targetElement.isTarget) { |
4508 registry.undefineTarget(body); | 4303 registry.undefineTarget(body); |
4509 } | 4304 } |
4510 return const NoneResult(); | 4305 return const NoneResult(); |
4511 } | 4306 } |
4512 | 4307 |
4513 ResolutionResult visitLiteralMap(LiteralMap node) { | 4308 ResolutionResult visitLiteralMap(LiteralMap node) { |
4514 bool isValidAsConstant = true; | 4309 bool isValidAsConstant = true; |
(...skipping 26 matching lines...) Expand all Loading... |
4541 } | 4336 } |
4542 } | 4337 } |
4543 DartType mapType; | 4338 DartType mapType; |
4544 if (valueTypeArgument != null) { | 4339 if (valueTypeArgument != null) { |
4545 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); | 4340 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
4546 } else { | 4341 } else { |
4547 mapType = coreTypes.mapType(); | 4342 mapType = coreTypes.mapType(); |
4548 } | 4343 } |
4549 if (node.isConst && mapType.containsTypeVariables) { | 4344 if (node.isConst && mapType.containsTypeVariables) { |
4550 reporter.reportErrorMessage( | 4345 reporter.reportErrorMessage( |
4551 arguments, | 4346 arguments, MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
4552 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | |
4553 isValidAsConstant = false; | 4347 isValidAsConstant = false; |
4554 } | 4348 } |
4555 registry.registerMapLiteral( | 4349 registry.registerMapLiteral(node, mapType, |
4556 node, | 4350 isConstant: node.isConst, isEmpty: node.entries.isEmpty); |
4557 mapType, | |
4558 isConstant: node.isConst, | |
4559 isEmpty: node.entries.isEmpty); | |
4560 | 4351 |
4561 if (node.isConst) { | 4352 if (node.isConst) { |
4562 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 4353 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
4563 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 4354 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
4564 inConstantContext(() { | 4355 inConstantContext(() { |
4565 for (LiteralMapEntry entry in node.entries) { | 4356 for (LiteralMapEntry entry in node.entries) { |
4566 ResolutionResult keyResult = visit(entry.key); | 4357 ResolutionResult keyResult = visit(entry.key); |
4567 ResolutionResult valueResult = visit(entry.value); | 4358 ResolutionResult valueResult = visit(entry.value); |
4568 if (isValidAsConstant && | 4359 if (isValidAsConstant && |
4569 keyResult.isConstant && | 4360 keyResult.isConstant && |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4617 return equals.enclosingClass != coreClasses.objectClass; | 4408 return equals.enclosingClass != coreClasses.objectClass; |
4618 } | 4409 } |
4619 | 4410 |
4620 void checkCaseExpressions(SwitchStatement node) { | 4411 void checkCaseExpressions(SwitchStatement node) { |
4621 CaseMatch firstCase = null; | 4412 CaseMatch firstCase = null; |
4622 DartType firstCaseType = null; | 4413 DartType firstCaseType = null; |
4623 DiagnosticMessage error; | 4414 DiagnosticMessage error; |
4624 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; | 4415 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
4625 | 4416 |
4626 for (Link<Node> cases = node.cases.nodes; | 4417 for (Link<Node> cases = node.cases.nodes; |
4627 !cases.isEmpty; | 4418 !cases.isEmpty; |
4628 cases = cases.tail) { | 4419 cases = cases.tail) { |
4629 SwitchCase switchCase = cases.head; | 4420 SwitchCase switchCase = cases.head; |
4630 | 4421 |
4631 for (Node labelOrCase in switchCase.labelsAndCases) { | 4422 for (Node labelOrCase in switchCase.labelsAndCases) { |
4632 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 4423 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
4633 if (caseMatch == null) continue; | 4424 if (caseMatch == null) continue; |
4634 | 4425 |
4635 // Analyze the constant. | 4426 // Analyze the constant. |
4636 ConstantExpression constant = | 4427 ConstantExpression constant = |
4637 registry.getConstant(caseMatch.expression); | 4428 registry.getConstant(caseMatch.expression); |
4638 assert(invariant(node, constant != null, | 4429 assert(invariant(node, constant != null, |
4639 message: 'No constant computed for $node')); | 4430 message: 'No constant computed for $node')); |
4640 | 4431 |
4641 ConstantValue value = compiler.constants.getConstantValue(constant); | 4432 ConstantValue value = compiler.constants.getConstantValue(constant); |
4642 DartType caseType = value.getType(coreTypes);//typeOfConstant(value); | 4433 DartType caseType = value.getType(coreTypes); //typeOfConstant(value); |
4643 | 4434 |
4644 if (firstCaseType == null) { | 4435 if (firstCaseType == null) { |
4645 firstCase = caseMatch; | 4436 firstCase = caseMatch; |
4646 firstCaseType = caseType; | 4437 firstCaseType = caseType; |
4647 | 4438 |
4648 // We only report the bad type on the first class element. All others | 4439 // We only report the bad type on the first class element. All others |
4649 // get a "type differs" error. | 4440 // get a "type differs" error. |
4650 if (caseType == coreTypes.doubleType) { | 4441 if (caseType == coreTypes.doubleType) { |
4651 reporter.reportErrorMessage( | 4442 reporter.reportErrorMessage( |
4652 node, | 4443 node, |
4653 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4444 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
4654 {'type': "double"}); | 4445 {'type': "double"}); |
4655 } else if (caseType == coreTypes.functionType) { | 4446 } else if (caseType == coreTypes.functionType) { |
4656 reporter.reportErrorMessage( | 4447 reporter.reportErrorMessage( |
4657 node, MessageKind.SWITCH_CASE_FORBIDDEN, | 4448 node, MessageKind.SWITCH_CASE_FORBIDDEN, {'type': "Function"}); |
4658 {'type': "Function"}); | |
4659 } else if (value.isObject && overridesEquals(caseType)) { | 4449 } else if (value.isObject && overridesEquals(caseType)) { |
4660 reporter.reportErrorMessage( | 4450 reporter.reportErrorMessage( |
4661 firstCase.expression, | 4451 firstCase.expression, |
4662 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, | 4452 MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS, |
4663 {'type': caseType}); | 4453 {'type': caseType}); |
4664 } | 4454 } |
4665 } else { | 4455 } else { |
4666 if (caseType != firstCaseType) { | 4456 if (caseType != firstCaseType) { |
4667 if (error == null) { | 4457 if (error == null) { |
4668 error = reporter.createMessage( | 4458 error = reporter.createMessage( |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4702 continue; | 4492 continue; |
4703 } | 4493 } |
4704 Label label = labelOrCase; | 4494 Label label = labelOrCase; |
4705 String labelName = label.labelName; | 4495 String labelName = label.labelName; |
4706 | 4496 |
4707 LabelDefinition existingElement = continueLabels[labelName]; | 4497 LabelDefinition existingElement = continueLabels[labelName]; |
4708 if (existingElement != null) { | 4498 if (existingElement != null) { |
4709 // It's an error if the same label occurs twice in the same switch. | 4499 // It's an error if the same label occurs twice in the same switch. |
4710 reporter.reportError( | 4500 reporter.reportError( |
4711 reporter.createMessage( | 4501 reporter.createMessage( |
4712 label, | 4502 label, MessageKind.DUPLICATE_LABEL, {'labelName': labelName}), |
4713 MessageKind.DUPLICATE_LABEL, | |
4714 {'labelName': labelName}), | |
4715 <DiagnosticMessage>[ | 4503 <DiagnosticMessage>[ |
4716 reporter.createMessage( | 4504 reporter.createMessage(existingElement.label, |
4717 existingElement.label, | 4505 MessageKind.EXISTING_LABEL, {'labelName': labelName}), |
4718 MessageKind.EXISTING_LABEL, | |
4719 {'labelName': labelName}), | |
4720 ]); | 4506 ]); |
4721 } else { | 4507 } else { |
4722 // It's only a warning if it shadows another label. | 4508 // It's only a warning if it shadows another label. |
4723 existingElement = statementScope.lookupLabel(labelName); | 4509 existingElement = statementScope.lookupLabel(labelName); |
4724 if (existingElement != null) { | 4510 if (existingElement != null) { |
4725 reporter.reportWarning( | 4511 reporter.reportWarning( |
4726 reporter.createMessage( | 4512 reporter.createMessage(label, MessageKind.DUPLICATE_LABEL, |
4727 label, | |
4728 MessageKind.DUPLICATE_LABEL, | |
4729 {'labelName': labelName}), | 4513 {'labelName': labelName}), |
4730 <DiagnosticMessage>[ | 4514 <DiagnosticMessage>[ |
4731 reporter.createMessage( | 4515 reporter.createMessage(existingElement.label, |
4732 existingElement.label, | 4516 MessageKind.EXISTING_LABEL, {'labelName': labelName}), |
4733 MessageKind.EXISTING_LABEL, | |
4734 {'labelName': labelName}), | |
4735 ]); | 4517 ]); |
4736 } | 4518 } |
4737 } | 4519 } |
4738 | 4520 |
4739 JumpTarget targetElement = getOrDefineTarget(switchCase); | 4521 JumpTarget targetElement = getOrDefineTarget(switchCase); |
4740 LabelDefinition labelElement = targetElement.addLabel(label, labelName); | 4522 LabelDefinition labelElement = targetElement.addLabel(label, labelName); |
4741 registry.defineLabel(label, labelElement); | 4523 registry.defineLabel(label, labelElement); |
4742 continueLabels[labelName] = labelElement; | 4524 continueLabels[labelName] = labelElement; |
4743 } | 4525 } |
4744 cases = cases.tail; | 4526 cases = cases.tail; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4800 | 4582 |
4801 ResolutionResult visitCatchBlock(CatchBlock node) { | 4583 ResolutionResult visitCatchBlock(CatchBlock node) { |
4802 registry.registerFeature(Feature.CATCH_STATEMENT); | 4584 registry.registerFeature(Feature.CATCH_STATEMENT); |
4803 // Check that if catch part is present, then | 4585 // Check that if catch part is present, then |
4804 // it has one or two formal parameters. | 4586 // it has one or two formal parameters. |
4805 VariableDefinitions exceptionDefinition; | 4587 VariableDefinitions exceptionDefinition; |
4806 VariableDefinitions stackTraceDefinition; | 4588 VariableDefinitions stackTraceDefinition; |
4807 if (node.formals != null) { | 4589 if (node.formals != null) { |
4808 Link<Node> formalsToProcess = node.formals.nodes; | 4590 Link<Node> formalsToProcess = node.formals.nodes; |
4809 if (formalsToProcess.isEmpty) { | 4591 if (formalsToProcess.isEmpty) { |
4810 reporter.reportErrorMessage( | 4592 reporter.reportErrorMessage(node, MessageKind.EMPTY_CATCH_DECLARATION); |
4811 node, MessageKind.EMPTY_CATCH_DECLARATION); | |
4812 } else { | 4593 } else { |
4813 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); | 4594 exceptionDefinition = formalsToProcess.head.asVariableDefinitions(); |
4814 formalsToProcess = formalsToProcess.tail; | 4595 formalsToProcess = formalsToProcess.tail; |
4815 if (!formalsToProcess.isEmpty) { | 4596 if (!formalsToProcess.isEmpty) { |
4816 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); | 4597 stackTraceDefinition = formalsToProcess.head.asVariableDefinitions(); |
4817 formalsToProcess = formalsToProcess.tail; | 4598 formalsToProcess = formalsToProcess.tail; |
4818 if (!formalsToProcess.isEmpty) { | 4599 if (!formalsToProcess.isEmpty) { |
4819 for (Node extra in formalsToProcess) { | 4600 for (Node extra in formalsToProcess) { |
4820 reporter.reportErrorMessage( | 4601 reporter.reportErrorMessage( |
4821 extra, MessageKind.EXTRA_CATCH_DECLARATION); | 4602 extra, MessageKind.EXTRA_CATCH_DECLARATION); |
4822 } | 4603 } |
4823 } | 4604 } |
4824 registry.registerFeature(Feature.STACK_TRACE_IN_CATCH); | 4605 registry.registerFeature(Feature.STACK_TRACE_IN_CATCH); |
4825 } | 4606 } |
4826 } | 4607 } |
4827 | 4608 |
4828 // Check that the formals aren't optional and that they have no | 4609 // Check that the formals aren't optional and that they have no |
4829 // modifiers or type. | 4610 // modifiers or type. |
4830 for (Link<Node> link = node.formals.nodes; | 4611 for (Link<Node> link = node.formals.nodes; |
4831 !link.isEmpty; | 4612 !link.isEmpty; |
4832 link = link.tail) { | 4613 link = link.tail) { |
4833 // If the formal parameter is a node list, it means that it is a | 4614 // If the formal parameter is a node list, it means that it is a |
4834 // sequence of optional parameters. | 4615 // sequence of optional parameters. |
4835 NodeList nodeList = link.head.asNodeList(); | 4616 NodeList nodeList = link.head.asNodeList(); |
4836 if (nodeList != null) { | 4617 if (nodeList != null) { |
4837 reporter.reportErrorMessage( | 4618 reporter.reportErrorMessage( |
4838 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); | 4619 nodeList, MessageKind.OPTIONAL_PARAMETER_IN_CATCH); |
4839 } else { | 4620 } else { |
4840 VariableDefinitions declaration = link.head; | 4621 VariableDefinitions declaration = link.head; |
4841 for (Node modifier in declaration.modifiers.nodes) { | 4622 for (Node modifier in declaration.modifiers.nodes) { |
4842 reporter.reportErrorMessage( | 4623 reporter.reportErrorMessage( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4874 VariableElementX stackTraceElement = | 4655 VariableElementX stackTraceElement = |
4875 registry.getDefinition(stackTraceVariable); | 4656 registry.getDefinition(stackTraceVariable); |
4876 InterfaceType stackTraceType = coreTypes.stackTraceType; | 4657 InterfaceType stackTraceType = coreTypes.stackTraceType; |
4877 stackTraceElement.variables.type = stackTraceType; | 4658 stackTraceElement.variables.type = stackTraceType; |
4878 } | 4659 } |
4879 return const NoneResult(); | 4660 return const NoneResult(); |
4880 } | 4661 } |
4881 } | 4662 } |
4882 | 4663 |
4883 /// Looks up [name] in [scope] and unwraps the result. | 4664 /// Looks up [name] in [scope] and unwraps the result. |
4884 Element lookupInScope(DiagnosticReporter reporter, Node node, | 4665 Element lookupInScope( |
4885 Scope scope, String name) { | 4666 DiagnosticReporter reporter, Node node, Scope scope, String name) { |
4886 return Elements.unwrap(scope.lookup(name), reporter, node); | 4667 return Elements.unwrap(scope.lookup(name), reporter, node); |
4887 } | 4668 } |
OLD | NEW |