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 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |