OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of resolution; | 5 part of resolution; |
6 | 6 |
7 /** | 7 /** |
8 * Core implementation of resolution. | 8 * Core implementation of resolution. |
9 * | 9 * |
10 * Do not subclass or instantiate this class outside this library | 10 * Do not subclass or instantiate this class outside this library |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 ? Scope.buildEnclosingScope(element) : element.buildScope(), | 95 ? Scope.buildEnclosingScope(element) : element.buildScope(), |
96 // The type annotations on a typedef do not imply type checks. | 96 // The type annotations on a typedef do not imply type checks. |
97 // TODO(karlklose): clean this up (dartbug.com/8870). | 97 // TODO(karlklose): clean this up (dartbug.com/8870). |
98 inCheckContext = compiler.enableTypeAssertions && | 98 inCheckContext = compiler.enableTypeAssertions && |
99 !element.isLibrary && | 99 !element.isLibrary && |
100 !element.isTypedef && | 100 !element.isTypedef && |
101 !element.enclosingElement.isTypedef, | 101 !element.enclosingElement.isTypedef, |
102 inCatchBlock = false, | 102 inCatchBlock = false, |
103 super(compiler, registry); | 103 super(compiler, registry); |
104 | 104 |
| 105 CoreTypes get coreTypes => compiler.coreTypes; |
| 106 |
105 AsyncMarker get currentAsyncMarker { | 107 AsyncMarker get currentAsyncMarker { |
106 if (enclosingElement is FunctionElement) { | 108 if (enclosingElement is FunctionElement) { |
107 FunctionElement function = enclosingElement; | 109 FunctionElement function = enclosingElement; |
108 return function.asyncMarker; | 110 return function.asyncMarker; |
109 } | 111 } |
110 return AsyncMarker.SYNC; | 112 return AsyncMarker.SYNC; |
111 } | 113 } |
112 | 114 |
113 Element reportLookupErrorIfAny(Element result, Node node, String name) { | 115 Element reportLookupErrorIfAny(Element result, Node node, String name) { |
114 if (!Elements.isUnresolved(result)) { | 116 if (!Elements.isUnresolved(result)) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 return result; | 161 return result; |
160 } | 162 } |
161 | 163 |
162 doInPromotionScope(Node node, action()) { | 164 doInPromotionScope(Node node, action()) { |
163 promotionScope = promotionScope.prepend(node); | 165 promotionScope = promotionScope.prepend(node); |
164 var result = action(); | 166 var result = action(); |
165 promotionScope = promotionScope.tail; | 167 promotionScope = promotionScope.tail; |
166 return result; | 168 return result; |
167 } | 169 } |
168 | 170 |
169 visitInStaticContext(Node node) { | 171 ResolutionResult visitInStaticContext(Node node) { |
170 inStaticContext(() => visit(node)); | 172 return inStaticContext(() => visit(node)); |
171 } | 173 } |
172 | 174 |
173 ErroneousElement reportAndCreateErroneousElement( | 175 ErroneousElement reportAndCreateErroneousElement( |
174 Node node, | 176 Node node, |
175 String name, | 177 String name, |
176 MessageKind kind, | 178 MessageKind kind, |
177 Map arguments, | 179 Map arguments, |
178 {bool isError: false}) { | 180 {bool isError: false}) { |
179 if (isError) { | 181 if (isError) { |
180 compiler.reportError(node, kind, arguments); | 182 compiler.reportError(node, kind, arguments); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 registry.registerThrowNoSuchMethod(); | 225 registry.registerThrowNoSuchMethod(); |
224 return reportAndCreateErroneousElement( | 226 return reportAndCreateErroneousElement( |
225 node, name, kind, arguments, isError: inInitializer); | 227 node, name, kind, arguments, isError: inInitializer); |
226 } | 228 } |
227 | 229 |
228 ResolutionResult visitIdentifier(Identifier node) { | 230 ResolutionResult visitIdentifier(Identifier node) { |
229 if (node.isThis()) { | 231 if (node.isThis()) { |
230 if (!inInstanceContext) { | 232 if (!inInstanceContext) { |
231 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); | 233 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); |
232 } | 234 } |
233 return null; | 235 return const NoneResult(); |
234 } else if (node.isSuper()) { | 236 } else if (node.isSuper()) { |
235 if (!inInstanceContext) { | 237 if (!inInstanceContext) { |
236 error(node, MessageKind.NO_SUPER_IN_STATIC); | 238 error(node, MessageKind.NO_SUPER_IN_STATIC); |
237 } | 239 } |
238 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 240 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
239 error(node, MessageKind.INVALID_USE_OF_SUPER); | 241 error(node, MessageKind.INVALID_USE_OF_SUPER); |
240 } | 242 } |
241 return null; | 243 return const NoneResult(); |
242 } else { | 244 } else { |
243 String name = node.source; | 245 String name = node.source; |
244 Element element = lookupInScope(compiler, node, scope, name); | 246 Element element = lookupInScope(compiler, node, scope, name); |
245 if (Elements.isUnresolved(element) && name == 'dynamic') { | 247 if (Elements.isUnresolved(element) && name == 'dynamic') { |
246 // TODO(johnniwinther): Remove this hack when we can return more complex | 248 // TODO(johnniwinther): Remove this hack when we can return more complex |
247 // objects than [Element] from this method. | 249 // objects than [Element] from this method. |
248 element = compiler.typeClass; | 250 element = compiler.typeClass; |
249 // Set the type to be `dynamic` to mark that this is a type literal. | 251 // Set the type to be `dynamic` to mark that this is a type literal. |
250 registry.setType(node, const DynamicType()); | 252 registry.setType(node, const DynamicType()); |
251 } | 253 } |
(...skipping 13 matching lines...) Expand all Loading... |
265 } | 267 } |
266 } | 268 } |
267 if (!Elements.isUnresolved(element) && element.isClass) { | 269 if (!Elements.isUnresolved(element) && element.isClass) { |
268 ClassElement classElement = element; | 270 ClassElement classElement = element; |
269 classElement.ensureResolved(compiler); | 271 classElement.ensureResolved(compiler); |
270 } | 272 } |
271 return new ElementResult(registry.useElement(node, element)); | 273 return new ElementResult(registry.useElement(node, element)); |
272 } | 274 } |
273 } | 275 } |
274 | 276 |
275 ResolutionResult visitTypeAnnotation(TypeAnnotation node) { | 277 TypeResult visitTypeAnnotation(TypeAnnotation node) { |
276 DartType type = resolveTypeAnnotation(node); | 278 DartType type = resolveTypeAnnotation(node); |
277 if (inCheckContext) { | 279 if (inCheckContext) { |
278 registry.registerIsCheck(type); | 280 registry.registerIsCheck(type); |
279 } | 281 } |
280 return new TypeResult(type); | 282 return new TypeResult(type); |
281 } | 283 } |
282 | 284 |
283 bool isNamedConstructor(Send node) => node.receiver != null; | 285 bool isNamedConstructor(Send node) => node.receiver != null; |
284 | 286 |
285 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { | 287 Selector getRedirectingThisOrSuperConstructorSelector(Send node) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 compiler.resolver.constantCompiler.compileConstant(parameter); | 353 compiler.resolver.constantCompiler.compileConstant(parameter); |
352 }); | 354 }); |
353 }); | 355 }); |
354 if (inCheckContext) { | 356 if (inCheckContext) { |
355 functionParameters.forEachParameter((ParameterElement element) { | 357 functionParameters.forEachParameter((ParameterElement element) { |
356 registry.registerIsCheck(element.type); | 358 registry.registerIsCheck(element.type); |
357 }); | 359 }); |
358 } | 360 } |
359 } | 361 } |
360 | 362 |
361 visitCascade(Cascade node) { | 363 ResolutionResult visitCascade(Cascade node) { |
362 visit(node.expression); | 364 visit(node.expression); |
| 365 return const NoneResult(); |
363 } | 366 } |
364 | 367 |
365 visitCascadeReceiver(CascadeReceiver node) { | 368 ResolutionResult visitCascadeReceiver(CascadeReceiver node) { |
366 visit(node.expression); | 369 visit(node.expression); |
| 370 return const NoneResult(); |
367 } | 371 } |
368 | 372 |
369 visitClassNode(ClassNode node) { | 373 ResolutionResult visitIn(Node node, Scope nestedScope) { |
370 internalError(node, "shouldn't be called"); | |
371 } | |
372 | |
373 visitIn(Node node, Scope nestedScope) { | |
374 Scope oldScope = scope; | 374 Scope oldScope = scope; |
375 scope = nestedScope; | 375 scope = nestedScope; |
376 ResolutionResult result = visit(node); | 376 ResolutionResult result = visit(node); |
377 scope = oldScope; | 377 scope = oldScope; |
378 return result; | 378 return result; |
379 } | 379 } |
380 | 380 |
381 /** | 381 /** |
382 * Introduces new default targets for break and continue | 382 * Introduces new default targets for break and continue |
383 * before visiting the body of the loop | 383 * before visiting the body of the loop |
384 */ | 384 */ |
385 visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) { | 385 void visitLoopBodyIn(Loop loop, Node body, Scope bodyScope) { |
386 JumpTarget element = getOrDefineTarget(loop); | 386 JumpTarget element = getOrDefineTarget(loop); |
387 statementScope.enterLoop(element); | 387 statementScope.enterLoop(element); |
388 visitIn(body, bodyScope); | 388 visitIn(body, bodyScope); |
389 statementScope.exitLoop(); | 389 statementScope.exitLoop(); |
390 if (!element.isTarget) { | 390 if (!element.isTarget) { |
391 registry.undefineTarget(loop); | 391 registry.undefineTarget(loop); |
392 } | 392 } |
393 } | 393 } |
394 | 394 |
395 visitBlock(Block node) { | 395 ResolutionResult visitBlock(Block node) { |
396 visitIn(node.statements, new BlockScope(scope)); | 396 visitIn(node.statements, new BlockScope(scope)); |
| 397 return const NoneResult(); |
397 } | 398 } |
398 | 399 |
399 visitDoWhile(DoWhile node) { | 400 ResolutionResult visitDoWhile(DoWhile node) { |
400 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 401 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
401 visit(node.condition); | 402 visit(node.condition); |
| 403 return const NoneResult(); |
402 } | 404 } |
403 | 405 |
404 visitEmptyStatement(EmptyStatement node) { } | 406 ResolutionResult visitEmptyStatement(EmptyStatement node) { |
| 407 return const NoneResult(); |
| 408 } |
405 | 409 |
406 visitExpressionStatement(ExpressionStatement node) { | 410 ResolutionResult visitExpressionStatement(ExpressionStatement node) { |
407 ExpressionStatement oldExpressionStatement = currentExpressionStatement; | 411 ExpressionStatement oldExpressionStatement = currentExpressionStatement; |
408 currentExpressionStatement = node; | 412 currentExpressionStatement = node; |
409 visit(node.expression); | 413 visit(node.expression); |
410 currentExpressionStatement = oldExpressionStatement; | 414 currentExpressionStatement = oldExpressionStatement; |
| 415 return const NoneResult(); |
411 } | 416 } |
412 | 417 |
413 visitFor(For node) { | 418 ResolutionResult visitFor(For node) { |
414 Scope blockScope = new BlockScope(scope); | 419 Scope blockScope = new BlockScope(scope); |
415 visitIn(node.initializer, blockScope); | 420 visitIn(node.initializer, blockScope); |
416 visitIn(node.condition, blockScope); | 421 visitIn(node.condition, blockScope); |
417 visitIn(node.update, blockScope); | 422 visitIn(node.update, blockScope); |
418 visitLoopBodyIn(node, node.body, blockScope); | 423 visitLoopBodyIn(node, node.body, blockScope); |
| 424 return const NoneResult(); |
419 } | 425 } |
420 | 426 |
421 visitFunctionDeclaration(FunctionDeclaration node) { | 427 ResolutionResult visitFunctionDeclaration(FunctionDeclaration node) { |
422 assert(node.function.name != null); | 428 assert(node.function.name != null); |
423 visitFunctionExpression(node.function, inFunctionDeclaration: true); | 429 visitFunctionExpression(node.function, inFunctionDeclaration: true); |
| 430 return const NoneResult(); |
424 } | 431 } |
425 | 432 |
426 | 433 |
427 /// Process a local function declaration or an anonymous function expression. | 434 /// Process a local function declaration or an anonymous function expression. |
428 /// | 435 /// |
429 /// [inFunctionDeclaration] is `true` when the current node is the immediate | 436 /// [inFunctionDeclaration] is `true` when the current node is the immediate |
430 /// child of a function declaration. | 437 /// child of a function declaration. |
431 /// | 438 /// |
432 /// This is used to distinguish local function declarations from anonymous | 439 /// This is used to distinguish local function declarations from anonymous |
433 /// function expressions. | 440 /// function expressions. |
434 visitFunctionExpression(FunctionExpression node, | 441 ResolutionResult visitFunctionExpression( |
435 {bool inFunctionDeclaration: false}) { | 442 FunctionExpression node, |
| 443 {bool inFunctionDeclaration: false}) { |
436 bool doAddToScope = inFunctionDeclaration; | 444 bool doAddToScope = inFunctionDeclaration; |
437 if (!inFunctionDeclaration && node.name != null) { | 445 if (!inFunctionDeclaration && node.name != null) { |
438 compiler.reportError( | 446 compiler.reportError( |
439 node.name, | 447 node.name, |
440 MessageKind.NAMED_FUNCTION_EXPRESSION, | 448 MessageKind.NAMED_FUNCTION_EXPRESSION, |
441 {'name': node.name}); | 449 {'name': node.name}); |
442 } | 450 } |
443 visit(node.returnType); | 451 visit(node.returnType); |
444 String name; | 452 String name; |
445 if (node.name == null) { | 453 if (node.name == null) { |
(...skipping 27 matching lines...) Expand all Loading... |
473 StatementScope oldStatementScope = statementScope; | 481 StatementScope oldStatementScope = statementScope; |
474 statementScope = new StatementScope(); | 482 statementScope = new StatementScope(); |
475 visit(node.body); | 483 visit(node.body); |
476 statementScope = oldStatementScope; | 484 statementScope = oldStatementScope; |
477 | 485 |
478 scope = oldScope; | 486 scope = oldScope; |
479 enclosingElement = previousEnclosingElement; | 487 enclosingElement = previousEnclosingElement; |
480 | 488 |
481 registry.registerClosure(function); | 489 registry.registerClosure(function); |
482 registry.registerInstantiatedClass(compiler.functionClass); | 490 registry.registerInstantiatedClass(compiler.functionClass); |
| 491 return const NoneResult(); |
483 } | 492 } |
484 | 493 |
485 visitIf(If node) { | 494 ResolutionResult visitIf(If node) { |
486 doInPromotionScope(node.condition.expression, () => visit(node.condition)); | 495 doInPromotionScope(node.condition.expression, () => visit(node.condition)); |
487 doInPromotionScope(node.thenPart, | 496 doInPromotionScope(node.thenPart, |
488 () => visitIn(node.thenPart, new BlockScope(scope))); | 497 () => visitIn(node.thenPart, new BlockScope(scope))); |
489 visitIn(node.elsePart, new BlockScope(scope)); | 498 visitIn(node.elsePart, new BlockScope(scope)); |
| 499 return const NoneResult(); |
490 } | 500 } |
491 | 501 |
492 ResolutionResult resolveSend(Send node) { | 502 ResolutionResult resolveSend(Send node) { |
493 Selector selector = resolveSelector(node, null); | 503 Selector selector = resolveSelector(node, null); |
494 if (node.isSuperCall) registry.registerSuperUse(node); | 504 if (node.isSuperCall) registry.registerSuperUse(node); |
495 | 505 |
496 if (node.receiver == null) { | 506 if (node.receiver == null) { |
497 // If this send is of the form "assert(expr);", then | 507 // If this send is of the form "assert(expr);", then |
498 // this is an assertion. | 508 // this is an assertion. |
499 if (selector.isAssert) { | 509 if (selector.isAssert) { |
(...skipping 26 matching lines...) Expand all Loading... |
526 } | 536 } |
527 | 537 |
528 allowedCategory = oldCategory; | 538 allowedCategory = oldCategory; |
529 | 539 |
530 Element target; | 540 Element target; |
531 String name = node.selector.asIdentifier().source; | 541 String name = node.selector.asIdentifier().source; |
532 if (identical(name, 'this')) { | 542 if (identical(name, 'this')) { |
533 // TODO(ahe): Why is this using GENERIC? | 543 // TODO(ahe): Why is this using GENERIC? |
534 error(node.selector, MessageKind.GENERIC, | 544 error(node.selector, MessageKind.GENERIC, |
535 {'text': "expected an identifier"}); | 545 {'text': "expected an identifier"}); |
536 return null; | 546 return const NoneResult(); |
537 } else if (node.isSuperCall) { | 547 } else if (node.isSuperCall) { |
538 if (node.isOperator) { | 548 if (node.isOperator) { |
539 if (isUserDefinableOperator(name)) { | 549 if (isUserDefinableOperator(name)) { |
540 name = selector.name; | 550 name = selector.name; |
541 } else { | 551 } else { |
542 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); | 552 error(node.selector, MessageKind.ILLEGAL_SUPER_SEND, {'name': name}); |
543 return null; | 553 return const NoneResult(); |
544 } | 554 } |
545 } | 555 } |
546 if (!inInstanceContext) { | 556 if (!inInstanceContext) { |
547 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); | 557 error(node.receiver, MessageKind.NO_INSTANCE_AVAILABLE, {'name': name}); |
548 return null; | 558 return const NoneResult(); |
549 } | 559 } |
550 if (currentClass.supertype == null) { | 560 if (currentClass.supertype == null) { |
551 // This is just to guard against internal errors, so no need | 561 // This is just to guard against internal errors, so no need |
552 // for a real error message. | 562 // for a real error message. |
553 error(node.receiver, MessageKind.GENERIC, | 563 error(node.receiver, MessageKind.GENERIC, |
554 {'text': "Object has no superclass"}); | 564 {'text': "Object has no superclass"}); |
555 return null; | 565 return const NoneResult(); |
556 } | 566 } |
557 // TODO(johnniwinther): Ensure correct behavior if currentClass is a | 567 // TODO(johnniwinther): Ensure correct behavior if currentClass is a |
558 // patch. | 568 // patch. |
559 target = currentClass.lookupSuperByName(selector.memberName); | 569 target = currentClass.lookupSuperByName(selector.memberName); |
560 // [target] may be null which means invoking noSuchMethod on | 570 // [target] may be null which means invoking noSuchMethod on |
561 // super. | 571 // super. |
562 if (target == null) { | 572 if (target == null) { |
563 target = reportAndCreateErroneousElement( | 573 target = reportAndCreateErroneousElement( |
564 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, | 574 node, name, MessageKind.NO_SUCH_SUPER_MEMBER, |
565 {'className': currentClass.name, 'memberName': name}); | 575 {'className': currentClass.name, 'memberName': name}); |
566 // We still need to register the invocation, because we might | 576 // We still need to register the invocation, because we might |
567 // call [:super.noSuchMethod:] which calls | 577 // call [:super.noSuchMethod:] which calls |
568 // [JSInvocationMirror._invokeOn]. | 578 // [JSInvocationMirror._invokeOn]. |
569 registry.registerDynamicInvocation(selector); | 579 registry.registerDynamicInvocation(selector); |
570 registry.registerSuperNoSuchMethod(); | 580 registry.registerSuperNoSuchMethod(); |
571 } | 581 } |
572 } else if (resolvedReceiver == null || | 582 } else if (Elements.isUnresolved(resolvedReceiver.element)) { |
573 Elements.isUnresolved(resolvedReceiver.element)) { | 583 return const NoneResult(); |
574 return null; | |
575 } else if (resolvedReceiver.element.isClass) { | 584 } else if (resolvedReceiver.element.isClass) { |
576 ClassElement receiverClass = resolvedReceiver.element; | 585 ClassElement receiverClass = resolvedReceiver.element; |
577 receiverClass.ensureResolved(compiler); | 586 receiverClass.ensureResolved(compiler); |
578 if (node.isOperator) { | 587 if (node.isOperator) { |
579 // When the resolved receiver is a class, we can have two cases: | 588 // When the resolved receiver is a class, we can have two cases: |
580 // 1) a static send: C.foo, or | 589 // 1) a static send: C.foo, or |
581 // 2) an operator send, where the receiver is a class literal: 'C + 1'. | 590 // 2) an operator send, where the receiver is a class literal: 'C + 1'. |
582 // The following code that looks up the selector on the resolved | 591 // The following code that looks up the selector on the resolved |
583 // receiver will treat the second as the invocation of a static operator | 592 // receiver will treat the second as the invocation of a static operator |
584 // if the resolved receiver is not null. | 593 // if the resolved receiver is not null. |
585 return null; | 594 return const NoneResult(); |
586 } | 595 } |
587 MembersCreator.computeClassMembersByName( | 596 MembersCreator.computeClassMembersByName( |
588 compiler, receiverClass.declaration, name); | 597 compiler, receiverClass.declaration, name); |
589 target = receiverClass.lookupLocalMember(name); | 598 target = receiverClass.lookupLocalMember(name); |
590 if (target == null || target.isInstanceMember) { | 599 if (target == null || target.isInstanceMember) { |
591 registry.registerThrowNoSuchMethod(); | 600 registry.registerThrowNoSuchMethod(); |
592 // TODO(johnniwinther): With the simplified [TreeElements] invariant, | 601 // TODO(johnniwinther): With the simplified [TreeElements] invariant, |
593 // try to resolve injected elements if [currentClass] is in the patch | 602 // try to resolve injected elements if [currentClass] is in the patch |
594 // library of [receiverClass]. | 603 // library of [receiverClass]. |
595 | 604 |
(...skipping 27 matching lines...) Expand all Loading... |
623 AmbiguousElement ambiguous = target; | 632 AmbiguousElement ambiguous = target; |
624 target = reportAndCreateErroneousElement( | 633 target = reportAndCreateErroneousElement( |
625 node, name, ambiguous.messageKind, ambiguous.messageArguments); | 634 node, name, ambiguous.messageKind, ambiguous.messageArguments); |
626 ambiguous.diagnose(enclosingElement, compiler); | 635 ambiguous.diagnose(enclosingElement, compiler); |
627 return new ElementResult(target); | 636 return new ElementResult(target); |
628 } else if (target.kind == ElementKind.CLASS) { | 637 } else if (target.kind == ElementKind.CLASS) { |
629 ClassElement classElement = target; | 638 ClassElement classElement = target; |
630 classElement.ensureResolved(compiler); | 639 classElement.ensureResolved(compiler); |
631 } | 640 } |
632 } | 641 } |
633 return new ElementResult(target); | 642 return new ResolutionResult.forElement(target); |
634 } | 643 } |
635 | 644 |
636 static Selector computeSendSelector(Send node, | 645 static Selector computeSendSelector(Send node, |
637 LibraryElement library, | 646 LibraryElement library, |
638 Element element) { | 647 Element element) { |
639 // First determine if this is part of an assignment. | 648 // First determine if this is part of an assignment. |
640 bool isSet = node.asSendSet() != null; | 649 bool isSet = node.asSendSet() != null; |
641 | 650 |
642 if (node.isIndex) { | 651 if (node.isIndex) { |
643 return isSet ? new Selector.indexSet() : new Selector.index(); | 652 return isSet ? new Selector.indexSet() : new Selector.index(); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 type = resolveTypeAnnotation(typeNode); | 899 type = resolveTypeAnnotation(typeNode); |
891 sendStructure = new IsNotStructure(type); | 900 sendStructure = new IsNotStructure(type); |
892 } else { | 901 } else { |
893 // `e is T`. | 902 // `e is T`. |
894 Node typeNode = node.arguments.head; | 903 Node typeNode = node.arguments.head; |
895 type = resolveTypeAnnotation(typeNode); | 904 type = resolveTypeAnnotation(typeNode); |
896 sendStructure = new IsStructure(type); | 905 sendStructure = new IsStructure(type); |
897 } | 906 } |
898 registry.registerIsCheck(type); | 907 registry.registerIsCheck(type); |
899 registry.registerSendStructure(node, sendStructure); | 908 registry.registerSendStructure(node, sendStructure); |
900 return null; | 909 return const NoneResult(); |
901 } | 910 } |
902 | 911 |
903 /// Handle a type cast expression, like `a as T`. | 912 /// Handle a type cast expression, like `a as T`. |
904 ResolutionResult handleAs(Send node) { | 913 ResolutionResult handleAs(Send node) { |
905 Node expression = node.receiver; | 914 Node expression = node.receiver; |
906 visitExpression(expression); | 915 visitExpression(expression); |
907 | 916 |
908 Node typeNode = node.arguments.head; | 917 Node typeNode = node.arguments.head; |
909 DartType type = resolveTypeAnnotation(typeNode); | 918 DartType type = resolveTypeAnnotation(typeNode); |
910 registry.registerAsCheck(type); | 919 registry.registerAsCheck(type); |
911 registry.registerSendStructure(node, new AsStructure(type)); | 920 registry.registerSendStructure(node, new AsStructure(type)); |
912 return null; | 921 return const NoneResult(); |
913 } | 922 } |
914 | 923 |
915 /// Handle the unary expression of an unresolved unary operator [text], like | 924 /// Handle the unary expression of an unresolved unary operator [text], like |
916 /// the no longer supported `+a`. | 925 /// the no longer supported `+a`. |
917 ResolutionResult handleUnresolvedUnary(Send node, String text) { | 926 ResolutionResult handleUnresolvedUnary(Send node, String text) { |
918 Node expression = node.receiver; | 927 Node expression = node.receiver; |
919 if (node.isSuperCall) { | 928 if (node.isSuperCall) { |
920 checkSuperAccess(node); | 929 checkSuperAccess(node); |
921 } else { | 930 } else { |
922 visitExpression(expression); | 931 visitExpression(expression); |
923 } | 932 } |
924 | 933 |
925 registry.registerSendStructure(node, const InvalidUnaryStructure()); | 934 registry.registerSendStructure(node, const InvalidUnaryStructure()); |
926 return null; | 935 return const NoneResult(); |
927 } | 936 } |
928 | 937 |
929 /// Handle the unary expression of a user definable unary [operator], like | 938 /// Handle the unary expression of a user definable unary [operator], like |
930 /// `-a`, and `-super`. | 939 /// `-a`, and `-super`. |
931 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { | 940 ResolutionResult handleUserDefinableUnary(Send node, UnaryOperator operator) { |
| 941 ResolutionResult result = const NoneResult(); |
932 Node expression = node.receiver; | 942 Node expression = node.receiver; |
933 Selector selector = operator.selector; | 943 Selector selector = operator.selector; |
934 // TODO(johnniwinther): Remove this when all information goes through the | 944 // TODO(johnniwinther): Remove this when all information goes through the |
935 // [SendStructure]. | 945 // [SendStructure]. |
936 registry.setSelector(node, selector); | 946 registry.setSelector(node, selector); |
937 | 947 |
938 AccessSemantics semantics; | 948 AccessSemantics semantics; |
939 if (node.isSuperCall) { | 949 if (node.isSuperCall) { |
940 if (checkSuperAccess(node)) { | 950 if (checkSuperAccess(node)) { |
941 semantics = computeSuperSemantics(node, selector); | 951 semantics = computeSuperSemantics(node, selector); |
942 // TODO(johnniwinther): Add information to [AccessSemantics] about | 952 // TODO(johnniwinther): Add information to [AccessSemantics] about |
943 // whether it is erroneous. | 953 // whether it is erroneous. |
944 if (semantics.kind == AccessKind.SUPER_METHOD) { | 954 if (semantics.kind == AccessKind.SUPER_METHOD) { |
945 registry.registerStaticUse(semantics.element.declaration); | 955 registry.registerStaticUse(semantics.element.declaration); |
946 } | 956 } |
947 // TODO(johnniwinther): Remove this when all information goes through | 957 // TODO(johnniwinther): Remove this when all information goes through |
948 // the [SendStructure]. | 958 // the [SendStructure]. |
949 registry.useElement(node, semantics.element); | 959 registry.useElement(node, semantics.element); |
950 } | 960 } |
951 } else { | 961 } else { |
952 visitExpression(expression); | 962 ResolutionResult expressionResult = visitExpression(expression); |
953 semantics = new DynamicAccess.dynamicProperty(expression); | 963 semantics = new DynamicAccess.dynamicProperty(expression); |
954 registry.registerDynamicInvocation(selector); | 964 registry.registerDynamicInvocation(selector); |
| 965 |
| 966 if (expressionResult.isConstant) { |
| 967 bool isValidConstant; |
| 968 ConstantExpression expressionConstant = expressionResult.constant; |
| 969 DartType knownExpressionType = |
| 970 expressionConstant.getKnownType(coreTypes); |
| 971 switch (operator.kind) { |
| 972 case UnaryOperatorKind.COMPLEMENT: |
| 973 isValidConstant = |
| 974 knownExpressionType == coreTypes.intType; |
| 975 break; |
| 976 case UnaryOperatorKind.NEGATE: |
| 977 isValidConstant = |
| 978 knownExpressionType == coreTypes.intType || |
| 979 knownExpressionType == coreTypes.doubleType; |
| 980 break; |
| 981 case UnaryOperatorKind.NOT: |
| 982 internalError(node, |
| 983 "Unexpected user definable unary operator: $operator"); |
| 984 } |
| 985 if (isValidConstant) { |
| 986 // TODO(johnniwinther): Handle potentially invalid constant |
| 987 // expressions. |
| 988 ConstantExpression constant = |
| 989 new UnaryConstantExpression(operator, expressionConstant); |
| 990 registry.setConstant(node, constant); |
| 991 result = new ConstantResult(node, constant); |
| 992 } |
| 993 } |
955 } | 994 } |
956 if (semantics != null) { | 995 if (semantics != null) { |
957 // TODO(johnniwinther): Support invalid super access as an | 996 // TODO(johnniwinther): Support invalid super access as an |
958 // [AccessSemantics]. | 997 // [AccessSemantics]. |
959 registry.registerSendStructure(node, | 998 registry.registerSendStructure(node, |
960 new UnaryStructure(semantics, operator)); | 999 new UnaryStructure(semantics, operator)); |
961 } | 1000 } |
962 return null; | 1001 return result; |
963 } | 1002 } |
964 | 1003 |
965 /// Handle a not expression, like `!a`. | 1004 /// Handle a not expression, like `!a`. |
966 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1005 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
967 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1006 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); |
968 | 1007 |
969 Node expression = node.receiver; | 1008 Node expression = node.receiver; |
970 visitExpression(expression); | 1009 ResolutionResult result = visitExpression(expression); |
971 registry.registerSendStructure(node, | 1010 registry.registerSendStructure(node, |
972 new NotStructure(new DynamicAccess.dynamicProperty(expression))); | 1011 new NotStructure(new DynamicAccess.dynamicProperty(expression))); |
973 return null; | 1012 |
| 1013 if (result.isConstant) { |
| 1014 ConstantExpression expressionConstant = result.constant; |
| 1015 if (expressionConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1016 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1017 ConstantExpression constant = |
| 1018 new UnaryConstantExpression(operator, expressionConstant); |
| 1019 registry.setConstant(node, constant); |
| 1020 return new ConstantResult(node, constant); |
| 1021 } |
| 1022 } |
| 1023 |
| 1024 return const NoneResult(); |
974 } | 1025 } |
975 | 1026 |
976 /// Handle a logical and expression, like `a && b`. | 1027 /// Handle a logical and expression, like `a && b`. |
977 ResolutionResult handleLogicalAnd(Send node) { | 1028 ResolutionResult handleLogicalAnd(Send node) { |
978 Node left = node.receiver; | 1029 Node left = node.receiver; |
979 Node right = node.arguments.head; | 1030 Node right = node.arguments.head; |
980 doInPromotionScope(left, () => visitExpression(left)); | 1031 ResolutionResult leftResult = |
981 doInPromotionScope(right, () => visitExpression(right)); | 1032 doInPromotionScope(left, () => visitExpression(left)); |
| 1033 ResolutionResult rightResult = |
| 1034 doInPromotionScope(right, () => visitExpression(right)); |
982 registry.registerSendStructure(node, const LogicalAndStructure()); | 1035 registry.registerSendStructure(node, const LogicalAndStructure()); |
983 return null; | 1036 |
| 1037 if (leftResult.isConstant && rightResult.isConstant) { |
| 1038 ConstantExpression leftConstant = leftResult.constant; |
| 1039 ConstantExpression rightConstant = rightResult.constant; |
| 1040 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1041 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1042 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1043 ConstantExpression constant = new BinaryConstantExpression( |
| 1044 leftConstant, |
| 1045 BinaryOperator.LOGICAL_AND, |
| 1046 rightConstant); |
| 1047 registry.setConstant(node, constant); |
| 1048 return new ConstantResult(node, constant); |
| 1049 } |
| 1050 } |
| 1051 |
| 1052 return const NoneResult(); |
984 } | 1053 } |
985 | 1054 |
986 /// Handle a logical or expression, like `a || b`. | 1055 /// Handle a logical or expression, like `a || b`. |
987 ResolutionResult handleLogicalOr(Send node) { | 1056 ResolutionResult handleLogicalOr(Send node) { |
988 Node left = node.receiver; | 1057 Node left = node.receiver; |
989 Node right = node.arguments.head; | 1058 Node right = node.arguments.head; |
990 visitExpression(left); | 1059 ResolutionResult leftResult = visitExpression(left); |
991 visitExpression(right); | 1060 ResolutionResult rightResult = visitExpression(right); |
992 registry.registerSendStructure(node, const LogicalOrStructure()); | 1061 registry.registerSendStructure(node, const LogicalOrStructure()); |
993 return null; | 1062 |
| 1063 if (leftResult.isConstant && rightResult.isConstant) { |
| 1064 ConstantExpression leftConstant = leftResult.constant; |
| 1065 ConstantExpression rightConstant = rightResult.constant; |
| 1066 if (leftConstant.getKnownType(coreTypes) == coreTypes.boolType && |
| 1067 rightConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1068 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1069 ConstantExpression constant = new BinaryConstantExpression( |
| 1070 leftConstant, |
| 1071 BinaryOperator.LOGICAL_OR, |
| 1072 rightConstant); |
| 1073 registry.setConstant(node, constant); |
| 1074 return new ConstantResult(node, constant); |
| 1075 } |
| 1076 } |
| 1077 return const NoneResult(); |
994 } | 1078 } |
995 | 1079 |
996 /// Handle an if-null expression, like `a ?? b`. | 1080 /// Handle an if-null expression, like `a ?? b`. |
997 ResolutionResult handleIfNull(Send node) { | 1081 ResolutionResult handleIfNull(Send node) { |
998 Node left = node.receiver; | 1082 Node left = node.receiver; |
999 Node right = node.arguments.head; | 1083 Node right = node.arguments.head; |
1000 visitExpression(left); | 1084 visitExpression(left); |
1001 visitExpression(right); | 1085 visitExpression(right); |
1002 registry.registerSendStructure(node, const IfNullStructure()); | 1086 registry.registerSendStructure(node, const IfNullStructure()); |
1003 return null; | 1087 return const NoneResult(); |
1004 } | 1088 } |
1005 | 1089 |
1006 /// Handle the binary expression of an unresolved binary operator [text], like | 1090 /// Handle the binary expression of an unresolved binary operator [text], like |
1007 /// the no longer supported `a === b`. | 1091 /// the no longer supported `a === b`. |
1008 ResolutionResult handleUnresolvedBinary(Send node, String text) { | 1092 ResolutionResult handleUnresolvedBinary(Send node, String text) { |
1009 Node left = node.receiver; | 1093 Node left = node.receiver; |
1010 Node right = node.arguments.head; | 1094 Node right = node.arguments.head; |
1011 if (node.isSuperCall) { | 1095 if (node.isSuperCall) { |
1012 checkSuperAccess(node); | 1096 checkSuperAccess(node); |
1013 } else { | 1097 } else { |
1014 visitExpression(left); | 1098 visitExpression(left); |
1015 } | 1099 } |
1016 visitExpression(right); | 1100 visitExpression(right); |
1017 registry.registerSendStructure(node, const InvalidBinaryStructure()); | 1101 registry.registerSendStructure(node, const InvalidBinaryStructure()); |
1018 return null; | 1102 return const NoneResult(); |
1019 } | 1103 } |
1020 | 1104 |
1021 /// Handle the binary expression of a user definable binary [operator], like | 1105 /// Handle the binary expression of a user definable binary [operator], like |
1022 /// `a + b`, `super + b`, `a == b` and `a != b`. | 1106 /// `a + b`, `super + b`, `a == b` and `a != b`. |
1023 ResolutionResult handleUserDefinableBinary(Send node, | 1107 ResolutionResult handleUserDefinableBinary(Send node, |
1024 BinaryOperator operator) { | 1108 BinaryOperator operator) { |
| 1109 ResolutionResult result = const NoneResult(); |
1025 Node left = node.receiver; | 1110 Node left = node.receiver; |
1026 Node right = node.arguments.head; | 1111 Node right = node.arguments.head; |
1027 AccessSemantics semantics; | 1112 AccessSemantics semantics; |
1028 Selector selector; | 1113 Selector selector; |
1029 if (operator.kind == BinaryOperatorKind.INDEX) { | 1114 if (operator.kind == BinaryOperatorKind.INDEX) { |
1030 selector = new Selector.index(); | 1115 selector = new Selector.index(); |
1031 } else { | 1116 } else { |
1032 selector = new Selector.binaryOperator(operator.selectorName); | 1117 selector = new Selector.binaryOperator(operator.selectorName); |
1033 } | 1118 } |
1034 // TODO(johnniwinther): Remove this when all information goes through the | 1119 // TODO(johnniwinther): Remove this when all information goes through the |
1035 // [SendStructure]. | 1120 // [SendStructure]. |
1036 registry.setSelector(node, selector); | 1121 registry.setSelector(node, selector); |
1037 | 1122 |
1038 if (node.isSuperCall) { | 1123 if (node.isSuperCall) { |
1039 if (checkSuperAccess(node)) { | 1124 if (checkSuperAccess(node)) { |
1040 semantics = computeSuperSemantics(node, selector); | 1125 semantics = computeSuperSemantics(node, selector); |
1041 // TODO(johnniwinther): Add information to [AccessSemantics] about | 1126 // TODO(johnniwinther): Add information to [AccessSemantics] about |
1042 // whether it is erroneous. | 1127 // whether it is erroneous. |
1043 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1128 if (semantics.kind == AccessKind.SUPER_METHOD) { |
1044 registry.registerStaticUse(semantics.element.declaration); | 1129 registry.registerStaticUse(semantics.element.declaration); |
1045 } | 1130 } |
1046 // TODO(johnniwinther): Remove this when all information goes through | 1131 // TODO(johnniwinther): Remove this when all information goes through |
1047 // the [SendStructure]. | 1132 // the [SendStructure]. |
1048 registry.useElement(node, semantics.element); | 1133 registry.useElement(node, semantics.element); |
1049 } | 1134 } |
| 1135 visitExpression(right); |
1050 } else { | 1136 } else { |
1051 visitExpression(left); | 1137 ResolutionResult leftResult = visitExpression(left); |
| 1138 ResolutionResult rightResult = visitExpression(right); |
1052 registry.registerDynamicInvocation(selector); | 1139 registry.registerDynamicInvocation(selector); |
1053 semantics = new DynamicAccess.dynamicProperty(left); | 1140 semantics = new DynamicAccess.dynamicProperty(left); |
| 1141 |
| 1142 if (leftResult.isConstant && rightResult.isConstant) { |
| 1143 bool isValidConstant; |
| 1144 ConstantExpression leftConstant = leftResult.constant; |
| 1145 ConstantExpression rightConstant = leftResult.constant; |
| 1146 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
| 1147 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
| 1148 switch (operator.kind) { |
| 1149 case BinaryOperatorKind.EQ: |
| 1150 case BinaryOperatorKind.NOT_EQ: |
| 1151 isValidConstant = |
| 1152 (knownLeftType == coreTypes.intType || |
| 1153 knownLeftType == coreTypes.doubleType || |
| 1154 knownLeftType == coreTypes.stringType || |
| 1155 knownLeftType == coreTypes.boolType || |
| 1156 knownLeftType == coreTypes.nullType) && |
| 1157 (knownRightType == coreTypes.intType || |
| 1158 knownRightType == coreTypes.doubleType || |
| 1159 knownRightType == coreTypes.stringType || |
| 1160 knownRightType == coreTypes.boolType || |
| 1161 knownRightType == coreTypes.nullType); |
| 1162 break; |
| 1163 case BinaryOperatorKind.ADD: |
| 1164 isValidConstant = |
| 1165 (knownLeftType == coreTypes.intType || |
| 1166 knownLeftType == coreTypes.doubleType || |
| 1167 knownLeftType == coreTypes.stringType) && |
| 1168 (knownRightType == coreTypes.intType || |
| 1169 knownRightType == coreTypes.doubleType || |
| 1170 knownRightType == coreTypes.stringType); |
| 1171 break; |
| 1172 case BinaryOperatorKind.SUB: |
| 1173 case BinaryOperatorKind.MUL: |
| 1174 case BinaryOperatorKind.DIV: |
| 1175 case BinaryOperatorKind.IDIV: |
| 1176 case BinaryOperatorKind.MOD: |
| 1177 case BinaryOperatorKind.GTEQ: |
| 1178 case BinaryOperatorKind.GT: |
| 1179 case BinaryOperatorKind.LTEQ: |
| 1180 case BinaryOperatorKind.LT: |
| 1181 isValidConstant = |
| 1182 (knownLeftType == coreTypes.intType || |
| 1183 knownLeftType == coreTypes.doubleType) && |
| 1184 (knownRightType == coreTypes.intType || |
| 1185 knownRightType == coreTypes.doubleType); |
| 1186 break; |
| 1187 case BinaryOperatorKind.SHL: |
| 1188 case BinaryOperatorKind.SHR: |
| 1189 case BinaryOperatorKind.AND: |
| 1190 case BinaryOperatorKind.OR: |
| 1191 case BinaryOperatorKind.XOR: |
| 1192 isValidConstant = |
| 1193 knownLeftType == coreTypes.intType && |
| 1194 knownRightType == coreTypes.intType; |
| 1195 break; |
| 1196 case BinaryOperatorKind.INDEX: |
| 1197 isValidConstant = false; |
| 1198 break; |
| 1199 case BinaryOperatorKind.LOGICAL_AND: |
| 1200 case BinaryOperatorKind.LOGICAL_OR: |
| 1201 case BinaryOperatorKind.IF_NULL: |
| 1202 internalError(node, "Unexpected binary operator '${operator}'."); |
| 1203 break; |
| 1204 } |
| 1205 if (isValidConstant) { |
| 1206 // TODO(johnniwinther): Handle potentially invalid constant |
| 1207 // expressions. |
| 1208 ConstantExpression constant = new BinaryConstantExpression( |
| 1209 leftResult.constant, |
| 1210 operator, |
| 1211 rightResult.constant); |
| 1212 registry.setConstant(node, constant); |
| 1213 result = new ConstantResult(node, constant); |
| 1214 } |
| 1215 } |
1054 } | 1216 } |
1055 visitExpression(right); | |
1056 | 1217 |
1057 if (semantics != null) { | 1218 if (semantics != null) { |
1058 // TODO(johnniwinther): Support invalid super access as an | 1219 // TODO(johnniwinther): Support invalid super access as an |
1059 // [AccessSemantics]. | 1220 // [AccessSemantics]. |
1060 SendStructure sendStructure; | 1221 SendStructure sendStructure; |
1061 switch (operator.kind) { | 1222 switch (operator.kind) { |
1062 case BinaryOperatorKind.EQ: | 1223 case BinaryOperatorKind.EQ: |
1063 sendStructure = new EqualsStructure(semantics); | 1224 sendStructure = new EqualsStructure(semantics); |
1064 break; | 1225 break; |
1065 case BinaryOperatorKind.NOT_EQ: | 1226 case BinaryOperatorKind.NOT_EQ: |
(...skipping 20 matching lines...) Expand all Loading... |
1086 sendStructure = new BinaryStructure(semantics, operator); | 1247 sendStructure = new BinaryStructure(semantics, operator); |
1087 break; | 1248 break; |
1088 case BinaryOperatorKind.LOGICAL_AND: | 1249 case BinaryOperatorKind.LOGICAL_AND: |
1089 case BinaryOperatorKind.LOGICAL_OR: | 1250 case BinaryOperatorKind.LOGICAL_OR: |
1090 case BinaryOperatorKind.IF_NULL: | 1251 case BinaryOperatorKind.IF_NULL: |
1091 internalError(node, "Unexpected binary operator '${operator}'."); | 1252 internalError(node, "Unexpected binary operator '${operator}'."); |
1092 break; | 1253 break; |
1093 } | 1254 } |
1094 registry.registerSendStructure(node, sendStructure); | 1255 registry.registerSendStructure(node, sendStructure); |
1095 } | 1256 } |
1096 return null; | 1257 return result; |
1097 } | 1258 } |
1098 | 1259 |
1099 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. | 1260 /// Handle an invocation of an expression, like `(){}()` or `(foo)()`. |
1100 ResolutionResult handleExpressionInvoke(Send node) { | 1261 ResolutionResult handleExpressionInvoke(Send node) { |
1101 assert(invariant(node, node.isCall, | 1262 assert(invariant(node, node.isCall, |
1102 message: "Unexpected expression: $node")); | 1263 message: "Unexpected expression: $node")); |
1103 Node expression = node.selector; | 1264 Node expression = node.selector; |
1104 visitExpression(expression); | 1265 visitExpression(expression); |
1105 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1266 CallStructure callStructure = resolveArguments(node.argumentsNode); |
1106 Selector selector = callStructure.callSelector; | 1267 Selector selector = callStructure.callSelector; |
1107 // TODO(johnniwinther): Remove this when all information goes through the | 1268 // TODO(johnniwinther): Remove this when all information goes through the |
1108 // [SendStructure]. | 1269 // [SendStructure]. |
1109 registry.setSelector(node, selector); | 1270 registry.setSelector(node, selector); |
1110 registry.registerDynamicInvocation(selector); | 1271 registry.registerDynamicInvocation(selector); |
1111 registry.registerSendStructure(node, | 1272 registry.registerSendStructure(node, |
1112 new InvokeStructure(new AccessSemantics.expression(), selector)); | 1273 new InvokeStructure(new AccessSemantics.expression(), selector)); |
1113 return null; | 1274 return const NoneResult(); |
1114 } | 1275 } |
1115 | 1276 |
1116 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. | 1277 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. |
1117 ResolutionResult handleAssert(Send node) { | 1278 ResolutionResult handleAssert(Send node) { |
1118 assert(invariant(node, node.isCall, | 1279 assert(invariant(node, node.isCall, |
1119 message: "Unexpected assert: $node")); | 1280 message: "Unexpected assert: $node")); |
1120 // If this send is of the form "assert(expr);", then | 1281 // If this send is of the form "assert(expr);", then |
1121 // this is an assertion. | 1282 // this is an assertion. |
1122 | 1283 |
1123 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1284 CallStructure callStructure = resolveArguments(node.argumentsNode); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 assert(invariant(node, node.isPropertyAccess)); | 1316 assert(invariant(node, node.isPropertyAccess)); |
1156 selector = new Selector( | 1317 selector = new Selector( |
1157 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 1318 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
1158 registry.registerDynamicGetter(selector); | 1319 registry.registerDynamicGetter(selector); |
1159 sendStructure = new GetStructure(accessSemantics, selector); | 1320 sendStructure = new GetStructure(accessSemantics, selector); |
1160 } | 1321 } |
1161 registry.registerSendStructure(node, sendStructure); | 1322 registry.registerSendStructure(node, sendStructure); |
1162 // TODO(johnniwinther): Remove this when all information goes through | 1323 // TODO(johnniwinther): Remove this when all information goes through |
1163 // the [SendStructure]. | 1324 // the [SendStructure]. |
1164 registry.setSelector(node, selector); | 1325 registry.setSelector(node, selector); |
1165 return null; | 1326 return const NoneResult(); |
1166 } | 1327 } |
1167 | 1328 |
1168 /// Handle access on `this`, like `this()` and `this` when it is parsed as a | 1329 /// Handle access on `this`, like `this()` and `this` when it is parsed as a |
1169 /// [Send] node. | 1330 /// [Send] node. |
1170 ResolutionResult handleThisAccess(Send node) { | 1331 ResolutionResult handleThisAccess(Send node) { |
1171 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); | 1332 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); |
1172 if (node.isCall) { | 1333 if (node.isCall) { |
1173 CallStructure callStructure = resolveArguments(node.argumentsNode); | 1334 CallStructure callStructure = resolveArguments(node.argumentsNode); |
1174 Selector selector = callStructure.callSelector; | 1335 Selector selector = callStructure.callSelector; |
1175 // TODO(johnniwinther): Handle invalid this access as an | 1336 // TODO(johnniwinther): Handle invalid this access as an |
1176 // [AccessSemantics]. | 1337 // [AccessSemantics]. |
1177 if (checkThisAccess(node)) { | 1338 if (checkThisAccess(node)) { |
1178 registry.registerDynamicInvocation(selector); | 1339 registry.registerDynamicInvocation(selector); |
1179 registry.registerSendStructure(node, | 1340 registry.registerSendStructure(node, |
1180 new InvokeStructure(accessSemantics, selector)); | 1341 new InvokeStructure(accessSemantics, selector)); |
1181 } | 1342 } |
1182 // TODO(johnniwinther): Remove this when all information goes through | 1343 // TODO(johnniwinther): Remove this when all information goes through |
1183 // the [SendStructure]. | 1344 // the [SendStructure]. |
1184 registry.setSelector(node, selector); | 1345 registry.setSelector(node, selector); |
1185 } else { | 1346 } else { |
1186 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1347 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
1187 internalError(node, "Unexpected node '$node'."); | 1348 internalError(node, "Unexpected node '$node'."); |
1188 } | 1349 } |
1189 return null; | 1350 return const NoneResult(); |
1190 } | 1351 } |
1191 | 1352 |
1192 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1353 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
1193 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1354 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
1194 Element target; | 1355 Element target; |
1195 Selector selector; | 1356 Selector selector; |
1196 CallStructure callStructure = CallStructure.NO_ARGS; | 1357 CallStructure callStructure = CallStructure.NO_ARGS; |
1197 if (node.isCall) { | 1358 if (node.isCall) { |
1198 callStructure = resolveArguments(node.argumentsNode); | 1359 callStructure = resolveArguments(node.argumentsNode); |
1199 selector = new Selector(SelectorKind.CALL, name, callStructure); | 1360 selector = new Selector(SelectorKind.CALL, name, callStructure); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1258 registry.registerSendStructure(node, | 1419 registry.registerSendStructure(node, |
1259 new GetStructure(semantics, selector)); | 1420 new GetStructure(semantics, selector)); |
1260 } | 1421 } |
1261 target = semantics.element; | 1422 target = semantics.element; |
1262 } | 1423 } |
1263 | 1424 |
1264 // TODO(johnniwinther): Remove these when all information goes through | 1425 // TODO(johnniwinther): Remove these when all information goes through |
1265 // the [SendStructure]. | 1426 // the [SendStructure]. |
1266 registry.useElement(node, target); | 1427 registry.useElement(node, target); |
1267 registry.setSelector(node, selector); | 1428 registry.setSelector(node, selector); |
1268 return null; | 1429 return const NoneResult(); |
1269 } | 1430 } |
1270 | 1431 |
1271 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, | 1432 /// Handle a [Send] whose selector is an [Operator], like `a && b`, `a is T`, |
1272 /// `a + b`, and `~a`. | 1433 /// `a + b`, and `~a`. |
1273 ResolutionResult handleOperatorSend(Send node) { | 1434 ResolutionResult handleOperatorSend(Send node) { |
1274 String operatorText = node.selector.asOperator().source; | 1435 String operatorText = node.selector.asOperator().source; |
1275 if (operatorText == 'is') { | 1436 if (operatorText == 'is') { |
1276 return handleIs(node); | 1437 return handleIs(node); |
1277 } else if (operatorText == 'as') { | 1438 } else if (operatorText == 'as') { |
1278 return handleAs(node); | 1439 return handleAs(node); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 Identifier selector = node.selector.asIdentifier(); | 1495 Identifier selector = node.selector.asIdentifier(); |
1335 Name name = new Name(selector.source, enclosingElement.library); | 1496 Name name = new Name(selector.source, enclosingElement.library); |
1336 if (node.isSuperCall) { | 1497 if (node.isSuperCall) { |
1337 return handleSuperPropertyAccess(node, name); | 1498 return handleSuperPropertyAccess(node, name); |
1338 } else if (node.receiver.isThis()) { | 1499 } else if (node.receiver.isThis()) { |
1339 if (checkThisAccess(node)) { | 1500 if (checkThisAccess(node)) { |
1340 return handleThisPropertyAccess(node, name); | 1501 return handleThisPropertyAccess(node, name); |
1341 } | 1502 } |
1342 // TODO(johnniwinther): Handle invalid this access as an | 1503 // TODO(johnniwinther): Handle invalid this access as an |
1343 // [AccessSemantics]. | 1504 // [AccessSemantics]. |
1344 return null; | 1505 return const NoneResult(); |
1345 } | 1506 } |
1346 // TODO(johnniwinther): Handle remaining qualified sends. | 1507 // TODO(johnniwinther): Handle remaining qualified sends. |
1347 return oldVisitSend(node); | 1508 return oldVisitSend(node); |
1348 } | 1509 } |
1349 | 1510 |
1350 /// Handle access unresolved access to [name] in a non-instance context. | 1511 /// Handle access unresolved access to [name] in a non-instance context. |
1351 ResolutionResult handleUnresolvedAccess( | 1512 ResolutionResult handleUnresolvedAccess( |
1352 Send node, Name name, Element element) { | 1513 Send node, Name name, Element element) { |
1353 // TODO(johnniwinther): Support unresolved top level access as an | 1514 // TODO(johnniwinther): Support unresolved top level access as an |
1354 // [AccessSemantics]. | 1515 // [AccessSemantics]. |
(...skipping 10 matching lines...) Expand all Loading... |
1365 selector = new Selector( | 1526 selector = new Selector( |
1366 SelectorKind.GETTER, name, CallStructure.NO_ARGS); | 1527 SelectorKind.GETTER, name, CallStructure.NO_ARGS); |
1367 registry.registerDynamicGetter(selector); | 1528 registry.registerDynamicGetter(selector); |
1368 sendStructure = new GetStructure(accessSemantics, selector); | 1529 sendStructure = new GetStructure(accessSemantics, selector); |
1369 } | 1530 } |
1370 // TODO(johnniwinther): Remove this when all information goes through | 1531 // TODO(johnniwinther): Remove this when all information goes through |
1371 // the [SendStructure]. | 1532 // the [SendStructure]. |
1372 registry.setSelector(node, selector); | 1533 registry.setSelector(node, selector); |
1373 registry.useElement(node, element); | 1534 registry.useElement(node, element); |
1374 registry.registerSendStructure(node, sendStructure); | 1535 registry.registerSendStructure(node, sendStructure); |
1375 return null; | 1536 return const NoneResult(); |
1376 } | 1537 } |
1377 | 1538 |
1378 /// Handle an unqualified [Send], that is where the `node.receiver` is null, | 1539 /// Handle an unqualified [Send], that is where the `node.receiver` is null, |
1379 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. | 1540 /// like `a`, `a()`, `this()`, `assert()`, and `(){}()`. |
1380 ResolutionResult handleUnqualifiedSend(Send node) { | 1541 ResolutionResult handleUnqualifiedSend(Send node) { |
1381 Identifier selector = node.selector.asIdentifier(); | 1542 Identifier selector = node.selector.asIdentifier(); |
1382 if (selector == null) { | 1543 if (selector == null) { |
1383 // `(){}()` and `(foo)()`. | 1544 // `(){}()` and `(foo)()`. |
1384 return handleExpressionInvoke(node); | 1545 return handleExpressionInvoke(node); |
1385 } | 1546 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 return oldVisitSend(node); | 1583 return oldVisitSend(node); |
1423 } | 1584 } |
1424 | 1585 |
1425 ResolutionResult oldVisitSend(Send node) { | 1586 ResolutionResult oldVisitSend(Send node) { |
1426 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1587 bool oldSendIsMemberAccess = sendIsMemberAccess; |
1427 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 1588 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
1428 | 1589 |
1429 ResolutionResult result = resolveSend(node); | 1590 ResolutionResult result = resolveSend(node); |
1430 sendIsMemberAccess = oldSendIsMemberAccess; | 1591 sendIsMemberAccess = oldSendIsMemberAccess; |
1431 | 1592 |
1432 Element target = result != null ? result.element : null; | 1593 Element target = result.element; |
1433 | 1594 |
1434 if (target != null | 1595 if (target != null |
1435 && target == compiler.mirrorSystemGetNameFunction | 1596 && target == compiler.mirrorSystemGetNameFunction |
1436 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { | 1597 && !compiler.mirrorUsageAnalyzerTask.hasMirrorUsage(enclosingElement)) { |
1437 compiler.reportHint( | 1598 compiler.reportHint( |
1438 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, | 1599 node.selector, MessageKind.STATIC_FUNCTION_BLOAT, |
1439 {'class': compiler.mirrorSystemClass.name, | 1600 {'class': compiler.mirrorSystemClass.name, |
1440 'name': compiler.mirrorSystemGetNameFunction.name}); | 1601 'name': compiler.mirrorSystemGetNameFunction.name}); |
1441 } | 1602 } |
1442 | 1603 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 } | 1636 } |
1476 } | 1637 } |
1477 } | 1638 } |
1478 | 1639 |
1479 bool resolvedArguments = false; | 1640 bool resolvedArguments = false; |
1480 resolveArguments(node.argumentsNode); | 1641 resolveArguments(node.argumentsNode); |
1481 | 1642 |
1482 // If the selector is null, it means that we will not be generating | 1643 // If the selector is null, it means that we will not be generating |
1483 // code for this as a send. | 1644 // code for this as a send. |
1484 Selector selector = registry.getSelector(node); | 1645 Selector selector = registry.getSelector(node); |
1485 if (selector == null) return null; | 1646 if (selector == null) return const NoneResult(); |
1486 | 1647 |
1487 if (node.isCall) { | 1648 if (node.isCall) { |
1488 if (Elements.isUnresolved(target) || | 1649 if (Elements.isUnresolved(target) || |
1489 target.isGetter || | 1650 target.isGetter || |
1490 target.isField || | 1651 target.isField || |
1491 Elements.isClosureSend(node, target)) { | 1652 Elements.isClosureSend(node, target)) { |
1492 // If we don't know what we're calling or if we are calling a getter, | 1653 // If we don't know what we're calling or if we are calling a getter, |
1493 // we need to register that fact that we may be calling a closure | 1654 // we need to register that fact that we may be calling a closure |
1494 // with the same arguments. | 1655 // with the same arguments. |
1495 Selector call = new Selector.callClosureFrom(selector); | 1656 Selector call = new Selector.callClosureFrom(selector); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1528 } | 1689 } |
1529 } | 1690 } |
1530 } | 1691 } |
1531 } | 1692 } |
1532 | 1693 |
1533 registry.useElement(node, target); | 1694 registry.useElement(node, target); |
1534 registerSend(selector, target); | 1695 registerSend(selector, target); |
1535 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { | 1696 if (node.isPropertyAccess && Elements.isStaticOrTopLevelFunction(target)) { |
1536 registry.registerGetOfStaticFunction(target.declaration); | 1697 registry.registerGetOfStaticFunction(target.declaration); |
1537 } | 1698 } |
1538 return node.isPropertyAccess ? new ElementResult(target) : null; | 1699 return node.isPropertyAccess |
| 1700 ? new ResolutionResult.forElement(target) : const NoneResult(); |
1539 } | 1701 } |
1540 | 1702 |
1541 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. | 1703 /// Callback for native enqueuer to parse a type. Returns [:null:] on error. |
1542 DartType resolveTypeFromString(Node node, String typeName) { | 1704 DartType resolveTypeFromString(Node node, String typeName) { |
1543 Element element = lookupInScope(compiler, node, scope, typeName); | 1705 Element element = lookupInScope(compiler, node, scope, typeName); |
1544 if (element == null) return null; | 1706 if (element == null) return null; |
1545 if (element is! ClassElement) return null; | 1707 if (element is! ClassElement) return null; |
1546 ClassElement cls = element; | 1708 ClassElement cls = element; |
1547 cls.ensureResolved(compiler); | 1709 cls.ensureResolved(compiler); |
1548 return cls.computeType(compiler); | 1710 return cls.computeType(compiler); |
1549 } | 1711 } |
1550 | 1712 |
1551 ResolutionResult visitSendSet(SendSet node) { | 1713 ResolutionResult visitSendSet(SendSet node) { |
1552 bool oldSendIsMemberAccess = sendIsMemberAccess; | 1714 bool oldSendIsMemberAccess = sendIsMemberAccess; |
1553 sendIsMemberAccess = node.isPropertyAccess || node.isCall; | 1715 sendIsMemberAccess = node.isPropertyAccess || node.isCall; |
1554 ResolutionResult result = resolveSend(node); | 1716 ResolutionResult result = resolveSend(node); |
1555 sendIsMemberAccess = oldSendIsMemberAccess; | 1717 sendIsMemberAccess = oldSendIsMemberAccess; |
1556 Element target = result != null ? result.element : null; | 1718 Element target = result.element; |
1557 Element setter = target; | 1719 Element setter = target; |
1558 Element getter = target; | 1720 Element getter = target; |
1559 String operatorName = node.assignmentOperator.source; | 1721 String operatorName = node.assignmentOperator.source; |
1560 String source = operatorName; | 1722 String source = operatorName; |
1561 bool isComplex = !identical(source, '='); | 1723 bool isComplex = !identical(source, '='); |
1562 if (!(result is AssertResult || Elements.isUnresolved(target))) { | 1724 if (!(result is AssertResult || Elements.isUnresolved(target))) { |
1563 if (target.isAbstractField) { | 1725 if (target.isAbstractField) { |
1564 AbstractFieldElement field = target; | 1726 AbstractFieldElement field = target; |
1565 setter = field.setter; | 1727 setter = field.setter; |
1566 getter = field.getter; | 1728 getter = field.getter; |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 registry.registerInstantiatedClass(compiler.intClass); | 1832 registry.registerInstantiatedClass(compiler.intClass); |
1671 } else if (identical(source, '--')) { | 1833 } else if (identical(source, '--')) { |
1672 registerBinaryOperator('-'); | 1834 registerBinaryOperator('-'); |
1673 registry.registerInstantiatedClass(compiler.intClass); | 1835 registry.registerInstantiatedClass(compiler.intClass); |
1674 } else if (source.endsWith('=')) { | 1836 } else if (source.endsWith('=')) { |
1675 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); | 1837 registerBinaryOperator(Elements.mapToUserOperator(operatorName)); |
1676 } | 1838 } |
1677 } | 1839 } |
1678 | 1840 |
1679 registerSend(selector, setter); | 1841 registerSend(selector, setter); |
1680 return new ElementResult(registry.useElement(node, setter)); | 1842 return new ResolutionResult.forElement(registry.useElement(node, setter)); |
1681 } | 1843 } |
1682 | 1844 |
1683 void registerSend(Selector selector, Element target) { | 1845 void registerSend(Selector selector, Element target) { |
1684 if (target == null || target.isInstanceMember) { | 1846 if (target == null || target.isInstanceMember) { |
1685 if (selector.isGetter) { | 1847 if (selector.isGetter) { |
1686 registry.registerDynamicGetter(selector); | 1848 registry.registerDynamicGetter(selector); |
1687 } else if (selector.isSetter) { | 1849 } else if (selector.isSetter) { |
1688 registry.registerDynamicSetter(selector); | 1850 registry.registerDynamicSetter(selector); |
1689 } else { | 1851 } else { |
1690 registry.registerDynamicInvocation(selector); | 1852 registry.registerDynamicInvocation(selector); |
1691 } | 1853 } |
1692 } else if (Elements.isStaticOrTopLevel(target)) { | 1854 } else if (Elements.isStaticOrTopLevel(target)) { |
1693 // Avoid registration of type variables since they are not analyzable but | 1855 // Avoid registration of type variables since they are not analyzable but |
1694 // instead resolved through their enclosing type declaration. | 1856 // instead resolved through their enclosing type declaration. |
1695 if (!target.isTypeVariable) { | 1857 if (!target.isTypeVariable) { |
1696 // [target] might be the implementation element and only declaration | 1858 // [target] might be the implementation element and only declaration |
1697 // elements may be registered. | 1859 // elements may be registered. |
1698 registry.registerStaticUse(target.declaration); | 1860 registry.registerStaticUse(target.declaration); |
1699 } | 1861 } |
1700 } | 1862 } |
1701 } | 1863 } |
1702 | 1864 |
1703 visitLiteralInt(LiteralInt node) { | 1865 ConstantResult visitLiteralInt(LiteralInt node) { |
1704 registry.registerInstantiatedClass(compiler.intClass); | 1866 registry.registerInstantiatedType(coreTypes.intType); |
| 1867 ConstantExpression constant = new IntConstantExpression(node.value); |
| 1868 registry.setConstant(node, constant); |
| 1869 return new ConstantResult(node, constant); |
1705 } | 1870 } |
1706 | 1871 |
1707 visitLiteralDouble(LiteralDouble node) { | 1872 ConstantResult visitLiteralDouble(LiteralDouble node) { |
1708 registry.registerInstantiatedClass(compiler.doubleClass); | 1873 registry.registerInstantiatedType(coreTypes.doubleType); |
| 1874 ConstantExpression constant = new DoubleConstantExpression(node.value); |
| 1875 registry.setConstant(node, constant); |
| 1876 return new ConstantResult(node, constant); |
1709 } | 1877 } |
1710 | 1878 |
1711 visitLiteralBool(LiteralBool node) { | 1879 ConstantResult visitLiteralBool(LiteralBool node) { |
1712 registry.registerInstantiatedClass(compiler.boolClass); | 1880 registry.registerInstantiatedType(coreTypes.boolType); |
| 1881 ConstantExpression constant = new BoolConstantExpression(node.value); |
| 1882 registry.setConstant(node, constant); |
| 1883 return new ConstantResult(node, constant); |
1713 } | 1884 } |
1714 | 1885 |
1715 visitLiteralString(LiteralString node) { | 1886 ResolutionResult visitLiteralString(LiteralString node) { |
1716 registry.registerInstantiatedClass(compiler.stringClass); | 1887 registry.registerInstantiatedType(coreTypes.stringType); |
| 1888 if (node.dartString != null) { |
| 1889 // [dartString] might be null on parser errors. |
| 1890 ConstantExpression constant = |
| 1891 new StringConstantExpression(node.dartString.slowToString()); |
| 1892 registry.setConstant(node, constant); |
| 1893 return new ConstantResult(node, constant); |
| 1894 } |
| 1895 return const NoneResult(); |
1717 } | 1896 } |
1718 | 1897 |
1719 visitLiteralNull(LiteralNull node) { | 1898 ConstantResult visitLiteralNull(LiteralNull node) { |
1720 registry.registerInstantiatedClass(compiler.nullClass); | 1899 registry.registerInstantiatedType(coreTypes.nullType); |
| 1900 ConstantExpression constant = new NullConstantExpression(); |
| 1901 registry.setConstant(node, constant); |
| 1902 return new ConstantResult(node, constant); |
1721 } | 1903 } |
1722 | 1904 |
1723 visitLiteralSymbol(LiteralSymbol node) { | 1905 ConstantResult visitLiteralSymbol(LiteralSymbol node) { |
1724 registry.registerInstantiatedClass(compiler.symbolClass); | 1906 registry.registerInstantiatedClass(compiler.symbolClass); |
1725 registry.registerStaticUse(compiler.symbolConstructor.declaration); | 1907 registry.registerStaticUse(compiler.symbolConstructor.declaration); |
1726 registry.registerConstSymbol(node.slowNameString); | 1908 String name = node.slowNameString; |
1727 if (!validateSymbol(node, node.slowNameString, reportError: false)) { | 1909 registry.registerConstSymbol(name); |
| 1910 if (!validateSymbol(node, name, reportError: false)) { |
1728 compiler.reportError(node, | 1911 compiler.reportError(node, |
1729 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, | 1912 MessageKind.UNSUPPORTED_LITERAL_SYMBOL, |
1730 {'value': node.slowNameString}); | 1913 {'value': name}); |
1731 } | 1914 } |
1732 analyzeConstantDeferred(node); | 1915 analyzeConstantDeferred(node); |
| 1916 ConstantExpression constant = new SymbolConstantExpression(name); |
| 1917 registry.setConstant(node, constant); |
| 1918 return new ConstantResult(node, constant); |
1733 } | 1919 } |
1734 | 1920 |
1735 visitStringJuxtaposition(StringJuxtaposition node) { | 1921 ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) { |
1736 registry.registerInstantiatedClass(compiler.stringClass); | 1922 registry.registerInstantiatedType(coreTypes.stringType); |
1737 node.visitChildren(this); | 1923 ResolutionResult first = visit(node.first); |
| 1924 ResolutionResult second = visit(node.second); |
| 1925 if (first.isConstant && second.isConstant) { |
| 1926 ConstantExpression constant = new ConcatenateConstantExpression( |
| 1927 <ConstantExpression>[first.constant, second.constant]); |
| 1928 registry.setConstant(node, constant); |
| 1929 return new ConstantResult(node, constant); |
| 1930 } |
| 1931 return const NoneResult(); |
1738 } | 1932 } |
1739 | 1933 |
1740 visitNodeList(NodeList node) { | 1934 ResolutionResult visitNodeList(NodeList node) { |
1741 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | 1935 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { |
1742 visit(link.head); | 1936 visit(link.head); |
1743 } | 1937 } |
| 1938 return const NoneResult(); |
1744 } | 1939 } |
1745 | 1940 |
1746 visitOperator(Operator node) { | 1941 ResolutionResult visitRethrow(Rethrow node) { |
1747 internalError(node, 'operator'); | |
1748 } | |
1749 | |
1750 visitRethrow(Rethrow node) { | |
1751 if (!inCatchBlock) { | 1942 if (!inCatchBlock) { |
1752 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); | 1943 error(node, MessageKind.THROW_WITHOUT_EXPRESSION); |
1753 } | 1944 } |
| 1945 return const NoneResult(); |
1754 } | 1946 } |
1755 | 1947 |
1756 visitReturn(Return node) { | 1948 ResolutionResult visitReturn(Return node) { |
1757 Node expression = node.expression; | 1949 Node expression = node.expression; |
1758 if (expression != null) { | 1950 if (expression != null) { |
1759 if (enclosingElement.isGenerativeConstructor) { | 1951 if (enclosingElement.isGenerativeConstructor) { |
1760 // It is a compile-time error if a return statement of the form | 1952 // It is a compile-time error if a return statement of the form |
1761 // `return e;` appears in a generative constructor. (Dart Language | 1953 // `return e;` appears in a generative constructor. (Dart Language |
1762 // Specification 13.12.) | 1954 // Specification 13.12.) |
1763 compiler.reportError(expression, | 1955 compiler.reportError(expression, |
1764 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); | 1956 MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR); |
1765 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { | 1957 } else if (!node.isArrowBody && currentAsyncMarker.isYielding) { |
1766 compiler.reportError( | 1958 compiler.reportError( |
1767 node, | 1959 node, |
1768 MessageKind.RETURN_IN_GENERATOR, | 1960 MessageKind.RETURN_IN_GENERATOR, |
1769 {'modifier': currentAsyncMarker}); | 1961 {'modifier': currentAsyncMarker}); |
1770 } | 1962 } |
1771 } | 1963 } |
1772 visit(node.expression); | 1964 visit(node.expression); |
| 1965 return const NoneResult(); |
1773 } | 1966 } |
1774 | 1967 |
1775 visitYield(Yield node) { | 1968 ResolutionResult visitYield(Yield node) { |
1776 compiler.streamClass.ensureResolved(compiler); | 1969 compiler.streamClass.ensureResolved(compiler); |
1777 compiler.iterableClass.ensureResolved(compiler); | 1970 compiler.iterableClass.ensureResolved(compiler); |
1778 visit(node.expression); | 1971 visit(node.expression); |
| 1972 return const NoneResult(); |
1779 } | 1973 } |
1780 | 1974 |
1781 visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 1975 ResolutionResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
1782 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; | 1976 final isSymbolConstructor = enclosingElement == compiler.symbolConstructor; |
1783 if (!enclosingElement.isFactoryConstructor) { | 1977 if (!enclosingElement.isFactoryConstructor) { |
1784 compiler.reportError( | 1978 compiler.reportError( |
1785 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); | 1979 node, MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY); |
1786 compiler.reportHint( | 1980 compiler.reportHint( |
1787 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); | 1981 enclosingElement, MessageKind.MISSING_FACTORY_KEYWORD); |
1788 } | 1982 } |
1789 ConstructorElementX constructor = enclosingElement; | 1983 ConstructorElementX constructor = enclosingElement; |
1790 bool isConstConstructor = constructor.isConst; | 1984 bool isConstConstructor = constructor.isConst; |
1791 ConstructorElement redirectionTarget = resolveRedirectingFactory( | 1985 ConstructorElement redirectionTarget = resolveRedirectingFactory( |
1792 node, inConstContext: isConstConstructor); | 1986 node, inConstContext: isConstConstructor); |
1793 constructor.immediateRedirectionTarget = redirectionTarget; | 1987 constructor.immediateRedirectionTarget = redirectionTarget; |
1794 | 1988 |
1795 Node constructorReference = node.constructorReference; | 1989 Node constructorReference = node.constructorReference; |
1796 if (constructorReference is Send) { | 1990 if (constructorReference is Send) { |
1797 constructor.redirectionDeferredPrefix = | 1991 constructor.redirectionDeferredPrefix = |
1798 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, | 1992 compiler.deferredLoadTask.deferredPrefixElement(constructorReference, |
1799 registry.mapping); | 1993 registry.mapping); |
1800 } | 1994 } |
1801 | 1995 |
1802 registry.setRedirectingTargetConstructor(node, redirectionTarget); | 1996 registry.setRedirectingTargetConstructor(node, redirectionTarget); |
1803 if (Elements.isUnresolved(redirectionTarget)) { | 1997 if (Elements.isUnresolved(redirectionTarget)) { |
1804 registry.registerThrowNoSuchMethod(); | 1998 registry.registerThrowNoSuchMethod(); |
1805 return; | 1999 return const NoneResult(); |
1806 } else { | 2000 } else { |
1807 if (isConstConstructor && | 2001 if (isConstConstructor && |
1808 !redirectionTarget.isConst) { | 2002 !redirectionTarget.isConst) { |
1809 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 2003 compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
1810 } | 2004 } |
1811 if (redirectionTarget == constructor) { | 2005 if (redirectionTarget == constructor) { |
1812 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); | 2006 compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY); |
1813 } | 2007 } |
1814 } | 2008 } |
1815 | 2009 |
(...skipping 25 matching lines...) Expand all Loading... |
1841 compiler.resolver.resolveRedirectionChain(constructor, node); | 2035 compiler.resolver.resolveRedirectionChain(constructor, node); |
1842 }); | 2036 }); |
1843 | 2037 |
1844 registry.registerStaticUse(redirectionTarget); | 2038 registry.registerStaticUse(redirectionTarget); |
1845 // TODO(johnniwinther): Register the effective target type instead. | 2039 // TODO(johnniwinther): Register the effective target type instead. |
1846 registry.registerInstantiatedClass( | 2040 registry.registerInstantiatedClass( |
1847 redirectionTarget.enclosingClass.declaration); | 2041 redirectionTarget.enclosingClass.declaration); |
1848 if (isSymbolConstructor) { | 2042 if (isSymbolConstructor) { |
1849 registry.registerSymbolConstructor(); | 2043 registry.registerSymbolConstructor(); |
1850 } | 2044 } |
| 2045 return const NoneResult(); |
1851 } | 2046 } |
1852 | 2047 |
1853 visitThrow(Throw node) { | 2048 ResolutionResult visitThrow(Throw node) { |
1854 registry.registerThrowExpression(); | 2049 registry.registerThrowExpression(); |
1855 visit(node.expression); | 2050 visit(node.expression); |
| 2051 return const NoneResult(); |
1856 } | 2052 } |
1857 | 2053 |
1858 visitAwait(Await node) { | 2054 ResolutionResult visitAwait(Await node) { |
1859 compiler.futureClass.ensureResolved(compiler); | 2055 compiler.futureClass.ensureResolved(compiler); |
1860 visit(node.expression); | 2056 visit(node.expression); |
| 2057 return const NoneResult(); |
1861 } | 2058 } |
1862 | 2059 |
1863 visitVariableDefinitions(VariableDefinitions node) { | 2060 ResolutionResult visitVariableDefinitions(VariableDefinitions node) { |
1864 DartType type; | 2061 DartType type; |
1865 if (node.type != null) { | 2062 if (node.type != null) { |
1866 type = resolveTypeAnnotation(node.type); | 2063 type = resolveTypeAnnotation(node.type); |
1867 } else { | 2064 } else { |
1868 type = const DynamicType(); | 2065 type = const DynamicType(); |
1869 } | 2066 } |
1870 VariableList variables = new VariableList.node(node, type); | 2067 VariableList variables = new VariableList.node(node, type); |
1871 VariableDefinitionsVisitor visitor = | 2068 VariableDefinitionsVisitor visitor = |
1872 new VariableDefinitionsVisitor(compiler, node, this, variables); | 2069 new VariableDefinitionsVisitor(compiler, node, this, variables); |
1873 | 2070 |
(...skipping 24 matching lines...) Expand all Loading... |
1898 } | 2095 } |
1899 if (modifiers.isStatic) { | 2096 if (modifiers.isStatic) { |
1900 reportExtraModifier('static'); | 2097 reportExtraModifier('static'); |
1901 } | 2098 } |
1902 } | 2099 } |
1903 if (node.metadata != null) { | 2100 if (node.metadata != null) { |
1904 variables.metadata = | 2101 variables.metadata = |
1905 compiler.resolver.resolveMetadata(enclosingElement, node); | 2102 compiler.resolver.resolveMetadata(enclosingElement, node); |
1906 } | 2103 } |
1907 visitor.visit(node.definitions); | 2104 visitor.visit(node.definitions); |
| 2105 return const NoneResult(); |
1908 } | 2106 } |
1909 | 2107 |
1910 visitWhile(While node) { | 2108 ResolutionResult visitWhile(While node) { |
1911 visit(node.condition); | 2109 visit(node.condition); |
1912 visitLoopBodyIn(node, node.body, new BlockScope(scope)); | 2110 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 2111 return const NoneResult(); |
1913 } | 2112 } |
1914 | 2113 |
1915 visitParenthesizedExpression(ParenthesizedExpression node) { | 2114 ResolutionResult visitParenthesizedExpression(ParenthesizedExpression node) { |
1916 bool oldSendIsMemberAccess = sendIsMemberAccess; | 2115 bool oldSendIsMemberAccess = sendIsMemberAccess; |
1917 sendIsMemberAccess = false; | 2116 sendIsMemberAccess = false; |
1918 var oldCategory = allowedCategory; | 2117 var oldCategory = allowedCategory; |
1919 allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION | 2118 allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION |
1920 | ElementCategory.IMPLIES_TYPE; | 2119 | ElementCategory.IMPLIES_TYPE; |
1921 visit(node.expression); | 2120 ResolutionResult result = visit(node.expression); |
1922 allowedCategory = oldCategory; | 2121 allowedCategory = oldCategory; |
1923 sendIsMemberAccess = oldSendIsMemberAccess; | 2122 sendIsMemberAccess = oldSendIsMemberAccess; |
| 2123 if (result.kind == ResultKind.CONSTANT) { |
| 2124 return result; |
| 2125 } |
| 2126 return const NoneResult(); |
1924 } | 2127 } |
1925 | 2128 |
1926 ResolutionResult visitNewExpression(NewExpression node) { | 2129 ResolutionResult visitNewExpression(NewExpression node) { |
1927 Node selector = node.send.selector; | 2130 Node selector = node.send.selector; |
1928 FunctionElement constructor = resolveConstructor(node); | 2131 FunctionElement constructor = resolveConstructor(node); |
1929 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; | 2132 final bool isSymbolConstructor = constructor == compiler.symbolConstructor; |
1930 final bool isMirrorsUsedConstant = | 2133 final bool isMirrorsUsedConstant = |
1931 node.isConst && (constructor == compiler.mirrorsUsedConstructor); | 2134 node.isConst && (constructor == compiler.mirrorsUsedConstructor); |
1932 Selector callSelector = resolveSelector(node.send, constructor); | 2135 Selector callSelector = resolveSelector(node.send, constructor); |
1933 resolveArguments(node.send.argumentsNode); | 2136 resolveArguments(node.send.argumentsNode); |
1934 registry.useElement(node.send, constructor); | 2137 registry.useElement(node.send, constructor); |
1935 if (Elements.isUnresolved(constructor)) { | 2138 if (Elements.isUnresolved(constructor)) { |
1936 return new ElementResult(constructor); | 2139 return new ResolutionResult.forElement(constructor); |
1937 } | 2140 } |
1938 constructor.computeSignature(compiler); | 2141 constructor.computeSignature(compiler); |
1939 if (!callSelector.applies(constructor, compiler.world)) { | 2142 if (!callSelector.applies(constructor, compiler.world)) { |
1940 registry.registerThrowNoSuchMethod(); | 2143 registry.registerThrowNoSuchMethod(); |
1941 } | 2144 } |
1942 | 2145 |
1943 // [constructor] might be the implementation element | 2146 // [constructor] might be the implementation element |
1944 // and only declaration elements may be registered. | 2147 // and only declaration elements may be registered. |
1945 registry.registerStaticUse(constructor.declaration); | 2148 registry.registerStaticUse(constructor.declaration); |
1946 ClassElement cls = constructor.enclosingClass; | 2149 ClassElement cls = constructor.enclosingClass; |
(...skipping 17 matching lines...) Expand all Loading... |
1964 } | 2167 } |
1965 | 2168 |
1966 if (isSymbolConstructor) { | 2169 if (isSymbolConstructor) { |
1967 if (node.isConst) { | 2170 if (node.isConst) { |
1968 Node argumentNode = node.send.arguments.head; | 2171 Node argumentNode = node.send.arguments.head; |
1969 ConstantExpression constant = | 2172 ConstantExpression constant = |
1970 compiler.resolver.constantCompiler.compileNode( | 2173 compiler.resolver.constantCompiler.compileNode( |
1971 argumentNode, registry.mapping); | 2174 argumentNode, registry.mapping); |
1972 ConstantValue name = compiler.constants.getConstantValue(constant); | 2175 ConstantValue name = compiler.constants.getConstantValue(constant); |
1973 if (!name.isString) { | 2176 if (!name.isString) { |
1974 DartType type = name.getType(compiler.coreTypes); | 2177 DartType type = name.getType(coreTypes); |
1975 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, | 2178 compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED, |
1976 {'type': type}); | 2179 {'type': type}); |
1977 } else { | 2180 } else { |
1978 StringConstantValue stringConstant = name; | 2181 StringConstantValue stringConstant = name; |
1979 String nameString = stringConstant.toDartString().slowToString(); | 2182 String nameString = stringConstant.toDartString().slowToString(); |
1980 if (validateSymbol(argumentNode, nameString)) { | 2183 if (validateSymbol(argumentNode, nameString)) { |
1981 registry.registerConstSymbol(nameString); | 2184 registry.registerConstSymbol(nameString); |
1982 } | 2185 } |
1983 } | 2186 } |
1984 } else { | 2187 } else { |
1985 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( | 2188 if (!compiler.mirrorUsageAnalyzerTask.hasMirrorUsage( |
1986 enclosingElement)) { | 2189 enclosingElement)) { |
1987 compiler.reportHint( | 2190 compiler.reportHint( |
1988 node.newToken, MessageKind.NON_CONST_BLOAT, | 2191 node.newToken, MessageKind.NON_CONST_BLOAT, |
1989 {'name': compiler.symbolClass.name}); | 2192 {'name': compiler.symbolClass.name}); |
1990 } | 2193 } |
1991 registry.registerNewSymbol(); | 2194 registry.registerNewSymbol(); |
1992 } | 2195 } |
1993 } else if (isMirrorsUsedConstant) { | 2196 } else if (isMirrorsUsedConstant) { |
1994 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); | 2197 compiler.mirrorUsageAnalyzerTask.validate(node, registry.mapping); |
1995 } | 2198 } |
1996 if (node.isConst) { | 2199 if (node.isConst) { |
1997 analyzeConstantDeferred(node); | 2200 analyzeConstantDeferred(node); |
1998 } | 2201 } |
1999 | 2202 |
2000 return null; | 2203 return const NoneResult(); |
2001 } | 2204 } |
2002 | 2205 |
2003 void checkConstMapKeysDontOverrideEquals(Spannable spannable, | 2206 void checkConstMapKeysDontOverrideEquals(Spannable spannable, |
2004 MapConstantValue map) { | 2207 MapConstantValue map) { |
2005 for (ConstantValue key in map.keys) { | 2208 for (ConstantValue key in map.keys) { |
2006 if (!key.isObject) continue; | 2209 if (!key.isObject) continue; |
2007 ObjectConstantValue objectConstant = key; | 2210 ObjectConstantValue objectConstant = key; |
2008 DartType keyType = objectConstant.type; | 2211 DartType keyType = objectConstant.type; |
2009 ClassElement cls = keyType.element; | 2212 ClassElement cls = keyType.element; |
2010 if (cls == compiler.stringClass) continue; | 2213 if (cls == compiler.stringClass) continue; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2098 DartType type = typeResolver.resolveTypeAnnotation( | 2301 DartType type = typeResolver.resolveTypeAnnotation( |
2099 this, node, malformedIsError: malformedIsError, | 2302 this, node, malformedIsError: malformedIsError, |
2100 deferredIsMalformed: deferredIsMalformed); | 2303 deferredIsMalformed: deferredIsMalformed); |
2101 if (inCheckContext) { | 2304 if (inCheckContext) { |
2102 registry.registerIsCheck(type); | 2305 registry.registerIsCheck(type); |
2103 registry.registerRequiredType(type, enclosingElement); | 2306 registry.registerRequiredType(type, enclosingElement); |
2104 } | 2307 } |
2105 return type; | 2308 return type; |
2106 } | 2309 } |
2107 | 2310 |
2108 visitModifiers(Modifiers node) { | 2311 ResolutionResult visitLiteralList(LiteralList node) { |
2109 internalError(node, 'modifiers'); | 2312 bool isValidAsConstant = true; |
2110 } | |
2111 | |
2112 visitLiteralList(LiteralList node) { | |
2113 bool oldSendIsMemberAccess = sendIsMemberAccess; | |
2114 sendIsMemberAccess = false; | 2313 sendIsMemberAccess = false; |
2115 | 2314 |
2116 NodeList arguments = node.typeArguments; | 2315 NodeList arguments = node.typeArguments; |
2117 DartType typeArgument; | 2316 DartType typeArgument; |
2118 if (arguments != null) { | 2317 if (arguments != null) { |
2119 Link<Node> nodes = arguments.nodes; | 2318 Link<Node> nodes = arguments.nodes; |
2120 if (nodes.isEmpty) { | 2319 if (nodes.isEmpty) { |
2121 // The syntax [: <>[] :] is not allowed. | 2320 // The syntax [: <>[] :] is not allowed. |
2122 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2321 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2322 isValidAsConstant = false; |
2123 } else { | 2323 } else { |
2124 typeArgument = resolveTypeAnnotation(nodes.head); | 2324 typeArgument = resolveTypeAnnotation(nodes.head); |
2125 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2325 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
2126 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 2326 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
2127 resolveTypeAnnotation(nodes.head); | 2327 resolveTypeAnnotation(nodes.head); |
2128 } | 2328 } |
2129 } | 2329 } |
2130 } | 2330 } |
2131 DartType listType; | 2331 DartType listType; |
2132 if (typeArgument != null) { | 2332 if (typeArgument != null) { |
2133 if (node.isConst && typeArgument.containsTypeVariables) { | 2333 if (node.isConst && typeArgument.containsTypeVariables) { |
2134 compiler.reportError(arguments.nodes.head, | 2334 compiler.reportError(arguments.nodes.head, |
2135 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2335 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 2336 isValidAsConstant = false; |
2136 } | 2337 } |
2137 listType = new InterfaceType(compiler.listClass, [typeArgument]); | 2338 listType = coreTypes.listType(typeArgument); |
2138 } else { | 2339 } else { |
2139 compiler.listClass.computeType(compiler); | 2340 listType = coreTypes.listType(); |
2140 listType = compiler.listClass.rawType; | |
2141 } | 2341 } |
2142 registry.setType(node, listType); | 2342 registry.setType(node, listType); |
2143 registry.registerInstantiatedType(listType); | 2343 registry.registerInstantiatedType(listType); |
2144 registry.registerRequiredType(listType, enclosingElement); | 2344 registry.registerRequiredType(listType, enclosingElement); |
2145 visit(node.elements); | |
2146 if (node.isConst) { | 2345 if (node.isConst) { |
| 2346 List<ConstantExpression> constantExpressions = <ConstantExpression>[]; |
| 2347 for (Node element in node.elements) { |
| 2348 ResolutionResult elementResult = visit(element); |
| 2349 if (isValidAsConstant && elementResult.isConstant) { |
| 2350 constantExpressions.add(elementResult.constant); |
| 2351 } else { |
| 2352 isValidAsConstant = false; |
| 2353 } |
| 2354 } |
2147 analyzeConstantDeferred(node); | 2355 analyzeConstantDeferred(node); |
| 2356 sendIsMemberAccess = false; |
| 2357 if (isValidAsConstant) { |
| 2358 ConstantExpression constant = |
| 2359 new ListConstantExpression(listType, constantExpressions); |
| 2360 registry.setConstant(node, constant); |
| 2361 return new ConstantResult(node, constant); |
| 2362 } |
| 2363 } else { |
| 2364 visit(node.elements); |
| 2365 sendIsMemberAccess = false; |
| 2366 } |
| 2367 return const NoneResult(); |
| 2368 |
| 2369 } |
| 2370 |
| 2371 ResolutionResult visitConditional(Conditional node) { |
| 2372 ResolutionResult conditionResult = |
| 2373 doInPromotionScope(node.condition, () => visit(node.condition)); |
| 2374 ResolutionResult thenResult = |
| 2375 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)
); |
| 2376 ResolutionResult elseResult = visit(node.elseExpression); |
| 2377 if (conditionResult.isConstant && |
| 2378 thenResult.isConstant && |
| 2379 elseResult.isConstant) { |
| 2380 ConstantExpression constant = new ConditionalConstantExpression( |
| 2381 conditionResult.constant, |
| 2382 thenResult.constant, |
| 2383 elseResult.constant); |
| 2384 registry.setConstant(node, constant); |
| 2385 return new ConstantResult(node, constant); |
| 2386 } |
| 2387 return const NoneResult(); |
| 2388 } |
| 2389 |
| 2390 ResolutionResult visitStringInterpolation(StringInterpolation node) { |
| 2391 registry.registerInstantiatedType(coreTypes.stringType); |
| 2392 registry.registerStringInterpolation(); |
| 2393 registerImplicitInvocation('toString', 0); |
| 2394 |
| 2395 bool isValidAsConstant = true; |
| 2396 List<ConstantExpression> parts = <ConstantExpression>[]; |
| 2397 |
| 2398 void resolvePart(Node subnode) { |
| 2399 ResolutionResult result = visit(subnode); |
| 2400 if (isValidAsConstant && result.isConstant) { |
| 2401 parts.add(result.constant); |
| 2402 } else { |
| 2403 isValidAsConstant = false; |
| 2404 } |
2148 } | 2405 } |
2149 | 2406 |
2150 sendIsMemberAccess = false; | 2407 resolvePart(node.string); |
| 2408 for (StringInterpolationPart part in node.parts) { |
| 2409 resolvePart(part.expression); |
| 2410 resolvePart(part.string); |
| 2411 } |
| 2412 |
| 2413 if (isValidAsConstant) { |
| 2414 ConstantExpression constant = new ConcatenateConstantExpression(parts); |
| 2415 registry.setConstant(node, constant); |
| 2416 return new ConstantResult(node, constant); |
| 2417 } |
| 2418 return const NoneResult(); |
2151 } | 2419 } |
2152 | 2420 |
2153 visitConditional(Conditional node) { | 2421 ResolutionResult visitBreakStatement(BreakStatement node) { |
2154 doInPromotionScope(node.condition, () => visit(node.condition)); | |
2155 doInPromotionScope(node.thenExpression, () => visit(node.thenExpression)); | |
2156 visit(node.elseExpression); | |
2157 } | |
2158 | |
2159 visitStringInterpolation(StringInterpolation node) { | |
2160 registry.registerInstantiatedClass(compiler.stringClass); | |
2161 registry.registerStringInterpolation(); | |
2162 node.visitChildren(this); | |
2163 } | |
2164 | |
2165 visitStringInterpolationPart(StringInterpolationPart node) { | |
2166 registerImplicitInvocation('toString', 0); | |
2167 node.visitChildren(this); | |
2168 } | |
2169 | |
2170 visitBreakStatement(BreakStatement node) { | |
2171 JumpTarget target; | 2422 JumpTarget target; |
2172 if (node.target == null) { | 2423 if (node.target == null) { |
2173 target = statementScope.currentBreakTarget(); | 2424 target = statementScope.currentBreakTarget(); |
2174 if (target == null) { | 2425 if (target == null) { |
2175 error(node, MessageKind.NO_BREAK_TARGET); | 2426 error(node, MessageKind.NO_BREAK_TARGET); |
2176 return; | 2427 return const NoneResult(); |
2177 } | 2428 } |
2178 target.isBreakTarget = true; | 2429 target.isBreakTarget = true; |
2179 } else { | 2430 } else { |
2180 String labelName = node.target.source; | 2431 String labelName = node.target.source; |
2181 LabelDefinition label = statementScope.lookupLabel(labelName); | 2432 LabelDefinition label = statementScope.lookupLabel(labelName); |
2182 if (label == null) { | 2433 if (label == null) { |
2183 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 2434 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
2184 return; | 2435 return const NoneResult(); |
2185 } | 2436 } |
2186 target = label.target; | 2437 target = label.target; |
2187 if (!target.statement.isValidBreakTarget()) { | 2438 if (!target.statement.isValidBreakTarget()) { |
2188 error(node.target, MessageKind.INVALID_BREAK); | 2439 error(node.target, MessageKind.INVALID_BREAK); |
2189 return; | 2440 return const NoneResult(); |
2190 } | 2441 } |
2191 label.setBreakTarget(); | 2442 label.setBreakTarget(); |
2192 registry.useLabel(node, label); | 2443 registry.useLabel(node, label); |
2193 } | 2444 } |
2194 registry.registerTargetOf(node, target); | 2445 registry.registerTargetOf(node, target); |
| 2446 return const NoneResult(); |
2195 } | 2447 } |
2196 | 2448 |
2197 visitContinueStatement(ContinueStatement node) { | 2449 ResolutionResult visitContinueStatement(ContinueStatement node) { |
2198 JumpTarget target; | 2450 JumpTarget target; |
2199 if (node.target == null) { | 2451 if (node.target == null) { |
2200 target = statementScope.currentContinueTarget(); | 2452 target = statementScope.currentContinueTarget(); |
2201 if (target == null) { | 2453 if (target == null) { |
2202 error(node, MessageKind.NO_CONTINUE_TARGET); | 2454 error(node, MessageKind.NO_CONTINUE_TARGET); |
2203 return; | 2455 return const NoneResult(); |
2204 } | 2456 } |
2205 target.isContinueTarget = true; | 2457 target.isContinueTarget = true; |
2206 } else { | 2458 } else { |
2207 String labelName = node.target.source; | 2459 String labelName = node.target.source; |
2208 LabelDefinition label = statementScope.lookupLabel(labelName); | 2460 LabelDefinition label = statementScope.lookupLabel(labelName); |
2209 if (label == null) { | 2461 if (label == null) { |
2210 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); | 2462 error(node.target, MessageKind.UNBOUND_LABEL, {'labelName': labelName}); |
2211 return; | 2463 return const NoneResult(); |
2212 } | 2464 } |
2213 target = label.target; | 2465 target = label.target; |
2214 if (!target.statement.isValidContinueTarget()) { | 2466 if (!target.statement.isValidContinueTarget()) { |
2215 error(node.target, MessageKind.INVALID_CONTINUE); | 2467 error(node.target, MessageKind.INVALID_CONTINUE); |
2216 } | 2468 } |
2217 label.setContinueTarget(); | 2469 label.setContinueTarget(); |
2218 registry.useLabel(node, label); | 2470 registry.useLabel(node, label); |
2219 } | 2471 } |
2220 registry.registerTargetOf(node, target); | 2472 registry.registerTargetOf(node, target); |
| 2473 return const NoneResult(); |
2221 } | 2474 } |
2222 | 2475 |
2223 registerImplicitInvocation(String name, int arity) { | 2476 registerImplicitInvocation(String name, int arity) { |
2224 Selector selector = new Selector.call(name, null, arity); | 2477 Selector selector = new Selector.call(name, null, arity); |
2225 registry.registerDynamicInvocation(selector); | 2478 registry.registerDynamicInvocation(selector); |
2226 } | 2479 } |
2227 | 2480 |
2228 visitAsyncForIn(AsyncForIn node) { | 2481 ResolutionResult visitAsyncForIn(AsyncForIn node) { |
2229 registry.registerAsyncForIn(node); | 2482 registry.registerAsyncForIn(node); |
2230 registry.setCurrentSelector(node, compiler.currentSelector); | 2483 registry.setCurrentSelector(node, compiler.currentSelector); |
2231 registry.registerDynamicGetter(compiler.currentSelector); | 2484 registry.registerDynamicGetter(compiler.currentSelector); |
2232 registry.setMoveNextSelector(node, compiler.moveNextSelector); | 2485 registry.setMoveNextSelector(node, compiler.moveNextSelector); |
2233 registry.registerDynamicInvocation(compiler.moveNextSelector); | 2486 registry.registerDynamicInvocation(compiler.moveNextSelector); |
2234 | 2487 |
2235 visit(node.expression); | 2488 visit(node.expression); |
2236 | 2489 |
2237 Scope blockScope = new BlockScope(scope); | 2490 Scope blockScope = new BlockScope(scope); |
2238 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 2491 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
2239 visitLoopBodyIn(node, node.body, blockScope); | 2492 visitLoopBodyIn(node, node.body, blockScope); |
| 2493 return const NoneResult(); |
2240 } | 2494 } |
2241 | 2495 |
2242 visitSyncForIn(SyncForIn node) { | 2496 ResolutionResult visitSyncForIn(SyncForIn node) { |
2243 registry.registerSyncForIn(node); | 2497 registry.registerSyncForIn(node); |
2244 registry.setIteratorSelector(node, compiler.iteratorSelector); | 2498 registry.setIteratorSelector(node, compiler.iteratorSelector); |
2245 registry.registerDynamicGetter(compiler.iteratorSelector); | 2499 registry.registerDynamicGetter(compiler.iteratorSelector); |
2246 registry.setCurrentSelector(node, compiler.currentSelector); | 2500 registry.setCurrentSelector(node, compiler.currentSelector); |
2247 registry.registerDynamicGetter(compiler.currentSelector); | 2501 registry.registerDynamicGetter(compiler.currentSelector); |
2248 registry.setMoveNextSelector(node, compiler.moveNextSelector); | 2502 registry.setMoveNextSelector(node, compiler.moveNextSelector); |
2249 registry.registerDynamicInvocation(compiler.moveNextSelector); | 2503 registry.registerDynamicInvocation(compiler.moveNextSelector); |
2250 | 2504 |
2251 visit(node.expression); | 2505 visit(node.expression); |
2252 | 2506 |
2253 Scope blockScope = new BlockScope(scope); | 2507 Scope blockScope = new BlockScope(scope); |
2254 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); | 2508 visitForInDeclaredIdentifierIn(node.declaredIdentifier, node, blockScope); |
2255 visitLoopBodyIn(node, node.body, blockScope); | 2509 visitLoopBodyIn(node, node.body, blockScope); |
| 2510 return const NoneResult(); |
2256 } | 2511 } |
2257 | 2512 |
2258 visitForInDeclaredIdentifierIn(Node declaration, ForIn node, | 2513 void visitForInDeclaredIdentifierIn( |
2259 Scope blockScope) { | 2514 Node declaration, |
| 2515 ForIn node, |
| 2516 Scope blockScope) { |
2260 LibraryElement library = enclosingElement.library; | 2517 LibraryElement library = enclosingElement.library; |
2261 | 2518 |
2262 bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer; | 2519 bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer; |
2263 allowFinalWithoutInitializer = true; | 2520 allowFinalWithoutInitializer = true; |
2264 visitIn(declaration, blockScope); | 2521 visitIn(declaration, blockScope); |
2265 allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer; | 2522 allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer; |
2266 | 2523 |
2267 Send send = declaration.asSend(); | 2524 Send send = declaration.asSend(); |
2268 VariableDefinitions variableDefinitions = | 2525 VariableDefinitions variableDefinitions = |
2269 declaration.asVariableDefinitions(); | 2526 declaration.asVariableDefinitions(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 if (loopVariable != null) { | 2563 if (loopVariable != null) { |
2307 // loopVariable may be null if it could not be resolved. | 2564 // loopVariable may be null if it could not be resolved. |
2308 registry.setForInVariable(node, loopVariable); | 2565 registry.setForInVariable(node, loopVariable); |
2309 } | 2566 } |
2310 } | 2567 } |
2311 | 2568 |
2312 visitLabel(Label node) { | 2569 visitLabel(Label node) { |
2313 // Labels are handled by their containing statements/cases. | 2570 // Labels are handled by their containing statements/cases. |
2314 } | 2571 } |
2315 | 2572 |
2316 visitLabeledStatement(LabeledStatement node) { | 2573 ResolutionResult visitLabeledStatement(LabeledStatement node) { |
2317 Statement body = node.statement; | 2574 Statement body = node.statement; |
2318 JumpTarget targetElement = getOrDefineTarget(body); | 2575 JumpTarget targetElement = getOrDefineTarget(body); |
2319 Map<String, LabelDefinition> labelElements = <String, LabelDefinition>{}; | 2576 Map<String, LabelDefinition> labelElements = <String, LabelDefinition>{}; |
2320 for (Label label in node.labels) { | 2577 for (Label label in node.labels) { |
2321 String labelName = label.labelName; | 2578 String labelName = label.labelName; |
2322 if (labelElements.containsKey(labelName)) continue; | 2579 if (labelElements.containsKey(labelName)) continue; |
2323 LabelDefinition element = targetElement.addLabel(label, labelName); | 2580 LabelDefinition element = targetElement.addLabel(label, labelName); |
2324 labelElements[labelName] = element; | 2581 labelElements[labelName] = element; |
2325 } | 2582 } |
2326 statementScope.enterLabelScope(labelElements); | 2583 statementScope.enterLabelScope(labelElements); |
2327 visit(node.statement); | 2584 visit(node.statement); |
2328 statementScope.exitLabelScope(); | 2585 statementScope.exitLabelScope(); |
2329 labelElements.forEach((String labelName, LabelDefinition element) { | 2586 labelElements.forEach((String labelName, LabelDefinition element) { |
2330 if (element.isTarget) { | 2587 if (element.isTarget) { |
2331 registry.defineLabel(element.label, element); | 2588 registry.defineLabel(element.label, element); |
2332 } else { | 2589 } else { |
2333 warning(element.label, MessageKind.UNUSED_LABEL, | 2590 warning(element.label, MessageKind.UNUSED_LABEL, |
2334 {'labelName': labelName}); | 2591 {'labelName': labelName}); |
2335 } | 2592 } |
2336 }); | 2593 }); |
2337 if (!targetElement.isTarget) { | 2594 if (!targetElement.isTarget) { |
2338 registry.undefineTarget(body); | 2595 registry.undefineTarget(body); |
2339 } | 2596 } |
| 2597 return const NoneResult(); |
2340 } | 2598 } |
2341 | 2599 |
2342 visitLiteralMap(LiteralMap node) { | 2600 ResolutionResult visitLiteralMap(LiteralMap node) { |
| 2601 bool isValidAsConstant = true; |
2343 sendIsMemberAccess = false; | 2602 sendIsMemberAccess = false; |
2344 | 2603 |
2345 NodeList arguments = node.typeArguments; | 2604 NodeList arguments = node.typeArguments; |
2346 DartType keyTypeArgument; | 2605 DartType keyTypeArgument; |
2347 DartType valueTypeArgument; | 2606 DartType valueTypeArgument; |
2348 if (arguments != null) { | 2607 if (arguments != null) { |
2349 Link<Node> nodes = arguments.nodes; | 2608 Link<Node> nodes = arguments.nodes; |
2350 if (nodes.isEmpty) { | 2609 if (nodes.isEmpty) { |
2351 // The syntax [: <>{} :] is not allowed. | 2610 // The syntax [: <>{} :] is not allowed. |
2352 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2611 error(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
| 2612 isValidAsConstant = false; |
2353 } else { | 2613 } else { |
2354 keyTypeArgument = resolveTypeAnnotation(nodes.head); | 2614 keyTypeArgument = resolveTypeAnnotation(nodes.head); |
2355 nodes = nodes.tail; | 2615 nodes = nodes.tail; |
2356 if (nodes.isEmpty) { | 2616 if (nodes.isEmpty) { |
2357 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT); | 2617 warning(arguments, MessageKind.MISSING_TYPE_ARGUMENT); |
2358 } else { | 2618 } else { |
2359 valueTypeArgument = resolveTypeAnnotation(nodes.head); | 2619 valueTypeArgument = resolveTypeAnnotation(nodes.head); |
2360 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { | 2620 for (nodes = nodes.tail; !nodes.isEmpty; nodes = nodes.tail) { |
2361 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | 2621 warning(nodes.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); |
2362 resolveTypeAnnotation(nodes.head); | 2622 resolveTypeAnnotation(nodes.head); |
2363 } | 2623 } |
2364 } | 2624 } |
2365 } | 2625 } |
2366 } | 2626 } |
2367 DartType mapType; | 2627 DartType mapType; |
2368 if (valueTypeArgument != null) { | 2628 if (valueTypeArgument != null) { |
2369 mapType = new InterfaceType(compiler.mapClass, | 2629 mapType = coreTypes.mapType(keyTypeArgument, valueTypeArgument); |
2370 [keyTypeArgument, valueTypeArgument]); | |
2371 } else { | 2630 } else { |
2372 compiler.mapClass.computeType(compiler); | 2631 mapType = coreTypes.mapType(); |
2373 mapType = compiler.mapClass.rawType; | |
2374 } | 2632 } |
2375 if (node.isConst && mapType.containsTypeVariables) { | 2633 if (node.isConst && mapType.containsTypeVariables) { |
2376 compiler.reportError(arguments, | 2634 compiler.reportError(arguments, |
2377 MessageKind.TYPE_VARIABLE_IN_CONSTANT); | 2635 MessageKind.TYPE_VARIABLE_IN_CONSTANT); |
| 2636 isValidAsConstant = false; |
2378 } | 2637 } |
2379 registry.registerMapLiteral(node, mapType, node.isConst); | 2638 registry.registerMapLiteral(node, mapType, node.isConst); |
2380 registry.registerRequiredType(mapType, enclosingElement); | 2639 registry.registerRequiredType(mapType, enclosingElement); |
2381 node.visitChildren(this); | |
2382 if (node.isConst) { | 2640 if (node.isConst) { |
| 2641 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
| 2642 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
| 2643 for (LiteralMapEntry entry in node.entries) { |
| 2644 ResolutionResult keyResult = visit(entry.key); |
| 2645 ResolutionResult valueResult = visit(entry.value); |
| 2646 if (isValidAsConstant && |
| 2647 keyResult.isConstant && |
| 2648 valueResult.isConstant) { |
| 2649 keyExpressions.add(keyResult.constant); |
| 2650 valueExpressions.add(valueResult.constant); |
| 2651 } else { |
| 2652 isValidAsConstant = false; |
| 2653 } |
| 2654 } |
2383 analyzeConstantDeferred(node); | 2655 analyzeConstantDeferred(node); |
| 2656 sendIsMemberAccess = false; |
| 2657 if (isValidAsConstant) { |
| 2658 ConstantExpression constant = new MapConstantExpression( |
| 2659 mapType, keyExpressions, valueExpressions); |
| 2660 registry.setConstant(node, constant); |
| 2661 return new ConstantResult(node, constant); |
| 2662 } |
| 2663 } else { |
| 2664 node.visitChildren(this); |
| 2665 sendIsMemberAccess = false; |
2384 } | 2666 } |
2385 | 2667 return const NoneResult(); |
2386 sendIsMemberAccess = false; | |
2387 } | 2668 } |
2388 | 2669 |
2389 visitLiteralMapEntry(LiteralMapEntry node) { | 2670 ResolutionResult visitLiteralMapEntry(LiteralMapEntry node) { |
2390 node.visitChildren(this); | 2671 node.visitChildren(this); |
| 2672 return const NoneResult(); |
2391 } | 2673 } |
2392 | 2674 |
2393 visitNamedArgument(NamedArgument node) { | 2675 ResolutionResult visitNamedArgument(NamedArgument node) { |
2394 visit(node.expression); | 2676 return visit(node.expression); |
2395 } | 2677 } |
2396 | 2678 |
2397 DartType typeOfConstant(ConstantValue constant) { | 2679 DartType typeOfConstant(ConstantValue constant) { |
2398 if (constant.isInt) return compiler.intClass.rawType; | 2680 if (constant.isInt) return compiler.intClass.rawType; |
2399 if (constant.isBool) return compiler.boolClass.rawType; | 2681 if (constant.isBool) return compiler.boolClass.rawType; |
2400 if (constant.isDouble) return compiler.doubleClass.rawType; | 2682 if (constant.isDouble) return compiler.doubleClass.rawType; |
2401 if (constant.isString) return compiler.stringClass.rawType; | 2683 if (constant.isString) return compiler.stringClass.rawType; |
2402 if (constant.isNull) return compiler.nullClass.rawType; | 2684 if (constant.isNull) return compiler.nullClass.rawType; |
2403 if (constant.isFunction) return compiler.functionClass.rawType; | 2685 if (constant.isFunction) return compiler.functionClass.rawType; |
2404 assert(constant.isObject); | 2686 assert(constant.isObject); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2469 compiler.reportInfo( | 2751 compiler.reportInfo( |
2470 caseMatch.expression, | 2752 caseMatch.expression, |
2471 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, | 2753 MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE, |
2472 {'type': caseType}); | 2754 {'type': caseType}); |
2473 } | 2755 } |
2474 } | 2756 } |
2475 } | 2757 } |
2476 } | 2758 } |
2477 } | 2759 } |
2478 | 2760 |
2479 visitSwitchStatement(SwitchStatement node) { | 2761 ResolutionResult visitSwitchStatement(SwitchStatement node) { |
2480 node.expression.accept(this); | 2762 node.expression.accept(this); |
2481 | 2763 |
2482 JumpTarget breakElement = getOrDefineTarget(node); | 2764 JumpTarget breakElement = getOrDefineTarget(node); |
2483 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; | 2765 Map<String, LabelDefinition> continueLabels = <String, LabelDefinition>{}; |
2484 Link<Node> cases = node.cases.nodes; | 2766 Link<Node> cases = node.cases.nodes; |
2485 while (!cases.isEmpty) { | 2767 while (!cases.isEmpty) { |
2486 SwitchCase switchCase = cases.head; | 2768 SwitchCase switchCase = cases.head; |
2487 for (Node labelOrCase in switchCase.labelsAndCases) { | 2769 for (Node labelOrCase in switchCase.labelsAndCases) { |
2488 CaseMatch caseMatch = labelOrCase.asCaseMatch(); | 2770 CaseMatch caseMatch = labelOrCase.asCaseMatch(); |
2489 if (caseMatch != null) { | 2771 if (caseMatch != null) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2540 if (!label.isContinueTarget) { | 2822 if (!label.isContinueTarget) { |
2541 JumpTarget targetElement = label.target; | 2823 JumpTarget targetElement = label.target; |
2542 SwitchCase switchCase = targetElement.statement; | 2824 SwitchCase switchCase = targetElement.statement; |
2543 registry.undefineTarget(switchCase); | 2825 registry.undefineTarget(switchCase); |
2544 registry.undefineLabel(label.label); | 2826 registry.undefineLabel(label.label); |
2545 } | 2827 } |
2546 }); | 2828 }); |
2547 // TODO(15575): We should warn if we can detect a fall through | 2829 // TODO(15575): We should warn if we can detect a fall through |
2548 // error. | 2830 // error. |
2549 registry.registerFallThroughError(); | 2831 registry.registerFallThroughError(); |
| 2832 return const NoneResult(); |
2550 } | 2833 } |
2551 | 2834 |
2552 visitSwitchCase(SwitchCase node) { | 2835 ResolutionResult visitSwitchCase(SwitchCase node) { |
2553 node.labelsAndCases.accept(this); | 2836 node.labelsAndCases.accept(this); |
2554 visitIn(node.statements, new BlockScope(scope)); | 2837 visitIn(node.statements, new BlockScope(scope)); |
| 2838 return const NoneResult(); |
2555 } | 2839 } |
2556 | 2840 |
2557 visitCaseMatch(CaseMatch node) { | 2841 ResolutionResult visitCaseMatch(CaseMatch node) { |
2558 visit(node.expression); | 2842 visit(node.expression); |
| 2843 return const NoneResult(); |
2559 } | 2844 } |
2560 | 2845 |
2561 visitTryStatement(TryStatement node) { | 2846 ResolutionResult visitTryStatement(TryStatement node) { |
2562 visit(node.tryBlock); | 2847 visit(node.tryBlock); |
2563 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { | 2848 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { |
2564 error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); | 2849 error(node.getEndToken().next, MessageKind.NO_CATCH_NOR_FINALLY); |
2565 } | 2850 } |
2566 visit(node.catchBlocks); | 2851 visit(node.catchBlocks); |
2567 visit(node.finallyBlock); | 2852 visit(node.finallyBlock); |
| 2853 return const NoneResult(); |
2568 } | 2854 } |
2569 | 2855 |
2570 visitCatchBlock(CatchBlock node) { | 2856 ResolutionResult visitCatchBlock(CatchBlock node) { |
2571 registry.registerCatchStatement(); | 2857 registry.registerCatchStatement(); |
2572 // Check that if catch part is present, then | 2858 // Check that if catch part is present, then |
2573 // it has one or two formal parameters. | 2859 // it has one or two formal parameters. |
2574 VariableDefinitions exceptionDefinition; | 2860 VariableDefinitions exceptionDefinition; |
2575 VariableDefinitions stackTraceDefinition; | 2861 VariableDefinitions stackTraceDefinition; |
2576 if (node.formals != null) { | 2862 if (node.formals != null) { |
2577 Link<Node> formalsToProcess = node.formals.nodes; | 2863 Link<Node> formalsToProcess = node.formals.nodes; |
2578 if (formalsToProcess.isEmpty) { | 2864 if (formalsToProcess.isEmpty) { |
2579 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 2865 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
2580 } else { | 2866 } else { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2630 registry.getDefinition(exceptionVariable); | 2916 registry.getDefinition(exceptionVariable); |
2631 exceptionElement.variables.type = exceptionType; | 2917 exceptionElement.variables.type = exceptionType; |
2632 } | 2918 } |
2633 if (stackTraceDefinition != null) { | 2919 if (stackTraceDefinition != null) { |
2634 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; | 2920 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; |
2635 VariableElementX stackTraceElement = | 2921 VariableElementX stackTraceElement = |
2636 registry.getDefinition(stackTraceVariable); | 2922 registry.getDefinition(stackTraceVariable); |
2637 registry.registerInstantiatedClass(compiler.stackTraceClass); | 2923 registry.registerInstantiatedClass(compiler.stackTraceClass); |
2638 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; | 2924 stackTraceElement.variables.type = compiler.stackTraceClass.rawType; |
2639 } | 2925 } |
2640 } | 2926 return const NoneResult(); |
2641 | |
2642 visitTypedef(Typedef node) { | |
2643 internalError(node, 'typedef'); | |
2644 } | 2927 } |
2645 } | 2928 } |
2646 | 2929 |
2647 /// Looks up [name] in [scope] and unwraps the result. | 2930 /// Looks up [name] in [scope] and unwraps the result. |
2648 Element lookupInScope(Compiler compiler, Node node, | 2931 Element lookupInScope(Compiler compiler, Node node, |
2649 Scope scope, String name) { | 2932 Scope scope, String name) { |
2650 return Elements.unwrap(scope.lookup(name), compiler, node); | 2933 return Elements.unwrap(scope.lookup(name), compiler, node); |
2651 } | 2934 } |
OLD | NEW |