OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library dart2js.new_js_emitter.model; | 5 library dart2js.new_js_emitter.model; |
6 | 6 |
7 import '../constants/values.dart' show | 7 import '../constants/values.dart' show ConstantValue; |
8 ConstantValue; | 8 import '../deferred_load.dart' show OutputUnit; |
9 import '../deferred_load.dart' show | 9 import '../elements/elements.dart' show Element; |
10 OutputUnit; | 10 import '../js/js.dart' as js |
11 import '../elements/elements.dart' show | 11 show Expression, Literal, Name, Statement, TokenFinalizer; |
12 Element; | |
13 import '../js/js.dart' as js show | |
14 Expression, | |
15 Literal, | |
16 Name, | |
17 Statement, | |
18 TokenFinalizer; | |
19 | 12 |
20 import 'js_emitter.dart' show MetadataCollector; | 13 import 'js_emitter.dart' show MetadataCollector; |
21 | 14 |
22 class Program { | 15 class Program { |
23 final List<Fragment> fragments; | 16 final List<Fragment> fragments; |
24 final List<Holder> holders; | 17 final List<Holder> holders; |
25 final bool outputContainsConstantList; | 18 final bool outputContainsConstantList; |
26 final bool needsNativeSupport; | 19 final bool needsNativeSupport; |
27 final bool hasIsolateSupport; | 20 final bool hasIsolateSupport; |
| 21 |
28 /// A map from load id to the list of fragments that need to be loaded. | 22 /// A map from load id to the list of fragments that need to be loaded. |
29 final Map<String, List<Fragment>> loadMap; | 23 final Map<String, List<Fragment>> loadMap; |
| 24 |
30 /// A map from names to strings. | 25 /// A map from names to strings. |
31 /// | 26 /// |
32 /// This map is needed to support `const Symbol` expressions; | 27 /// This map is needed to support `const Symbol` expressions; |
33 final Map<js.Name, String> symbolsMap; | 28 final Map<js.Name, String> symbolsMap; |
34 | 29 |
35 // If this field is not `null` then its value must be emitted in the embedded | 30 // If this field is not `null` then its value must be emitted in the embedded |
36 // global `TYPE_TO_INTERCEPTOR_MAP`. The map references constants and classes. | 31 // global `TYPE_TO_INTERCEPTOR_MAP`. The map references constants and classes. |
37 final js.Expression typeToInterceptorMap; | 32 final js.Expression typeToInterceptorMap; |
38 | 33 |
39 // TODO(floitsch): we should store the metadata directly instead of storing | 34 // TODO(floitsch): we should store the metadata directly instead of storing |
40 // the collector. However, the old emitter still updates the data. | 35 // the collector. However, the old emitter still updates the data. |
41 final MetadataCollector _metadataCollector; | 36 final MetadataCollector _metadataCollector; |
42 final Iterable<js.TokenFinalizer> finalizers; | 37 final Iterable<js.TokenFinalizer> finalizers; |
43 | 38 |
44 Program(this.fragments, | 39 Program(this.fragments, this.holders, this.loadMap, this.symbolsMap, |
45 this.holders, | 40 this.typeToInterceptorMap, this._metadataCollector, this.finalizers, |
46 this.loadMap, | 41 {this.needsNativeSupport, |
47 this.symbolsMap, | 42 this.outputContainsConstantList, |
48 this.typeToInterceptorMap, | 43 this.hasIsolateSupport}) { |
49 this._metadataCollector, | |
50 this.finalizers, | |
51 {this.needsNativeSupport, | |
52 this.outputContainsConstantList, | |
53 this.hasIsolateSupport}) { | |
54 assert(needsNativeSupport != null); | 44 assert(needsNativeSupport != null); |
55 assert(outputContainsConstantList != null); | 45 assert(outputContainsConstantList != null); |
56 assert(hasIsolateSupport != null); | 46 assert(hasIsolateSupport != null); |
57 } | 47 } |
58 | 48 |
59 /// A list of metadata expressions. | 49 /// A list of metadata expressions. |
60 /// | 50 /// |
61 /// This list must be emitted in the `METADATA` embedded global. | 51 /// This list must be emitted in the `METADATA` embedded global. |
62 /// The list references constants and must hence be emitted after constants | 52 /// The list references constants and must hence be emitted after constants |
63 /// have been initialized. | 53 /// have been initialized. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 final List<Library> libraries; | 104 final List<Library> libraries; |
115 final List<Constant> constants; | 105 final List<Constant> constants; |
116 // TODO(floitsch): should we move static fields into libraries or classes? | 106 // TODO(floitsch): should we move static fields into libraries or classes? |
117 final List<StaticField> staticNonFinalFields; | 107 final List<StaticField> staticNonFinalFields; |
118 // TODO(floitsch): lazy fields should be in their library or even class. | 108 // TODO(floitsch): lazy fields should be in their library or even class. |
119 final List<StaticField> staticLazilyInitializedFields; | 109 final List<StaticField> staticLazilyInitializedFields; |
120 | 110 |
121 /// Output file name without extension. | 111 /// Output file name without extension. |
122 final String outputFileName; | 112 final String outputFileName; |
123 | 113 |
124 Fragment(this.outputUnit, | 114 Fragment( |
125 this.outputFileName, | 115 this.outputUnit, |
126 this.libraries, | 116 this.outputFileName, |
127 this.staticNonFinalFields, | 117 this.libraries, |
128 this.staticLazilyInitializedFields, | 118 this.staticNonFinalFields, |
129 this.constants); | 119 this.staticLazilyInitializedFields, |
| 120 this.constants); |
130 | 121 |
131 bool get isMainFragment; | 122 bool get isMainFragment; |
132 } | 123 } |
133 | 124 |
134 /** | 125 /** |
135 * The main output file. | 126 * The main output file. |
136 * | 127 * |
137 * This code emitted from this [Fragment] must be loaded first. It can then load | 128 * This code emitted from this [Fragment] must be loaded first. It can then load |
138 * other [DeferredFragment]s. | 129 * other [DeferredFragment]s. |
139 */ | 130 */ |
140 class MainFragment extends Fragment { | 131 class MainFragment extends Fragment { |
141 final js.Statement invokeMain; | 132 final js.Statement invokeMain; |
142 | 133 |
143 MainFragment(OutputUnit outputUnit, | 134 MainFragment( |
144 String outputFileName, | 135 OutputUnit outputUnit, |
145 this.invokeMain, | 136 String outputFileName, |
146 List<Library> libraries, | 137 this.invokeMain, |
147 List<StaticField> staticNonFinalFields, | 138 List<Library> libraries, |
148 List<StaticField> staticLazilyInitializedFields, | 139 List<StaticField> staticNonFinalFields, |
149 List<Constant> constants) | 140 List<StaticField> staticLazilyInitializedFields, |
150 : super(outputUnit, | 141 List<Constant> constants) |
151 outputFileName, | 142 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, |
152 libraries, | 143 staticLazilyInitializedFields, constants); |
153 staticNonFinalFields, | |
154 staticLazilyInitializedFields, | |
155 constants); | |
156 | 144 |
157 bool get isMainFragment => true; | 145 bool get isMainFragment => true; |
158 } | 146 } |
159 | 147 |
160 /** | 148 /** |
161 * An output (file) for deferred code. | 149 * An output (file) for deferred code. |
162 */ | 150 */ |
163 class DeferredFragment extends Fragment { | 151 class DeferredFragment extends Fragment { |
164 final String name; | 152 final String name; |
165 | 153 |
166 DeferredFragment(OutputUnit outputUnit, | 154 DeferredFragment( |
167 String outputFileName, | 155 OutputUnit outputUnit, |
168 this.name, | 156 String outputFileName, |
169 List<Library> libraries, | 157 this.name, |
170 List<StaticField> staticNonFinalFields, | 158 List<Library> libraries, |
171 List<StaticField> staticLazilyInitializedFields, | 159 List<StaticField> staticNonFinalFields, |
172 List<Constant> constants) | 160 List<StaticField> staticLazilyInitializedFields, |
173 : super(outputUnit, | 161 List<Constant> constants) |
174 outputFileName, | 162 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, |
175 libraries, | 163 staticLazilyInitializedFields, constants); |
176 staticNonFinalFields, | |
177 staticLazilyInitializedFields, | |
178 constants); | |
179 | 164 |
180 bool get isMainFragment => false; | 165 bool get isMainFragment => false; |
181 } | 166 } |
182 | 167 |
183 class Constant { | 168 class Constant { |
184 final js.Name name; | 169 final js.Name name; |
185 final Holder holder; | 170 final Holder holder; |
186 final ConstantValue value; | 171 final ConstantValue value; |
187 | 172 |
188 Constant(this.name, this.holder, this.value); | 173 Constant(this.name, this.holder, this.value); |
189 } | 174 } |
190 | 175 |
191 abstract class FieldContainer { | 176 abstract class FieldContainer { |
192 List<Field> get staticFieldsForReflection; | 177 List<Field> get staticFieldsForReflection; |
193 } | 178 } |
194 | 179 |
195 class Library implements FieldContainer { | 180 class Library implements FieldContainer { |
196 /// The element should only be used during the transition to the new model. | 181 /// The element should only be used during the transition to the new model. |
197 /// Uses indicate missing information in the model. | 182 /// Uses indicate missing information in the model. |
198 final Element element; | 183 final Element element; |
199 | 184 |
200 final String uri; | 185 final String uri; |
201 final List<StaticMethod> statics; | 186 final List<StaticMethod> statics; |
202 final List<Class> classes; | 187 final List<Class> classes; |
203 | 188 |
204 final List<Field> staticFieldsForReflection; | 189 final List<Field> staticFieldsForReflection; |
205 | 190 |
206 Library(this.element, this.uri, this.statics, this.classes, | 191 Library(this.element, this.uri, this.statics, this.classes, |
207 this.staticFieldsForReflection); | 192 this.staticFieldsForReflection); |
208 } | 193 } |
209 | 194 |
210 class StaticField { | 195 class StaticField { |
211 /// The element should only be used during the transition to the new model. | 196 /// The element should only be used during the transition to the new model. |
212 /// Uses indicate missing information in the model. | 197 /// Uses indicate missing information in the model. |
213 final Element element; | 198 final Element element; |
214 | 199 |
215 js.Name name; | 200 js.Name name; |
216 // TODO(floitsch): the holder for static fields is the isolate object. We | 201 // TODO(floitsch): the holder for static fields is the isolate object. We |
217 // could remove this field and use the isolate object directly. | 202 // could remove this field and use the isolate object directly. |
218 final Holder holder; | 203 final Holder holder; |
219 final js.Expression code; | 204 final js.Expression code; |
220 final bool isFinal; | 205 final bool isFinal; |
221 final bool isLazy; | 206 final bool isLazy; |
222 | 207 |
223 StaticField(this.element, | 208 StaticField(this.element, this.name, this.holder, this.code, this.isFinal, |
224 this.name, this.holder, this.code, | 209 this.isLazy); |
225 this.isFinal, this.isLazy); | |
226 } | 210 } |
227 | 211 |
228 class Class implements FieldContainer { | 212 class Class implements FieldContainer { |
229 /// The element should only be used during the transition to the new model. | 213 /// The element should only be used during the transition to the new model. |
230 /// Uses indicate missing information in the model. | 214 /// Uses indicate missing information in the model. |
231 final Element element; | 215 final Element element; |
232 | 216 |
233 final js.Name name; | 217 final js.Name name; |
234 final Holder holder; | 218 final Holder holder; |
235 Class _superclass; | 219 Class _superclass; |
(...skipping 24 matching lines...) Expand all Loading... |
260 | 244 |
261 /// Leaf tags. See [NativeEmitter.prepareNativeClasses]. | 245 /// Leaf tags. See [NativeEmitter.prepareNativeClasses]. |
262 List<String> nativeLeafTags; | 246 List<String> nativeLeafTags; |
263 | 247 |
264 /// Non-leaf tags. See [NativeEmitter.prepareNativeClasses]. | 248 /// Non-leaf tags. See [NativeEmitter.prepareNativeClasses]. |
265 List<String> nativeNonLeafTags; | 249 List<String> nativeNonLeafTags; |
266 | 250 |
267 /// Native extensions. See [NativeEmitter.prepareNativeClasses]. | 251 /// Native extensions. See [NativeEmitter.prepareNativeClasses]. |
268 List<Class> nativeExtensions; | 252 List<Class> nativeExtensions; |
269 | 253 |
270 Class(this.element, this.name, this.holder, | 254 Class( |
271 this.methods, | 255 this.element, |
272 this.fields, | 256 this.name, |
273 this.staticFieldsForReflection, | 257 this.holder, |
274 this.callStubs, | 258 this.methods, |
275 this.typeVariableReaderStubs, | 259 this.fields, |
276 this.noSuchMethodStubs, | 260 this.staticFieldsForReflection, |
277 this.checkedSetters, | 261 this.callStubs, |
278 this.isChecks, | 262 this.typeVariableReaderStubs, |
279 this.functionTypeIndex, | 263 this.noSuchMethodStubs, |
280 {this.onlyForRti, | 264 this.checkedSetters, |
281 this.isDirectlyInstantiated, | 265 this.isChecks, |
282 this.isNative}) { | 266 this.functionTypeIndex, |
| 267 {this.onlyForRti, |
| 268 this.isDirectlyInstantiated, |
| 269 this.isNative}) { |
283 assert(onlyForRti != null); | 270 assert(onlyForRti != null); |
284 assert(isDirectlyInstantiated != null); | 271 assert(isDirectlyInstantiated != null); |
285 assert(isNative != null); | 272 assert(isNative != null); |
286 } | 273 } |
287 | 274 |
288 bool get isMixinApplication => false; | 275 bool get isMixinApplication => false; |
289 Class get superclass => _superclass; | 276 Class get superclass => _superclass; |
290 | 277 |
291 void setSuperclass(Class superclass) { | 278 void setSuperclass(Class superclass) { |
292 _superclass = superclass; | 279 _superclass = superclass; |
293 } | 280 } |
294 | 281 |
295 js.Name get superclassName | 282 js.Name get superclassName => superclass == null ? null : superclass.name; |
296 => superclass == null ? null : superclass.name; | |
297 | 283 |
298 int get superclassHolderIndex | 284 int get superclassHolderIndex => |
299 => (superclass == null) ? 0 : superclass.holder.index; | 285 (superclass == null) ? 0 : superclass.holder.index; |
300 } | 286 } |
301 | 287 |
302 class MixinApplication extends Class { | 288 class MixinApplication extends Class { |
303 Class _mixinClass; | 289 Class _mixinClass; |
304 | 290 |
305 MixinApplication(Element element, js.Name name, Holder holder, | 291 MixinApplication( |
306 List<Field> instanceFields, | 292 Element element, |
307 List<Field> staticFieldsForReflection, | 293 js.Name name, |
308 List<StubMethod> callStubs, | 294 Holder holder, |
309 List<StubMethod> typeVariableReaderStubs, | 295 List<Field> instanceFields, |
310 List<StubMethod> checkedSetters, | 296 List<Field> staticFieldsForReflection, |
311 List<StubMethod> isChecks, | 297 List<StubMethod> callStubs, |
312 js.Expression functionTypeIndex, | 298 List<StubMethod> typeVariableReaderStubs, |
313 {bool onlyForRti, | 299 List<StubMethod> checkedSetters, |
314 bool isDirectlyInstantiated}) | 300 List<StubMethod> isChecks, |
315 : super(element, | 301 js.Expression functionTypeIndex, |
316 name, holder, | 302 {bool onlyForRti, |
317 const <Method>[], | 303 bool isDirectlyInstantiated}) |
318 instanceFields, | 304 : super( |
319 staticFieldsForReflection, | 305 element, |
320 callStubs, | 306 name, |
321 typeVariableReaderStubs, | 307 holder, |
322 const <StubMethod>[], | 308 const <Method>[], |
323 checkedSetters, | 309 instanceFields, |
324 isChecks, | 310 staticFieldsForReflection, |
325 functionTypeIndex, | 311 callStubs, |
326 onlyForRti: onlyForRti, | 312 typeVariableReaderStubs, |
327 isDirectlyInstantiated: isDirectlyInstantiated, | 313 const <StubMethod>[], |
328 isNative: false); | 314 checkedSetters, |
| 315 isChecks, |
| 316 functionTypeIndex, |
| 317 onlyForRti: onlyForRti, |
| 318 isDirectlyInstantiated: isDirectlyInstantiated, |
| 319 isNative: false); |
329 | 320 |
330 bool get isMixinApplication => true; | 321 bool get isMixinApplication => true; |
331 Class get mixinClass => _mixinClass; | 322 Class get mixinClass => _mixinClass; |
332 | 323 |
333 void setMixinClass(Class mixinClass) { | 324 void setMixinClass(Class mixinClass) { |
334 _mixinClass = mixinClass; | 325 _mixinClass = mixinClass; |
335 } | 326 } |
336 } | 327 } |
337 | 328 |
338 /// A field. | 329 /// A field. |
(...skipping 16 matching lines...) Expand all Loading... |
355 | 346 |
356 /// 00: Does not need any setter. | 347 /// 00: Does not need any setter. |
357 /// 01: function(value) { this.field = value; } | 348 /// 01: function(value) { this.field = value; } |
358 /// 10: function(receiver, value) { receiver.field = value; } | 349 /// 10: function(receiver, value) { receiver.field = value; } |
359 /// 11: function(receiver, value) { this.field = value; } | 350 /// 11: function(receiver, value) { this.field = value; } |
360 final int setterFlags; | 351 final int setterFlags; |
361 | 352 |
362 final bool needsCheckedSetter; | 353 final bool needsCheckedSetter; |
363 | 354 |
364 // TODO(floitsch): support renamed fields. | 355 // TODO(floitsch): support renamed fields. |
365 Field(this.element, this.name, this.accessorName, | 356 Field(this.element, this.name, this.accessorName, this.getterFlags, |
366 this.getterFlags, this.setterFlags, | 357 this.setterFlags, this.needsCheckedSetter); |
367 this.needsCheckedSetter); | |
368 | 358 |
369 bool get needsGetter => getterFlags != 0; | 359 bool get needsGetter => getterFlags != 0; |
370 bool get needsUncheckedSetter => setterFlags != 0; | 360 bool get needsUncheckedSetter => setterFlags != 0; |
371 | 361 |
372 bool get needsInterceptedGetter => getterFlags > 1; | 362 bool get needsInterceptedGetter => getterFlags > 1; |
373 bool get needsInterceptedSetter => setterFlags > 1; | 363 bool get needsInterceptedSetter => setterFlags > 1; |
374 | 364 |
375 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; | 365 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; |
376 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; | 366 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; |
377 | 367 |
378 bool get needsInterceptedGetterOnThis => getterFlags == 3; | 368 bool get needsInterceptedGetterOnThis => getterFlags == 3; |
379 bool get needsInterceptedSetterOnThis => setterFlags == 3; | 369 bool get needsInterceptedSetterOnThis => setterFlags == 3; |
380 } | 370 } |
381 | 371 |
382 abstract class Method { | 372 abstract class Method { |
383 /// The element should only be used during the transition to the new model. | 373 /// The element should only be used during the transition to the new model. |
384 /// Uses indicate missing information in the model. | 374 /// Uses indicate missing information in the model. |
385 final Element element; | 375 final Element element; |
| 376 |
386 /// The name of the method. If the method is a [ParameterStubMethod] for a | 377 /// The name of the method. If the method is a [ParameterStubMethod] for a |
387 /// static function, then the name can be `null`. In that case, only the | 378 /// static function, then the name can be `null`. In that case, only the |
388 /// [ParameterStubMethod.callName] should be used. | 379 /// [ParameterStubMethod.callName] should be used. |
389 final js.Name name; | 380 final js.Name name; |
390 final js.Expression code; | 381 final js.Expression code; |
391 | 382 |
392 Method(this.element, this.name, this.code); | 383 Method(this.element, this.name, this.code); |
393 } | 384 } |
394 | 385 |
395 /// A method that corresponds to a method in the original Dart program. | 386 /// A method that corresponds to a method in the original Dart program. |
(...skipping 15 matching lines...) Expand all Loading... |
411 // here if the method [canBeApplied] or [canBeReflected] | 402 // here if the method [canBeApplied] or [canBeReflected] |
412 final int requiredParameterCount; | 403 final int requiredParameterCount; |
413 final /* Map | List */ optionalParameterDefaultValues; | 404 final /* Map | List */ optionalParameterDefaultValues; |
414 | 405 |
415 // If this method can be torn off, contains the name of the corresponding | 406 // If this method can be torn off, contains the name of the corresponding |
416 // call method. For example, for the member `foo$1$name` it would be | 407 // call method. For example, for the member `foo$1$name` it would be |
417 // `call$1$name` (in unminified mode). | 408 // `call$1$name` (in unminified mode). |
418 final js.Name callName; | 409 final js.Name callName; |
419 | 410 |
420 DartMethod(Element element, js.Name name, js.Expression code, | 411 DartMethod(Element element, js.Name name, js.Expression code, |
421 this.parameterStubs, this.callName, | 412 this.parameterStubs, this.callName, |
422 {this.needsTearOff, this.tearOffName, this.canBeApplied, | 413 {this.needsTearOff, |
423 this.canBeReflected, this.requiredParameterCount, | 414 this.tearOffName, |
424 this.optionalParameterDefaultValues, this.functionType}) | 415 this.canBeApplied, |
| 416 this.canBeReflected, |
| 417 this.requiredParameterCount, |
| 418 this.optionalParameterDefaultValues, |
| 419 this.functionType}) |
425 : super(element, name, code) { | 420 : super(element, name, code) { |
426 assert(needsTearOff != null); | 421 assert(needsTearOff != null); |
427 assert(!needsTearOff || tearOffName != null); | 422 assert(!needsTearOff || tearOffName != null); |
428 assert(canBeApplied != null); | 423 assert(canBeApplied != null); |
429 assert(canBeReflected != null); | 424 assert(canBeReflected != null); |
430 assert((!canBeReflected && !canBeApplied) || | 425 assert((!canBeReflected && !canBeApplied) || |
431 (requiredParameterCount != null && | 426 (requiredParameterCount != null && |
432 optionalParameterDefaultValues != null)); | 427 optionalParameterDefaultValues != null)); |
433 } | 428 } |
434 | 429 |
435 bool get isStatic; | 430 bool get isStatic; |
436 } | 431 } |
437 | 432 |
438 class InstanceMethod extends DartMethod { | 433 class InstanceMethod extends DartMethod { |
439 /// An alternative name for this method. This is used to model calls to | 434 /// An alternative name for this method. This is used to model calls to |
440 /// a method via `super`. If [aliasName] is non-null, the emitter has to | 435 /// a method via `super`. If [aliasName] is non-null, the emitter has to |
441 /// ensure that this method is registered on the prototype under both [name] | 436 /// ensure that this method is registered on the prototype under both [name] |
442 /// and [aliasName]. | 437 /// and [aliasName]. |
443 final js.Name aliasName; | 438 final js.Name aliasName; |
444 | 439 |
445 /// True if this is the implicit `call` instance method of an anonymous | 440 /// True if this is the implicit `call` instance method of an anonymous |
446 /// closure. This predicate is false for explicit `call` methods and for | 441 /// closure. This predicate is false for explicit `call` methods and for |
447 /// functions that can be torn off. | 442 /// functions that can be torn off. |
448 final bool isClosureCallMethod; | 443 final bool isClosureCallMethod; |
449 | 444 |
450 | |
451 InstanceMethod(Element element, js.Name name, js.Expression code, | 445 InstanceMethod(Element element, js.Name name, js.Expression code, |
452 List<ParameterStubMethod> parameterStubs, | 446 List<ParameterStubMethod> parameterStubs, js.Name callName, |
453 js.Name callName, | 447 {bool needsTearOff, |
454 {bool needsTearOff, | 448 js.Name tearOffName, |
455 js.Name tearOffName, | 449 this.aliasName, |
456 this.aliasName, | 450 bool canBeApplied, |
457 bool canBeApplied, | 451 bool canBeReflected, |
458 bool canBeReflected, | 452 int requiredParameterCount, |
459 int requiredParameterCount, | 453 /* List | Map */ optionalParameterDefaultValues, |
460 /* List | Map */ optionalParameterDefaultValues, | 454 this.isClosureCallMethod, |
461 this.isClosureCallMethod, | 455 js.Expression functionType}) |
462 js.Expression functionType}) | |
463 : super(element, name, code, parameterStubs, callName, | 456 : super(element, name, code, parameterStubs, callName, |
464 needsTearOff: needsTearOff, | 457 needsTearOff: needsTearOff, |
465 tearOffName: tearOffName, | 458 tearOffName: tearOffName, |
466 canBeApplied: canBeApplied, | 459 canBeApplied: canBeApplied, |
467 canBeReflected: canBeReflected, | 460 canBeReflected: canBeReflected, |
468 requiredParameterCount: requiredParameterCount, | 461 requiredParameterCount: requiredParameterCount, |
469 optionalParameterDefaultValues: optionalParameterDefaultValues, | 462 optionalParameterDefaultValues: optionalParameterDefaultValues, |
470 functionType: functionType) { | 463 functionType: functionType) { |
471 assert(isClosureCallMethod != null); | 464 assert(isClosureCallMethod != null); |
472 } | 465 } |
473 | 466 |
474 bool get isStatic => false; | 467 bool get isStatic => false; |
475 } | 468 } |
476 | 469 |
477 /// A method that is generated by the backend and has not direct correspondence | 470 /// A method that is generated by the backend and has not direct correspondence |
478 /// to a method in the original Dart program. Examples are getter and setter | 471 /// to a method in the original Dart program. Examples are getter and setter |
479 /// stubs and stubs to dispatch calls to methods with optional parameters. | 472 /// stubs and stubs to dispatch calls to methods with optional parameters. |
480 class StubMethod extends Method { | 473 class StubMethod extends Method { |
481 StubMethod(js.Name name, js.Expression code, | 474 StubMethod(js.Name name, js.Expression code, {Element element}) |
482 {Element element}) | |
483 : super(element, name, code); | 475 : super(element, name, code); |
484 } | 476 } |
485 | 477 |
486 /// A stub that adapts and redirects to the main method (the one containing) | 478 /// A stub that adapts and redirects to the main method (the one containing) |
487 /// the actual code. | 479 /// the actual code. |
488 /// | 480 /// |
489 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter | 481 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter |
490 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. | 482 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. |
491 /// | 483 /// |
492 /// ParameterStubMethods are always attached to (static or instance) methods. | 484 /// ParameterStubMethods are always attached to (static or instance) methods. |
(...skipping 11 matching lines...) Expand all Loading... |
504 : super(name, code); | 496 : super(name, code); |
505 } | 497 } |
506 | 498 |
507 abstract class StaticMethod implements Method { | 499 abstract class StaticMethod implements Method { |
508 Holder get holder; | 500 Holder get holder; |
509 } | 501 } |
510 | 502 |
511 class StaticDartMethod extends DartMethod implements StaticMethod { | 503 class StaticDartMethod extends DartMethod implements StaticMethod { |
512 final Holder holder; | 504 final Holder holder; |
513 | 505 |
514 StaticDartMethod(Element element, js.Name name, this.holder, | 506 StaticDartMethod( |
515 js.Expression code, List<ParameterStubMethod> parameterStubs, | 507 Element element, |
516 js.Name callName, | 508 js.Name name, |
517 {bool needsTearOff, js.Name tearOffName, | 509 this.holder, |
518 bool canBeApplied, bool canBeReflected, | 510 js.Expression code, |
519 int requiredParameterCount, | 511 List<ParameterStubMethod> parameterStubs, |
520 /* List | Map */ optionalParameterDefaultValues, | 512 js.Name callName, |
521 js.Expression functionType}) | 513 {bool needsTearOff, |
| 514 js.Name tearOffName, |
| 515 bool canBeApplied, |
| 516 bool canBeReflected, |
| 517 int requiredParameterCount, |
| 518 /* List | Map */ optionalParameterDefaultValues, |
| 519 js.Expression functionType}) |
522 : super(element, name, code, parameterStubs, callName, | 520 : super(element, name, code, parameterStubs, callName, |
523 needsTearOff: needsTearOff, | 521 needsTearOff: needsTearOff, |
524 tearOffName : tearOffName, | 522 tearOffName: tearOffName, |
525 canBeApplied : canBeApplied, | 523 canBeApplied: canBeApplied, |
526 canBeReflected : canBeReflected, | 524 canBeReflected: canBeReflected, |
527 requiredParameterCount: requiredParameterCount, | 525 requiredParameterCount: requiredParameterCount, |
528 optionalParameterDefaultValues: optionalParameterDefaultValues, | 526 optionalParameterDefaultValues: optionalParameterDefaultValues, |
529 functionType: functionType); | 527 functionType: functionType); |
530 | 528 |
531 bool get isStatic => true; | 529 bool get isStatic => true; |
532 } | 530 } |
533 | 531 |
534 class StaticStubMethod extends StubMethod implements StaticMethod { | 532 class StaticStubMethod extends StubMethod implements StaticMethod { |
535 Holder holder; | 533 Holder holder; |
536 StaticStubMethod(js.Name name, this.holder, js.Expression code) | 534 StaticStubMethod(js.Name name, this.holder, js.Expression code) |
537 : super(name, code); | 535 : super(name, code); |
538 } | 536 } |
OLD | NEW |