Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(56)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 11886097: Get the most basic mixin applications working. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Diff against right branch. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 2299 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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}"),
2827 element.getCompilationUnit(),
2828 compiler.getNextFreeClassId(),
2829 fakeTree);
2830 doApplyMixinTo(mixinApplication, supertype, mixinType);
2831 mixinApplication.resolutionState = STATE_DONE;
2832 return mixinApplication.computeType(compiler);
2833 }
2834
2835 void doApplyMixinTo(ClassElement mixinApplication,
2836 DartType supertype,
2837 DartType mixinType) {
2838 assert(mixinApplication.supertype == null);
2839 mixinApplication.supertype = supertype;
2840
2841 assert(mixinApplication.interfaces == null);
2842 mixinApplication.interfaces = const Link<DartType>();
2843
2844 assert(element.mixin == null);
2845 mixinApplication.mixin = mixinType.element;
2846 mixinApplication.mixin.ensureResolved(compiler);
2847 mixinApplication.addDefaultConstructorIfNeeded(compiler);
2848 calculateAllSupertypes(mixinApplication);
2849 }
2850
2851
2827 // TODO(johnniwinther): Remove when default class is no longer supported. 2852 // TODO(johnniwinther): Remove when default class is no longer supported.
2828 DartType visitTypeAnnotation(TypeAnnotation node) { 2853 DartType visitTypeAnnotation(TypeAnnotation node) {
2829 return visit(node.typeName); 2854 return visit(node.typeName);
2830 } 2855 }
2831 2856
2832 // TODO(johnniwinther): Remove when default class is no longer supported. 2857 // TODO(johnniwinther): Remove when default class is no longer supported.
2833 DartType visitIdentifier(Identifier node) { 2858 DartType visitIdentifier(Identifier node) {
2834 Element element = scope.lookup(node.source); 2859 Element element = scope.lookup(node.source);
2835 if (element == null) { 2860 if (element == null) {
2836 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); 2861 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
(...skipping 30 matching lines...) Expand all
2867 PrefixElement prefixElement = element; 2892 PrefixElement prefixElement = element;
2868 Identifier selector = node.selector.asIdentifier(); 2893 Identifier selector = node.selector.asIdentifier();
2869 var e = prefixElement.lookupLocalMember(selector.source); 2894 var e = prefixElement.lookupLocalMember(selector.source);
2870 if (e == null || !e.impliesType()) { 2895 if (e == null || !e.impliesType()) {
2871 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); 2896 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
2872 return null; 2897 return null;
2873 } 2898 }
2874 return e.computeType(compiler); 2899 return e.computeType(compiler);
2875 } 2900 }
2876 2901
2902 DartType resolveSupertype(ClassElement cls, TypeAnnotation superclass) {
2903 DartType supertype;
2904 if (superclass != null) {
2905 supertype = typeResolver.resolveTypeAnnotation(
2906 superclass, scope, cls, onFailure: error);
2907 }
2908 if (supertype != null) {
2909 if (identical(supertype.kind, TypeKind.MALFORMED_TYPE)) {
2910 // Error has already been reported.
2911 } else if (!identical(supertype.kind, TypeKind.INTERFACE)) {
2912 // TODO(johnniwinther): Handle dynamic.
2913 error(superclass.typeName, MessageKind.CLASS_NAME_EXPECTED, []);
2914 return null;
2915 } else if (isBlackListed(supertype)) {
2916 error(superclass, MessageKind.CANNOT_EXTEND, [supertype]);
2917 return null;
2918 }
2919 }
2920 return supertype;
2921 }
2922
2877 void calculateAllSupertypes(ClassElement cls) { 2923 void calculateAllSupertypes(ClassElement cls) {
2878 // TODO(karlklose): check if type arguments match, if a classelement occurs 2924 // TODO(karlklose): Check if type arguments match, if a class
2879 // more than once in the supertypes. 2925 // element occurs more than once in the supertypes.
2880 if (cls.allSupertypes != null) return; 2926 if (cls.allSupertypes != null) return;
2881 final DartType supertype = cls.supertype; 2927 final DartType supertype = cls.supertype;
2882 if (supertype != null) { 2928 if (supertype != null) {
2883 var allSupertypes = new LinkBuilder<DartType>(); 2929 var allSupertypes = new LinkBuilder<DartType>();
2884 addAllSupertypes(allSupertypes, supertype); 2930 addAllSupertypes(allSupertypes, supertype);
2885 for (Link<DartType> interfaces = cls.interfaces; 2931 for (Link<DartType> interfaces = cls.interfaces;
2886 !interfaces.isEmpty; 2932 !interfaces.isEmpty;
2887 interfaces = interfaces.tail) { 2933 interfaces = interfaces.tail) {
2888 addAllSupertypes(allSupertypes, interfaces.head); 2934 addAllSupertypes(allSupertypes, interfaces.head);
2889 } 2935 }
(...skipping 17 matching lines...) Expand all
2907 assert(invariant(element, supertypes != null, 2953 assert(invariant(element, supertypes != null,
2908 message: "Supertypes not computed on $classElement " 2954 message: "Supertypes not computed on $classElement "
2909 "during resolution of $element")); 2955 "during resolution of $element"));
2910 while (!supertypes.isEmpty) { 2956 while (!supertypes.isEmpty) {
2911 DartType supertype = supertypes.head; 2957 DartType supertype = supertypes.head;
2912 builder.addLast(supertype.subst(typeArguments, typeVariables)); 2958 builder.addLast(supertype.subst(typeArguments, typeVariables));
2913 supertypes = supertypes.tail; 2959 supertypes = supertypes.tail;
2914 } 2960 }
2915 } 2961 }
2916 2962
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) { 2963 isBlackListed(DartType type) {
2929 LibraryElement lib = element.getLibrary(); 2964 LibraryElement lib = element.getLibrary();
2930 return 2965 return
2931 !identical(lib, compiler.coreLibrary) && 2966 !identical(lib, compiler.coreLibrary) &&
2932 !identical(lib, compiler.jsHelperLibrary) && 2967 !identical(lib, compiler.jsHelperLibrary) &&
2933 !identical(lib, compiler.interceptorsLibrary) && 2968 !identical(lib, compiler.interceptorsLibrary) &&
2934 (identical(type.element, compiler.dynamicClass) || 2969 (identical(type.element, compiler.dynamicClass) ||
2935 identical(type.element, compiler.boolClass) || 2970 identical(type.element, compiler.boolClass) ||
2936 identical(type.element, compiler.numClass) || 2971 identical(type.element, compiler.numClass) ||
2937 identical(type.element, compiler.intClass) || 2972 identical(type.element, compiler.intClass) ||
(...skipping 11 matching lines...) Expand all
2949 ClassSupertypeResolver(Compiler compiler, ClassElement cls) 2984 ClassSupertypeResolver(Compiler compiler, ClassElement cls)
2950 : context = Scope.buildEnclosingScope(cls), 2985 : context = Scope.buildEnclosingScope(cls),
2951 this.classElement = cls, 2986 this.classElement = cls,
2952 super(compiler); 2987 super(compiler);
2953 2988
2954 void loadSupertype(ClassElement element, Node from) { 2989 void loadSupertype(ClassElement element, Node from) {
2955 compiler.resolver.loadSupertypes(element, from); 2990 compiler.resolver.loadSupertypes(element, from);
2956 element.ensureResolved(compiler); 2991 element.ensureResolved(compiler);
2957 } 2992 }
2958 2993
2994 void visitNodeList(NodeList node) {
2995 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
2996 link.head.accept(this);
2997 }
2998 }
2999
2959 void visitClassNode(ClassNode node) { 3000 void visitClassNode(ClassNode node) {
2960 if (node.superclass == null) { 3001 if (node.superclass == null) {
2961 if (!identical(classElement, compiler.objectClass)) { 3002 if (!identical(classElement, compiler.objectClass)) {
2962 loadSupertype(compiler.objectClass, node); 3003 loadSupertype(compiler.objectClass, node);
2963 } 3004 }
2964 } else { 3005 } else {
2965 node.superclass.accept(this); 3006 node.superclass.accept(this);
2966 } 3007 }
2967 for (Link<Node> link = node.interfaces.nodes; 3008 visitNodeList(node.interfaces);
2968 !link.isEmpty; 3009 }
2969 link = link.tail) { 3010
2970 link.head.accept(this); 3011 void visitMixinApplication(MixinApplication node) {
2971 } 3012 node.superclass.accept(this);
3013 visitNodeList(node.mixins);
2972 } 3014 }
2973 3015
2974 void visitTypeAnnotation(TypeAnnotation node) { 3016 void visitTypeAnnotation(TypeAnnotation node) {
2975 node.typeName.accept(this); 3017 node.typeName.accept(this);
2976 } 3018 }
2977 3019
2978 void visitIdentifier(Identifier node) { 3020 void visitIdentifier(Identifier node) {
2979 Element element = context.lookup(node.source); 3021 Element element = context.lookup(node.source);
2980 if (element == null) { 3022 if (element == null) {
2981 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); 3023 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
3408 return e; 3450 return e;
3409 } 3451 }
3410 3452
3411 /// Assumed to be called by [resolveRedirectingFactory]. 3453 /// Assumed to be called by [resolveRedirectingFactory].
3412 Element visitReturn(Return node) { 3454 Element visitReturn(Return node) {
3413 Node expression = node.expression; 3455 Node expression = node.expression;
3414 return finishConstructorReference(visit(expression), 3456 return finishConstructorReference(visit(expression),
3415 expression, expression); 3457 expression, expression);
3416 } 3458 }
3417 } 3459 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698