Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dev_compiler.src.codegen.js_codegen; | 5 library dev_compiler.src.codegen.js_codegen; |
| 6 | 6 |
| 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; | 7 import 'dart:collection' show HashSet, HashMap, SplayTreeSet; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
| 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; | 10 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator; |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 | 559 |
| 560 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { | 560 JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { |
| 561 var name = type.name; | 561 var name = type.name; |
| 562 var genericName = '$name\$'; | 562 var genericName = '$name\$'; |
| 563 var typeParams = type.typeParameters.map((p) => p.name); | 563 var typeParams = type.typeParameters.map((p) => p.name); |
| 564 if (isPublic(name)) _exports.add(genericName); | 564 if (isPublic(name)) _exports.add(genericName); |
| 565 return js.statement('let # = dart.generic(function(#) { #; return #; });', | 565 return js.statement('let # = dart.generic(function(#) { #; return #; });', |
| 566 [genericName, typeParams, body, name]); | 566 [genericName, typeParams, body, name]); |
| 567 } | 567 } |
| 568 | 568 |
| 569 final _hasDeferredSupertype = new Set<ClassElement>(); | |
|
vsm
2015/11/10 23:20:29
Not sure I need a Set here, but with the load-on-d
Jennifer Messerly
2015/11/10 23:32:09
yeah seems fine. small nit: you could use HashSet,
vsm
2015/11/10 23:41:50
Done.
| |
| 570 | |
| 571 bool _deferIfNeeded(DartType type, ClassElement current) { | |
| 572 if (type is ParameterizedType) { | |
| 573 var typeArguments = type.typeArguments; | |
| 574 for (var typeArg in typeArguments) { | |
| 575 var typeElement = typeArg.element; | |
| 576 // FIXME(vsm): This does not track mutual recursive dependences. | |
| 577 if ((current == typeElement) || _deferIfNeeded(typeArg, current)) { | |
|
Jennifer Messerly
2015/11/10 23:32:09
parens not needed around ==
vsm
2015/11/10 23:41:50
Done.
| |
| 578 return true; | |
| 579 } | |
| 580 } | |
| 581 } | |
| 582 return false; | |
| 583 } | |
| 584 | |
| 569 JS.Expression _classHeritage(ClassElement element) { | 585 JS.Expression _classHeritage(ClassElement element) { |
| 570 var type = element.type; | 586 var type = element.type; |
| 571 if (type.isObject) return null; | 587 if (type.isObject) return null; |
| 572 | 588 |
| 573 // Assume we can load eagerly, until proven otherwise. | 589 // Assume we can load eagerly, until proven otherwise. |
| 574 _loader.startTopLevel(element); | 590 _loader.startTopLevel(element); |
| 575 | 591 |
| 576 JS.Expression heritage = _emitTypeName(type.superclass); | 592 // Find the super type |
| 593 JS.Expression heritage; | |
| 594 var supertype = type.superclass; | |
| 595 if (_deferIfNeeded(supertype, element)) { | |
| 596 // Fall back to raw type. | |
| 597 supertype = fillDynamicTypeArgs(supertype.element.type, rules.provider); | |
| 598 _hasDeferredSupertype.add(element); | |
| 599 } | |
| 600 heritage = _emitTypeName(supertype); | |
| 601 | |
| 577 if (type.mixins.isNotEmpty) { | 602 if (type.mixins.isNotEmpty) { |
| 578 var mixins = type.mixins.map(_emitTypeName).toList(); | 603 var mixins = type.mixins.map(_emitTypeName).toList(); |
| 579 mixins.insert(0, heritage); | 604 mixins.insert(0, heritage); |
| 580 heritage = js.call('dart.mixin(#)', [mixins]); | 605 heritage = js.call('dart.mixin(#)', [mixins]); |
| 581 } | 606 } |
| 582 | 607 |
| 583 _loader.finishTopLevel(element); | 608 _loader.finishTopLevel(element); |
| 584 return heritage; | 609 return heritage; |
| 585 } | 610 } |
| 586 | 611 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 } | 719 } |
| 695 | 720 |
| 696 body.add(new JS.ClassDeclaration(cls)); | 721 body.add(new JS.ClassDeclaration(cls)); |
| 697 | 722 |
| 698 // TODO(jmesserly): we should really just extend native Array. | 723 // TODO(jmesserly): we should really just extend native Array. |
| 699 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { | 724 if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { |
| 700 body.add(js.statement('dart.setBaseClass(#, dart.global.#);', | 725 body.add(js.statement('dart.setBaseClass(#, dart.global.#);', |
| 701 [classElem.name, _propertyName(jsPeerName)])); | 726 [classElem.name, _propertyName(jsPeerName)])); |
| 702 } | 727 } |
| 703 | 728 |
| 729 // Deferred Superclass | |
| 730 if (_hasDeferredSupertype.contains(classElem)) { | |
| 731 body.add(js.statement('#.prototype.__proto__ = #.prototype;', | |
| 732 [name, _emitTypeName(classElem.type.superclass)])); | |
| 733 } | |
| 734 | |
| 704 // Interfaces | 735 // Interfaces |
| 705 if (classElem.interfaces.isNotEmpty) { | 736 if (classElem.interfaces.isNotEmpty) { |
| 706 body.add(js.statement('#[dart.implements] = () => #;', [ | 737 body.add(js.statement('#[dart.implements] = () => #;', [ |
| 707 name, | 738 name, |
| 708 new JS.ArrayInitializer(new List<JS.Expression>.from( | 739 new JS.ArrayInitializer(new List<JS.Expression>.from( |
| 709 classElem.interfaces.map(_emitTypeName))) | 740 classElem.interfaces.map(_emitTypeName))) |
| 710 ])); | 741 ])); |
| 711 } | 742 } |
| 712 | 743 |
| 713 // Named constructors | 744 // Named constructors |
| (...skipping 2602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3316 | 3347 |
| 3317 /// A special kind of element created by the compiler, signifying a temporary | 3348 /// A special kind of element created by the compiler, signifying a temporary |
| 3318 /// variable. These objects use instance equality, and should be shared | 3349 /// variable. These objects use instance equality, and should be shared |
| 3319 /// everywhere in the tree where they are treated as the same variable. | 3350 /// everywhere in the tree where they are treated as the same variable. |
| 3320 class TemporaryVariableElement extends LocalVariableElementImpl { | 3351 class TemporaryVariableElement extends LocalVariableElementImpl { |
| 3321 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); | 3352 TemporaryVariableElement.forNode(Identifier name) : super.forNode(name); |
| 3322 | 3353 |
| 3323 int get hashCode => identityHashCode(this); | 3354 int get hashCode => identityHashCode(this); |
| 3324 bool operator ==(Object other) => identical(this, other); | 3355 bool operator ==(Object other) => identical(this, other); |
| 3325 } | 3356 } |
| OLD | NEW |