Chromium Code Reviews| 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 abstract class TreeElements { | 5 abstract class TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 DartType getType(TypeAnnotation annotation); | 8 DartType getType(TypeAnnotation annotation); |
| 9 bool isParameterChecked(Element element); | 9 bool isParameterChecked(Element element); |
| 10 } | 10 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 if (kind === ElementKind.PARAMETER || | 80 if (kind === ElementKind.PARAMETER || |
| 81 kind === ElementKind.FIELD_PARAMETER) { | 81 kind === ElementKind.FIELD_PARAMETER) { |
| 82 return resolveParameter(element); | 82 return resolveParameter(element); |
| 83 } | 83 } |
| 84 | 84 |
| 85 compiler.unimplemented("resolve($element)", | 85 compiler.unimplemented("resolve($element)", |
| 86 node: element.parseNode(compiler)); | 86 node: element.parseNode(compiler)); |
| 87 }); | 87 }); |
| 88 } | 88 } |
| 89 | 89 |
| 90 SourceString getConstructorName(Send node) { | 90 bool isNamedConstructor(Send node) => node.receiver !== null; |
| 91 if (node.receiver !== null) { | 91 SourceString getConstructorName(Send node) => |
| 92 return node.selector.asIdentifier().source; | 92 node.selector.asIdentifier().source; |
| 93 } else { | |
| 94 return const SourceString(''); | |
| 95 } | |
| 96 } | |
| 97 | 93 |
| 98 FunctionElement resolveConstructorRedirection(FunctionElement constructor) { | 94 String createConstructorFullName(SourceString className, |
| 95 SourceString constructorName) { | |
| 96 String classNameString = className.slowToString(); | |
| 97 String constructorNameString = constructorName.slowToString(); | |
| 98 return (constructorName === const SourceString('')) | |
| 99 ? classNameString | |
|
kasperl
2012/10/08 08:06:41
4 space indent of ? and :.
aam-me
2012/10/09 04:08:42
Done.
| |
| 100 : "$classNameString.$constructorNameString"; | |
| 101 } | |
| 102 | |
| 103 FunctionElement resolveConstructorRedirection(InitializerResolver resolver, | |
| 104 FunctionElement constructor) { | |
| 99 if (constructor.isPatched) { | 105 if (constructor.isPatched) { |
| 100 checkMatchingPatchSignatures(constructor, constructor.patch); | 106 checkMatchingPatchSignatures(constructor, constructor.patch); |
| 101 constructor = constructor.patch; | 107 constructor = constructor.patch; |
| 102 } | 108 } |
| 103 FunctionExpression node = constructor.parseNode(compiler); | 109 FunctionExpression node = constructor.parseNode(compiler); |
| 104 | 110 |
| 105 // A synthetic constructor does not have a node. | 111 // A synthetic constructor does not have a node. |
| 106 if (node === null) return null; | 112 if (node === null) return null; |
| 107 if (node.initializers === null) return null; | 113 if (node.initializers === null) return null; |
| 108 Link<Node> initializers = node.initializers.nodes; | 114 Link<Node> initializers = node.initializers.nodes; |
| 109 if (!initializers.isEmpty() && | 115 if (!initializers.isEmpty() && |
| 110 Initializers.isConstructorRedirect(initializers.head)) { | 116 Initializers.isConstructorRedirect(initializers.head)) { |
| 111 final ClassElement classElement = constructor.getEnclosingClass(); | 117 final ClassElement classElement = constructor.getEnclosingClass(); |
| 112 final SourceString constructorName = | 118 Selector selector; |
| 113 getConstructorName(initializers.head); | 119 if (isNamedConstructor(initializers.head)) { |
| 114 final SourceString className = classElement.name; | 120 SourceString constructorName = getConstructorName(initializers.head); |
| 115 return classElement.lookupConstructor(className, constructorName); | 121 selector = new Selector.callConstructor( |
| 122 classElement.name, | |
| 123 constructorName, | |
| 124 resolver.visitor.enclosingElement.getLibrary()); | |
| 125 } else { | |
| 126 selector = new Selector.callDefaultConstructor( | |
| 127 classElement.name, | |
| 128 resolver.visitor.enclosingElement.getLibrary()); | |
| 129 } | |
| 130 return classElement.lookupConstructor(selector); | |
| 116 } | 131 } |
| 117 return null; | 132 return null; |
| 118 } | 133 } |
| 119 | 134 |
| 120 void resolveRedirectingConstructor(InitializerResolver resolver, | 135 void resolveRedirectingConstructor(InitializerResolver resolver, |
| 121 Node node, | 136 Node node, |
| 122 FunctionElement constructor, | 137 FunctionElement constructor, |
| 123 FunctionElement redirection) { | 138 FunctionElement redirection) { |
| 124 Set<FunctionElement> seen = new Set<FunctionElement>(); | 139 Set<FunctionElement> seen = new Set<FunctionElement>(); |
| 125 seen.add(constructor); | 140 seen.add(constructor); |
| 126 while (redirection !== null) { | 141 while (redirection !== null) { |
| 127 if (seen.contains(redirection)) { | 142 if (seen.contains(redirection)) { |
| 128 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); | 143 resolver.visitor.error(node, MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE); |
| 129 return; | 144 return; |
| 130 } | 145 } |
| 131 seen.add(redirection); | 146 seen.add(redirection); |
| 132 redirection = resolveConstructorRedirection(redirection); | 147 redirection = resolveConstructorRedirection(resolver, redirection); |
| 133 } | 148 } |
| 134 } | 149 } |
| 135 | 150 |
| 136 void checkMatchingPatchSignatures(FunctionElement origin, | 151 void checkMatchingPatchSignatures(FunctionElement origin, |
| 137 FunctionElement patch) { | 152 FunctionElement patch) { |
| 138 // TODO(johnniwinther): Stub. Implementation in a later CL. | 153 // TODO(johnniwinther): Stub. Implementation in a later CL. |
| 139 } | 154 } |
| 140 | 155 |
| 141 TreeElements resolveMethodElement(FunctionElement element) { | 156 TreeElements resolveMethodElement(FunctionElement element) { |
| 142 assert(invariant(element, element.isDeclaration)); | 157 assert(invariant(element, element.isDeclaration)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 207 // We have now established the following: | 222 // We have now established the following: |
| 208 // [intrface] is an interface, let's say "MyInterface". | 223 // [intrface] is an interface, let's say "MyInterface". |
| 209 // [defaultClass] is a class, let's say "MyClass". | 224 // [defaultClass] is a class, let's say "MyClass". |
| 210 | 225 |
| 211 // If the default class implements the interface then we must use the | 226 // If the default class implements the interface then we must use the |
| 212 // default class' name. Otherwise we look for a factory with the name | 227 // default class' name. Otherwise we look for a factory with the name |
| 213 // of the interface. | 228 // of the interface. |
| 214 SourceString name; | 229 SourceString name; |
| 215 if (defaultClass.implementsInterface(intrface)) { | 230 if (defaultClass.implementsInterface(intrface)) { |
| 216 // TODO(ahe): Don't use string replacement here. | 231 // TODO(ahe): Don't use string replacement here. |
| 217 name = new SourceString(constructor.name.slowToString().replaceFirst( | 232 name = new SourceString(constructor.name.slowToString().replaceFirst( |
|
ahe
2012/10/08 08:25:43
It is code like this I would like to get rid of.
aam-me
2012/10/09 04:08:42
This code is gone, but is replaced with another st
| |
| 218 intrface.name.slowToString(), | 233 intrface.name.slowToString(), |
| 219 defaultClass.name.slowToString())); | 234 defaultClass.name.slowToString())); |
| 220 } else { | 235 } else { |
| 221 name = constructor.name; | 236 name = constructor.name; |
| 222 } | 237 } |
| 223 constructor.defaultImplementation = defaultClass.lookupConstructor(name); | |
| 224 | 238 |
| 239 constructor.defaultImplementation = defaultClass.lookupConstructor( | |
|
ahe
2012/10/08 08:25:43
Currently, lookupConstructor expects something lik
aam-me
2012/10/08 15:03:35
Peter,
I see, but you can have multiple factor
ahe
2012/10/08 16:35:52
I'll send an email to Anton and see if he has time
aam-me
2012/10/09 04:08:42
Thanks, Peter.
Further issues down the path of us
| |
| 240 new Selector.callDefaultConstructor(name, | |
| 241 defaultClass.getLibrary())); | |
| 225 if (constructor.defaultImplementation === null) { | 242 if (constructor.defaultImplementation === null) { |
| 226 // We failed to find a constructor named either | 243 // We failed to find a constructor named either |
| 227 // "MyInterface.name" or "MyClass.name". | 244 // "MyInterface.name" or "MyClass.name". |
| 228 error(node, | 245 error(node, |
| 229 MessageKind.CANNOT_FIND_CONSTRUCTOR2, | 246 MessageKind.CANNOT_FIND_CONSTRUCTOR2, |
| 230 [name, defaultClass.name]); | 247 [name, defaultClass.name]); |
| 231 } | 248 } |
| 232 } | 249 } |
| 233 | 250 |
| 234 TreeElements resolveField(Element element) { | 251 TreeElements resolveField(Element element) { |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 } else { | 607 } else { |
| 591 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 608 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 592 } | 609 } |
| 593 visitor.useElement(init, target); | 610 visitor.useElement(init, target); |
| 594 visitor.world.registerStaticUse(target); | 611 visitor.world.registerStaticUse(target); |
| 595 checkForDuplicateInitializers(name, init); | 612 checkForDuplicateInitializers(name, init); |
| 596 // Resolve initializing value. | 613 // Resolve initializing value. |
| 597 visitor.visitInStaticContext(init.arguments.head); | 614 visitor.visitInStaticContext(init.arguments.head); |
| 598 } | 615 } |
| 599 | 616 |
| 617 ClassElement getSuperOrThisLookupTarget(FunctionElement constructor, | |
| 618 bool isSuperCall, | |
| 619 Node diagnosticNode) { | |
| 620 ClassElement lookupTarget = constructor.getEnclosingClass(); | |
| 621 if (isSuperCall) { | |
| 622 // Calculate correct lookup target and constructor name. | |
| 623 if (lookupTarget === visitor.compiler.objectClass) { | |
| 624 error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); | |
| 625 } else { | |
| 626 lookupTarget = lookupTarget.supertype.element; | |
| 627 } | |
| 628 } | |
| 629 return lookupTarget; | |
| 630 } | |
| 631 | |
| 600 Element resolveSuperOrThisForSend(FunctionElement constructor, | 632 Element resolveSuperOrThisForSend(FunctionElement constructor, |
| 601 FunctionExpression functionNode, | 633 FunctionExpression functionNode, |
| 602 Send call) { | 634 Send call) { |
| 603 // Resolve the selector and the arguments. | 635 // Resolve the selector and the arguments. |
| 604 ResolverTask resolver = visitor.compiler.resolver; | 636 ResolverTask resolver = visitor.compiler.resolver; |
| 605 visitor.inStaticContext(() { | 637 visitor.inStaticContext(() { |
| 606 visitor.resolveSelector(call); | 638 visitor.resolveSelector(call); |
| 607 visitor.resolveArguments(call.argumentsNode); | 639 visitor.resolveArguments(call.argumentsNode); |
| 608 }); | 640 }); |
| 609 Selector selector = visitor.mapping.getSelector(call); | 641 Selector selector = visitor.mapping.getSelector(call); |
| 610 bool isSuperCall = Initializers.isSuperConstructorCall(call); | 642 bool isSuperCall = Initializers.isSuperConstructorCall(call); |
| 611 SourceString constructorName = resolver.getConstructorName(call); | 643 |
| 612 Element result = resolveSuperOrThis( | 644 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, |
| 613 constructor, isSuperCall, false, constructorName, selector, call); | 645 isSuperCall, |
| 614 visitor.useElement(call, result); | 646 call); |
| 615 visitor.world.registerStaticUse(result); | 647 final SourceString className = lookupTarget.name; |
| 616 return result; | 648 |
| 649 SourceString constructorName; | |
| 650 Selector lookupSelector; | |
| 651 if (resolver.isNamedConstructor(call)) { | |
| 652 constructorName = resolver.getConstructorName(call); | |
| 653 lookupSelector = new Selector.callConstructor( | |
| 654 className, | |
| 655 constructorName, | |
| 656 visitor.enclosingElement.getLibrary()); | |
| 657 } else { | |
| 658 constructorName = const SourceString(''); | |
| 659 lookupSelector = new Selector.callDefaultConstructor( | |
| 660 className, | |
| 661 visitor.enclosingElement.getLibrary()); | |
| 662 } | |
| 663 | |
| 664 FunctionElement lookedupConstructor = | |
| 665 lookupTarget.lookupConstructor(lookupSelector); | |
| 666 | |
| 667 final bool isImplicitSuperCall = false; | |
| 668 verifyThatConstructorMatchesCall(lookedupConstructor, | |
| 669 selector, | |
| 670 isImplicitSuperCall, | |
| 671 call, | |
| 672 constructorName, | |
| 673 className); | |
| 674 | |
| 675 visitor.useElement(call, lookedupConstructor); | |
| 676 visitor.world.registerStaticUse(lookedupConstructor); | |
| 677 return lookedupConstructor; | |
| 617 } | 678 } |
| 618 | 679 |
| 619 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 680 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 620 FunctionExpression functionNode) { | 681 FunctionExpression functionNode) { |
| 621 // If the class has a super resolve the implicit super call. | 682 // If the class has a super resolve the implicit super call. |
| 622 ClassElement classElement = constructor.getEnclosingClass(); | 683 ClassElement classElement = constructor.getEnclosingClass(); |
| 623 ClassElement superClass = classElement.superclass; | 684 ClassElement superClass = classElement.superclass; |
| 624 if (classElement != visitor.compiler.objectClass) { | 685 if (classElement != visitor.compiler.objectClass) { |
| 625 assert(superClass !== null); | 686 assert(superClass !== null); |
| 626 assert(superClass.resolutionState == STATE_DONE); | 687 assert(superClass.resolutionState == STATE_DONE); |
| 627 SourceString name = const SourceString(''); | 688 SourceString constructorName = const SourceString(''); |
| 628 Selector call = new Selector.call(name, classElement.getLibrary(), 0); | 689 Selector callToMatch = new Selector.call( |
| 629 var element = resolveSuperOrThis(constructor, true, true, | 690 constructorName, |
| 630 name, call, functionNode); | 691 classElement.getLibrary(), |
| 631 visitor.world.registerStaticUse(element); | 692 0); |
| 693 | |
| 694 final bool isSuperCall = true; | |
| 695 ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor, | |
| 696 isSuperCall, | |
| 697 functionNode); | |
| 698 final SourceString className = lookupTarget.name; | |
| 699 Element calledConstructor = lookupTarget.lookupConstructor( | |
| 700 new Selector.callDefaultConstructor( | |
| 701 className, | |
| 702 visitor.enclosingElement.getLibrary())); | |
| 703 | |
| 704 final bool isImplicitSuperCall = true; | |
| 705 verifyThatConstructorMatchesCall(calledConstructor, | |
| 706 callToMatch, | |
| 707 isImplicitSuperCall, | |
| 708 functionNode, | |
| 709 className, | |
| 710 const SourceString('')); | |
| 711 | |
| 712 visitor.world.registerStaticUse(calledConstructor); | |
| 632 } | 713 } |
| 633 } | 714 } |
| 634 | 715 |
| 635 Element resolveSuperOrThis(FunctionElement constructor, | 716 void verifyThatConstructorMatchesCall( |
| 636 bool isSuperCall, | 717 FunctionElement lookedupConstructor, |
| 637 bool isImplicitSuperCall, | 718 Selector call, |
| 638 SourceString constructorName, | 719 bool isImplicitSuperCall, |
| 639 Selector selector, | 720 Node diagnosticNode, |
| 640 Node diagnosticNode) { | 721 SourceString className, |
| 641 ClassElement lookupTarget = constructor.getEnclosingClass(); | 722 SourceString constructorName) { |
| 642 bool validTarget = true; | 723 if (lookedupConstructor === null |
| 643 FunctionElement result; | 724 || !lookedupConstructor.isGenerativeConstructor()) { |
| 644 if (isSuperCall) { | 725 var fullConstructorName = |
| 645 // Calculate correct lookup target and constructor name. | 726 visitor.compiler.resolver.createConstructorFullName(className, |
| 646 if (lookupTarget === visitor.compiler.objectClass) { | 727 constructorName); |
| 647 error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT); | |
| 648 } else { | |
| 649 lookupTarget = lookupTarget.supertype.element; | |
| 650 } | |
| 651 } | |
| 652 | |
| 653 // Lookup constructor and try to match it to the selector. | |
| 654 ResolverTask resolver = visitor.compiler.resolver; | |
| 655 final SourceString className = lookupTarget.name; | |
| 656 result = lookupTarget.lookupConstructor(className, constructorName); | |
| 657 if (result === null || !result.isGenerativeConstructor()) { | |
| 658 String classNameString = className.slowToString(); | |
| 659 String constructorNameString = constructorName.slowToString(); | |
| 660 String name = (constructorName === const SourceString('')) | |
| 661 ? classNameString | |
| 662 : "$classNameString.$constructorNameString"; | |
| 663 MessageKind kind = isImplicitSuperCall | 728 MessageKind kind = isImplicitSuperCall |
| 664 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT | 729 ? MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT |
| 665 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; | 730 : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR; |
| 666 error(diagnosticNode, kind, [name]); | 731 error(diagnosticNode, kind, [fullConstructorName]); |
| 667 } else { | 732 } else { |
| 668 if (!selector.applies(result, visitor.compiler)) { | 733 if (!call.applies(lookedupConstructor, visitor.compiler)) { |
| 669 MessageKind kind = isImplicitSuperCall | 734 MessageKind kind = isImplicitSuperCall |
| 670 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT | 735 ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT |
| 671 : MessageKind.NO_MATCHING_CONSTRUCTOR; | 736 : MessageKind.NO_MATCHING_CONSTRUCTOR; |
| 672 error(diagnosticNode, kind); | 737 error(diagnosticNode, kind); |
| 673 } | 738 } |
| 674 } | 739 } |
| 675 return result; | |
| 676 } | 740 } |
| 677 | 741 |
| 678 FunctionElement resolveRedirection(FunctionElement constructor, | 742 FunctionElement resolveRedirection(FunctionElement constructor, |
| 679 FunctionExpression functionNode) { | 743 FunctionExpression functionNode) { |
| 680 if (functionNode.initializers === null) return null; | 744 if (functionNode.initializers === null) return null; |
| 681 Link<Node> link = functionNode.initializers.nodes; | 745 Link<Node> link = functionNode.initializers.nodes; |
| 682 if (!link.isEmpty() && Initializers.isConstructorRedirect(link.head)) { | 746 if (!link.isEmpty() && Initializers.isConstructorRedirect(link.head)) { |
| 683 return resolveSuperOrThisForSend(constructor, functionNode, link.head); | 747 return resolveSuperOrThisForSend(constructor, functionNode, link.head); |
| 684 } | 748 } |
| 685 return null; | 749 return null; |
| (...skipping 2024 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2710 return new ErroneousFunctionElement(kind, arguments, targetName, | 2774 return new ErroneousFunctionElement(kind, arguments, targetName, |
| 2711 enclosing); | 2775 enclosing); |
| 2712 } | 2776 } |
| 2713 } | 2777 } |
| 2714 | 2778 |
| 2715 // TODO(ngeoffray): method named lookup should not report errors. | 2779 // TODO(ngeoffray): method named lookup should not report errors. |
| 2716 FunctionElement lookupConstructor(ClassElement cls, | 2780 FunctionElement lookupConstructor(ClassElement cls, |
| 2717 Node diagnosticNode, | 2781 Node diagnosticNode, |
| 2718 SourceString constructorName) { | 2782 SourceString constructorName) { |
| 2719 cls.ensureResolved(compiler); | 2783 cls.ensureResolved(compiler); |
| 2720 Element result = cls.lookupConstructor(cls.name, constructorName); | 2784 Selector selector = |
| 2785 constructorName === const SourceString('') | |
| 2786 ? new Selector.callDefaultConstructor( | |
|
kasperl
2012/10/08 08:06:41
4 space indent of ? and :.
aam-me
2012/10/09 04:08:42
Done.
| |
| 2787 cls.name, | |
| 2788 resolver.enclosingElement.getLibrary()) | |
| 2789 : new Selector.callConstructor(cls.name, | |
| 2790 constructorName, | |
| 2791 resolver.enclosingElement.getLibrary()); | |
| 2792 Element result = cls.lookupConstructor(selector); | |
| 2721 if (result === null) { | 2793 if (result === null) { |
| 2722 String fullConstructorName = cls.name.slowToString(); | 2794 String fullConstructorName = |
| 2723 if (constructorName !== const SourceString('')) { | 2795 resolver.compiler.resolver.createConstructorFullName( |
| 2724 fullConstructorName = '$fullConstructorName' | 2796 cls.name, |
| 2725 '.${constructorName.slowToString()}'; | 2797 constructorName); |
| 2726 } | 2798 return failOrReturnErroneousElement( |
| 2727 return failOrReturnErroneousElement(cls, diagnosticNode, | 2799 cls, |
| 2728 new SourceString(fullConstructorName), | 2800 diagnosticNode, |
| 2729 MessageKind.CANNOT_FIND_CONSTRUCTOR, | 2801 new SourceString(fullConstructorName), |
| 2730 [fullConstructorName]); | 2802 MessageKind.CANNOT_FIND_CONSTRUCTOR, |
| 2803 [fullConstructorName]); | |
| 2731 } else if (inConstContext && !result.modifiers.isConst()) { | 2804 } else if (inConstContext && !result.modifiers.isConst()) { |
| 2732 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); | 2805 error(diagnosticNode, MessageKind.CONSTRUCTOR_IS_NOT_CONST); |
| 2733 } | 2806 } |
| 2734 return result; | 2807 return result; |
| 2735 } | 2808 } |
| 2736 | 2809 |
| 2737 visitNewExpression(NewExpression node) { | 2810 visitNewExpression(NewExpression node) { |
| 2738 Node selector = node.send.selector; | 2811 Node selector = node.send.selector; |
| 2739 Element e = visit(selector); | 2812 Element e = visit(selector); |
| 2740 if (!Elements.isUnresolved(e) && e.kind === ElementKind.CLASS) { | 2813 if (!Elements.isUnresolved(e) && e.kind === ElementKind.CLASS) { |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3055 return result; | 3128 return result; |
| 3056 } | 3129 } |
| 3057 Element lookup(SourceString name) => localLookup(name); | 3130 Element lookup(SourceString name) => localLookup(name); |
| 3058 Element lexicalLookup(SourceString name) => localLookup(name); | 3131 Element lexicalLookup(SourceString name) => localLookup(name); |
| 3059 | 3132 |
| 3060 Element add(Element newElement) { | 3133 Element add(Element newElement) { |
| 3061 throw "Cannot add an element in a patch library scope"; | 3134 throw "Cannot add an element in a patch library scope"; |
| 3062 } | 3135 } |
| 3063 String toString() => 'PatchLibraryScope($origin,$patch)'; | 3136 String toString() => 'PatchLibraryScope($origin,$patch)'; |
| 3064 } | 3137 } |
| OLD | NEW |