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 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element operator[](Node node); | 8 Element operator[](Node node); |
| 9 Selector getSelector(Send send); | 9 Selector getSelector(Send send); |
| 10 DartType getType(Node node); | 10 DartType getType(Node node); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 379 } | 379 } |
| 380 return result; | 380 return result; |
| 381 } | 381 } |
| 382 | 382 |
| 383 /** | 383 /** |
| 384 * Load and resolve the supertypes of [cls]. | 384 * Load and resolve the supertypes of [cls]. |
| 385 * | 385 * |
| 386 * Warning: do not call this method directly. It should only be | 386 * Warning: do not call this method directly. It should only be |
| 387 * called by [resolveClass] and [ClassSupertypeResolver]. | 387 * called by [resolveClass] and [ClassSupertypeResolver]. |
| 388 */ | 388 */ |
| 389 void loadSupertypes(ClassElement cls, Node from) { | 389 void loadSupertypes(ClassElement cls, Spannable from) { |
| 390 compiler.withCurrentElement(cls, () => measure(() { | 390 compiler.withCurrentElement(cls, () => measure(() { |
| 391 if (cls.supertypeLoadState == STATE_DONE) return; | 391 if (cls.supertypeLoadState == STATE_DONE) return; |
| 392 if (cls.supertypeLoadState == STATE_STARTED) { | 392 if (cls.supertypeLoadState == STATE_STARTED) { |
| 393 compiler.reportMessage( | 393 compiler.reportMessage( |
| 394 compiler.spanFromSpannable(from), | 394 compiler.spanFromSpannable(from), |
| 395 MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), | 395 MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), |
| 396 Diagnostic.ERROR); | 396 Diagnostic.ERROR); |
| 397 cls.supertypeLoadState = STATE_DONE; | 397 cls.supertypeLoadState = STATE_DONE; |
| 398 cls.allSupertypes = const Link<DartType>().prepend( | 398 cls.allSupertypes = const Link<DartType>().prepend( |
| 399 compiler.objectClass.computeType(compiler)); | 399 compiler.objectClass.computeType(compiler)); |
| 400 // TODO(ahe): We should also set cls.supertype here to avoid | 400 // TODO(ahe): We should also set cls.supertype here to avoid |
| 401 // creating a malformed class hierarchy. | 401 // creating a malformed class hierarchy. |
| 402 return; | 402 return; |
| 403 } | 403 } |
| 404 cls.supertypeLoadState = STATE_STARTED; | 404 cls.supertypeLoadState = STATE_STARTED; |
| 405 compiler.withCurrentElement(cls, () { | 405 compiler.withCurrentElement(cls, () { |
| 406 // TODO(ahe): Cache the node in cls. | 406 // TODO(ahe): Cache the node in cls. |
| 407 cls.parseNode(compiler).accept(new ClassSupertypeResolver(compiler, | 407 cls.parseNode(compiler).accept( |
| 408 cls)); | 408 new ClassSupertypeResolver(compiler, cls)); |
| 409 if (cls.supertypeLoadState != STATE_DONE) { | 409 if (cls.supertypeLoadState != STATE_DONE) { |
| 410 cls.supertypeLoadState = STATE_DONE; | 410 cls.supertypeLoadState = STATE_DONE; |
| 411 } | 411 } |
| 412 }); | 412 }); |
| 413 })); | 413 })); |
| 414 } | 414 } |
| 415 | 415 |
| 416 // TODO(johnniwinther): Remove this queue when resolution has been split into | 416 // TODO(johnniwinther): Remove this queue when resolution has been split into |
| 417 // syntax and semantic resolution. | 417 // syntax and semantic resolution. |
| 418 ClassElement currentlyResolvedClass; | 418 ClassElement currentlyResolvedClass; |
| 419 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>(); | 419 Queue<ClassElement> pendingClassesToBeResolved = new Queue<ClassElement>(); |
| 420 | 420 |
| 421 void resolveMixinApplication(MixinApplicationElement element) { | |
| 422 // TODO(kasperl): Implement this. | |
| 423 assert(element.resolutionState == STATE_NOT_STARTED); | |
| 424 element.resolutionState = STATE_STARTED; | |
| 425 compiler.reportMessage( | |
| 426 compiler.spanFromSpannable(element.cachedNode), | |
| 427 MessageKind.GENERIC.error(['unimplemented mixin application']), | |
| 428 Diagnostic.ERROR); | |
| 429 element.resolutionState = STATE_DONE; | |
| 430 } | |
| 431 | |
| 432 /** | 421 /** |
| 433 * Resolve the class [element]. | 422 * Resolve the class [element]. |
| 434 * | 423 * |
| 435 * Before calling this method, [element] was constructed by the | 424 * Before calling this method, [element] was constructed by the |
| 436 * scanner and most fields are null or empty. This method fills in | 425 * scanner and most fields are null or empty. This method fills in |
| 437 * these fields and also ensure that the supertypes of [element] are | 426 * these fields and also ensure that the supertypes of [element] are |
| 438 * resolved. | 427 * resolved. |
| 439 * | 428 * |
| 440 * Warning: Do not call this method directly. Instead use | 429 * Warning: Do not call this method directly. Instead use |
| 441 * [:element.ensureResolved(compiler):]. | 430 * [:element.ensureResolved(compiler):]. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 458 } else { | 447 } else { |
| 459 pendingClassesToBeResolved.add(element); | 448 pendingClassesToBeResolved.add(element); |
| 460 } | 449 } |
| 461 } | 450 } |
| 462 | 451 |
| 463 void resolveClassInternal(ClassElement element) { | 452 void resolveClassInternal(ClassElement element) { |
| 464 if (!element.isPatch) { | 453 if (!element.isPatch) { |
| 465 compiler.withCurrentElement(element, () => measure(() { | 454 compiler.withCurrentElement(element, () => measure(() { |
| 466 assert(element.resolutionState == STATE_NOT_STARTED); | 455 assert(element.resolutionState == STATE_NOT_STARTED); |
| 467 element.resolutionState = STATE_STARTED; | 456 element.resolutionState = STATE_STARTED; |
| 468 ClassNode tree = element.parseNode(compiler); | 457 Node tree = element.parseNode(compiler); |
| 469 loadSupertypes(element, tree); | 458 loadSupertypes(element, tree); |
| 470 | 459 |
| 471 ClassResolverVisitor visitor = | 460 ClassResolverVisitor visitor = |
| 472 new ClassResolverVisitor(compiler, element); | 461 new ClassResolverVisitor(compiler, element); |
| 473 visitor.visit(tree); | 462 visitor.visit(tree); |
| 474 element.resolutionState = STATE_DONE; | 463 element.resolutionState = STATE_DONE; |
| 475 })); | 464 })); |
| 476 if (element.isPatched) { | 465 if (element.isPatched) { |
| 477 // Ensure handling patch after origin. | 466 // Ensure handling patch after origin. |
| 478 element.patch.ensureResolved(compiler); | 467 element.patch.ensureResolved(compiler); |
| (...skipping 2262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2741 compiler.ensure(element != null); | 2730 compiler.ensure(element != null); |
| 2742 compiler.ensure(element.resolutionState == STATE_STARTED); | 2731 compiler.ensure(element.resolutionState == STATE_STARTED); |
| 2743 | 2732 |
| 2744 InterfaceType type = element.computeType(compiler); | 2733 InterfaceType type = element.computeType(compiler); |
| 2745 scope = new TypeDeclarationScope(scope, element); | 2734 scope = new TypeDeclarationScope(scope, element); |
| 2746 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. | 2735 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. |
| 2747 // As a side-effect, this may get us back here trying to | 2736 // As a side-effect, this may get us back here trying to |
| 2748 // resolve this class again. | 2737 // resolve this class again. |
| 2749 resolveTypeVariableBounds(node.typeParameters); | 2738 resolveTypeVariableBounds(node.typeParameters); |
| 2750 | 2739 |
| 2751 // Find super type. | 2740 // Resolve super type and deal with the Object class nicely. |
| 2752 DartType supertype = null; | 2741 element.supertype = resolveSupertype(element, node.superclass); |
| 2753 if (node.superclass != null) { | |
| 2754 supertype = typeResolver.resolveTypeAnnotation(node.superclass, scope, | |
| 2755 element, onFailure: error); | |
| 2756 } | |
| 2757 if (supertype != null) { | |
| 2758 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | |
| 2759 // Error has already been reported. | |
| 2760 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | |
| 2761 // TODO(johnniwinther): Handle dynamic. | |
| 2762 error(node.superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []); | |
| 2763 } else if (isBlackListed(supertype)) { | |
| 2764 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | |
| 2765 } else { | |
| 2766 element.supertype = supertype; | |
| 2767 } | |
| 2768 } | |
| 2769 final objectElement = compiler.objectClass; | 2742 final objectElement = compiler.objectClass; |
| 2770 if (!identical(element, objectElement) && element.supertype == null) { | 2743 if (!identical(element, objectElement) && element.supertype == null) { |
| 2771 if (objectElement == null) { | 2744 if (objectElement == null) { |
| 2772 compiler.internalError("Internal error: cannot resolve Object", | 2745 compiler.internalError("Internal error: cannot resolve Object", |
| 2773 node: node); | 2746 node: node); |
| 2774 } else { | 2747 } else { |
| 2775 objectElement.ensureResolved(compiler); | 2748 objectElement.ensureResolved(compiler); |
| 2776 } | 2749 } |
| 2777 element.supertype = objectElement.computeType(compiler); | 2750 element.supertype = objectElement.computeType(compiler); |
| 2778 } | 2751 } |
| 2752 | |
| 2779 assert(element.interfaces == null); | 2753 assert(element.interfaces == null); |
| 2780 Link<DartType> interfaces = const Link<DartType>(); | 2754 Link<DartType> interfaces = const Link<DartType>(); |
| 2781 for (Link<Node> link = node.interfaces.nodes; | 2755 for (Link<Node> link = node.interfaces.nodes; |
| 2782 !link.isEmpty; | 2756 !link.isEmpty; |
| 2783 link = link.tail) { | 2757 link = link.tail) { |
| 2784 DartType interfaceType = typeResolver.resolveTypeAnnotation( | 2758 DartType interfaceType = typeResolver.resolveTypeAnnotation( |
| 2785 link.head, scope, element, onFailure: error); | 2759 link.head, scope, element, onFailure: error); |
| 2786 if (interfaceType != null) { | 2760 if (interfaceType != null) { |
| 2787 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { | 2761 if (identical(interfaceType.kind, TypeKind.MALFORMED_TYPE)) { |
| 2788 // Error has already been reported. | 2762 // Error has already been reported. |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2813 } | 2787 } |
| 2814 } | 2788 } |
| 2815 } | 2789 } |
| 2816 } | 2790 } |
| 2817 element.interfaces = interfaces; | 2791 element.interfaces = interfaces; |
| 2818 calculateAllSupertypes(element); | 2792 calculateAllSupertypes(element); |
| 2819 | 2793 |
| 2820 if (node.defaultClause != null) { | 2794 if (node.defaultClause != null) { |
| 2821 element.defaultClass = visit(node.defaultClause); | 2795 element.defaultClass = visit(node.defaultClause); |
| 2822 } | 2796 } |
| 2823 addDefaultConstructorIfNeeded(element); | 2797 element.addDefaultConstructorIfNeeded(compiler); |
| 2824 return element.computeType(compiler); | 2798 return element.computeType(compiler); |
| 2825 } | 2799 } |
| 2826 | 2800 |
| 2801 DartType visitMixinApplication(MixinApplication node) { | |
| 2802 compiler.ensure(element != null); | |
| 2803 compiler.ensure(element.resolutionState == STATE_STARTED); | |
| 2804 | |
| 2805 // Generate anonymous mixin application elements for the | |
| 2806 // intermediate mixin applications (excluding the last). | |
| 2807 DartType supertype = resolveSupertype(element, node.superclass); | |
| 2808 Link<Node> link = node.mixins.nodes; | |
| 2809 while (!link.tail.isEmpty) { | |
| 2810 supertype = applyMixin(supertype, visit(link.head)); | |
| 2811 link = link.tail; | |
| 2812 } | |
| 2813 doApplyMixinTo(element, supertype, visit(link.head)); | |
| 2814 return element.computeType(compiler); | |
| 2815 } | |
| 2816 | |
| 2817 DartType applyMixin(DartType supertype, DartType mixinType) { | |
| 2818 String superName = supertype.name.slowToString(); | |
| 2819 String mixinName = mixinType.name.slowToString(); | |
| 2820 // TODO(kasperl): This is a little bit weird. Maybe we should | |
| 2821 // restructure the parsed nodes for mixin applications to better | |
| 2822 // match the nesting implied by the list of mixins so that each | |
| 2823 // mixin application element could get it's own proper node. | |
| 2824 MixinApplication fakeTree = element.parseNode(compiler); | |
| 2825 ClassElement mixinApplication = new MixinApplicationElementX( | |
| 2826 new SourceString("${superName}_${mixinName}"), | |
|
ahe
2013/01/18 12:40:12
I'm really concerned about this. We did something
| |
| 2827 element.getCompilationUnit(), | |
| 2828 compiler.getNextFreeClassId(), | |
| 2829 fakeTree); | |
| 2830 doApplyMixinTo(mixinApplication, supertype, mixinType); | |
| 2831 mixinApplication.resolutionState = STATE_DONE; | |
| 2832 mixinApplication.supertypeLoadState = STATE_DONE; | |
| 2833 return mixinApplication.computeType(compiler); | |
| 2834 } | |
| 2835 | |
| 2836 void doApplyMixinTo(ClassElement mixinApplication, | |
| 2837 DartType supertype, | |
| 2838 DartType mixinType) { | |
| 2839 assert(mixinApplication.supertype == null); | |
| 2840 mixinApplication.supertype = supertype; | |
| 2841 | |
| 2842 // The class that is the result of a mixin application implements | |
| 2843 // the interface of the class that was mixed in. | |
| 2844 Link<DartType> interfaces = const Link<DartType>(); | |
| 2845 interfaces = interfaces.prepend(mixinType); | |
| 2846 assert(mixinApplication.interfaces == null); | |
| 2847 mixinApplication.interfaces = interfaces; | |
| 2848 | |
| 2849 assert(element.mixin == null); | |
| 2850 mixinApplication.mixin = mixinType.element; | |
| 2851 mixinApplication.mixin.ensureResolved(compiler); | |
| 2852 mixinApplication.addDefaultConstructorIfNeeded(compiler); | |
| 2853 calculateAllSupertypes(mixinApplication); | |
| 2854 } | |
| 2855 | |
| 2856 | |
| 2827 // TODO(johnniwinther): Remove when default class is no longer supported. | 2857 // TODO(johnniwinther): Remove when default class is no longer supported. |
| 2828 DartType visitTypeAnnotation(TypeAnnotation node) { | 2858 DartType visitTypeAnnotation(TypeAnnotation node) { |
| 2829 return visit(node.typeName); | 2859 return visit(node.typeName); |
| 2830 } | 2860 } |
| 2831 | 2861 |
| 2832 // TODO(johnniwinther): Remove when default class is no longer supported. | 2862 // TODO(johnniwinther): Remove when default class is no longer supported. |
| 2833 DartType visitIdentifier(Identifier node) { | 2863 DartType visitIdentifier(Identifier node) { |
| 2834 Element element = scope.lookup(node.source); | 2864 Element element = scope.lookup(node.source); |
| 2835 if (element == null) { | 2865 if (element == null) { |
| 2836 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 2866 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2867 PrefixElement prefixElement = element; | 2897 PrefixElement prefixElement = element; |
| 2868 Identifier selector = node.selector.asIdentifier(); | 2898 Identifier selector = node.selector.asIdentifier(); |
| 2869 var e = prefixElement.lookupLocalMember(selector.source); | 2899 var e = prefixElement.lookupLocalMember(selector.source); |
| 2870 if (e == null || !e.impliesType()) { | 2900 if (e == null || !e.impliesType()) { |
| 2871 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | 2901 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| 2872 return null; | 2902 return null; |
| 2873 } | 2903 } |
| 2874 return e.computeType(compiler); | 2904 return e.computeType(compiler); |
| 2875 } | 2905 } |
| 2876 | 2906 |
| 2907 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) { | |
| 2908 DartType supertype; | |
| 2909 if (superclass != null) { | |
| 2910 supertype = typeResolver.resolveTypeAnnotation( | |
| 2911 superclass, scope, cls, onFailure: error); | |
| 2912 } | |
| 2913 if (supertype != null) { | |
| 2914 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) { | |
| 2915 // Error has already been reported. | |
| 2916 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) { | |
| 2917 // TODO(johnniwinther): Handle dynamic. | |
| 2918 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []); | |
| 2919 return null; | |
| 2920 } else if (isBlackListed(supertype)) { | |
| 2921 error(superclass, MessageKind.CANNOT_EXTEND, [supertype]); | |
| 2922 return null; | |
| 2923 } | |
| 2924 } | |
| 2925 return supertype; | |
| 2926 } | |
| 2927 | |
| 2877 void calculateAllSupertypes(ClassElement cls) { | 2928 void calculateAllSupertypes(ClassElement cls) { |
| 2878 // TODO(karlklose): check if type arguments match, if a classelement occurs | 2929 // TODO(karlklose): Check if type arguments match, if a class |
| 2879 // more than once in the supertypes. | 2930 // element occurs more than once in the supertypes. |
| 2880 if (cls.allSupertypes != null) return; | 2931 if (cls.allSupertypes != null) return; |
| 2881 final DartType supertype = cls.supertype; | 2932 final DartType supertype = cls.supertype; |
| 2882 if (supertype != null) { | 2933 if (supertype != null) { |
| 2883 var allSupertypes = new LinkBuilder<DartType>(); | 2934 var allSupertypes = new LinkBuilder<DartType>(); |
| 2884 addAllSupertypes(allSupertypes, supertype); | 2935 addAllSupertypes(allSupertypes, supertype); |
| 2885 for (Link<DartType> interfaces = cls.interfaces; | 2936 for (Link<DartType> interfaces = cls.interfaces; |
| 2886 !interfaces.isEmpty; | 2937 !interfaces.isEmpty; |
| 2887 interfaces = interfaces.tail) { | 2938 interfaces = interfaces.tail) { |
| 2888 addAllSupertypes(allSupertypes, interfaces.head); | 2939 addAllSupertypes(allSupertypes, interfaces.head); |
| 2889 } | 2940 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2907 assert(invariant(element, supertypes != null, | 2958 assert(invariant(element, supertypes != null, |
| 2908 message: "Supertypes not computed on $classElement " | 2959 message: "Supertypes not computed on $classElement " |
| 2909 "during resolution of $element")); | 2960 "during resolution of $element")); |
| 2910 while (!supertypes.isEmpty) { | 2961 while (!supertypes.isEmpty) { |
| 2911 DartType supertype = supertypes.head; | 2962 DartType supertype = supertypes.head; |
| 2912 builder.addLast(supertype.subst(typeArguments, typeVariables)); | 2963 builder.addLast(supertype.subst(typeArguments, typeVariables)); |
| 2913 supertypes = supertypes.tail; | 2964 supertypes = supertypes.tail; |
| 2914 } | 2965 } |
| 2915 } | 2966 } |
| 2916 | 2967 |
| 2917 /** | |
| 2918 * Add a synthetic nullary constructor if there are no other | |
| 2919 * constructors. | |
| 2920 */ | |
| 2921 void addDefaultConstructorIfNeeded(ClassElement element) { | |
| 2922 if (element.hasConstructor) return; | |
| 2923 FunctionElement constructor = | |
| 2924 new SynthesizedConstructorElementX.forDefault(element, compiler); | |
| 2925 element.addToScope(constructor, compiler); | |
| 2926 } | |
| 2927 | |
| 2928 isBlackListed(DartType type) { | 2968 isBlackListed(DartType type) { |
| 2929 LibraryElement lib = element.getLibrary(); | 2969 LibraryElement lib = element.getLibrary(); |
| 2930 return | 2970 return |
| 2931 !identical(lib, compiler.coreLibrary) && | 2971 !identical(lib, compiler.coreLibrary) && |
| 2932 !identical(lib, compiler.jsHelperLibrary) && | 2972 !identical(lib, compiler.jsHelperLibrary) && |
| 2933 !identical(lib, compiler.interceptorsLibrary) && | 2973 !identical(lib, compiler.interceptorsLibrary) && |
| 2934 (identical(type.element, compiler.dynamicClass) || | 2974 (identical(type.element, compiler.dynamicClass) || |
| 2935 identical(type.element, compiler.boolClass) || | 2975 identical(type.element, compiler.boolClass) || |
| 2936 identical(type.element, compiler.numClass) || | 2976 identical(type.element, compiler.numClass) || |
| 2937 identical(type.element, compiler.intClass) || | 2977 identical(type.element, compiler.intClass) || |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 2949 ClassSupertypeResolver(Compiler compiler, ClassElement cls) | 2989 ClassSupertypeResolver(Compiler compiler, ClassElement cls) |
| 2950 : context = Scope.buildEnclosingScope(cls), | 2990 : context = Scope.buildEnclosingScope(cls), |
| 2951 this.classElement = cls, | 2991 this.classElement = cls, |
| 2952 super(compiler); | 2992 super(compiler); |
| 2953 | 2993 |
| 2954 void loadSupertype(ClassElement element, Node from) { | 2994 void loadSupertype(ClassElement element, Node from) { |
| 2955 compiler.resolver.loadSupertypes(element, from); | 2995 compiler.resolver.loadSupertypes(element, from); |
| 2956 element.ensureResolved(compiler); | 2996 element.ensureResolved(compiler); |
| 2957 } | 2997 } |
| 2958 | 2998 |
| 2999 void visitNodeList(NodeList node) { | |
| 3000 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { | |
| 3001 link.head.accept(this); | |
| 3002 } | |
| 3003 } | |
| 3004 | |
| 2959 void visitClassNode(ClassNode node) { | 3005 void visitClassNode(ClassNode node) { |
| 2960 if (node.superclass == null) { | 3006 if (node.superclass == null) { |
| 2961 if (!identical(classElement, compiler.objectClass)) { | 3007 if (!identical(classElement, compiler.objectClass)) { |
| 2962 loadSupertype(compiler.objectClass, node); | 3008 loadSupertype(compiler.objectClass, node); |
| 2963 } | 3009 } |
| 2964 } else { | 3010 } else { |
| 2965 node.superclass.accept(this); | 3011 node.superclass.accept(this); |
| 2966 } | 3012 } |
| 2967 for (Link<Node> link = node.interfaces.nodes; | 3013 visitNodeList(node.interfaces); |
|
ahe
2013/01/18 12:40:12
Generally, I don't like calling the visitor method
| |
| 2968 !link.isEmpty; | 3014 } |
| 2969 link = link.tail) { | 3015 |
| 2970 link.head.accept(this); | 3016 void visitMixinApplication(MixinApplication node) { |
| 2971 } | 3017 node.superclass.accept(this); |
| 3018 visitNodeList(node.mixins); | |
|
ahe
2013/01/18 12:40:12
Ditto.
| |
| 2972 } | 3019 } |
| 2973 | 3020 |
| 2974 void visitTypeAnnotation(TypeAnnotation node) { | 3021 void visitTypeAnnotation(TypeAnnotation node) { |
| 2975 node.typeName.accept(this); | 3022 node.typeName.accept(this); |
| 2976 } | 3023 } |
| 2977 | 3024 |
| 2978 void visitIdentifier(Identifier node) { | 3025 void visitIdentifier(Identifier node) { |
| 2979 Element element = context.lookup(node.source); | 3026 Element element = context.lookup(node.source); |
| 2980 if (element == null) { | 3027 if (element == null) { |
| 2981 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 3028 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3414 return e; | 3461 return e; |
| 3415 } | 3462 } |
| 3416 | 3463 |
| 3417 /// Assumed to be called by [resolveRedirectingFactory]. | 3464 /// Assumed to be called by [resolveRedirectingFactory]. |
| 3418 Element visitReturn(Return node) { | 3465 Element visitReturn(Return node) { |
| 3419 Node expression = node.expression; | 3466 Node expression = node.expression; |
| 3420 return finishConstructorReference(visit(expression), | 3467 return finishConstructorReference(visit(expression), |
| 3421 expression, expression); | 3468 expression, expression); |
| 3422 } | 3469 } |
| 3423 } | 3470 } |
| OLD | NEW |