OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 elements.modelx; | 5 library elements.modelx; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../common/resolution.dart' show Resolution, Parsing; | 8 import '../common/resolution.dart' show Resolution, Parsing; |
9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
10 import '../constants/constant_constructors.dart'; | 10 import '../constants/constant_constructors.dart'; |
(...skipping 2310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2321 | 2321 |
2322 /** | 2322 /** |
2323 * A constructor that is not defined in the source code but rather implied by | 2323 * A constructor that is not defined in the source code but rather implied by |
2324 * the language semantics. | 2324 * the language semantics. |
2325 * | 2325 * |
2326 * This class is used to represent default constructors and forwarding | 2326 * This class is used to represent default constructors and forwarding |
2327 * constructors for mixin applications. | 2327 * constructors for mixin applications. |
2328 */ | 2328 */ |
2329 class SynthesizedConstructorElementX extends ConstructorElementX { | 2329 class SynthesizedConstructorElementX extends ConstructorElementX { |
2330 final ConstructorElement definingConstructor; | 2330 final ConstructorElement definingConstructor; |
2331 final bool isDefaultConstructor; | 2331 ResolvedAst _resolvedAst; |
2332 | 2332 |
2333 SynthesizedConstructorElementX.notForDefault( | 2333 SynthesizedConstructorElementX.notForDefault( |
2334 String name, this.definingConstructor, Element enclosing) | 2334 String name, this.definingConstructor, Element enclosing) |
2335 : isDefaultConstructor = false, | 2335 : super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, |
2336 super(name, ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, | 2336 enclosing) { |
2337 enclosing); | 2337 _resolvedAst = new SynthesizedResolvedAst( |
| 2338 this, ResolvedAstKind.FORWARDING_CONSTRUCTOR); |
| 2339 } |
2338 | 2340 |
2339 SynthesizedConstructorElementX.forDefault( | 2341 SynthesizedConstructorElementX.forDefault( |
2340 this.definingConstructor, Element enclosing) | 2342 this.definingConstructor, Element enclosing) |
2341 : isDefaultConstructor = true, | 2343 : super('', ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, |
2342 super('', ElementKind.GENERATIVE_CONSTRUCTOR, Modifiers.EMPTY, | |
2343 enclosing) { | 2344 enclosing) { |
2344 functionSignature = new FunctionSignatureX( | 2345 functionSignature = new FunctionSignatureX( |
2345 type: new FunctionType.synthesized(enclosingClass.thisType)); | 2346 type: new FunctionType.synthesized(enclosingClass.thisType)); |
| 2347 _resolvedAst = |
| 2348 new SynthesizedResolvedAst(this, ResolvedAstKind.DEFAULT_CONSTRUCTOR); |
| 2349 } |
| 2350 |
| 2351 bool get isDefaultConstructor { |
| 2352 return _resolvedAst.kind == ResolvedAstKind.DEFAULT_CONSTRUCTOR; |
2346 } | 2353 } |
2347 | 2354 |
2348 FunctionExpression parseNode(Parsing parsing) => null; | 2355 FunctionExpression parseNode(Parsing parsing) => null; |
2349 | 2356 |
2350 bool get hasNode => false; | 2357 bool get hasNode => false; |
2351 | 2358 |
2352 FunctionExpression get node => null; | 2359 FunctionExpression get node => null; |
2353 | 2360 |
2354 Token get position => enclosingElement.position; | 2361 Token get position => enclosingElement.position; |
2355 | 2362 |
2356 bool get isSynthesized => true; | 2363 bool get isSynthesized => true; |
2357 | 2364 |
| 2365 bool get hasResolvedAst => true; |
| 2366 |
| 2367 ResolvedAst get resolvedAst => _resolvedAst; |
| 2368 |
2358 DartType get type { | 2369 DartType get type { |
2359 if (isDefaultConstructor) { | 2370 if (isDefaultConstructor) { |
2360 return super.type; | 2371 return super.type; |
2361 } else { | 2372 } else { |
2362 // TODO(johnniwinther): Ensure that the function type substitutes type | 2373 // TODO(johnniwinther): Ensure that the function type substitutes type |
2363 // variables correctly. | 2374 // variables correctly. |
2364 return definingConstructor.type; | 2375 return definingConstructor.type; |
2365 } | 2376 } |
2366 } | 2377 } |
2367 | 2378 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2687 if (origin != null) { | 2698 if (origin != null) { |
2688 return 'patch ${super.toString()}'; | 2699 return 'patch ${super.toString()}'; |
2689 } else if (patch != null) { | 2700 } else if (patch != null) { |
2690 return 'origin ${super.toString()}'; | 2701 return 'origin ${super.toString()}'; |
2691 } else { | 2702 } else { |
2692 return super.toString(); | 2703 return super.toString(); |
2693 } | 2704 } |
2694 } | 2705 } |
2695 } | 2706 } |
2696 | 2707 |
| 2708 /// This element is used to encode an enum class. |
| 2709 /// |
| 2710 /// For instance |
| 2711 /// |
| 2712 /// enum A { b, c, } |
| 2713 /// |
| 2714 /// is modelled as |
| 2715 /// |
| 2716 /// class A { |
| 2717 /// final int index; |
| 2718 /// |
| 2719 /// const A(this.index); |
| 2720 /// |
| 2721 /// String toString() { |
| 2722 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2723 /// } |
| 2724 /// |
| 2725 /// static const A b = const A(0); |
| 2726 /// static const A c = const A(1); |
| 2727 /// |
| 2728 /// static const List<A> values = const <A>[b, c]; |
| 2729 /// } |
| 2730 /// |
| 2731 /// where the `A` class is encoded using this element. |
| 2732 /// |
2697 class EnumClassElementX extends ClassElementX | 2733 class EnumClassElementX extends ClassElementX |
2698 implements EnumClassElement, DeclarationSite { | 2734 implements EnumClassElement, DeclarationSite { |
2699 final Enum node; | 2735 final Enum node; |
2700 List<FieldElement> _enumValues; | 2736 List<FieldElement> _enumValues; |
2701 | 2737 |
2702 EnumClassElementX(String name, Element enclosing, int id, this.node) | 2738 EnumClassElementX(String name, Element enclosing, int id, this.node) |
2703 : super(name, enclosing, id, STATE_NOT_STARTED); | 2739 : super(name, enclosing, id, STATE_NOT_STARTED); |
2704 | 2740 |
2705 @override | 2741 @override |
2706 bool get hasNode => true; | 2742 bool get hasNode => true; |
(...skipping 23 matching lines...) Expand all Loading... |
2730 void set enumValues(List<FieldElement> values) { | 2766 void set enumValues(List<FieldElement> values) { |
2731 assert(invariant(this, _enumValues == null, | 2767 assert(invariant(this, _enumValues == null, |
2732 message: "enumValues has already been computed for $this.")); | 2768 message: "enumValues has already been computed for $this.")); |
2733 _enumValues = values; | 2769 _enumValues = values; |
2734 } | 2770 } |
2735 | 2771 |
2736 @override | 2772 @override |
2737 DeclarationSite get declarationSite => this; | 2773 DeclarationSite get declarationSite => this; |
2738 } | 2774 } |
2739 | 2775 |
| 2776 /// This element is used to encode the implicit constructor in an enum class. |
| 2777 /// |
| 2778 /// For instance |
| 2779 /// |
| 2780 /// enum A { b, c, } |
| 2781 /// |
| 2782 /// is modelled as |
| 2783 /// |
| 2784 /// class A { |
| 2785 /// final int index; |
| 2786 /// |
| 2787 /// const A(this.index); |
| 2788 /// |
| 2789 /// String toString() { |
| 2790 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2791 /// } |
| 2792 /// |
| 2793 /// static const A b = const A(0); |
| 2794 /// static const A c = const A(1); |
| 2795 /// |
| 2796 /// static const List<A> values = const <A>[b, c]; |
| 2797 /// } |
| 2798 /// |
| 2799 /// where the `const A(...)` constructor is encoded using this element. |
| 2800 /// |
2740 class EnumConstructorElementX extends ConstructorElementX { | 2801 class EnumConstructorElementX extends ConstructorElementX { |
2741 final FunctionExpression node; | 2802 final FunctionExpression node; |
2742 | 2803 |
2743 EnumConstructorElementX( | 2804 EnumConstructorElementX( |
2744 EnumClassElementX enumClass, Modifiers modifiers, this.node) | 2805 EnumClassElementX enumClass, Modifiers modifiers, this.node) |
2745 : super( | 2806 : super( |
2746 '', // Name. | 2807 '', // Name. |
2747 ElementKind.GENERATIVE_CONSTRUCTOR, | 2808 ElementKind.GENERATIVE_CONSTRUCTOR, |
2748 modifiers, | 2809 modifiers, |
2749 enumClass); | 2810 enumClass); |
2750 | 2811 |
2751 @override | 2812 @override |
2752 bool get hasNode => true; | 2813 bool get hasNode => true; |
2753 | 2814 |
2754 @override | 2815 @override |
2755 FunctionExpression parseNode(Parsing parsing) => node; | 2816 FunctionExpression parseNode(Parsing parsing) => node; |
2756 | 2817 |
2757 @override | 2818 @override |
2758 SourceSpan get sourcePosition => enclosingClass.sourcePosition; | 2819 SourceSpan get sourcePosition => enclosingClass.sourcePosition; |
2759 } | 2820 } |
2760 | 2821 |
| 2822 /// This element is used to encode the implicit methods in an enum class. |
| 2823 /// |
| 2824 /// For instance |
| 2825 /// |
| 2826 /// enum A { b, c, } |
| 2827 /// |
| 2828 /// is modelled as |
| 2829 /// |
| 2830 /// class A { |
| 2831 /// final int index; |
| 2832 /// |
| 2833 /// const A(this.index); |
| 2834 /// |
| 2835 /// String toString() { |
| 2836 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2837 /// } |
| 2838 /// |
| 2839 /// static const A b = const A(0); |
| 2840 /// static const A c = const A(1); |
| 2841 /// |
| 2842 /// static const List<A> values = const <A>[b, c]; |
| 2843 /// } |
| 2844 /// |
| 2845 /// where the `toString` method is encoded using this element. |
| 2846 /// |
2761 class EnumMethodElementX extends MethodElementX { | 2847 class EnumMethodElementX extends MethodElementX { |
2762 final FunctionExpression node; | 2848 final FunctionExpression node; |
2763 | 2849 |
2764 EnumMethodElementX( | 2850 EnumMethodElementX( |
2765 String name, EnumClassElementX enumClass, Modifiers modifiers, this.node) | 2851 String name, EnumClassElementX enumClass, Modifiers modifiers, this.node) |
2766 : super(name, ElementKind.FUNCTION, modifiers, enumClass, true); | 2852 : super(name, ElementKind.FUNCTION, modifiers, enumClass, true); |
2767 | 2853 |
2768 @override | 2854 @override |
2769 bool get hasNode => true; | 2855 bool get hasNode => true; |
2770 | 2856 |
2771 @override | 2857 @override |
2772 FunctionExpression parseNode(Parsing parsing) => node; | 2858 FunctionExpression parseNode(Parsing parsing) => node; |
2773 | 2859 |
2774 @override | 2860 @override |
2775 SourceSpan get sourcePosition => enclosingClass.sourcePosition; | 2861 SourceSpan get sourcePosition => enclosingClass.sourcePosition; |
2776 } | 2862 } |
2777 | 2863 |
| 2864 /// This element is used to encode the initializing formal of the implicit |
| 2865 /// constructor in an enum class. |
| 2866 /// |
| 2867 /// For instance |
| 2868 /// |
| 2869 /// enum A { b, c, } |
| 2870 /// |
| 2871 /// is modelled as |
| 2872 /// |
| 2873 /// class A { |
| 2874 /// final int index; |
| 2875 /// |
| 2876 /// const A(this.index); |
| 2877 /// |
| 2878 /// String toString() { |
| 2879 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2880 /// } |
| 2881 /// |
| 2882 /// static const A b = const A(0); |
| 2883 /// static const A c = const A(1); |
| 2884 /// |
| 2885 /// static const List<A> values = const <A>[b, c]; |
| 2886 /// } |
| 2887 /// |
| 2888 /// where the `this.index` formal is encoded using this element. |
| 2889 /// |
2778 class EnumFormalElementX extends InitializingFormalElementX { | 2890 class EnumFormalElementX extends InitializingFormalElementX { |
2779 EnumFormalElementX( | 2891 EnumFormalElementX( |
2780 ConstructorElement constructor, | 2892 ConstructorElement constructor, |
2781 VariableDefinitions variables, | 2893 VariableDefinitions variables, |
2782 Identifier identifier, | 2894 Identifier identifier, |
2783 EnumFieldElementX fieldElement) | 2895 EnumFieldElementX fieldElement) |
2784 : super(constructor, variables, identifier, null, fieldElement) { | 2896 : super(constructor, variables, identifier, null, fieldElement) { |
2785 typeCache = fieldElement.type; | 2897 typeCache = fieldElement.type; |
2786 } | 2898 } |
2787 | 2899 |
2788 @override | 2900 @override |
2789 SourceSpan get sourcePosition => enclosingClass.sourcePosition; | 2901 SourceSpan get sourcePosition => enclosingClass.sourcePosition; |
2790 } | 2902 } |
2791 | 2903 |
| 2904 /// This element is used to encode the implicitly fields in an enum class. |
| 2905 /// |
| 2906 /// For instance |
| 2907 /// |
| 2908 /// enum A { b, c, } |
| 2909 /// |
| 2910 /// is modelled as |
| 2911 /// |
| 2912 /// class A { |
| 2913 /// final int index; |
| 2914 /// |
| 2915 /// const A(this.index); |
| 2916 /// |
| 2917 /// String toString() { |
| 2918 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2919 /// } |
| 2920 /// |
| 2921 /// static const A b = const A(0); |
| 2922 /// static const A c = const A(1); |
| 2923 /// |
| 2924 /// static const List<A> values = const <A>[b, c]; |
| 2925 /// } |
| 2926 /// |
| 2927 /// where the `index` and `values` fields are encoded using this element. |
| 2928 /// |
2792 class EnumFieldElementX extends FieldElementX { | 2929 class EnumFieldElementX extends FieldElementX { |
2793 EnumFieldElementX(Identifier name, EnumClassElementX enumClass, | 2930 EnumFieldElementX(Identifier name, EnumClassElementX enumClass, |
2794 VariableList variableList, Node definition, | 2931 VariableList variableList, Node definition, |
2795 [Expression initializer]) | 2932 [Expression initializer]) |
2796 : super(name, enumClass, variableList) { | 2933 : super(name, enumClass, variableList) { |
2797 definitionsCache = new VariableDefinitions( | 2934 definitionsCache = new VariableDefinitions( |
2798 null, variableList.modifiers, new NodeList.singleton(definition)); | 2935 null, variableList.modifiers, new NodeList.singleton(definition)); |
2799 initializerCache = initializer; | 2936 initializerCache = initializer; |
2800 } | 2937 } |
2801 | 2938 |
2802 @override | 2939 @override |
2803 SourceSpan get sourcePosition => enclosingClass.sourcePosition; | 2940 SourceSpan get sourcePosition => enclosingClass.sourcePosition; |
2804 } | 2941 } |
2805 | 2942 |
| 2943 /// This element is used to encode the constant value in an enum class. |
| 2944 /// |
| 2945 /// For instance |
| 2946 /// |
| 2947 /// enum A { b, c, } |
| 2948 /// |
| 2949 /// is modelled as |
| 2950 /// |
| 2951 /// class A { |
| 2952 /// final int index; |
| 2953 /// |
| 2954 /// const A(this.index); |
| 2955 /// |
| 2956 /// String toString() { |
| 2957 /// return const <int, A>{0: 'A.b', 1: 'A.c'}[index]; |
| 2958 /// } |
| 2959 /// |
| 2960 /// static const A b = const A(0); |
| 2961 /// static const A c = const A(1); |
| 2962 /// |
| 2963 /// static const List<A> values = const <A>[b, c]; |
| 2964 /// } |
| 2965 /// |
| 2966 /// where the `b` and `c` fields are encoded using this element. |
| 2967 /// |
2806 class EnumConstantElementX extends EnumFieldElementX | 2968 class EnumConstantElementX extends EnumFieldElementX |
2807 implements EnumConstantElement { | 2969 implements EnumConstantElement { |
2808 final int index; | 2970 final int index; |
2809 | 2971 |
2810 EnumConstantElementX( | 2972 EnumConstantElementX( |
2811 Identifier name, | 2973 Identifier name, |
2812 EnumClassElementX enumClass, | 2974 EnumClassElementX enumClass, |
2813 VariableList variableList, | 2975 VariableList variableList, |
2814 Node definition, | 2976 Node definition, |
2815 Expression initializer, | 2977 Expression initializer, |
2816 this.index) | 2978 this.index) |
2817 : super(name, enumClass, variableList, definition, initializer); | 2979 : super(name, enumClass, variableList, definition, initializer); |
2818 | 2980 |
2819 @override | 2981 @override |
2820 SourceSpan get sourcePosition { | 2982 SourceSpan get sourcePosition { |
2821 return new SourceSpan( | 2983 return new SourceSpan(enclosingClass.sourcePosition.uri, |
2822 enclosingClass.sourcePosition.uri, | |
2823 position.charOffset, position.charEnd); | 2984 position.charOffset, position.charEnd); |
2824 } | 2985 } |
2825 } | 2986 } |
2826 | 2987 |
2827 abstract class MixinApplicationElementX extends BaseClassElementX | 2988 abstract class MixinApplicationElementX extends BaseClassElementX |
2828 with MixinApplicationElementCommon | 2989 with MixinApplicationElementCommon |
2829 implements MixinApplicationElement { | 2990 implements MixinApplicationElement { |
2830 Link<ConstructorElement> constructors = new Link<ConstructorElement>(); | 2991 Link<ConstructorElement> constructors = new Link<ConstructorElement>(); |
2831 | 2992 |
2832 InterfaceType mixinType; | 2993 InterfaceType mixinType; |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3119 /// found through [declaration] since its node define the inheritance relation | 3280 /// found through [declaration] since its node define the inheritance relation |
3120 /// for the class. For unpatched elements the defining element is the element | 3281 /// for the class. For unpatched elements the defining element is the element |
3121 /// itself. | 3282 /// itself. |
3122 AstElement get definingElement; | 3283 AstElement get definingElement; |
3123 | 3284 |
3124 bool get hasResolvedAst { | 3285 bool get hasResolvedAst { |
3125 return definingElement.hasNode && definingElement.hasTreeElements; | 3286 return definingElement.hasNode && definingElement.hasTreeElements; |
3126 } | 3287 } |
3127 | 3288 |
3128 ResolvedAst get resolvedAst { | 3289 ResolvedAst get resolvedAst { |
3129 return new ResolvedAst( | 3290 return new ParsedResolvedAst( |
3130 declaration, definingElement.node, definingElement.treeElements); | 3291 declaration, definingElement.node, definingElement.treeElements); |
3131 } | 3292 } |
3132 } | 3293 } |
OLD | NEW |