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

Side by Side Diff: pkg/analyzer/lib/src/summary/link.dart

Issue 2016873002: Implement AST-based type inference involving expression-type closures. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong/inferred_type_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/task/strong/inferred_type_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698