OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 /** | 5 /** |
6 * This library is capable of producing linked summaries from unlinked | 6 * This library is capable of producing linked summaries from unlinked |
7 * ones (or prelinked ones). It functions by building a miniature | 7 * ones (or prelinked ones). It functions by building a miniature |
8 * element model to represent the contents of the summaries, and then | 8 * element model to represent the contents of the summaries, and then |
9 * scanning the element model to gather linked information and adding | 9 * scanning the element model to gather linked information and adding |
10 * it to the summary data structures. | 10 * it to the summary data structures. |
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 break; | 2160 break; |
2161 case UnlinkedConstOperation.throwException: | 2161 case UnlinkedConstOperation.throwException: |
2162 stack.removeLast(); | 2162 stack.removeLast(); |
2163 stack.add(BottomTypeImpl.instance); | 2163 stack.add(BottomTypeImpl.instance); |
2164 break; | 2164 break; |
2165 case UnlinkedConstOperation.pushLocalFunctionReference: | 2165 case UnlinkedConstOperation.pushLocalFunctionReference: |
2166 int popCount = _getNextInt(); | 2166 int popCount = _getNextInt(); |
2167 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. | 2167 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. |
2168 stack.add(function.functions[_getNextInt()].type); | 2168 stack.add(function.functions[_getNextInt()].type); |
2169 break; | 2169 break; |
| 2170 case UnlinkedConstOperation.pushParameter: |
| 2171 stack.add(_findParameterType(_getNextString())); |
| 2172 break; |
2170 default: | 2173 default: |
2171 // TODO(paulberry): implement. | 2174 // TODO(paulberry): implement. |
2172 throw new UnimplementedError('$operation'); | 2175 throw new UnimplementedError('$operation'); |
2173 } | 2176 } |
2174 } | 2177 } |
2175 assert(intPtr == unlinkedConst.ints.length); | 2178 assert(intPtr == unlinkedConst.ints.length); |
2176 assert(refPtr == unlinkedConst.references.length); | 2179 assert(refPtr == unlinkedConst.references.length); |
2177 assert(strPtr == unlinkedConst.strings.length); | 2180 assert(strPtr == unlinkedConst.strings.length); |
2178 assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length); | 2181 assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length); |
2179 assert(stack.length == 1); | 2182 assert(stack.length == 1); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2428 // to by expressions. | 2431 // to by expressions. |
2429 assert(ref.syntheticReturnType == null); | 2432 assert(ref.syntheticReturnType == null); |
2430 // Nor can implicit function types derived from | 2433 // Nor can implicit function types derived from |
2431 // function-typed parameters. | 2434 // function-typed parameters. |
2432 assert(ref.implicitFunctionTypeIndices.isEmpty); | 2435 assert(ref.implicitFunctionTypeIndices.isEmpty); |
2433 ReferenceableElementForLink element = unit.resolveRef(ref.reference); | 2436 ReferenceableElementForLink element = unit.resolveRef(ref.reference); |
2434 stack.add(element.asStaticType); | 2437 stack.add(element.asStaticType); |
2435 } | 2438 } |
2436 } | 2439 } |
2437 | 2440 |
| 2441 /** |
| 2442 * Find the parameter in scope called [parameterName] and return its type. |
| 2443 */ |
| 2444 DartType _findParameterType(String parameterName) { |
| 2445 FunctionElementForLink_Local f = this.function; |
| 2446 while (true) { |
| 2447 for (ParameterElement parameter in f.parameters) { |
| 2448 if (parameter.name == parameterName) { |
| 2449 return parameter.type; |
| 2450 } |
| 2451 } |
| 2452 Element parent = f.enclosingElement; |
| 2453 if (parent is FunctionElementForLink_Local) { |
| 2454 f = parent; |
| 2455 } else { |
| 2456 // Parameter not found. This should never happen in a well-formed |
| 2457 // summary. |
| 2458 assert(false); |
| 2459 return DynamicTypeImpl.instance; |
| 2460 } |
| 2461 } |
| 2462 } |
| 2463 |
2438 int _getNextInt() { | 2464 int _getNextInt() { |
2439 return unlinkedConst.ints[intPtr++]; | 2465 return unlinkedConst.ints[intPtr++]; |
2440 } | 2466 } |
2441 | 2467 |
2442 EntityRef _getNextRef() => unlinkedConst.references[refPtr++]; | 2468 EntityRef _getNextRef() => unlinkedConst.references[refPtr++]; |
2443 | 2469 |
2444 String _getNextString() { | 2470 String _getNextString() { |
2445 return unlinkedConst.strings[strPtr++]; | 2471 return unlinkedConst.strings[strPtr++]; |
2446 } | 2472 } |
2447 | 2473 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2650 /** | 2676 /** |
2651 * Store the results of type inference for this field in | 2677 * Store the results of type inference for this field in |
2652 * [compilationUnit]. | 2678 * [compilationUnit]. |
2653 */ | 2679 */ |
2654 void link(CompilationUnitElementInBuildUnit compilationUnit) { | 2680 void link(CompilationUnitElementInBuildUnit compilationUnit) { |
2655 if (hasImplicitType) { | 2681 if (hasImplicitType) { |
2656 compilationUnit._storeLinkedType( | 2682 compilationUnit._storeLinkedType( |
2657 unlinkedVariable.inferredTypeSlot, | 2683 unlinkedVariable.inferredTypeSlot, |
2658 isStatic ? inferredType : _inferredInstanceType, | 2684 isStatic ? inferredType : _inferredInstanceType, |
2659 _typeParameterContext); | 2685 _typeParameterContext); |
| 2686 initializer?.link(compilationUnit); |
2660 } | 2687 } |
2661 } | 2688 } |
2662 | 2689 |
2663 @override | 2690 @override |
2664 String toString() => '$enclosingElement.$name'; | 2691 String toString() => '$enclosingElement.$name'; |
2665 } | 2692 } |
2666 | 2693 |
2667 /** | 2694 /** |
2668 * Specialization of [FieldElementForLink] for enum fields. | 2695 * Specialization of [FieldElementForLink] for enum fields. |
2669 */ | 2696 */ |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2765 * Element representing the initializer expression of a variable. | 2792 * Element representing the initializer expression of a variable. |
2766 */ | 2793 */ |
2767 class FunctionElementForLink_Initializer extends Object | 2794 class FunctionElementForLink_Initializer extends Object |
2768 with ReferenceableElementForLink, TypeParameterizedElementMixin | 2795 with ReferenceableElementForLink, TypeParameterizedElementMixin |
2769 implements FunctionElementForLink_Local { | 2796 implements FunctionElementForLink_Local { |
2770 /** | 2797 /** |
2771 * The variable for which this element is the initializer. | 2798 * The variable for which this element is the initializer. |
2772 */ | 2799 */ |
2773 final VariableElementForLink _variable; | 2800 final VariableElementForLink _variable; |
2774 | 2801 |
| 2802 /** |
| 2803 * The type inference node for this function, or `null` if it hasn't been |
| 2804 * computed yet. |
| 2805 */ |
| 2806 TypeInferenceNode _typeInferenceNode; |
| 2807 |
2775 List<FunctionElementForLink_Local_NonSynthetic> _functions; | 2808 List<FunctionElementForLink_Local_NonSynthetic> _functions; |
2776 | 2809 |
2777 FunctionElementForLink_Initializer(this._variable); | 2810 FunctionElementForLink_Initializer(this._variable); |
2778 | 2811 |
2779 @override | 2812 @override |
| 2813 TypeInferenceNode get asTypeInferenceNode => |
| 2814 _typeInferenceNode ??= new TypeInferenceNode(this); |
| 2815 |
| 2816 @override |
2780 CompilationUnitElementForLink get compilationUnit => | 2817 CompilationUnitElementForLink get compilationUnit => |
2781 _variable.compilationUnit; | 2818 _variable.compilationUnit; |
2782 | 2819 |
2783 @override | 2820 @override |
2784 VariableElementForLink get enclosingElement => _variable; | 2821 VariableElementForLink get enclosingElement => _variable; |
2785 | 2822 |
2786 TypeParameterizedElementMixin get enclosingTypeParameterContext => | 2823 TypeParameterizedElementMixin get enclosingTypeParameterContext => |
2787 _variable.enclosingElement is ClassElementForLink | 2824 _variable.enclosingElement is ClassElementForLink |
2788 ? _variable.enclosingElement | 2825 ? _variable.enclosingElement |
2789 : null; | 2826 : null; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2832 @override | 2869 @override |
2833 UnlinkedExecutable get _unlinkedExecutable => | 2870 UnlinkedExecutable get _unlinkedExecutable => |
2834 _variable.unlinkedVariable.initializer; | 2871 _variable.unlinkedVariable.initializer; |
2835 | 2872 |
2836 @override | 2873 @override |
2837 FunctionElementForLink_Local getLocalFunction(int index) { | 2874 FunctionElementForLink_Local getLocalFunction(int index) { |
2838 List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions; | 2875 List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions; |
2839 return index < functions.length ? functions[index] : null; | 2876 return index < functions.length ? functions[index] : null; |
2840 } | 2877 } |
2841 | 2878 |
| 2879 /** |
| 2880 * Store the results of type inference for this initializer in |
| 2881 * [compilationUnit]. |
| 2882 */ |
| 2883 void link(CompilationUnitElementInBuildUnit compilationUnit) { |
| 2884 for (FunctionElementForLink_Local_NonSynthetic function in functions) { |
| 2885 function.link(compilationUnit); |
| 2886 } |
| 2887 } |
| 2888 |
2842 @override | 2889 @override |
2843 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 2890 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
2844 | 2891 |
2845 @override | 2892 @override |
2846 void _setInferredType(DartType type) { | 2893 void _setInferredType(DartType type) { |
2847 assert(!_hasTypeBeenInferred); | 2894 assert(!_hasTypeBeenInferred); |
2848 _variable._inferredType = type; | 2895 _variable._inferredType = type; |
2849 } | 2896 } |
2850 } | 2897 } |
2851 | 2898 |
(...skipping 20 matching lines...) Expand all Loading... |
2872 /** | 2919 /** |
2873 * Element representing a local function (possibly a closure) inside another | 2920 * Element representing a local function (possibly a closure) inside another |
2874 * executable. | 2921 * executable. |
2875 */ | 2922 */ |
2876 class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink | 2923 class FunctionElementForLink_Local_NonSynthetic extends ExecutableElementForLink |
2877 with ReferenceableElementForLink | 2924 with ReferenceableElementForLink |
2878 implements FunctionElementForLink_Local { | 2925 implements FunctionElementForLink_Local { |
2879 @override | 2926 @override |
2880 final ExecutableElementForLink enclosingElement; | 2927 final ExecutableElementForLink enclosingElement; |
2881 | 2928 |
| 2929 List<FunctionElementForLink_Local_NonSynthetic> _functions; |
| 2930 |
| 2931 /** |
| 2932 * The type inference node for this function, or `null` if it hasn't been |
| 2933 * computed yet. |
| 2934 */ |
| 2935 TypeInferenceNode _typeInferenceNode; |
| 2936 |
2882 FunctionElementForLink_Local_NonSynthetic( | 2937 FunctionElementForLink_Local_NonSynthetic( |
2883 CompilationUnitElementForLink compilationUnit, | 2938 CompilationUnitElementForLink compilationUnit, |
2884 this.enclosingElement, | 2939 this.enclosingElement, |
2885 UnlinkedExecutable unlinkedExecutable) | 2940 UnlinkedExecutable unlinkedExecutable) |
2886 : super(compilationUnit, unlinkedExecutable); | 2941 : super(compilationUnit, unlinkedExecutable); |
2887 | 2942 |
2888 @override | 2943 @override |
| 2944 TypeInferenceNode get asTypeInferenceNode => |
| 2945 _typeInferenceNode ??= new TypeInferenceNode(this); |
| 2946 |
| 2947 @override |
2889 TypeParameterizedElementMixin get enclosingTypeParameterContext => | 2948 TypeParameterizedElementMixin get enclosingTypeParameterContext => |
2890 enclosingElement; | 2949 enclosingElement; |
2891 | 2950 |
2892 @override | 2951 @override |
2893 bool get _hasTypeBeenInferred { | 2952 List<FunctionElementForLink_Local_NonSynthetic> get functions => |
2894 // TODO(paulberry): add logic to infer types of nonsynthetic functions. | 2953 _functions ??= _unlinkedExecutable.localFunctions |
2895 return true; | 2954 .map((UnlinkedExecutable ex) => |
2896 } | 2955 new FunctionElementForLink_Local_NonSynthetic( |
| 2956 compilationUnit, this, ex)) |
| 2957 .toList(); |
| 2958 |
| 2959 @override |
| 2960 bool get _hasTypeBeenInferred => _inferredReturnType != null; |
2897 | 2961 |
2898 @override | 2962 @override |
2899 DartType buildType( | 2963 DartType buildType( |
2900 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { | 2964 DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) { |
2901 assert(implicitFunctionTypeIndices.isEmpty); | 2965 assert(implicitFunctionTypeIndices.isEmpty); |
2902 return type; | 2966 return type; |
2903 } | 2967 } |
2904 | 2968 |
2905 @override | 2969 @override |
2906 FunctionElementForLink_Local getLocalFunction(int index) { | 2970 FunctionElementForLink_Local getLocalFunction(int index) { |
2907 // TODO(paulberry): implement. | 2971 List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions; |
2908 throw new UnimplementedError(); | 2972 return index < functions.length ? functions[index] : null; |
| 2973 } |
| 2974 |
| 2975 /** |
| 2976 * Store the results of type inference for this function in [compilationUnit]. |
| 2977 */ |
| 2978 void link(CompilationUnitElementInBuildUnit compilationUnit) { |
| 2979 compilationUnit._storeLinkedType( |
| 2980 _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this); |
| 2981 for (FunctionElementForLink_Local_NonSynthetic function in functions) { |
| 2982 function.link(compilationUnit); |
| 2983 } |
2909 } | 2984 } |
2910 | 2985 |
2911 @override | 2986 @override |
2912 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 2987 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
2913 | 2988 |
2914 @override | 2989 @override |
2915 void _setInferredType(DartType type) { | 2990 void _setInferredType(DartType type) { |
2916 // TODO(paulberry): add logic to infer types of nonsynthetic functions. | 2991 // TODO(paulberry): store the inferred return type in the summary. |
2917 throw new UnimplementedError(); | 2992 assert(!_hasTypeBeenInferred); |
| 2993 _inferredReturnType = type; |
2918 } | 2994 } |
2919 } | 2995 } |
2920 | 2996 |
2921 /** | 2997 /** |
2922 * Element representing a typedef resynthesized from a summary during linking. | 2998 * Element representing a typedef resynthesized from a summary during linking. |
2923 */ | 2999 */ |
2924 class FunctionTypeAliasElementForLink extends Object | 3000 class FunctionTypeAliasElementForLink extends Object |
2925 with | 3001 with |
2926 TypeParameterizedElementMixin, | 3002 TypeParameterizedElementMixin, |
2927 ParameterParentElementForLink, | 3003 ParameterParentElementForLink, |
(...skipping 1405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4333 * Store the results of type inference for this variable in | 4409 * Store the results of type inference for this variable in |
4334 * [compilationUnit]. | 4410 * [compilationUnit]. |
4335 */ | 4411 */ |
4336 void link(CompilationUnitElementInBuildUnit compilationUnit) { | 4412 void link(CompilationUnitElementInBuildUnit compilationUnit) { |
4337 if (hasImplicitType) { | 4413 if (hasImplicitType) { |
4338 TypeInferenceNode typeInferenceNode = this._typeInferenceNode; | 4414 TypeInferenceNode typeInferenceNode = this._typeInferenceNode; |
4339 if (typeInferenceNode != null) { | 4415 if (typeInferenceNode != null) { |
4340 compilationUnit._storeLinkedType( | 4416 compilationUnit._storeLinkedType( |
4341 unlinkedVariable.inferredTypeSlot, inferredType, null); | 4417 unlinkedVariable.inferredTypeSlot, inferredType, null); |
4342 } | 4418 } |
| 4419 initializer?.link(compilationUnit); |
4343 } | 4420 } |
4344 } | 4421 } |
4345 } | 4422 } |
4346 | 4423 |
4347 /** | 4424 /** |
4348 * Specialization of [DependencyWalker] for performing type inferrence | 4425 * Specialization of [DependencyWalker] for performing type inferrence |
4349 * on static and top level variables. | 4426 * on static and top level variables. |
4350 */ | 4427 */ |
4351 class TypeInferenceDependencyWalker | 4428 class TypeInferenceDependencyWalker |
4352 extends DependencyWalker<TypeInferenceNode> { | 4429 extends DependencyWalker<TypeInferenceNode> { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4446 case UnlinkedConstOperation.invokeMethod: | 4523 case UnlinkedConstOperation.invokeMethod: |
4447 intPtr += 2; | 4524 intPtr += 2; |
4448 break; | 4525 break; |
4449 case UnlinkedConstOperation.typeCast: | 4526 case UnlinkedConstOperation.typeCast: |
4450 case UnlinkedConstOperation.typeCheck: | 4527 case UnlinkedConstOperation.typeCheck: |
4451 refPtr++; | 4528 refPtr++; |
4452 break; | 4529 break; |
4453 case UnlinkedConstOperation.pushLocalFunctionReference: | 4530 case UnlinkedConstOperation.pushLocalFunctionReference: |
4454 int popCount = unlinkedConst.ints[intPtr++]; | 4531 int popCount = unlinkedConst.ints[intPtr++]; |
4455 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. | 4532 assert(popCount == 0); // TODO(paulberry): handle the nonzero case. |
4456 collectDependencies( | 4533 dependencies.add(functionElement |
4457 dependencies, | 4534 .getLocalFunction(unlinkedConst.ints[intPtr++]) |
4458 unlinkedExecutable.localFunctions[unlinkedConst.ints[intPtr++]], | 4535 .asTypeInferenceNode); |
4459 compilationUnit); | |
4460 break; | 4536 break; |
4461 default: | 4537 default: |
4462 break; | 4538 break; |
4463 } | 4539 } |
4464 } | 4540 } |
4465 assert(refPtr == unlinkedConst.references.length); | 4541 assert(refPtr == unlinkedConst.references.length); |
4466 assert(intPtr == unlinkedConst.ints.length); | 4542 assert(intPtr == unlinkedConst.ints.length); |
4467 } | 4543 } |
4468 | 4544 |
4469 @override | 4545 @override |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4680 /** | 4756 /** |
4681 * The compilation unit in which this variable appears. | 4757 * The compilation unit in which this variable appears. |
4682 */ | 4758 */ |
4683 final CompilationUnitElementForLink compilationUnit; | 4759 final CompilationUnitElementForLink compilationUnit; |
4684 | 4760 |
4685 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) { | 4761 VariableElementForLink(this.unlinkedVariable, this.compilationUnit) { |
4686 if (compilationUnit.isInBuildUnit && | 4762 if (compilationUnit.isInBuildUnit && |
4687 unlinkedVariable.initializer?.bodyExpr != null) { | 4763 unlinkedVariable.initializer?.bodyExpr != null) { |
4688 _constNode = new ConstVariableNode(this); | 4764 _constNode = new ConstVariableNode(this); |
4689 if (unlinkedVariable.type == null) { | 4765 if (unlinkedVariable.type == null) { |
4690 _typeInferenceNode = new TypeInferenceNode(initializer); | 4766 _typeInferenceNode = initializer.asTypeInferenceNode; |
4691 } | 4767 } |
4692 } | 4768 } |
4693 } | 4769 } |
4694 | 4770 |
4695 /** | 4771 /** |
4696 * If the variable has an explicitly declared return type, return it. | 4772 * If the variable has an explicitly declared return type, return it. |
4697 * Otherwise return `null`. | 4773 * Otherwise return `null`. |
4698 */ | 4774 */ |
4699 DartType get declaredType { | 4775 DartType get declaredType { |
4700 if (unlinkedVariable.type == null) { | 4776 if (unlinkedVariable.type == null) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4793 * there are no type parameters in scope. | 4869 * there are no type parameters in scope. |
4794 */ | 4870 */ |
4795 TypeParameterizedElementMixin get _typeParameterContext; | 4871 TypeParameterizedElementMixin get _typeParameterContext; |
4796 | 4872 |
4797 @override | 4873 @override |
4798 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | 4874 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); |
4799 | 4875 |
4800 @override | 4876 @override |
4801 String toString() => '$enclosingElement.$name'; | 4877 String toString() => '$enclosingElement.$name'; |
4802 } | 4878 } |
OLD | NEW |