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/entities.dart'; | 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; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 * classes or functions. | 82 * classes or functions. |
83 */ | 83 */ |
84 class Holder { | 84 class Holder { |
85 final String name; | 85 final String name; |
86 final int index; | 86 final int index; |
87 final bool isStaticStateHolder; | 87 final bool isStaticStateHolder; |
88 final bool isConstantsHolder; | 88 final bool isConstantsHolder; |
89 | 89 |
90 Holder(this.name, this.index, | 90 Holder(this.name, this.index, |
91 {this.isStaticStateHolder: false, this.isConstantsHolder: false}); | 91 {this.isStaticStateHolder: false, this.isConstantsHolder: false}); |
| 92 |
| 93 String toString() { |
| 94 return 'Holder(name=${name})'; |
| 95 } |
92 } | 96 } |
93 | 97 |
94 /** | 98 /** |
95 * This class represents one output file. | 99 * This class represents one output file. |
96 * | 100 * |
97 * If no library is deferred, there is only one [Fragment] of type | 101 * If no library is deferred, there is only one [Fragment] of type |
98 * [MainFragment]. | 102 * [MainFragment]. |
99 */ | 103 */ |
100 abstract class Fragment { | 104 abstract class Fragment { |
101 /// The outputUnit should only be used during the transition to the new model. | 105 /// The outputUnit should only be used during the transition to the new model. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 String outputFileName, | 141 String outputFileName, |
138 this.invokeMain, | 142 this.invokeMain, |
139 List<Library> libraries, | 143 List<Library> libraries, |
140 List<StaticField> staticNonFinalFields, | 144 List<StaticField> staticNonFinalFields, |
141 List<StaticField> staticLazilyInitializedFields, | 145 List<StaticField> staticLazilyInitializedFields, |
142 List<Constant> constants) | 146 List<Constant> constants) |
143 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, | 147 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, |
144 staticLazilyInitializedFields, constants); | 148 staticLazilyInitializedFields, constants); |
145 | 149 |
146 bool get isMainFragment => true; | 150 bool get isMainFragment => true; |
| 151 |
| 152 String toString() { |
| 153 return 'MainFragment()'; |
| 154 } |
147 } | 155 } |
148 | 156 |
149 /** | 157 /** |
150 * An output (file) for deferred code. | 158 * An output (file) for deferred code. |
151 */ | 159 */ |
152 class DeferredFragment extends Fragment { | 160 class DeferredFragment extends Fragment { |
153 final String name; | 161 final String name; |
154 | 162 |
155 DeferredFragment( | 163 DeferredFragment( |
156 OutputUnit outputUnit, | 164 OutputUnit outputUnit, |
157 String outputFileName, | 165 String outputFileName, |
158 this.name, | 166 this.name, |
159 List<Library> libraries, | 167 List<Library> libraries, |
160 List<StaticField> staticNonFinalFields, | 168 List<StaticField> staticNonFinalFields, |
161 List<StaticField> staticLazilyInitializedFields, | 169 List<StaticField> staticLazilyInitializedFields, |
162 List<Constant> constants) | 170 List<Constant> constants) |
163 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, | 171 : super(outputUnit, outputFileName, libraries, staticNonFinalFields, |
164 staticLazilyInitializedFields, constants); | 172 staticLazilyInitializedFields, constants); |
165 | 173 |
166 bool get isMainFragment => false; | 174 bool get isMainFragment => false; |
| 175 |
| 176 String toString() { |
| 177 return 'DeferredFragment(name=${name})'; |
| 178 } |
167 } | 179 } |
168 | 180 |
169 class Constant { | 181 class Constant { |
170 final js.Name name; | 182 final js.Name name; |
171 final Holder holder; | 183 final Holder holder; |
172 final ConstantValue value; | 184 final ConstantValue value; |
173 | 185 |
174 Constant(this.name, this.holder, this.value); | 186 Constant(this.name, this.holder, this.value); |
| 187 |
| 188 String toString() { |
| 189 return 'Constant(name=${name},value=${value.toStructuredText()})'; |
| 190 } |
175 } | 191 } |
176 | 192 |
177 abstract class FieldContainer { | 193 abstract class FieldContainer { |
178 List<Field> get staticFieldsForReflection; | 194 List<Field> get staticFieldsForReflection; |
179 } | 195 } |
180 | 196 |
181 class Library implements FieldContainer { | 197 class Library implements FieldContainer { |
182 /// The element should only be used during the transition to the new model. | 198 /// The element should only be used during the transition to the new model. |
183 /// Uses indicate missing information in the model. | 199 /// Uses indicate missing information in the model. |
184 final LibraryEntity element; | 200 final LibraryEntity element; |
185 | 201 |
186 final String uri; | 202 final String uri; |
187 final List<StaticMethod> statics; | 203 final List<StaticMethod> statics; |
188 final List<Class> classes; | 204 final List<Class> classes; |
189 | 205 |
190 final List<Field> staticFieldsForReflection; | 206 final List<Field> staticFieldsForReflection; |
191 | 207 |
192 Library(this.element, this.uri, this.statics, this.classes, | 208 Library(this.element, this.uri, this.statics, this.classes, |
193 this.staticFieldsForReflection); | 209 this.staticFieldsForReflection); |
| 210 |
| 211 String toString() { |
| 212 return 'Library(uri=${uri},element=${element})'; |
| 213 } |
194 } | 214 } |
195 | 215 |
196 class StaticField { | 216 class StaticField { |
197 /// The element should only be used during the transition to the new model. | 217 /// The element should only be used during the transition to the new model. |
198 /// Uses indicate missing information in the model. | 218 /// Uses indicate missing information in the model. |
199 final FieldEntity element; | 219 final FieldEntity element; |
200 | 220 |
201 js.Name name; | 221 js.Name name; |
202 // TODO(floitsch): the holder for static fields is the isolate object. We | 222 // TODO(floitsch): the holder for static fields is the isolate object. We |
203 // could remove this field and use the isolate object directly. | 223 // could remove this field and use the isolate object directly. |
204 final Holder holder; | 224 final Holder holder; |
205 final js.Expression code; | 225 final js.Expression code; |
206 final bool isFinal; | 226 final bool isFinal; |
207 final bool isLazy; | 227 final bool isLazy; |
208 | 228 |
209 StaticField(this.element, this.name, this.holder, this.code, this.isFinal, | 229 StaticField(this.element, this.name, this.holder, this.code, this.isFinal, |
210 this.isLazy); | 230 this.isLazy); |
| 231 |
| 232 String toString() { |
| 233 return 'StaticField(name=${name},element=${element})'; |
| 234 } |
211 } | 235 } |
212 | 236 |
213 class Class implements FieldContainer { | 237 class Class implements FieldContainer { |
214 /// The element should only be used during the transition to the new model. | 238 /// The element should only be used during the transition to the new model. |
215 /// Uses indicate missing information in the model. | 239 /// Uses indicate missing information in the model. |
216 final ClassEntity element; | 240 final ClassEntity element; |
217 | 241 |
218 final js.Name name; | 242 final js.Name name; |
219 final Holder holder; | 243 final Holder holder; |
220 Class _superclass; | 244 Class _superclass; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 | 309 |
286 void setSuperclass(Class superclass) { | 310 void setSuperclass(Class superclass) { |
287 _superclass = superclass; | 311 _superclass = superclass; |
288 } | 312 } |
289 | 313 |
290 js.Name get superclassName => superclass == null ? null : superclass.name; | 314 js.Name get superclassName => superclass == null ? null : superclass.name; |
291 | 315 |
292 int get superclassHolderIndex => | 316 int get superclassHolderIndex => |
293 (superclass == null) ? 0 : superclass.holder.index; | 317 (superclass == null) ? 0 : superclass.holder.index; |
294 | 318 |
295 String toString() => 'Class(${element.name})'; | 319 String toString() => 'Class(name=${name},element=$element)'; |
296 } | 320 } |
297 | 321 |
298 class MixinApplication extends Class { | 322 class MixinApplication extends Class { |
299 Class _mixinClass; | 323 Class _mixinClass; |
300 | 324 |
301 MixinApplication( | 325 MixinApplication( |
302 ClassEntity element, | 326 ClassEntity element, |
303 js.Name name, | 327 js.Name name, |
304 Holder holder, | 328 Holder holder, |
305 List<Field> instanceFields, | 329 List<Field> instanceFields, |
(...skipping 22 matching lines...) Expand all Loading... |
328 isDirectlyInstantiated: isDirectlyInstantiated, | 352 isDirectlyInstantiated: isDirectlyInstantiated, |
329 isNative: false, | 353 isNative: false, |
330 isClosureBaseClass: false); | 354 isClosureBaseClass: false); |
331 | 355 |
332 bool get isMixinApplication => true; | 356 bool get isMixinApplication => true; |
333 Class get mixinClass => _mixinClass; | 357 Class get mixinClass => _mixinClass; |
334 | 358 |
335 void setMixinClass(Class mixinClass) { | 359 void setMixinClass(Class mixinClass) { |
336 _mixinClass = mixinClass; | 360 _mixinClass = mixinClass; |
337 } | 361 } |
| 362 |
| 363 String toString() => 'Mixin(name=${name},element=$element)'; |
338 } | 364 } |
339 | 365 |
340 /// A field. | 366 /// A field. |
341 /// | 367 /// |
342 /// In general represents an instance field, but for reflection may also | 368 /// In general represents an instance field, but for reflection may also |
343 /// represent static fields. | 369 /// represent static fields. |
344 class Field { | 370 class Field { |
345 /// The element should only be used during the transition to the new model. | 371 /// The element should only be used during the transition to the new model. |
346 /// Uses indicate missing information in the model. | 372 /// Uses indicate missing information in the model. |
347 final FieldEntity element; | 373 final FieldEntity element; |
(...skipping 23 matching lines...) Expand all Loading... |
371 bool get needsUncheckedSetter => setterFlags != 0; | 397 bool get needsUncheckedSetter => setterFlags != 0; |
372 | 398 |
373 bool get needsInterceptedGetter => getterFlags > 1; | 399 bool get needsInterceptedGetter => getterFlags > 1; |
374 bool get needsInterceptedSetter => setterFlags > 1; | 400 bool get needsInterceptedSetter => setterFlags > 1; |
375 | 401 |
376 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; | 402 bool get needsInterceptedGetterOnReceiver => getterFlags == 2; |
377 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; | 403 bool get needsInterceptedSetterOnReceiver => setterFlags == 2; |
378 | 404 |
379 bool get needsInterceptedGetterOnThis => getterFlags == 3; | 405 bool get needsInterceptedGetterOnThis => getterFlags == 3; |
380 bool get needsInterceptedSetterOnThis => setterFlags == 3; | 406 bool get needsInterceptedSetterOnThis => setterFlags == 3; |
| 407 |
| 408 String toString() { |
| 409 return 'Field(name=${name},element=${element})'; |
| 410 } |
381 } | 411 } |
382 | 412 |
383 abstract class Method { | 413 abstract class Method { |
384 /// The element should only be used during the transition to the new model. | 414 /// The element should only be used during the transition to the new model. |
385 /// Uses indicate missing information in the model. | 415 /// Uses indicate missing information in the model. |
386 final MemberEntity element; | 416 final MemberEntity element; |
387 | 417 |
388 /// The name of the method. If the method is a [ParameterStubMethod] for a | 418 /// The name of the method. If the method is a [ParameterStubMethod] for a |
389 /// static function, then the name can be `null`. In that case, only the | 419 /// static function, then the name can be `null`. In that case, only the |
390 /// [ParameterStubMethod.callName] should be used. | 420 /// [ParameterStubMethod.callName] should be used. |
391 final js.Name name; | 421 final js.Name name; |
392 final js.Expression code; | 422 final js.Expression code; |
393 | 423 |
394 Method(this.element, this.name, this.code); | 424 Method(this.element, this.name, this.code); |
395 | |
396 String toString() { | |
397 return 'method[name=${name},element=${element}' | |
398 ',code=${js.nodeToString(code)}]'; | |
399 } | |
400 } | 425 } |
401 | 426 |
402 /// A method that corresponds to a method in the original Dart program. | 427 /// A method that corresponds to a method in the original Dart program. |
403 abstract class DartMethod extends Method { | 428 abstract class DartMethod extends Method { |
404 final bool needsTearOff; | 429 final bool needsTearOff; |
405 final js.Name tearOffName; | 430 final js.Name tearOffName; |
406 final List<ParameterStubMethod> parameterStubs; | 431 final List<ParameterStubMethod> parameterStubs; |
407 final bool canBeApplied; | 432 final bool canBeApplied; |
408 final bool canBeReflected; | 433 final bool canBeReflected; |
409 | 434 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 tearOffName: tearOffName, | 499 tearOffName: tearOffName, |
475 canBeApplied: canBeApplied, | 500 canBeApplied: canBeApplied, |
476 canBeReflected: canBeReflected, | 501 canBeReflected: canBeReflected, |
477 requiredParameterCount: requiredParameterCount, | 502 requiredParameterCount: requiredParameterCount, |
478 optionalParameterDefaultValues: optionalParameterDefaultValues, | 503 optionalParameterDefaultValues: optionalParameterDefaultValues, |
479 functionType: functionType) { | 504 functionType: functionType) { |
480 assert(isClosureCallMethod != null); | 505 assert(isClosureCallMethod != null); |
481 } | 506 } |
482 | 507 |
483 bool get isStatic => false; | 508 bool get isStatic => false; |
| 509 |
| 510 String toString() { |
| 511 return 'InstanceMethod(name=${name},element=${element}' |
| 512 ',code=${js.nodeToString(code)})'; |
| 513 } |
484 } | 514 } |
485 | 515 |
486 /// A method that is generated by the backend and has not direct correspondence | 516 /// A method that is generated by the backend and has not direct correspondence |
487 /// to a method in the original Dart program. Examples are getter and setter | 517 /// to a method in the original Dart program. Examples are getter and setter |
488 /// stubs and stubs to dispatch calls to methods with optional parameters. | 518 /// stubs and stubs to dispatch calls to methods with optional parameters. |
489 class StubMethod extends Method { | 519 class StubMethod extends Method { |
490 StubMethod(js.Name name, js.Expression code, {MemberEntity element}) | 520 StubMethod(js.Name name, js.Expression code, {MemberEntity element}) |
491 : super(element, name, code); | 521 : super(element, name, code); |
492 | 522 |
493 String toString() { | 523 String toString() { |
494 return 'stub[name=${name},element=${element},code=${js.nodeToString(code)}]'
; | 524 return 'StubMethod(name=${name},element=${element}' |
| 525 ',code=${js.nodeToString(code)})'; |
495 } | 526 } |
496 } | 527 } |
497 | 528 |
498 /// A stub that adapts and redirects to the main method (the one containing) | 529 /// A stub that adapts and redirects to the main method (the one containing) |
499 /// the actual code. | 530 /// the actual code. |
500 /// | 531 /// |
501 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter | 532 /// For example, given a method `foo$2(x, [y: 499])` a possible parameter |
502 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. | 533 /// stub-method could be `foo$1(x) => foo$2(x, 499)`. |
503 /// | 534 /// |
504 /// ParameterStubMethods are always attached to (static or instance) methods. | 535 /// ParameterStubMethods are always attached to (static or instance) methods. |
505 class ParameterStubMethod extends StubMethod { | 536 class ParameterStubMethod extends StubMethod { |
506 /// The `call` name of this stub. | 537 /// The `call` name of this stub. |
507 /// | 538 /// |
508 /// When an instance method is torn off, it is invoked as a `call` member and | 539 /// When an instance method is torn off, it is invoked as a `call` member and |
509 /// not it's original name anymore. The [callName] provides the stub's | 540 /// not it's original name anymore. The [callName] provides the stub's |
510 /// name when it is used this way. | 541 /// name when it is used this way. |
511 /// | 542 /// |
512 /// If a stub's member can not be torn off, the [callName] is `null`. | 543 /// If a stub's member can not be torn off, the [callName] is `null`. |
513 js.Name callName; | 544 js.Name callName; |
514 | 545 |
515 ParameterStubMethod(js.Name name, this.callName, js.Expression code) | 546 ParameterStubMethod(js.Name name, this.callName, js.Expression code) |
516 : super(name, code); | 547 : super(name, code); |
| 548 |
| 549 String toString() { |
| 550 return 'ParameterStubMethod(name=${name},element=${element}' |
| 551 ',code=${js.nodeToString(code)})'; |
| 552 } |
517 } | 553 } |
518 | 554 |
519 abstract class StaticMethod implements Method { | 555 abstract class StaticMethod implements Method { |
520 Holder get holder; | 556 Holder get holder; |
521 } | 557 } |
522 | 558 |
523 class StaticDartMethod extends DartMethod implements StaticMethod { | 559 class StaticDartMethod extends DartMethod implements StaticMethod { |
524 final Holder holder; | 560 final Holder holder; |
525 | 561 |
526 StaticDartMethod( | 562 StaticDartMethod( |
(...skipping 15 matching lines...) Expand all Loading... |
542 tearOffName: tearOffName, | 578 tearOffName: tearOffName, |
543 canBeApplied: canBeApplied, | 579 canBeApplied: canBeApplied, |
544 canBeReflected: canBeReflected, | 580 canBeReflected: canBeReflected, |
545 requiredParameterCount: requiredParameterCount, | 581 requiredParameterCount: requiredParameterCount, |
546 optionalParameterDefaultValues: optionalParameterDefaultValues, | 582 optionalParameterDefaultValues: optionalParameterDefaultValues, |
547 functionType: functionType); | 583 functionType: functionType); |
548 | 584 |
549 bool get isStatic => true; | 585 bool get isStatic => true; |
550 | 586 |
551 String toString() { | 587 String toString() { |
552 return 'static_method[name=${name},element=${element}}]'; | 588 return 'StaticDartMethod(name=${name},element=${element}' |
| 589 ',code=${js.nodeToString(code)})'; |
553 } | 590 } |
554 } | 591 } |
555 | 592 |
556 class StaticStubMethod extends StubMethod implements StaticMethod { | 593 class StaticStubMethod extends StubMethod implements StaticMethod { |
557 Holder holder; | 594 Holder holder; |
558 StaticStubMethod(js.Name name, this.holder, js.Expression code) | 595 StaticStubMethod(js.Name name, this.holder, js.Expression code) |
559 : super(name, code); | 596 : super(name, code); |
| 597 |
| 598 String toString() { |
| 599 return 'StaticStubMethod(name=${name},element=${element}}' |
| 600 ',code=${js.nodeToString(code)})'; |
| 601 } |
560 } | 602 } |
OLD | NEW |