Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(237)

Side by Side Diff: pkg/compiler/lib/src/resolution/members.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/member_impl.dart ('k') | pkg/compiler/lib/src/resolution/operators.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698