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 |