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

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

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

Powered by Google App Engine
This is Rietveld 408576698