OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart2js.semantics_visitor; | 5 part of dart2js.semantics_visitor; |
6 | 6 |
7 enum SendStructureKind { | 7 enum SendStructureKind { |
8 GET, | 8 GET, |
9 SET, | 9 SET, |
10 INVOKE, | 10 INVOKE, |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 // This happens for code like `C.this`. | 423 // This happens for code like `C.this`. |
424 return new StaticAccess.unresolved(null); | 424 return new StaticAccess.unresolved(null); |
425 } else { | 425 } else { |
426 return handleStaticallyResolvedAccess(node, element, getter); | 426 return handleStaticallyResolvedAccess(node, element, getter); |
427 } | 427 } |
428 } | 428 } |
429 } | 429 } |
430 | 430 |
431 ConstructorAccessSemantics computeConstructorAccessSemantics( | 431 ConstructorAccessSemantics computeConstructorAccessSemantics( |
432 ConstructorElement constructor, | 432 ConstructorElement constructor, |
433 DartType type) { | 433 DartType type, |
| 434 {bool mustBeConstant: false}) { |
| 435 if (mustBeConstant && !constructor.isConst) { |
| 436 return new ConstructorAccessSemantics( |
| 437 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type); |
| 438 } |
434 if (constructor.isErroneous) { | 439 if (constructor.isErroneous) { |
435 if (constructor is ErroneousElement) { | 440 if (constructor is ErroneousElement) { |
436 ErroneousElement error = constructor; | 441 ErroneousElement error = constructor; |
437 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 442 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
438 return new ConstructorAccessSemantics( | 443 return new ConstructorAccessSemantics( |
439 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type); | 444 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type); |
440 } | 445 } |
441 } | 446 } |
442 return new ConstructorAccessSemantics( | 447 return new ConstructorAccessSemantics( |
443 ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type); | 448 ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type); |
444 } else if (constructor.isRedirectingFactory) { | 449 } else if (constructor.isRedirectingFactory) { |
445 ConstructorElement effectiveTarget = constructor.effectiveTarget; | 450 ConstructorElement effectiveTarget = constructor.effectiveTarget; |
446 if (effectiveTarget == constructor || | 451 if (effectiveTarget == constructor || |
447 effectiveTarget.isErroneous) { | 452 effectiveTarget.isErroneous || |
| 453 (mustBeConstant && !effectiveTarget.isConst)) { |
448 return new ConstructorAccessSemantics( | 454 return new ConstructorAccessSemantics( |
449 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, | 455 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, |
450 constructor, | 456 constructor, |
451 type); | 457 type); |
452 } | 458 } |
453 ConstructorAccessSemantics effectiveTargetSemantics = | 459 ConstructorAccessSemantics effectiveTargetSemantics = |
454 computeConstructorAccessSemantics( | 460 computeConstructorAccessSemantics( |
455 effectiveTarget, | 461 effectiveTarget, |
456 constructor.computeEffectiveTargetType(type)); | 462 constructor.computeEffectiveTargetType(type)); |
457 if (effectiveTargetSemantics.isErroneous) { | 463 if (effectiveTargetSemantics.isErroneous) { |
(...skipping 21 matching lines...) Expand all Loading... |
479 } else if (constructor.enclosingClass.isAbstract) { | 485 } else if (constructor.enclosingClass.isAbstract) { |
480 return new ConstructorAccessSemantics( | 486 return new ConstructorAccessSemantics( |
481 ConstructorAccessKind.ABSTRACT, constructor, type); | 487 ConstructorAccessKind.ABSTRACT, constructor, type); |
482 } else { | 488 } else { |
483 return new ConstructorAccessSemantics( | 489 return new ConstructorAccessSemantics( |
484 ConstructorAccessKind.GENERATIVE, constructor, type); | 490 ConstructorAccessKind.GENERATIVE, constructor, type); |
485 } | 491 } |
486 } | 492 } |
487 | 493 |
488 NewStructure computeNewStructure(NewExpression node) { | 494 NewStructure computeNewStructure(NewExpression node) { |
489 if (node.isConst) { | |
490 ConstantExpression constant = elements.getConstant(node); | |
491 if (constant is ConstructedConstantExpression) { | |
492 return new ConstInvokeStructure(constant); | |
493 } | |
494 } | |
495 | |
496 Element element = elements[node.send]; | 495 Element element = elements[node.send]; |
497 Selector selector = elements.getSelector(node.send); | 496 Selector selector = elements.getSelector(node.send); |
498 DartType type = elements.getType(node); | 497 DartType type = elements.getType(node); |
499 | 498 |
500 ConstructorAccessSemantics constructorAccessSemantics; | 499 ConstructorAccessSemantics constructorAccessSemantics = |
| 500 computeConstructorAccessSemantics( |
| 501 element, type, mustBeConstant: node.isConst); |
501 if (node.isConst) { | 502 if (node.isConst) { |
502 // This is a non-constant constant constructor invocation, like | 503 ConstantExpression constant = elements.getConstant(node); |
503 // `const Const(method())`. | 504 if (constructorAccessSemantics.isErroneous || |
504 constructorAccessSemantics = new ConstructorAccessSemantics( | 505 constant is! ConstructedConstantExpression) { |
505 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type); | 506 // This is a non-constant constant constructor invocation, like |
506 } else { | 507 // `const Const(method())`. |
507 constructorAccessSemantics = | 508 constructorAccessSemantics = new ConstructorAccessSemantics( |
508 computeConstructorAccessSemantics(element, type); | 509 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type); |
| 510 } else { |
| 511 return new ConstInvokeStructure(constant); |
| 512 } |
509 } | 513 } |
510 return new NewInvokeStructure(constructorAccessSemantics, selector); | 514 return new NewInvokeStructure(constructorAccessSemantics, selector); |
511 } | 515 } |
512 } | 516 } |
513 | 517 |
514 abstract class DeclStructure<R, A> { | 518 abstract class DeclStructure<R, A> { |
515 final FunctionElement element; | 519 final FunctionElement element; |
516 | 520 |
517 DeclStructure(this.element); | 521 DeclStructure(this.element); |
518 | 522 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 return internalError(node, "Unexpected variable $element."); | 813 return internalError(node, "Unexpected variable $element."); |
810 } | 814 } |
811 if (element.isConst) { | 815 if (element.isConst) { |
812 ConstantExpression constant = elements.getConstant(element.initializer); | 816 ConstantExpression constant = elements.getConstant(element.initializer); |
813 return new ConstantVariableStructure(kind, node, element, constant); | 817 return new ConstantVariableStructure(kind, node, element, constant); |
814 } else { | 818 } else { |
815 return new NonConstantVariableStructure(kind, node, element); | 819 return new NonConstantVariableStructure(kind, node, element); |
816 } | 820 } |
817 } | 821 } |
818 } | 822 } |
OLD | NEW |