Chromium Code Reviews| 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 |