| 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 |