| 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 ConstantValue; | 7 import '../constants/values.dart' show ConstantValue; |
| 8 import '../deferred_load.dart' show OutputUnit; | 8 import '../deferred_load.dart' show OutputUnit; |
| 9 import '../elements/elements.dart' show Element, FieldElement; | 9 import '../elements/entities.dart'; |
| 10 import '../js/js.dart' as js show Expression, Name, Statement, TokenFinalizer; | 10 import '../js/js.dart' as js show Expression, Name, Statement, TokenFinalizer; |
| 11 import 'js_emitter.dart' show MetadataCollector; | 11 import 'js_emitter.dart' show MetadataCollector; |
| 12 | 12 |
| 13 class Program { | 13 class Program { |
| 14 final List<Fragment> fragments; | 14 final List<Fragment> fragments; |
| 15 final List<Holder> holders; | 15 final List<Holder> holders; |
| 16 final bool outputContainsConstantList; | 16 final bool outputContainsConstantList; |
| 17 final bool needsNativeSupport; | 17 final bool needsNativeSupport; |
| 18 final bool hasIsolateSupport; | 18 final bool hasIsolateSupport; |
| 19 | 19 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 Constant(this.name, this.holder, this.value); | 171 Constant(this.name, this.holder, this.value); |
| 172 } | 172 } |
| 173 | 173 |
| 174 abstract class FieldContainer { | 174 abstract class FieldContainer { |
| 175 List<Field> get staticFieldsForReflection; | 175 List<Field> get staticFieldsForReflection; |
| 176 } | 176 } |
| 177 | 177 |
| 178 class Library implements FieldContainer { | 178 class Library implements FieldContainer { |
| 179 /// The element should only be used during the transition to the new model. | 179 /// The element should only be used during the transition to the new model. |
| 180 /// Uses indicate missing information in the model. | 180 /// Uses indicate missing information in the model. |
| 181 final Element element; | 181 final LibraryEntity element; |
| 182 | 182 |
| 183 final String uri; | 183 final String uri; |
| 184 final List<StaticMethod> statics; | 184 final List<StaticMethod> statics; |
| 185 final List<Class> classes; | 185 final List<Class> classes; |
| 186 | 186 |
| 187 final List<Field> staticFieldsForReflection; | 187 final List<Field> staticFieldsForReflection; |
| 188 | 188 |
| 189 Library(this.element, this.uri, this.statics, this.classes, | 189 Library(this.element, this.uri, this.statics, this.classes, |
| 190 this.staticFieldsForReflection); | 190 this.staticFieldsForReflection); |
| 191 } | 191 } |
| 192 | 192 |
| 193 class StaticField { | 193 class StaticField { |
| 194 /// The element should only be used during the transition to the new model. | 194 /// The element should only be used during the transition to the new model. |
| 195 /// Uses indicate missing information in the model. | 195 /// Uses indicate missing information in the model. |
| 196 final Element element; | 196 final FieldEntity element; |
| 197 | 197 |
| 198 js.Name name; | 198 js.Name name; |
| 199 // TODO(floitsch): the holder for static fields is the isolate object. We | 199 // TODO(floitsch): the holder for static fields is the isolate object. We |
| 200 // could remove this field and use the isolate object directly. | 200 // could remove this field and use the isolate object directly. |
| 201 final Holder holder; | 201 final Holder holder; |
| 202 final js.Expression code; | 202 final js.Expression code; |
| 203 final bool isFinal; | 203 final bool isFinal; |
| 204 final bool isLazy; | 204 final bool isLazy; |
| 205 | 205 |
| 206 StaticField(this.element, this.name, this.holder, this.code, this.isFinal, | 206 StaticField(this.element, this.name, this.holder, this.code, this.isFinal, |
| 207 this.isLazy); | 207 this.isLazy); |
| 208 } | 208 } |
| 209 | 209 |
| 210 class Class implements FieldContainer { | 210 class Class implements FieldContainer { |
| 211 /// The element should only be used during the transition to the new model. | 211 /// The element should only be used during the transition to the new model. |
| 212 /// Uses indicate missing information in the model. | 212 /// Uses indicate missing information in the model. |
| 213 final Element element; | 213 final ClassEntity element; |
| 214 | 214 |
| 215 final js.Name name; | 215 final js.Name name; |
| 216 final Holder holder; | 216 final Holder holder; |
| 217 Class _superclass; | 217 Class _superclass; |
| 218 final List<Method> methods; | 218 final List<Method> methods; |
| 219 final List<Field> fields; | 219 final List<Field> fields; |
| 220 final List<StubMethod> isChecks; | 220 final List<StubMethod> isChecks; |
| 221 final List<StubMethod> checkedSetters; | 221 final List<StubMethod> checkedSetters; |
| 222 | 222 |
| 223 /// Stub methods for this class that are call stubs for getters. | 223 /// Stub methods for this class that are call stubs for getters. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 js.Name get superclassName => superclass == null ? null : superclass.name; | 282 js.Name get superclassName => superclass == null ? null : superclass.name; |
| 283 | 283 |
| 284 int get superclassHolderIndex => | 284 int get superclassHolderIndex => |
| 285 (superclass == null) ? 0 : superclass.holder.index; | 285 (superclass == null) ? 0 : superclass.holder.index; |
| 286 } | 286 } |
| 287 | 287 |
| 288 class MixinApplication extends Class { | 288 class MixinApplication extends Class { |
| 289 Class _mixinClass; | 289 Class _mixinClass; |
| 290 | 290 |
| 291 MixinApplication( | 291 MixinApplication( |
| 292 Element element, | 292 ClassEntity element, |
| 293 js.Name name, | 293 js.Name name, |
| 294 Holder holder, | 294 Holder holder, |
| 295 List<Field> instanceFields, | 295 List<Field> instanceFields, |
| 296 List<Field> staticFieldsForReflection, | 296 List<Field> staticFieldsForReflection, |
| 297 List<StubMethod> callStubs, | 297 List<StubMethod> callStubs, |
| 298 List<StubMethod> typeVariableReaderStubs, | 298 List<StubMethod> typeVariableReaderStubs, |
| 299 List<StubMethod> checkedSetters, | 299 List<StubMethod> checkedSetters, |
| 300 List<StubMethod> isChecks, | 300 List<StubMethod> isChecks, |
| 301 js.Expression functionTypeIndex, | 301 js.Expression functionTypeIndex, |
| 302 {bool hasRtiField, | 302 {bool hasRtiField, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 328 } | 328 } |
| 329 } | 329 } |
| 330 | 330 |
| 331 /// A field. | 331 /// A field. |
| 332 /// | 332 /// |
| 333 /// In general represents an instance field, but for reflection may also | 333 /// In general represents an instance field, but for reflection may also |
| 334 /// represent static fields. | 334 /// represent static fields. |
| 335 class Field { | 335 class Field { |
| 336 /// The element should only be used during the transition to the new model. | 336 /// The element should only be used during the transition to the new model. |
| 337 /// Uses indicate missing information in the model. | 337 /// Uses indicate missing information in the model. |
| 338 final FieldElement element; | 338 final FieldEntity element; |
| 339 | 339 |
| 340 final js.Name name; | 340 final js.Name name; |
| 341 final js.Name accessorName; | 341 final js.Name accessorName; |
| 342 | 342 |
| 343 /// 00: Does not need any getter. | 343 /// 00: Does not need any getter. |
| 344 /// 01: function() { return this.field; } | 344 /// 01: function() { return this.field; } |
| 345 /// 10: function(receiver) { return receiver.field; } | 345 /// 10: function(receiver) { return receiver.field; } |
| 346 /// 11: function(receiver) { return this.field; } | 346 /// 11: function(receiver) { return this.field; } |
| 347 final int getterFlags; | 347 final int getterFlags; |
| 348 | 348 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 367 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; | 367 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; |
| 368 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; | 368 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; |
| 369 | 369 |
| 370 bool get needsInterceptedGetterOnThis => getterFlags == 3; | 370 bool get needsInterceptedGetterOnThis => getterFlags == 3; |
| 371 bool get needsInterceptedSetterOnThis => setterFlags == 3; | 371 bool get needsInterceptedSetterOnThis => setterFlags == 3; |
| 372 } | 372 } |
| 373 | 373 |
| 374 abstract class Method { | 374 abstract class Method { |
| 375 /// The element should only be used during the transition to the new model. | 375 /// The element should only be used during the transition to the new model. |
| 376 /// Uses indicate missing information in the model. | 376 /// Uses indicate missing information in the model. |
| 377 final Element element; | 377 final MemberEntity element; |
| 378 | 378 |
| 379 /// The name of the method. If the method is a [ParameterStubMethod] for a | 379 /// The name of the method. If the method is a [ParameterStubMethod] for a |
| 380 /// static function, then the name can be `null`. In that case, only the | 380 /// static function, then the name can be `null`. In that case, only the |
| 381 /// [ParameterStubMethod.callName] should be used. | 381 /// [ParameterStubMethod.callName] should be used. |
| 382 final js.Name name; | 382 final js.Name name; |
| 383 final js.Expression code; | 383 final js.Expression code; |
| 384 | 384 |
| 385 Method(this.element, this.name, this.code); | 385 Method(this.element, this.name, this.code); |
| 386 } | 386 } |
| 387 | 387 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 403 // Signature information for this method. This is only required and stored | 403 // Signature information for this method. This is only required and stored |
| 404 // here if the method [canBeApplied] or [canBeReflected] | 404 // here if the method [canBeApplied] or [canBeReflected] |
| 405 final int requiredParameterCount; | 405 final int requiredParameterCount; |
| 406 final /* Map | List */ optionalParameterDefaultValues; | 406 final /* Map | List */ optionalParameterDefaultValues; |
| 407 | 407 |
| 408 // If this method can be torn off, contains the name of the corresponding | 408 // If this method can be torn off, contains the name of the corresponding |
| 409 // call method. For example, for the member `foo$1$name` it would be | 409 // call method. For example, for the member `foo$1$name` it would be |
| 410 // `call$1$name` (in unminified mode). | 410 // `call$1$name` (in unminified mode). |
| 411 final js.Name callName; | 411 final js.Name callName; |
| 412 | 412 |
| 413 DartMethod(Element element, js.Name name, js.Expression code, | 413 DartMethod(FunctionEntity element, js.Name name, js.Expression code, |
| 414 this.parameterStubs, this.callName, | 414 this.parameterStubs, this.callName, |
| 415 {this.needsTearOff, | 415 {this.needsTearOff, |
| 416 this.tearOffName, | 416 this.tearOffName, |
| 417 this.canBeApplied, | 417 this.canBeApplied, |
| 418 this.canBeReflected, | 418 this.canBeReflected, |
| 419 this.requiredParameterCount, | 419 this.requiredParameterCount, |
| 420 this.optionalParameterDefaultValues, | 420 this.optionalParameterDefaultValues, |
| 421 this.functionType}) | 421 this.functionType}) |
| 422 : super(element, name, code) { | 422 : super(element, name, code) { |
| 423 assert(needsTearOff != null); | 423 assert(needsTearOff != null); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 437 /// a method via `super`. If [aliasName] is non-null, the emitter has to | 437 /// a method via `super`. If [aliasName] is non-null, the emitter has to |
| 438 /// ensure that this method is registered on the prototype under both [name] | 438 /// ensure that this method is registered on the prototype under both [name] |
| 439 /// and [aliasName]. | 439 /// and [aliasName]. |
| 440 final js.Name aliasName; | 440 final js.Name aliasName; |
| 441 | 441 |
| 442 /// True if this is the implicit `call` instance method of an anonymous | 442 /// True if this is the implicit `call` instance method of an anonymous |
| 443 /// closure. This predicate is false for explicit `call` methods and for | 443 /// closure. This predicate is false for explicit `call` methods and for |
| 444 /// functions that can be torn off. | 444 /// functions that can be torn off. |
| 445 final bool isClosureCallMethod; | 445 final bool isClosureCallMethod; |
| 446 | 446 |
| 447 InstanceMethod(Element element, js.Name name, js.Expression code, | 447 InstanceMethod(FunctionEntity element, js.Name name, js.Expression code, |
| 448 List<ParameterStubMethod> parameterStubs, js.Name callName, | 448 List<ParameterStubMethod> parameterStubs, js.Name callName, |
| 449 {bool needsTearOff, | 449 {bool needsTearOff, |
| 450 js.Name tearOffName, | 450 js.Name tearOffName, |
| 451 this.aliasName, | 451 this.aliasName, |
| 452 bool canBeApplied, | 452 bool canBeApplied, |
| 453 bool canBeReflected, | 453 bool canBeReflected, |
| 454 int requiredParameterCount, | 454 int requiredParameterCount, |
| 455 /* List | Map */ optionalParameterDefaultValues, | 455 /* List | Map */ optionalParameterDefaultValues, |
| 456 this.isClosureCallMethod, | 456 this.isClosureCallMethod, |
| 457 js.Expression functionType}) | 457 js.Expression functionType}) |
| 458 : super(element, name, code, parameterStubs, callName, | 458 : super(element, name, code, parameterStubs, callName, |
| 459 needsTearOff: needsTearOff, | 459 needsTearOff: needsTearOff, |
| 460 tearOffName: tearOffName, | 460 tearOffName: tearOffName, |
| 461 canBeApplied: canBeApplied, | 461 canBeApplied: canBeApplied, |
| 462 canBeReflected: canBeReflected, | 462 canBeReflected: canBeReflected, |
| 463 requiredParameterCount: requiredParameterCount, | 463 requiredParameterCount: requiredParameterCount, |
| 464 optionalParameterDefaultValues: optionalParameterDefaultValues, | 464 optionalParameterDefaultValues: optionalParameterDefaultValues, |
| 465 functionType: functionType) { | 465 functionType: functionType) { |
| 466 assert(isClosureCallMethod != null); | 466 assert(isClosureCallMethod != null); |
| 467 } | 467 } |
| 468 | 468 |
| 469 bool get isStatic => false; | 469 bool get isStatic => false; |
| 470 } | 470 } |
| 471 | 471 |
| 472 /// A method that is generated by the backend and has not direct correspondence | 472 /// A method that is generated by the backend and has not direct correspondence |
| 473 /// to a method in the original Dart program. Examples are getter and setter | 473 /// to a method in the original Dart program. Examples are getter and setter |
| 474 /// stubs and stubs to dispatch calls to methods with optional parameters. | 474 /// stubs and stubs to dispatch calls to methods with optional parameters. |
| 475 class StubMethod extends Method { | 475 class StubMethod extends Method { |
| 476 StubMethod(js.Name name, js.Expression code, {Element element}) | 476 StubMethod(js.Name name, js.Expression code, {MemberEntity element}) |
| 477 : super(element, name, code); | 477 : super(element, name, code); |
| 478 } | 478 } |
| 479 | 479 |
| 480 /// A stub that adapts and redirects to the main method (the one containing) | 480 /// A stub that adapts and redirects to the main method (the one containing) |
| 481 /// the actual code. | 481 /// the actual code. |
| 482 /// | 482 /// |
| 483 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter | 483 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter |
| 484 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. | 484 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. |
| 485 /// | 485 /// |
| 486 /// ParameterStubMethods are always attached to (static or instance) methods. | 486 /// ParameterStubMethods are always attached to (static or instance) methods. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 499 } | 499 } |
| 500 | 500 |
| 501 abstract class StaticMethod implements Method { | 501 abstract class StaticMethod implements Method { |
| 502 Holder get holder; | 502 Holder get holder; |
| 503 } | 503 } |
| 504 | 504 |
| 505 class StaticDartMethod extends DartMethod implements StaticMethod { | 505 class StaticDartMethod extends DartMethod implements StaticMethod { |
| 506 final Holder holder; | 506 final Holder holder; |
| 507 | 507 |
| 508 StaticDartMethod( | 508 StaticDartMethod( |
| 509 Element element, | 509 FunctionEntity element, |
| 510 js.Name name, | 510 js.Name name, |
| 511 this.holder, | 511 this.holder, |
| 512 js.Expression code, | 512 js.Expression code, |
| 513 List<ParameterStubMethod> parameterStubs, | 513 List<ParameterStubMethod> parameterStubs, |
| 514 js.Name callName, | 514 js.Name callName, |
| 515 {bool needsTearOff, | 515 {bool needsTearOff, |
| 516 js.Name tearOffName, | 516 js.Name tearOffName, |
| 517 bool canBeApplied, | 517 bool canBeApplied, |
| 518 bool canBeReflected, | 518 bool canBeReflected, |
| 519 int requiredParameterCount, | 519 int requiredParameterCount, |
| 520 /* List | Map */ optionalParameterDefaultValues, | 520 /* List | Map */ optionalParameterDefaultValues, |
| 521 js.Expression functionType}) | 521 js.Expression functionType}) |
| 522 : super(element, name, code, parameterStubs, callName, | 522 : super(element, name, code, parameterStubs, callName, |
| 523 needsTearOff: needsTearOff, | 523 needsTearOff: needsTearOff, |
| 524 tearOffName: tearOffName, | 524 tearOffName: tearOffName, |
| 525 canBeApplied: canBeApplied, | 525 canBeApplied: canBeApplied, |
| 526 canBeReflected: canBeReflected, | 526 canBeReflected: canBeReflected, |
| 527 requiredParameterCount: requiredParameterCount, | 527 requiredParameterCount: requiredParameterCount, |
| 528 optionalParameterDefaultValues: optionalParameterDefaultValues, | 528 optionalParameterDefaultValues: optionalParameterDefaultValues, |
| 529 functionType: functionType); | 529 functionType: functionType); |
| 530 | 530 |
| 531 bool get isStatic => true; | 531 bool get isStatic => true; |
| 532 } | 532 } |
| 533 | 533 |
| 534 class StaticStubMethod extends StubMethod implements StaticMethod { | 534 class StaticStubMethod extends StubMethod implements StaticMethod { |
| 535 Holder holder; | 535 Holder holder; |
| 536 StaticStubMethod(js.Name name, this.holder, js.Expression code) | 536 StaticStubMethod(js.Name name, this.holder, js.Expression code) |
| 537 : super(name, code); | 537 : super(name, code); |
| 538 } | 538 } |
| OLD | NEW |