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 | 2 |
3 // for details. All rights reserved. Use of this source code is governed by a | 3 // for details. All rights reserved. Use of this source code is governed by a |
4 // BSD-style license that can be found in the LICENSE file. | 4 // BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 import 'dart:collection' show HashMap, HashSet; | 6 import 'dart:collection' show HashMap, HashSet; |
7 import 'dart:math' show min, max; | 7 import 'dart:math' show min, max; |
8 | 8 |
9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; | 9 import 'package:analyzer/analyzer.dart' hide ConstantEvaluator; |
10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
760 | 760 |
761 var body = <JS.Statement>[]; | 761 var body = <JS.Statement>[]; |
762 _initExtensionSymbols(classElem, methods, fields, body); | 762 _initExtensionSymbols(classElem, methods, fields, body); |
763 _emitSuperHelperSymbols(_superHelperSymbols, body); | 763 _emitSuperHelperSymbols(_superHelperSymbols, body); |
764 | 764 |
765 // Emit the class, e.g. `core.Object = class Object { ... }` | 765 // Emit the class, e.g. `core.Object = class Object { ... }` |
766 _defineClass(classElem, className, classExpr, isCallable, body); | 766 _defineClass(classElem, className, classExpr, isCallable, body); |
767 | 767 |
768 // Emit things that come after the ES6 `class ... { ... }`. | 768 // Emit things that come after the ES6 `class ... { ... }`. |
769 var jsPeerNames = _getJSPeerNames(classElem); | 769 var jsPeerNames = _getJSPeerNames(classElem); |
770 _setBaseClass(classElem, className, jsPeerNames, body); | 770 JS.Statement deferredBaseClass = |
| 771 _setBaseClass(classElem, className, jsPeerNames, body); |
771 | 772 |
772 _emitClassTypeTests(classElem, className, body); | 773 _emitClassTypeTests(classElem, className, body); |
773 | 774 |
774 _defineNamedConstructors(ctors, body, className, isCallable); | 775 _defineNamedConstructors(ctors, body, className, isCallable); |
775 body.addAll(virtualFieldSymbols); | 776 body.addAll(virtualFieldSymbols); |
776 _emitClassSignature( | 777 _emitClassSignature( |
777 methods, allFields, classElem, ctors, extensions, className, body); | 778 methods, allFields, classElem, ctors, extensions, className, body); |
778 _defineExtensionMembers(extensions, className, body); | 779 _defineExtensionMembers(extensions, className, body); |
779 _emitClassMetadata(node.metadata, className, body); | 780 _emitClassMetadata(node.metadata, className, body); |
780 | 781 |
781 JS.Statement classDef = _statement(body); | 782 JS.Statement classDef = _statement(body); |
| 783 |
782 var typeFormals = classElem.typeParameters; | 784 var typeFormals = classElem.typeParameters; |
783 if (typeFormals.isNotEmpty) { | 785 if (typeFormals.isNotEmpty) { |
784 classDef = _defineClassTypeArguments(classElem, typeFormals, classDef); | 786 classDef = _defineClassTypeArguments( |
| 787 classElem, typeFormals, classDef, className, deferredBaseClass); |
785 } | 788 } |
786 | 789 |
787 body = <JS.Statement>[classDef]; | 790 body = <JS.Statement>[classDef]; |
788 _emitStaticFields(staticFields, staticFieldOverrides, classElem, body); | 791 _emitStaticFields(staticFields, staticFieldOverrides, classElem, body); |
789 for (var peer in jsPeerNames) { | 792 for (var peer in jsPeerNames) { |
790 _registerExtensionType(classElem, peer, body); | 793 _registerExtensionType(classElem, peer, body); |
791 } | 794 } |
792 return _statement(body); | 795 return _statement(body); |
793 } | 796 } |
794 | 797 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1119 id, | 1122 id, |
1120 new JS.ArrayInitializer(fields.map((f) => _propertyName(f.name)).toList(), | 1123 new JS.ArrayInitializer(fields.map((f) => _propertyName(f.name)).toList(), |
1121 multiline: true) | 1124 multiline: true) |
1122 ])); | 1125 ])); |
1123 | 1126 |
1124 return _statement(result); | 1127 return _statement(result); |
1125 } | 1128 } |
1126 | 1129 |
1127 /// Wraps a possibly generic class in its type arguments. | 1130 /// Wraps a possibly generic class in its type arguments. |
1128 JS.Statement _defineClassTypeArguments(TypeDefiningElement element, | 1131 JS.Statement _defineClassTypeArguments(TypeDefiningElement element, |
1129 List<TypeParameterElement> formals, JS.Statement body) { | 1132 List<TypeParameterElement> formals, JS.Statement body, |
| 1133 [JS.Expression className, JS.Statement deferredBaseClass]) { |
1130 assert(formals.isNotEmpty); | 1134 assert(formals.isNotEmpty); |
1131 var genericCall = _callHelper('generic((#) => { #; #; return #; })', [ | 1135 var typeConstructor = js.call('(#) => { #; #; return #; }', [ |
1132 _emitTypeFormals(formals), | 1136 _emitTypeFormals(formals), |
1133 _typeTable.discharge(formals), | 1137 _typeTable.discharge(formals), |
1134 body, | 1138 body, |
1135 element.name | 1139 element.name |
1136 ]); | 1140 ]); |
| 1141 |
| 1142 var genericArgs = [typeConstructor]; |
| 1143 if (deferredBaseClass != null) { |
| 1144 genericArgs.add(js.call('(#) => { #; }', [className, deferredBaseClass])); |
| 1145 } |
| 1146 |
| 1147 var genericCall = _callHelper('generic(#)', [genericArgs]); |
| 1148 |
1137 if (element.library.isDartAsync && | 1149 if (element.library.isDartAsync && |
1138 (element.name == "Future" || element.name == "_Future")) { | 1150 (element.name == "Future" || element.name == "_Future")) { |
1139 genericCall = _callHelper('flattenFutures(#)', [genericCall]); | 1151 genericCall = _callHelper('flattenFutures(#)', [genericCall]); |
1140 } | 1152 } |
1141 var genericDef = js.statement( | 1153 var genericDef = js.statement( |
1142 '# = #;', [_emitTopLevelName(element, suffix: r'$'), genericCall]); | 1154 '# = #;', [_emitTopLevelName(element, suffix: r'$'), genericCall]); |
1143 var dynType = fillDynamicTypeArgs(element.type); | 1155 var dynType = fillDynamicTypeArgs(element.type); |
1144 var genericInst = _emitType(dynType, lowerGeneric: true); | 1156 var genericInst = _emitType(dynType, lowerGeneric: true); |
1145 return js.statement( | 1157 return js.statement( |
1146 '{ #; # = #; }', [genericDef, _emitTopLevelName(element), genericInst]); | 1158 '{ #; # = #; }', [genericDef, _emitTopLevelName(element), genericInst]); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 ClassElement classElem, String jsPeerName, List<JS.Statement> body) { | 1606 ClassElement classElem, String jsPeerName, List<JS.Statement> body) { |
1595 if (jsPeerName != null) { | 1607 if (jsPeerName != null) { |
1596 body.add(_callHelperStatement('registerExtension(#.global.#, #);', [ | 1608 body.add(_callHelperStatement('registerExtension(#.global.#, #);', [ |
1597 _runtimeModule, | 1609 _runtimeModule, |
1598 _propertyName(jsPeerName), | 1610 _propertyName(jsPeerName), |
1599 _emitTopLevelName(classElem) | 1611 _emitTopLevelName(classElem) |
1600 ])); | 1612 ])); |
1601 } | 1613 } |
1602 } | 1614 } |
1603 | 1615 |
1604 void _setBaseClass(ClassElement classElem, JS.Expression className, | 1616 JS.Statement _setBaseClass(ClassElement classElem, JS.Expression className, |
1605 List<String> jsPeerNames, List<JS.Statement> body) { | 1617 List<String> jsPeerNames, List<JS.Statement> body) { |
1606 if (jsPeerNames.isNotEmpty && classElem.typeParameters.isNotEmpty) { | 1618 var typeFormals = classElem.typeParameters; |
| 1619 if (jsPeerNames.isNotEmpty && typeFormals.isNotEmpty) { |
1607 for (var peer in jsPeerNames) { | 1620 for (var peer in jsPeerNames) { |
1608 // TODO(jmesserly): we should just extend Array in the first place | 1621 // TODO(jmesserly): we should just extend Array in the first place |
1609 var newBaseClass = _callHelper('global.#', [peer]); | 1622 var newBaseClass = _callHelper('global.#', [peer]); |
1610 body.add(_callHelperStatement( | 1623 body.add(_callHelperStatement( |
1611 'setExtensionBaseClass(#, #);', [className, newBaseClass])); | 1624 'setExtensionBaseClass(#, #);', [className, newBaseClass])); |
1612 } | 1625 } |
1613 } else if (_hasDeferredSupertype.contains(classElem)) { | 1626 } else if (_hasDeferredSupertype.contains(classElem)) { |
1614 var newBaseClass = _emitType(classElem.type.superclass, | 1627 var newBaseClass = _emitType(classElem.type.superclass, |
1615 nameType: false, subClass: classElem, className: className); | 1628 nameType: false, subClass: classElem, className: className); |
1616 body.add(_callHelperStatement( | 1629 var deferredBaseClass = _callHelperStatement( |
1617 'setBaseClass(#, #);', [className, newBaseClass])); | 1630 'setBaseClass(#, #);', [className, newBaseClass]); |
| 1631 if (typeFormals.isNotEmpty) return deferredBaseClass; |
| 1632 body.add(deferredBaseClass); |
1618 } | 1633 } |
| 1634 return null; |
1619 } | 1635 } |
1620 | 1636 |
1621 void _defineNamedConstructors(List<ConstructorDeclaration> ctors, | 1637 void _defineNamedConstructors(List<ConstructorDeclaration> ctors, |
1622 List<JS.Statement> body, JS.Expression className, bool isCallable) { | 1638 List<JS.Statement> body, JS.Expression className, bool isCallable) { |
1623 var code = isCallable | 1639 var code = isCallable |
1624 ? 'defineNamedConstructorCallable(#, #, #);' | 1640 ? 'defineNamedConstructorCallable(#, #, #);' |
1625 : 'defineNamedConstructor(#, #)'; | 1641 : 'defineNamedConstructor(#, #)'; |
1626 | 1642 |
1627 for (ConstructorDeclaration member in ctors) { | 1643 for (ConstructorDeclaration member in ctors) { |
1628 if (member.name != null && member.factoryKeyword == null) { | 1644 if (member.name != null && member.factoryKeyword == null) { |
(...skipping 1318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2947 | 2963 |
2948 if (type is ParameterizedType) { | 2964 if (type is ParameterizedType) { |
2949 var args = type.typeArguments; | 2965 var args = type.typeArguments; |
2950 Iterable jsArgs = null; | 2966 Iterable jsArgs = null; |
2951 if (args.any((a) => !a.isDynamic)) { | 2967 if (args.any((a) => !a.isDynamic)) { |
2952 jsArgs = args.map((x) => _emitType(x, | 2968 jsArgs = args.map((x) => _emitType(x, |
2953 nameType: nameType, | 2969 nameType: nameType, |
2954 hoistType: hoistType, | 2970 hoistType: hoistType, |
2955 subClass: subClass, | 2971 subClass: subClass, |
2956 className: className)); | 2972 className: className)); |
2957 } else if (lowerGeneric) { | 2973 } else if (lowerGeneric || element == subClass) { |
2958 jsArgs = []; | 2974 jsArgs = []; |
2959 } | 2975 } |
2960 if (jsArgs != null) { | 2976 if (jsArgs != null) { |
2961 var genericName = _emitTopLevelName(element, suffix: '\$'); | 2977 var genericName = _emitTopLevelName(element, suffix: '\$'); |
2962 var typeRep = js.call('#(#)', [genericName, jsArgs]); | 2978 var typeRep = js.call('#(#)', [genericName, jsArgs]); |
2963 return nameType | 2979 return nameType |
2964 ? _typeTable.nameType(type, typeRep, hoistType: hoistType) | 2980 ? _typeTable.nameType(type, typeRep, hoistType: hoistType) |
2965 : typeRep; | 2981 : typeRep; |
2966 } | 2982 } |
2967 } | 2983 } |
(...skipping 2660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5628 var targetIdentifier = target as SimpleIdentifier; | 5644 var targetIdentifier = target as SimpleIdentifier; |
5629 | 5645 |
5630 if (targetIdentifier.staticElement is! PrefixElement) return false; | 5646 if (targetIdentifier.staticElement is! PrefixElement) return false; |
5631 var prefix = targetIdentifier.staticElement as PrefixElement; | 5647 var prefix = targetIdentifier.staticElement as PrefixElement; |
5632 | 5648 |
5633 // The library the prefix is referring to must come from a deferred import. | 5649 // The library the prefix is referring to must come from a deferred import. |
5634 var containingLibrary = (target.root as CompilationUnit).element.library; | 5650 var containingLibrary = (target.root as CompilationUnit).element.library; |
5635 var imports = containingLibrary.getImportsWithPrefix(prefix); | 5651 var imports = containingLibrary.getImportsWithPrefix(prefix); |
5636 return imports.length == 1 && imports[0].isDeferred; | 5652 return imports.length == 1 && imports[0].isDeferred; |
5637 } | 5653 } |
OLD | NEW |