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

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

Issue 2092333002: fix #25794, infer parameter type from default value, in AST summaries (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix comment Created 4 years, 5 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/lib/src/summary/summarize_ast.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 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1234 * compilation unit. 1234 * compilation unit.
1235 */ 1235 */
1236 void link() { 1236 void link() {
1237 if (library._linker.strongMode) { 1237 if (library._linker.strongMode) {
1238 new InstanceMemberInferrer(enclosingElement._linker.typeProvider, 1238 new InstanceMemberInferrer(enclosingElement._linker.typeProvider,
1239 enclosingElement.inheritanceManager) 1239 enclosingElement.inheritanceManager)
1240 .inferCompilationUnit(this); 1240 .inferCompilationUnit(this);
1241 for (TopLevelVariableElementForLink variable in topLevelVariables) { 1241 for (TopLevelVariableElementForLink variable in topLevelVariables) {
1242 variable.link(this); 1242 variable.link(this);
1243 } 1243 }
1244 for (TopLevelFunctionElementForLink function in functions) {
1245 function.link(this);
1246 }
1244 } 1247 }
1245 for (ClassElementForLink classElement in types) { 1248 for (ClassElementForLink classElement in types) {
1246 classElement.link(this); 1249 classElement.link(this);
1247 } 1250 }
1248 } 1251 }
1249 1252
1250 /** 1253 /**
1251 * Throw away any information stored in the summary by a previous call to 1254 * Throw away any information stored in the summary by a previous call to
1252 * [link]. 1255 * [link].
1253 */ 1256 */
(...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 2972
2970 @override 2973 @override
2971 void _setInferredType(DartType type) { 2974 void _setInferredType(DartType type) {
2972 assert(!_hasTypeBeenInferred); 2975 assert(!_hasTypeBeenInferred);
2973 _inferredReturnType = type; 2976 _inferredReturnType = type;
2974 _variable._inferredType = _dynamicIfNull(type); 2977 _variable._inferredType = _dynamicIfNull(type);
2975 } 2978 }
2976 } 2979 }
2977 2980
2978 /** 2981 /**
2982 * Element representing the initializer expression of a parameter.
2983 */
2984 class FunctionElementForLink_ParameterInitializer extends Object
Jennifer Messerly 2016/06/25 00:37:46 this is almost entirely a copy+paste of FunctionEl
2985 with ReferenceableElementForLink, TypeParameterizedElementMixin
2986 implements FunctionElementForLink_Local {
2987 /**
2988 * The variable for which this element is the initializer.
2989 */
2990 final ParameterElementForLink _param;
2991
2992 /**
2993 * The type inference node for this function, or `null` if it hasn't been
2994 * computed yet.
2995 */
2996 TypeInferenceNode _typeInferenceNode;
2997
2998 List<FunctionElementForLink_Local_NonSynthetic> _functions;
2999 DartType _inferredReturnType;
3000
3001 FunctionElementForLink_ParameterInitializer(this._param);
3002
3003 @override
3004 TypeInferenceNode get asTypeInferenceNode =>
3005 _typeInferenceNode ??= new TypeInferenceNode(this);
3006
3007 @override
3008 CompilationUnitElementForLink get compilationUnit =>
3009 _param.compilationUnit;
3010
3011 @override
3012 ParameterElementForLink get enclosingElement => _param;
3013
3014 TypeParameterizedElementMixin get enclosingTypeParameterContext =>
3015 _param.getAncestor((e) => e is ClassElementForLink);
Jennifer Messerly 2016/06/25 00:37:47 I think this was the only actual change
3016
3017 @override
3018 CompilationUnitElementForLink get enclosingUnit => _param.compilationUnit;
3019
3020 @override
3021 List<FunctionElementForLink_Local_NonSynthetic> get functions =>
3022 _functions ??= _param._unlinkedParam.initializer.localFunctions
3023 .map((UnlinkedExecutable ex) =>
3024 new FunctionElementForLink_Local_NonSynthetic(
3025 _param.compilationUnit, this, ex))
3026 .toList();
3027
3028 @override
3029 DartType get returnType {
3030 // If this is a variable whose type needs inferring, infer it.
3031 if (_param.hasImplicitType) {
3032 return _param.inferredType;
3033 } else {
3034 // There's no reason linking should need to access the type of
3035 // this FunctionElement, since the variable doesn't need its
3036 // type inferred.
3037 assert(false);
3038 // But for robustness, return the dynamic type.
3039 return DynamicTypeImpl.instance;
3040 }
3041 }
3042
3043 @override
3044 void set returnType(DartType newType) {
3045 // InstanceMemberInferrer stores the new type both here and on the variable
3046 // element. We don't need to record both values, so we ignore it here.
3047 }
3048
3049 @override
3050 TypeParameterizedElementMixin get typeParameterContext => this;
3051
3052 @override
3053 List<UnlinkedTypeParam> get unlinkedTypeParams => const [];
3054
3055 @override
3056 bool get _hasTypeBeenInferred => _inferredReturnType != null;
3057
3058 @override
3059 UnlinkedExecutable get _unlinkedExecutable =>
3060 _param._unlinkedParam.initializer;
3061
3062 @override
3063 FunctionElementForLink_Local getLocalFunction(int index) {
3064 List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
3065 return index < functions.length ? functions[index] : null;
3066 }
3067
3068 /**
3069 * Store the results of type inference for this initializer in
3070 * [compilationUnit].
3071 */
3072 void link(CompilationUnitElementInBuildUnit compilationUnit) {
3073 compilationUnit._storeLinkedType(_unlinkedExecutable.inferredReturnTypeSlot,
3074 _inferredReturnType, typeParameterContext);
3075 for (FunctionElementForLink_Local_NonSynthetic function in functions) {
3076 function.link(compilationUnit);
3077 }
3078 }
3079
3080 @override
3081 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
3082
3083 @override
3084 void _setInferredType(DartType type) {
3085 assert(!_hasTypeBeenInferred);
3086 _inferredReturnType = type;
3087 _param._inferredType = _dynamicIfNull(type);
3088 }
3089 }
3090
3091 /**
2979 * Element representing a local function (possibly a closure). 3092 * Element representing a local function (possibly a closure).
2980 */ 3093 */
2981 abstract class FunctionElementForLink_Local 3094 abstract class FunctionElementForLink_Local
2982 implements 3095 implements
2983 ExecutableElementForLink, 3096 ExecutableElementForLink,
2984 FunctionElementImpl, 3097 FunctionElementImpl,
2985 ReferenceableElementForLink { 3098 ReferenceableElementForLink {
2986 /** 3099 /**
2987 * Indicates whether type inference has completed for this function. 3100 * Indicates whether type inference has completed for this function.
2988 */ 3101 */
(...skipping 892 matching lines...) Expand 10 before | Expand all | Expand 10 after
3881 final CompilationUnitElementForLink compilationUnit; 3994 final CompilationUnitElementForLink compilationUnit;
3882 3995
3883 /** 3996 /**
3884 * The index of this parameter within [enclosingElement]'s parameter list. 3997 * The index of this parameter within [enclosingElement]'s parameter list.
3885 */ 3998 */
3886 final int _parameterIndex; 3999 final int _parameterIndex;
3887 4000
3888 @override 4001 @override
3889 final ParameterParentElementForLink enclosingElement; 4002 final ParameterParentElementForLink enclosingElement;
3890 4003
4004 /**
4005 * If this variable has an initializer and an implicit type, and the enclosing
4006 * library is part of the build unit being linked, the variable's node in the
4007 * type inference dependency graph. Otherwise `null`.
4008 */
4009 TypeInferenceNode _typeInferenceNode;
4010
4011 FunctionElementForLink_ParameterInitializer _initializer;
4012
3891 DartType _inferredType; 4013 DartType _inferredType;
3892 DartType _declaredType; 4014 DartType _declaredType;
3893 4015
3894 ParameterElementForLink(this.enclosingElement, this._unlinkedParam, 4016 ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
3895 this._typeParameterContext, this.compilationUnit, this._parameterIndex) { 4017 this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
3896 if (_unlinkedParam.initializer?.bodyExpr != null) { 4018 if (_unlinkedParam.initializer?.bodyExpr != null) {
3897 _constNode = new ConstParameterNode(this); 4019 _constNode = new ConstParameterNode(this);
4020 if (hasImplicitType) {
4021 _typeInferenceNode = initializer.asTypeInferenceNode;
4022 }
3898 } 4023 }
3899 } 4024 }
3900 4025
4026 @override
4027 FunctionElementForLink_ParameterInitializer get initializer {
4028 if (_unlinkedParam.initializer == null) {
4029 return null;
4030 } else {
4031 return _initializer ??=
4032 new FunctionElementForLink_ParameterInitializer(this);
4033 }
4034 }
4035
3901 @override 4036 @override
3902 String get displayName => _unlinkedParam.name; 4037 String get displayName => _unlinkedParam.name;
3903 4038
3904 @override 4039 @override
3905 bool get hasImplicitType => 4040 bool get hasImplicitType =>
3906 !_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null; 4041 !_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
3907 4042
3908 @override 4043 @override
3909 String get name => _unlinkedParam.name; 4044 String get name => _unlinkedParam.name;
3910 4045
3911 @override 4046 @override
3912 ParameterKind get parameterKind { 4047 ParameterKind get parameterKind {
3913 switch (_unlinkedParam.kind) { 4048 switch (_unlinkedParam.kind) {
3914 case UnlinkedParamKind.required: 4049 case UnlinkedParamKind.required:
3915 return ParameterKind.REQUIRED; 4050 return ParameterKind.REQUIRED;
3916 case UnlinkedParamKind.positional: 4051 case UnlinkedParamKind.positional:
3917 return ParameterKind.POSITIONAL; 4052 return ParameterKind.POSITIONAL;
3918 case UnlinkedParamKind.named: 4053 case UnlinkedParamKind.named:
3919 return ParameterKind.NAMED; 4054 return ParameterKind.NAMED;
3920 } 4055 }
3921 return null; 4056 return null;
3922 } 4057 }
3923 4058
3924 @override 4059 /**
3925 DartType get type { 4060 * If the variable has an explicitly declared return type, return it.
3926 if (_inferredType != null) { 4061 * Otherwise return `null`.
3927 return _inferredType; 4062 */
3928 } else if (_declaredType == null) { 4063 DartType get declaredType {
Jennifer Messerly 2016/06/25 00:37:47 this pattern more or less copy+paste from Variable
3929 if (_unlinkedParam.isFunctionTyped) { 4064 if (hasImplicitType) {
3930 _declaredType = new FunctionTypeImpl( 4065 return null;
3931 new FunctionElementForLink_FunctionTypedParam( 4066 } else if (_declaredType != null) {
3932 this, _typeParameterContext, _unlinkedParam.parameters)); 4067 return _declaredType;
3933 } else if (_unlinkedParam.type == null) { 4068 } else if (_unlinkedParam.isFunctionTyped) {
3934 if (!compilationUnit.isInBuildUnit) { 4069 return _declaredType = new FunctionTypeImpl(
3935 _inferredType = compilationUnit.getLinkedType( 4070 new FunctionElementForLink_FunctionTypedParam(
3936 _unlinkedParam.inferredTypeSlot, _typeParameterContext); 4071 this, _typeParameterContext, _unlinkedParam.parameters));
3937 return _inferredType; 4072 } else {
3938 } else { 4073 return _declaredType = compilationUnit.resolveTypeRef(
3939 _declaredType = DynamicTypeImpl.instance; 4074 _unlinkedParam.type, _typeParameterContext);
4075 }
4076 }
4077
4078 /**
4079 * Return the inferred type of the parameter element.
4080 *
4081 * Should only be called if no type was explicitly declared.
4082 */
4083 DartType get inferredType {
4084 // We should only try to infer a type when none is explicitly declared.
4085 assert(_unlinkedParam.type == null);
4086 if (_inferredType == null) {
4087 if (_typeInferenceNode != null) {
4088 assert(Linker._initializerTypeInferenceCycle == null);
4089 Linker._initializerTypeInferenceCycle =
4090 compilationUnit.library.libraryCycleForLink;
4091 try {
4092 new TypeInferenceDependencyWalker().walk(_typeInferenceNode);
Jennifer Messerly 2016/06/25 00:37:46 Aside -- I'm reusing logic from the static/top-lev
4093 assert(_inferredType != null);
4094 } finally {
4095 Linker._initializerTypeInferenceCycle = null;
3940 } 4096 }
4097 } else if (compilationUnit.isInBuildUnit) {
4098 _inferredType = DynamicTypeImpl.instance;
3941 } else { 4099 } else {
3942 _declaredType = compilationUnit.resolveTypeRef( 4100 _inferredType = compilationUnit.getLinkedType(
3943 _unlinkedParam.type, _typeParameterContext); 4101 _unlinkedParam.inferredTypeSlot, _typeParameterContext);
3944 } 4102 }
3945 } 4103 }
3946 return _declaredType; 4104 return _inferredType;
3947 } 4105 }
3948 4106
3949 @override 4107 @override
4108 DartType get type => declaredType ?? inferredType;
4109
4110 @override
3950 void set type(DartType inferredType) { 4111 void set type(DartType inferredType) {
3951 assert(_inferredType == null); 4112 assert(_inferredType == null);
3952 _inferredType = inferredType; 4113 _inferredType = inferredType;
3953 } 4114 }
3954 4115
3955 /** 4116 /**
3956 * Store the results of type inference for this parameter in 4117 * Store the results of type inference for this parameter in
3957 * [compilationUnit]. 4118 * [compilationUnit].
3958 */ 4119 */
3959 void link(CompilationUnitElementInBuildUnit compilationUnit) { 4120 void link(CompilationUnitElementInBuildUnit compilationUnit) {
Jennifer Messerly 2016/06/25 00:37:46 "link" method seems like the thing that actually f
3960 compilationUnit._storeLinkedType( 4121 if (hasImplicitType) {
3961 _unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext); 4122 compilationUnit._storeLinkedType(
4123 _unlinkedParam.inferredTypeSlot, inferredType, _typeParameterContext);
4124 initializer?.link(compilationUnit);
4125 }
3962 } 4126 }
3963 4127
3964 @override 4128 @override
3965 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 4129 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
3966 } 4130 }
3967 4131
3968 /** 4132 /**
3969 * Element representing the parameter of a synthetic setter for a variable 4133 * Element representing the parameter of a synthetic setter for a variable
3970 * resynthesized during linking. 4134 * resynthesized during linking.
3971 */ 4135 */
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
4953 * there are no type parameters in scope. 5117 * there are no type parameters in scope.
4954 */ 5118 */
4955 TypeParameterizedElementMixin get _typeParameterContext; 5119 TypeParameterizedElementMixin get _typeParameterContext;
4956 5120
4957 @override 5121 @override
4958 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); 5122 noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
4959 5123
4960 @override 5124 @override
4961 String toString() => '$enclosingElement.$name'; 5125 String toString() => '$enclosingElement.$name';
4962 } 5126 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/summary/summarize_ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698