| 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 |