Chromium Code Reviews| 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 library dart2js.resolution.constructors; | 5 library dart2js.resolution.constructors; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/resolution.dart' show | 8 import '../common/resolution.dart' show |
| 9 Feature; | 9 Feature; |
| 10 import '../compiler.dart' show | 10 import '../compiler.dart' show |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 diagnosticNode, kind, arguments); | 496 diagnosticNode, kind, arguments); |
| 497 } else { | 497 } else { |
| 498 reporter.reportWarningMessage( | 498 reporter.reportWarningMessage( |
| 499 diagnosticNode, kind, arguments); | 499 diagnosticNode, kind, arguments); |
| 500 } | 500 } |
| 501 ErroneousElement error = new ErroneousConstructorElementX( | 501 ErroneousElement error = new ErroneousConstructorElementX( |
| 502 kind, arguments, name, enclosing); | 502 kind, arguments, name, enclosing); |
| 503 if (type == null) { | 503 if (type == null) { |
| 504 type = new MalformedType(error, null); | 504 type = new MalformedType(error, null); |
| 505 } | 505 } |
| 506 return new ConstructorResult(resultKind, error, type); | 506 return new ConstructorResult.forError(resultKind, error, type); |
| 507 } | 507 } |
| 508 | 508 |
| 509 ConstructorResult resolveConstructor( | 509 ConstructorResult resolveConstructor( |
| 510 PrefixElement prefix, | |
| 510 InterfaceType type, | 511 InterfaceType type, |
| 511 Node diagnosticNode, | 512 Node diagnosticNode, |
| 512 String constructorName) { | 513 String constructorName) { |
| 513 ClassElement cls = type.element; | 514 ClassElement cls = type.element; |
| 514 cls.ensureResolved(resolution); | 515 cls.ensureResolved(resolution); |
| 515 ConstructorElement constructor = findConstructor( | 516 ConstructorElement constructor = findConstructor( |
| 516 resolver.enclosingElement.library, cls, constructorName); | 517 resolver.enclosingElement.library, cls, constructorName); |
| 517 if (constructor == null) { | 518 if (constructor == null) { |
| 518 MessageKind kind = constructorName.isEmpty | 519 MessageKind kind = constructorName.isEmpty |
| 519 ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR | 520 ? MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR |
| 520 : MessageKind.CANNOT_FIND_CONSTRUCTOR; | 521 : MessageKind.CANNOT_FIND_CONSTRUCTOR; |
| 521 return reportAndCreateErroneousConstructorElement( | 522 return reportAndCreateErroneousConstructorElement( |
| 522 diagnosticNode, | 523 diagnosticNode, |
| 523 ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type, | 524 ConstructorResultKind.UNRESOLVED_CONSTRUCTOR, type, |
| 524 cls, constructorName, kind, | 525 cls, constructorName, kind, |
| 525 {'className': cls.name, 'constructorName': constructorName}, | 526 {'className': cls.name, 'constructorName': constructorName}, |
| 526 missingConstructor: true); | 527 missingConstructor: true); |
| 527 } else if (inConstContext && !constructor.isConst) { | 528 } else if (inConstContext && !constructor.isConst) { |
| 528 reporter.reportErrorMessage( | 529 reporter.reportErrorMessage( |
| 529 diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 530 diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 530 return new ConstructorResult( | 531 return new ConstructorResult.forError( |
| 531 ConstructorResultKind.NON_CONSTANT, constructor, type); | 532 ConstructorResultKind.NON_CONSTANT, constructor, type); |
| 532 } else { | 533 } else { |
| 534 if (cls.isEnumClass && resolver.currentClass != cls) { | |
| 535 return reportAndCreateErroneousConstructorElement( | |
| 536 diagnosticNode, | |
| 537 ConstructorResultKind.INVALID_TYPE, type, | |
| 538 cls, constructorName, | |
| 539 MessageKind.CANNOT_INSTANTIATE_ENUM, | |
| 540 {'enumName': cls.name}, | |
| 541 isError: true); | |
| 542 } | |
| 533 if (constructor.isGenerativeConstructor) { | 543 if (constructor.isGenerativeConstructor) { |
| 534 if (cls.isAbstract) { | 544 if (cls.isAbstract) { |
| 535 reporter.reportWarningMessage( | 545 reporter.reportWarningMessage( |
| 536 diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION); | 546 diagnosticNode, MessageKind.ABSTRACT_CLASS_INSTANTIATION); |
| 537 registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION); | 547 registry.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION); |
| 538 return new ConstructorResult( | 548 return new ConstructorResult( |
| 539 ConstructorResultKind.ABSTRACT, constructor, type); | 549 ConstructorResultKind.ABSTRACT, prefix, constructor, type); |
| 540 } else { | 550 } else { |
| 541 return new ConstructorResult( | 551 return new ConstructorResult( |
| 542 ConstructorResultKind.GENERATIVE, constructor, type); | 552 ConstructorResultKind.GENERATIVE, prefix, constructor, type); |
| 543 } | 553 } |
| 544 } else { | 554 } else { |
| 545 assert(invariant(diagnosticNode, constructor.isFactoryConstructor, | 555 assert(invariant(diagnosticNode, constructor.isFactoryConstructor, |
| 546 message: "Unexpected constructor $constructor.")); | 556 message: "Unexpected constructor $constructor.")); |
| 547 return new ConstructorResult( | 557 return new ConstructorResult( |
| 548 ConstructorResultKind.FACTORY, constructor, type); | 558 ConstructorResultKind.FACTORY, prefix, constructor, type); |
| 549 } | 559 } |
| 550 } | 560 } |
| 551 } | 561 } |
| 552 | 562 |
| 553 ConstructorResult visitNewExpression(NewExpression node) { | 563 ConstructorResult visitNewExpression(NewExpression node) { |
| 554 Node selector = node.send.selector; | 564 Node selector = node.send.selector; |
| 555 ConstructorResult result = visit(selector); | 565 ConstructorResult result = visit(selector); |
| 556 assert(invariant(selector, result != null, | 566 assert(invariant(selector, result != null, |
| 557 message: 'No result returned for $selector.')); | 567 message: 'No result returned for $selector.')); |
| 558 return finishConstructorReference(result, node.send.selector, node); | 568 return finishConstructorReference(result, node.send.selector, node); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 569 | 579 |
| 570 if (result.kind != null) { | 580 if (result.kind != null) { |
| 571 resolver.registry.setType(expression, result.type); | 581 resolver.registry.setType(expression, result.type); |
| 572 return result; | 582 return result; |
| 573 } | 583 } |
| 574 | 584 |
| 575 // Find the unnamed constructor if the reference resolved to a | 585 // Find the unnamed constructor if the reference resolved to a |
| 576 // class. | 586 // class. |
| 577 if (result.type != null) { | 587 if (result.type != null) { |
| 578 // The unnamed constructor may not exist, so [e] may become unresolved. | 588 // The unnamed constructor may not exist, so [e] may become unresolved. |
| 579 result = resolveConstructor(result.type, diagnosticNode, ''); | 589 result = resolveConstructor( |
| 590 result.prefix, result.type, diagnosticNode, ''); | |
| 580 } else { | 591 } else { |
| 581 Element element = result.element; | 592 Element element = result.element; |
| 582 if (element.isMalformed) { | 593 if (element.isMalformed) { |
| 583 result = constructorResultForErroneous(diagnosticNode, element); | 594 result = constructorResultForErroneous(diagnosticNode, element); |
| 584 } else { | 595 } else { |
| 585 result = reportAndCreateErroneousConstructorElement( | 596 result = reportAndCreateErroneousConstructorElement( |
| 586 diagnosticNode, | 597 diagnosticNode, |
| 587 ConstructorResultKind.INVALID_TYPE, null, | 598 ConstructorResultKind.INVALID_TYPE, null, |
| 588 element, element.name, | 599 element, element.name, |
| 589 MessageKind.NOT_A_TYPE, {'node': diagnosticNode}); | 600 MessageKind.NOT_A_TYPE, {'node': diagnosticNode}); |
| 590 } | 601 } |
| 591 } | 602 } |
| 592 resolver.registry.setType(expression, result.type); | 603 resolver.registry.setType(expression, result.type); |
| 593 return result; | 604 return result; |
| 594 } | 605 } |
| 595 | 606 |
| 596 ConstructorResult visitTypeAnnotation(TypeAnnotation node) { | 607 ConstructorResult visitTypeAnnotation(TypeAnnotation node) { |
| 597 // This is not really resolving a type-annotation, but the name of the | 608 // This is not really resolving a type-annotation, but the name of the |
| 598 // constructor. Therefore we allow deferred types. | 609 // constructor. Therefore we allow deferred types. |
| 599 DartType type = resolver.resolveTypeAnnotation( | 610 DartType type = resolver.resolveTypeAnnotation( |
| 600 node, | 611 node, |
| 601 malformedIsError: inConstContext, | 612 malformedIsError: inConstContext, |
| 602 deferredIsMalformed: false); | 613 deferredIsMalformed: false); |
| 603 return constructorResultForType(node, type); | 614 Send send = node.typeName.asSend(); |
| 615 PrefixElement prefix; | |
| 616 if (send != null) { | |
| 617 // The type name is of the form [: prefix . identifier :]. | |
| 618 String name = send.receiver.asIdentifier().source; | |
| 619 Element element = resolver.reportLookupErrorIfAny( | |
| 620 lookupInScope(reporter, send, resolver.scope, name), node, name); | |
| 621 if (element != null && element.isPrefix) { | |
| 622 prefix = element; | |
| 623 } | |
| 624 } | |
| 625 return constructorResultForType(node, type, prefix: prefix); | |
| 604 } | 626 } |
| 605 | 627 |
| 606 ConstructorResult visitSend(Send node) { | 628 ConstructorResult visitSend(Send node) { |
| 607 ConstructorResult receiver = visit(node.receiver); | 629 ConstructorResult receiver = visit(node.receiver); |
| 608 assert(invariant(node.receiver, receiver != null, | 630 assert(invariant(node.receiver, receiver != null, |
| 609 message: 'No result returned for $node.receiver.')); | 631 message: 'No result returned for $node.receiver.')); |
| 610 if (receiver.kind != null) { | 632 if (receiver.kind != null) { |
| 611 assert(invariant(node, receiver.element.isMalformed, | 633 assert(invariant(node, receiver.element.isMalformed, |
| 612 message: "Unexpected prefix result: $receiver.")); | 634 message: "Unexpected prefix result: $receiver.")); |
| 613 // We have already found an error. | 635 // We have already found an error. |
| 614 return receiver; | 636 return receiver; |
| 615 } | 637 } |
| 616 | 638 |
| 617 Identifier name = node.selector.asIdentifier(); | 639 Identifier name = node.selector.asIdentifier(); |
| 618 if (name == null) { | 640 if (name == null) { |
| 619 reporter.internalError(node.selector, 'unexpected node'); | 641 reporter.internalError(node.selector, 'unexpected node'); |
| 620 } | 642 } |
| 621 | 643 |
| 622 if (receiver.type != null) { | 644 if (receiver.type != null) { |
| 623 if (receiver.type.isInterfaceType) { | 645 if (receiver.type.isInterfaceType) { |
| 624 return resolveConstructor(receiver.type, name, name.source); | 646 return resolveConstructor( |
| 647 receiver.prefix, receiver.type, name, name.source); | |
| 625 } else { | 648 } else { |
| 626 // TODO(johnniwinther): Update the message for the different types. | 649 // TODO(johnniwinther): Update the message for the different types. |
| 627 return reportAndCreateErroneousConstructorElement( | 650 return reportAndCreateErroneousConstructorElement( |
| 628 name, | 651 name, |
| 629 ConstructorResultKind.INVALID_TYPE, null, | 652 ConstructorResultKind.INVALID_TYPE, null, |
| 630 resolver.enclosingElement, name.source, | 653 resolver.enclosingElement, name.source, |
| 631 MessageKind.NOT_A_TYPE, {'node': name}); | 654 MessageKind.NOT_A_TYPE, {'node': name}); |
| 632 } | 655 } |
| 633 } else if (receiver.element.isPrefix) { | 656 } else if (receiver.element.isPrefix) { |
| 634 PrefixElement prefix = receiver.element; | 657 PrefixElement prefix = receiver.element; |
| 635 Element member = prefix.lookupLocalMember(name.source); | 658 Element member = prefix.lookupLocalMember(name.source); |
| 636 return constructorResultForElement(node, name.source, member); | 659 return constructorResultForElement( |
| 660 node, name.source, member, prefix: prefix); | |
| 637 } else { | 661 } else { |
| 638 return reporter.internalError( | 662 return reporter.internalError( |
| 639 node.receiver, 'unexpected receiver $receiver'); | 663 node.receiver, 'unexpected receiver $receiver'); |
| 640 } | 664 } |
| 641 } | 665 } |
| 642 | 666 |
| 643 ConstructorResult visitIdentifier(Identifier node) { | 667 ConstructorResult visitIdentifier(Identifier node) { |
| 644 String name = node.source; | 668 String name = node.source; |
| 645 Element element = resolver.reportLookupErrorIfAny( | 669 Element element = resolver.reportLookupErrorIfAny( |
| 646 lookupInScope(reporter, node, resolver.scope, name), node, name); | 670 lookupInScope(reporter, node, resolver.scope, name), node, name); |
| 647 registry.useElement(node, element); | 671 registry.useElement(node, element); |
| 648 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. | 672 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. |
| 649 return constructorResultForElement(node, name, element); | 673 return constructorResultForElement(node, name, element); |
| 650 } | 674 } |
| 651 | 675 |
| 652 /// Assumed to be called by [resolveRedirectingFactory]. | 676 /// Assumed to be called by [resolveRedirectingFactory]. |
| 653 ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { | 677 ConstructorResult visitRedirectingFactoryBody(RedirectingFactoryBody node) { |
| 654 Node constructorReference = node.constructorReference; | 678 Node constructorReference = node.constructorReference; |
| 655 return finishConstructorReference(visit(constructorReference), | 679 return finishConstructorReference(visit(constructorReference), |
| 656 constructorReference, node); | 680 constructorReference, node); |
| 657 } | 681 } |
| 658 | 682 |
| 659 ConstructorResult constructorResultForElement( | 683 ConstructorResult constructorResultForElement( |
| 660 Node node, String name, Element element) { | 684 Node node, String name, Element element, |
| 685 {PrefixElement prefix}) { | |
| 661 element = Elements.unwrap(element, reporter, node); | 686 element = Elements.unwrap(element, reporter, node); |
| 662 if (element == null) { | 687 if (element == null) { |
| 663 return reportAndCreateErroneousConstructorElement( | 688 return reportAndCreateErroneousConstructorElement( |
| 664 node, | 689 node, |
| 665 ConstructorResultKind.INVALID_TYPE, null, | 690 ConstructorResultKind.INVALID_TYPE, null, |
| 666 resolver.enclosingElement, name, | 691 resolver.enclosingElement, name, |
| 667 MessageKind.CANNOT_RESOLVE, | 692 MessageKind.CANNOT_RESOLVE, |
| 668 {'name': name}); | 693 {'name': name}); |
| 669 } else if (element.isMalformed) { | 694 } else if (element.isMalformed) { |
| 670 return constructorResultForErroneous(node, element); | 695 return constructorResultForErroneous(node, element); |
| 671 } else if (element.isClass) { | 696 } else if (element.isClass) { |
| 672 ClassElement cls = element; | 697 ClassElement cls = element; |
| 673 cls.computeType(resolution); | 698 cls.computeType(resolution); |
| 674 return constructorResultForType(node, cls.rawType); | 699 return constructorResultForType(node, cls.rawType, prefix: prefix); |
| 675 } else if (element.isPrefix) { | 700 } else if (element.isPrefix) { |
| 676 return new ConstructorResult.forElement(element); | 701 return new ConstructorResult.forElement(element); |
| 677 } else if (element.isTypedef) { | 702 } else if (element.isTypedef) { |
| 678 TypedefElement typdef = element; | 703 TypedefElement typdef = element; |
| 679 typdef.ensureResolved(resolution); | 704 typdef.ensureResolved(resolution); |
| 680 return constructorResultForType(node, typdef.rawType); | 705 return constructorResultForType(node, typdef.rawType); |
| 681 } else if (element.isTypeVariable) { | 706 } else if (element.isTypeVariable) { |
| 682 TypeVariableElement typeVariableElement = element; | 707 TypeVariableElement typeVariableElement = element; |
| 683 return constructorResultForType(node, typeVariableElement.type); | 708 return constructorResultForType(node, typeVariableElement.type); |
| 684 } else { | 709 } else { |
| 685 return reportAndCreateErroneousConstructorElement( | 710 return reportAndCreateErroneousConstructorElement( |
| 686 node, | 711 node, |
| 687 ConstructorResultKind.INVALID_TYPE, null, | 712 ConstructorResultKind.INVALID_TYPE, null, |
| 688 resolver.enclosingElement, name, | 713 resolver.enclosingElement, name, |
| 689 MessageKind.NOT_A_TYPE, {'node': name}); | 714 MessageKind.NOT_A_TYPE, {'node': name}); |
| 690 } | 715 } |
| 691 } | 716 } |
| 692 | 717 |
| 693 ConstructorResult constructorResultForErroneous( | 718 ConstructorResult constructorResultForErroneous( |
| 694 Node node, Element error) { | 719 Node node, Element error) { |
| 695 if (error is! ErroneousElementX) { | 720 if (error is! ErroneousElementX) { |
| 696 // Parser error. The error has already been reported. | 721 // Parser error. The error has already been reported. |
| 697 error = new ErroneousConstructorElementX( | 722 error = new ErroneousConstructorElementX( |
| 698 MessageKind.NOT_A_TYPE, {'node': node}, | 723 MessageKind.NOT_A_TYPE, {'node': node}, |
| 699 error.name, error); | 724 error.name, error); |
| 700 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); | 725 registry.registerFeature(Feature.THROW_RUNTIME_ERROR); |
| 701 } | 726 } |
| 702 return new ConstructorResult( | 727 return new ConstructorResult.forError( |
| 703 ConstructorResultKind.INVALID_TYPE, | 728 ConstructorResultKind.INVALID_TYPE, |
| 704 error, | 729 error, |
| 705 new MalformedType(error, null)); | 730 new MalformedType(error, null)); |
| 706 } | 731 } |
| 707 | 732 |
| 708 ConstructorResult constructorResultForType( | 733 ConstructorResult constructorResultForType( |
| 709 Node node, | 734 Node node, |
| 710 DartType type) { | 735 DartType type, |
| 736 {PrefixElement prefix}) { | |
| 711 String name = type.name; | 737 String name = type.name; |
| 712 if (type.isMalformed) { | 738 if (type.isMalformed) { |
| 713 return new ConstructorResult( | 739 return new ConstructorResult.forError( |
| 714 ConstructorResultKind.INVALID_TYPE, type.element, type); | 740 ConstructorResultKind.INVALID_TYPE, type.element, type); |
| 715 } else if (type.isInterfaceType) { | 741 } else if (type.isInterfaceType) { |
| 716 return new ConstructorResult.forType(type); | 742 return new ConstructorResult.forType(prefix, type); |
| 717 } else if (type.isTypedef) { | 743 } else if (type.isTypedef) { |
| 718 return reportAndCreateErroneousConstructorElement( | 744 return reportAndCreateErroneousConstructorElement( |
| 719 node, | 745 node, |
| 720 ConstructorResultKind.INVALID_TYPE, type, | 746 ConstructorResultKind.INVALID_TYPE, type, |
| 721 resolver.enclosingElement, name, | 747 resolver.enclosingElement, name, |
| 722 MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name}); | 748 MessageKind.CANNOT_INSTANTIATE_TYPEDEF, {'typedefName': name}); |
| 723 } else if (type.isTypeVariable) { | 749 } else if (type.isTypeVariable) { |
| 724 return reportAndCreateErroneousConstructorElement( | 750 return reportAndCreateErroneousConstructorElement( |
| 725 node, | 751 node, |
| 726 ConstructorResultKind.INVALID_TYPE, type, | 752 ConstructorResultKind.INVALID_TYPE, type, |
| 727 resolver.enclosingElement, name, | 753 resolver.enclosingElement, name, |
| 728 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, | 754 MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, |
| 729 {'typeVariableName': name}); | 755 {'typeVariableName': name}); |
| 730 } | 756 } |
| 731 return reporter.internalError(node, "Unexpected constructor type $type"); | 757 return reporter.internalError(node, "Unexpected constructor type $type"); |
| 732 } | 758 } |
| 733 | 759 |
| 734 } | 760 } |
| 735 | 761 |
| 736 enum ConstructorResultKind { | 762 enum ConstructorResultKind { |
| 737 GENERATIVE, | 763 GENERATIVE, |
| 738 FACTORY, | 764 FACTORY, |
| 739 ABSTRACT, | 765 ABSTRACT, |
| 740 INVALID_TYPE, | 766 INVALID_TYPE, |
| 741 UNRESOLVED_CONSTRUCTOR, | 767 UNRESOLVED_CONSTRUCTOR, |
| 742 NON_CONSTANT, | 768 NON_CONSTANT, |
|
sigurdm
2015/11/11 08:24:52
Add comment to explain what NON_CONSTANT means? Is
Johnni Winther
2015/11/11 09:56:29
Done.
| |
| 743 } | 769 } |
| 744 | 770 |
| 745 class ConstructorResult { | 771 class ConstructorResult { |
|
sigurdm
2015/11/11 08:24:52
Add dartdoc
Johnni Winther
2015/11/11 09:56:29
Done.
| |
| 772 final PrefixElement prefix; | |
|
Johnni Winther
2015/11/10 13:42:20
This prepares for handling of deferred access whic
sigurdm
2015/11/11 08:24:51
Would it make sense to call it deferredPrefix and
Johnni Winther
2015/11/11 09:56:29
I'd rather have receivers test `result.isDeferred`
| |
| 746 final ConstructorResultKind kind; | 773 final ConstructorResultKind kind; |
| 747 final Element element; | 774 final Element element; |
|
sigurdm
2015/11/11 08:24:52
Could this be a `ConstructorElement`?
| |
| 748 final DartType type; | 775 final DartType type; |
| 749 | 776 |
| 750 ConstructorResult(this.kind, this.element, this.type); | 777 ConstructorResult(this.kind, this.prefix, this.element, this.type); |
| 778 | |
| 779 ConstructorResult.forError(this.kind, this.element, this.type) | |
| 780 : prefix = null; | |
| 751 | 781 |
| 752 ConstructorResult.forElement(this.element) | 782 ConstructorResult.forElement(this.element) |
|
sigurdm
2015/11/11 08:24:52
Add dartdoc
Johnni Winther
2015/11/11 09:56:29
Done.
| |
| 753 : kind = null, | 783 : prefix = null, |
| 784 kind = null, | |
| 754 type = null; | 785 type = null; |
| 755 | 786 |
| 756 ConstructorResult.forType(this.type) | 787 ConstructorResult.forType(this.prefix, this.type) |
|
sigurdm
2015/11/11 08:24:52
add dartdoc
Johnni Winther
2015/11/11 09:56:29
Done.
| |
| 757 : kind = null, | 788 : kind = null, |
| 758 element = null; | 789 element = null; |
| 759 | 790 |
| 791 bool get isDeferred => prefix != null && prefix.isDeferred; | |
| 792 | |
| 760 String toString() { | 793 String toString() { |
| 761 StringBuffer sb = new StringBuffer(); | 794 StringBuffer sb = new StringBuffer(); |
| 762 sb.write('ConstructorResult('); | 795 sb.write('ConstructorResult('); |
| 763 if (kind != null) { | 796 if (kind != null) { |
| 764 sb.write('kind=$kind,'); | 797 sb.write('kind=$kind,'); |
| 798 if (prefix != null) { | |
| 799 sb.write('prefix=$prefix,'); | |
| 800 } | |
| 765 sb.write('element=$element,'); | 801 sb.write('element=$element,'); |
| 766 sb.write('type=$type'); | 802 sb.write('type=$type'); |
| 767 } else if (element != null) { | 803 } else if (element != null) { |
| 768 sb.write('element=$element'); | 804 sb.write('element=$element'); |
| 769 } else { | 805 } else { |
| 806 if (prefix != null) { | |
| 807 sb.write('prefix=$prefix,'); | |
| 808 } | |
| 770 sb.write('type=$type'); | 809 sb.write('type=$type'); |
| 771 } | 810 } |
| 772 sb.write(')'); | 811 sb.write(')'); |
| 773 return sb.toString(); | 812 return sb.toString(); |
| 774 } | 813 } |
| 775 } | 814 } |
| 776 | 815 |
| 777 /// Lookup the [constructorName] constructor in [cls] and normalize the result | 816 /// Lookup the [constructorName] constructor in [cls] and normalize the result |
| 778 /// with respect to privacy and patching. | 817 /// with respect to privacy and patching. |
| 779 ConstructorElement findConstructor( | 818 ConstructorElement findConstructor( |
| 780 LibraryElement currentLibrary, | 819 LibraryElement currentLibrary, |
| 781 ClassElement cls, | 820 ClassElement cls, |
| 782 String constructorName) { | 821 String constructorName) { |
|
sigurdm
2015/11/11 08:24:52
Not this CL.
This could take a Name instead of a
Johnni Winther
2015/11/11 09:56:29
Acknowledged.
| |
| 783 if (Name.isPrivateName(constructorName) && | 822 if (Name.isPrivateName(constructorName) && |
| 784 currentLibrary.library != cls.library) { | 823 currentLibrary.library != cls.library) { |
| 785 // TODO(johnniwinther): Report a special error on unaccessible private | 824 // TODO(johnniwinther): Report a special error on unaccessible private |
| 786 // constructors. | 825 // constructors. |
| 787 return null; | 826 return null; |
| 788 } | 827 } |
| 789 // TODO(johnniwinther): Use [Name] for lookup. | 828 // TODO(johnniwinther): Use [Name] for lookup. |
| 790 ConstructorElement constructor = cls.lookupConstructor(constructorName); | 829 ConstructorElement constructor = cls.lookupConstructor(constructorName); |
| 791 if (constructor != null) { | 830 if (constructor != null) { |
| 792 constructor = constructor.declaration; | 831 constructor = constructor.declaration; |
| 793 } | 832 } |
| 794 return constructor; | 833 return constructor; |
| 795 } | 834 } |
| OLD | NEW |