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

Side by Side Diff: pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart

Issue 2916893002: Handle int constant (Closed)
Patch Set: Updated cf. comments Created 3 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 import '../common/resolution.dart';
6 import '../common_elements.dart'; 5 import '../common_elements.dart';
7 import '../constants/constant_system.dart'; 6 import '../constants/constant_system.dart';
8 import '../constants/values.dart'; 7 import '../constants/values.dart';
9 import '../elements/elements.dart';
10 import '../elements/entities.dart'; 8 import '../elements/entities.dart';
11 import '../elements/resolution_types.dart'; 9 import '../elements/types.dart';
12 import '../universe/call_structure.dart'; 10 import '../universe/call_structure.dart';
13 import '../universe/use.dart' show ConstantUse, StaticUse; 11 import '../universe/use.dart' show ConstantUse, StaticUse;
14 import '../universe/world_impact.dart' 12 import '../universe/world_impact.dart'
15 show WorldImpact, StagedWorldImpactBuilder; 13 show WorldImpact, StagedWorldImpactBuilder;
16 import 'backend_usage.dart' show BackendUsageBuilder; 14 import 'backend_usage.dart' show BackendUsageBuilder;
17 import 'native_data.dart'; 15 import 'native_data.dart';
18 16
19 /** 17 /**
20 * Support for Custom Elements. 18 * Support for Custom Elements.
21 * 19 *
(...skipping 26 matching lines...) Expand all
48 * final tag; 46 * final tag;
49 * Component(this.tag); 47 * Component(this.tag);
50 * void register() => document.register(T, tag); 48 * void register() => document.register(T, tag);
51 * } 49 * }
52 * const Component<FancyButton>('x-fancy-button').register(); 50 * const Component<FancyButton>('x-fancy-button').register();
53 * 51 *
54 * In these cases we conservatively generate all viable entries in the table. 52 * In these cases we conservatively generate all viable entries in the table.
55 */ 53 */
56 abstract class CustomElementsAnalysisBase { 54 abstract class CustomElementsAnalysisBase {
57 final NativeBasicData _nativeData; 55 final NativeBasicData _nativeData;
58 final Resolution _resolution; 56 final ElementEnvironment _elementEnvironment;
59 final CommonElements _commonElements; 57 final CommonElements _commonElements;
60 58
61 CustomElementsAnalysisBase( 59 CustomElementsAnalysisBase(
62 this._resolution, this._commonElements, this._nativeData); 60 this._elementEnvironment, this._commonElements, this._nativeData);
63 61
64 CustomElementsAnalysisJoin get join; 62 CustomElementsAnalysisJoin get join;
65 63
66 void registerInstantiatedClass(ClassElement classElement) { 64 void registerInstantiatedClass(ClassEntity cls) {
67 classElement.ensureResolved(_resolution); 65 if (!_nativeData.isNativeOrExtendsNative(cls)) return;
68 if (!_nativeData.isNativeOrExtendsNative(classElement)) return; 66 if (_elementEnvironment.isUnnamedMixinApplication(cls)) return;
69 if (classElement.isMixinApplication) return; 67 if (cls.isAbstract) return;
70 if (classElement.isAbstract) return;
71 // JsInterop classes are opaque interfaces without a concrete 68 // JsInterop classes are opaque interfaces without a concrete
72 // implementation. 69 // implementation.
73 if (_nativeData.isJsInteropClass(classElement)) return; 70 if (_nativeData.isJsInteropClass(cls)) return;
74 join.instantiatedClasses.add(classElement); 71 join.instantiatedClasses.add(cls);
75 } 72 }
76 73
77 void registerStaticUse(MemberEntity element) { 74 void registerStaticUse(MemberEntity element) {
78 assert(element != null); 75 assert(element != null);
79 if (element == _commonElements.findIndexForNativeSubclassType) { 76 if (element == _commonElements.findIndexForNativeSubclassType) {
80 join.demanded = true; 77 join.demanded = true;
81 } 78 }
82 } 79 }
83 80
84 /// Computes the [WorldImpact] of the classes registered since last flush. 81 /// Computes the [WorldImpact] of the classes registered since last flush.
85 WorldImpact flush() => join.flush(); 82 WorldImpact flush() => join.flush();
86 } 83 }
87 84
88 class CustomElementsResolutionAnalysis extends CustomElementsAnalysisBase { 85 class CustomElementsResolutionAnalysis extends CustomElementsAnalysisBase {
89 final CustomElementsAnalysisJoin join; 86 final CustomElementsAnalysisJoin join;
90 87
91 CustomElementsResolutionAnalysis( 88 CustomElementsResolutionAnalysis(
92 Resolution resolution,
93 ConstantSystem constantSystem, 89 ConstantSystem constantSystem,
90 ElementEnvironment elementEnvironment,
94 CommonElements commonElements, 91 CommonElements commonElements,
95 NativeBasicData nativeData, 92 NativeBasicData nativeData,
96 BackendUsageBuilder backendUsageBuilder) 93 BackendUsageBuilder backendUsageBuilder)
97 : join = new CustomElementsAnalysisJoin( 94 : join = new CustomElementsAnalysisJoin(
98 resolution, constantSystem, commonElements, nativeData, 95 constantSystem, elementEnvironment, commonElements, nativeData,
99 backendUsageBuilder: backendUsageBuilder), 96 backendUsageBuilder: backendUsageBuilder),
100 super(resolution, commonElements, nativeData) { 97 super(elementEnvironment, commonElements, nativeData) {
101 // TODO(sra): Remove this work-around. We should mark allClassesSelected in 98 // TODO(sra): Remove this work-around. We should mark allClassesSelected in
102 // both joins only when we see a construct generating an unknown [Type] but 99 // both joins only when we see a construct generating an unknown [Type] but
103 // we can't currently recognize all cases. In particular, the work-around 100 // we can't currently recognize all cases. In particular, the work-around
104 // for the unimplemented `ClassMirror.reflectedType` is not recognizable. 101 // for the unimplemented `ClassMirror.reflectedType` is not recognizable.
105 // TODO(12607): Match on [ClassMirror.reflectedType] 102 // TODO(12607): Match on [ClassMirror.reflectedType]
106 join.allClassesSelected = true; 103 join.allClassesSelected = true;
107 } 104 }
108 105
109 void registerTypeLiteral(ResolutionDartType type) { 106 void registerTypeLiteral(DartType type) {
110 if (type.isInterfaceType) { 107 if (type.isInterfaceType) {
111 // TODO(sra): If we had a flow query from the type literal expression to 108 // TODO(sra): If we had a flow query from the type literal expression to
112 // the Type argument of the metadata lookup, we could tell if this type 109 // the Type argument of the metadata lookup, we could tell if this type
113 // literal is really a demand for the metadata. 110 // literal is really a demand for the metadata.
114 join.selectedClasses.add(type.element); 111 InterfaceType interfaceType = type;
112 join.selectedClasses.add(interfaceType.element);
115 } else if (type.isTypeVariable) { 113 } else if (type.isTypeVariable) {
116 // This is a type parameter of a parameterized class. 114 // This is a type parameter of a parameterized class.
117 // TODO(sra): Is there a way to determine which types are bound to the 115 // TODO(sra): Is there a way to determine which types are bound to the
118 // parameter? 116 // parameter?
119 join.allClassesSelected = true; 117 join.allClassesSelected = true;
120 } 118 }
121 } 119 }
122 } 120 }
123 121
124 class CustomElementsCodegenAnalysis extends CustomElementsAnalysisBase { 122 class CustomElementsCodegenAnalysis extends CustomElementsAnalysisBase {
125 final CustomElementsAnalysisJoin join; 123 final CustomElementsAnalysisJoin join;
126 124
127 CustomElementsCodegenAnalysis( 125 CustomElementsCodegenAnalysis(
128 Resolution resolution,
129 ConstantSystem constantSystem, 126 ConstantSystem constantSystem,
130 CommonElements commonElements, 127 CommonElements commonElements,
128 ElementEnvironment elementEnvironment,
131 NativeBasicData nativeData) 129 NativeBasicData nativeData)
132 : join = new CustomElementsAnalysisJoin( 130 : join = new CustomElementsAnalysisJoin(
133 resolution, constantSystem, commonElements, nativeData), 131 constantSystem, elementEnvironment, commonElements, nativeData),
134 super(resolution, commonElements, nativeData) { 132 super(elementEnvironment, commonElements, nativeData) {
135 // TODO(sra): Remove this work-around. We should mark allClassesSelected in 133 // TODO(sra): Remove this work-around. We should mark allClassesSelected in
136 // both joins only when we see a construct generating an unknown [Type] but 134 // both joins only when we see a construct generating an unknown [Type] but
137 // we can't currently recognize all cases. In particular, the work-around 135 // we can't currently recognize all cases. In particular, the work-around
138 // for the unimplemented `ClassMirror.reflectedType` is not recognizable. 136 // for the unimplemented `ClassMirror.reflectedType` is not recognizable.
139 // TODO(12607): Match on [ClassMirror.reflectedType] 137 // TODO(12607): Match on [ClassMirror.reflectedType]
140 join.allClassesSelected = true; 138 join.allClassesSelected = true;
141 } 139 }
142 140
143 void registerTypeConstant(ClassElement element) { 141 void registerTypeConstant(ClassEntity cls) {
144 assert(element.isClass); 142 join.selectedClasses.add(cls);
145 join.selectedClasses.add(element);
146 } 143 }
147 144
148 bool get needsTable => join.demanded; 145 bool get needsTable => join.demanded;
149 146
150 bool needsClass(ClassElement classElement) => 147 bool needsClass(ClassEntity cls) => join.activeClasses.contains(cls);
151 join.activeClasses.contains(classElement);
152 148
153 List<ConstructorElement> constructors(ClassElement classElement) => 149 List<ConstructorEntity> constructors(ClassEntity cls) =>
154 join.computeEscapingConstructors(classElement); 150 join.computeEscapingConstructors(cls);
155 } 151 }
156 152
157 class CustomElementsAnalysisJoin { 153 class CustomElementsAnalysisJoin {
158 final Resolution _resolution;
159 final ConstantSystem _constantSystem; 154 final ConstantSystem _constantSystem;
155 final ElementEnvironment _elementEnvironment;
160 final CommonElements _commonElements; 156 final CommonElements _commonElements;
161 final NativeBasicData _nativeData; 157 final NativeBasicData _nativeData;
162 final BackendUsageBuilder _backendUsageBuilder; 158 final BackendUsageBuilder _backendUsageBuilder;
163 159
164 final bool forResolution; 160 final bool forResolution;
165 161
166 final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder(); 162 final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
167 163
168 // Classes that are candidates for needing constructors. Classes are moved to 164 // Classes that are candidates for needing constructors. Classes are moved to
169 // [activeClasses] when we know they need constructors. 165 // [activeClasses] when we know they need constructors.
170 final instantiatedClasses = new Set<ClassElement>(); 166 final Set<ClassEntity> instantiatedClasses = new Set<ClassEntity>();
171 167
172 // Classes explicitly named. 168 // Classes explicitly named.
173 final selectedClasses = new Set<ClassElement>(); 169 final Set<ClassEntity> selectedClasses = new Set<ClassEntity>();
174 170
175 // True if we must conservatively include all extension classes. 171 // True if we must conservatively include all extension classes.
176 bool allClassesSelected = false; 172 bool allClassesSelected = false;
177 173
178 // Did we see a demand for the data? 174 // Did we see a demand for the data?
179 bool demanded = false; 175 bool demanded = false;
180 176
181 // ClassesOutput: classes requiring metadata. 177 // ClassesOutput: classes requiring metadata.
182 final activeClasses = new Set<ClassElement>(); 178 final Set<ClassEntity> activeClasses = new Set<ClassEntity>();
183 179
184 CustomElementsAnalysisJoin(this._resolution, this._constantSystem, 180 CustomElementsAnalysisJoin(this._constantSystem, this._elementEnvironment,
185 this._commonElements, this._nativeData, 181 this._commonElements, this._nativeData,
186 {BackendUsageBuilder backendUsageBuilder}) 182 {BackendUsageBuilder backendUsageBuilder})
187 : this._backendUsageBuilder = backendUsageBuilder, 183 : this._backendUsageBuilder = backendUsageBuilder,
188 this.forResolution = backendUsageBuilder != null; 184 this.forResolution = backendUsageBuilder != null;
189 185
190 WorldImpact flush() { 186 WorldImpact flush() {
191 if (!demanded) return const WorldImpact(); 187 if (!demanded) return const WorldImpact();
192 var newActiveClasses = new Set<ClassElement>(); 188 var newActiveClasses = new Set<ClassEntity>();
193 for (ClassElement classElement in instantiatedClasses) { 189 for (ClassEntity cls in instantiatedClasses) {
194 bool isNative = _nativeData.isNativeClass(classElement); 190 bool isNative = _nativeData.isNativeClass(cls);
195 bool isExtension = 191 bool isExtension = !isNative && _nativeData.isNativeOrExtendsNative(cls);
196 !isNative && _nativeData.isNativeOrExtendsNative(classElement);
197 // Generate table entries for native classes that are explicitly named and 192 // Generate table entries for native classes that are explicitly named and
198 // extensions that fix our criteria. 193 // extensions that fix our criteria.
199 if ((isNative && selectedClasses.contains(classElement)) || 194 if ((isNative && selectedClasses.contains(cls)) ||
200 (isExtension && 195 (isExtension &&
201 (allClassesSelected || selectedClasses.contains(classElement)))) { 196 (allClassesSelected || selectedClasses.contains(cls)))) {
202 newActiveClasses.add(classElement); 197 newActiveClasses.add(cls);
203 Iterable<ConstructorElement> escapingConstructors = 198 Iterable<ConstructorEntity> escapingConstructors =
204 computeEscapingConstructors(classElement); 199 computeEscapingConstructors(cls);
205 for (ConstructorElement constructor in escapingConstructors) { 200 for (ConstructorEntity constructor in escapingConstructors) {
206 impactBuilder.registerStaticUse(new StaticUse.constructorInvoke( 201 impactBuilder.registerStaticUse(new StaticUse.constructorInvoke(
207 constructor, CallStructure.NO_ARGS)); 202 constructor, CallStructure.NO_ARGS));
208 } 203 }
209 if (forResolution) { 204 if (forResolution) {
210 escapingConstructors 205 escapingConstructors
211 .forEach(_backendUsageBuilder.registerGlobalFunctionDependency); 206 .forEach(_backendUsageBuilder.registerGlobalFunctionDependency);
212 } 207 }
213 // Force the generaton of the type constant that is the key to an entry 208 // Force the generaton of the type constant that is the key to an entry
214 // in the generated table. 209 // in the generated table.
215 ConstantValue constant = _makeTypeConstant(classElement); 210 ConstantValue constant = _makeTypeConstant(cls);
216 impactBuilder 211 impactBuilder
217 .registerConstantUse(new ConstantUse.customElements(constant)); 212 .registerConstantUse(new ConstantUse.customElements(constant));
218 } 213 }
219 } 214 }
220 activeClasses.addAll(newActiveClasses); 215 activeClasses.addAll(newActiveClasses);
221 instantiatedClasses.removeAll(newActiveClasses); 216 instantiatedClasses.removeAll(newActiveClasses);
222 return impactBuilder.flush(); 217 return impactBuilder.flush();
223 } 218 }
224 219
225 TypeConstantValue _makeTypeConstant(ClassElement element) { 220 TypeConstantValue _makeTypeConstant(ClassEntity cls) {
226 ResolutionDartType elementType = element.rawType; 221 DartType type = _elementEnvironment.getRawType(cls);
227 return _constantSystem.createType(_commonElements, elementType); 222 return _constantSystem.createType(_commonElements, type);
228 } 223 }
229 224
230 List<ConstructorElement> computeEscapingConstructors( 225 List<ConstructorEntity> computeEscapingConstructors(ClassEntity cls) {
231 ClassElement classElement) { 226 List<ConstructorEntity> result = <ConstructorEntity>[];
232 List<ConstructorElement> result = <ConstructorElement>[];
233 // Only classes that extend native classes have constructors in the table. 227 // Only classes that extend native classes have constructors in the table.
234 // We could refine this to classes that extend Element, but that would break 228 // We could refine this to classes that extend Element, but that would break
235 // the tests and there is no sane reason to subclass other native classes. 229 // the tests and there is no sane reason to subclass other native classes.
236 if (_nativeData.isNativeClass(classElement)) return result; 230 if (_nativeData.isNativeClass(cls)) return result;
237 231
238 void selectGenerativeConstructors(ClassElement enclosing, Element member) { 232 _elementEnvironment.forEachConstructor(cls,
239 if (member.isGenerativeConstructor) { 233 (ConstructorEntity constructor) {
234 if (constructor.isGenerativeConstructor) {
235 // Ensure that parameter structure has been computed by querying the
236 // function type.
237 _elementEnvironment.getFunctionType(constructor);
240 // Ignore constructors that cannot be called with zero arguments. 238 // Ignore constructors that cannot be called with zero arguments.
241 ConstructorElement constructor = member; 239 if (constructor.parameterStructure.requiredParameters == 0) {
242 constructor.computeType(_resolution); 240 result.add(constructor);
243 FunctionSignature parameters = constructor.functionSignature;
244 if (parameters.requiredParameterCount == 0) {
245 result.add(member);
246 } 241 }
247 } 242 }
248 } 243 });
249
250 classElement.forEachMember(selectGenerativeConstructors,
251 includeBackendMembers: false, includeSuperAndInjectedMembers: false);
252 return result; 244 return result;
253 } 245 }
254 } 246 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698