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 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 // that throws instead? | 709 // that throws instead? |
710 assert(options.unsafeForceCompile || options.replCompile); | 710 assert(options.unsafeForceCompile || options.replCompile); |
711 return _callHelper('dynamic'); | 711 return _callHelper('dynamic'); |
712 } | 712 } |
713 return _emitType(node.type); | 713 return _emitType(node.type); |
714 } | 714 } |
715 | 715 |
716 @override | 716 @override |
717 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { | 717 JS.Statement visitClassTypeAlias(ClassTypeAlias node) { |
718 ClassElement element = node.element; | 718 ClassElement element = node.element; |
| 719 var supertype = element.supertype; |
719 | 720 |
720 // Forward all generative constructors from the base class. | 721 // Forward all generative constructors from the base class. |
721 var methods = <JS.Method>[]; | 722 var methods = <JS.Method>[]; |
722 | |
723 var supertype = element.supertype; | |
724 if (!supertype.isObject) { | 723 if (!supertype.isObject) { |
725 for (var ctor in element.constructors) { | 724 for (var ctor in element.constructors) { |
726 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); | 725 var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); |
727 // TODO(jmesserly): this avoids spread args for perf. Revisit. | 726 // TODO(jmesserly): this avoids spread args for perf. Revisit. |
728 var jsParams = <JS.Identifier>[]; | 727 var jsParams = <JS.Identifier>[]; |
729 for (var p in ctor.parameters) { | 728 for (var p in ctor.parameters) { |
730 if (p.parameterKind != ParameterKind.NAMED) { | 729 if (p.parameterKind != ParameterKind.NAMED) { |
731 jsParams.add(new JS.Identifier(p.name)); | 730 jsParams.add(new JS.Identifier(p.name)); |
732 } else { | 731 } else { |
733 jsParams.add(new JS.TemporaryId('namedArgs')); | 732 jsParams.add(new JS.TemporaryId('namedArgs')); |
734 break; | 733 break; |
735 } | 734 } |
736 } | 735 } |
737 var fun = js.call('function(#) { super.#(#); }', | 736 var fun = js.call('function(#) { super.#(#); }', |
738 [jsParams, _constructorName(parentCtor), jsParams]) as JS.Fun; | 737 [jsParams, _constructorName(parentCtor), jsParams]) as JS.Fun; |
739 methods.add(new JS.Method(_constructorName(ctor), fun)); | 738 methods.add(new JS.Method(_constructorName(ctor), fun)); |
740 } | 739 } |
741 } | 740 } |
742 | 741 |
| 742 var typeFormals = element.typeParameters; |
| 743 var isGeneric = typeFormals.isNotEmpty; |
| 744 var className = isGeneric ? element.name : _emitTopLevelName(element); |
| 745 JS.Statement declareInterfaces(JS.Statement decl) { |
| 746 if (element.interfaces.isNotEmpty) { |
| 747 var body = [decl] |
| 748 ..add(js.statement('#[#.implements] = () => #;', [ |
| 749 className, |
| 750 _runtimeModule, |
| 751 new JS.ArrayInitializer( |
| 752 new List<JS.Expression>.from(element.interfaces.map(_emitType))) |
| 753 ])); |
| 754 decl = _statement(body); |
| 755 } |
| 756 return decl; |
| 757 } |
| 758 |
| 759 if (supertype.isObject && element.mixins.length == 1) { |
| 760 // Special case where supertype is Object, and we mixin a single class. |
| 761 // The resulting 'class' is a mixable class in this case. |
| 762 var classExpr = _emitClassHeritage(element); |
| 763 if (isGeneric) { |
| 764 var classStmt = js.statement('const # = #;', [className, classExpr]); |
| 765 return _defineClassTypeArguments( |
| 766 element, typeFormals, declareInterfaces(classStmt)); |
| 767 } else { |
| 768 var classStmt = js.statement('# = #;', [className, classExpr]); |
| 769 return declareInterfaces(classStmt); |
| 770 } |
| 771 } |
| 772 |
743 var classExpr = _emitClassExpression(element, methods); | 773 var classExpr = _emitClassExpression(element, methods); |
744 | 774 if (isGeneric) { |
745 var typeFormals = element.typeParameters; | 775 var classStmt = new JS.ClassDeclaration(classExpr); |
746 if (typeFormals.isNotEmpty) { | |
747 return _defineClassTypeArguments( | 776 return _defineClassTypeArguments( |
748 element, typeFormals, new JS.ClassDeclaration(classExpr)); | 777 element, typeFormals, declareInterfaces(classStmt)); |
749 } else { | 778 } else { |
750 return js.statement('# = #;', [_emitTopLevelName(element), classExpr]); | 779 var classStmt = js.statement('# = #;', [className, classExpr]); |
| 780 return declareInterfaces(classStmt); |
751 } | 781 } |
752 } | 782 } |
753 | 783 |
754 JS.Statement _emitJsType(Element e) { | 784 JS.Statement _emitJsType(Element e) { |
755 var jsTypeName = getAnnotationName(e, isJSAnnotation); | 785 var jsTypeName = getAnnotationName(e, isJSAnnotation); |
756 if (jsTypeName == null || jsTypeName == e.name) return null; | 786 if (jsTypeName == null || jsTypeName == e.name) return null; |
757 | 787 |
758 // We export the JS type as if it was a Dart type. For example this allows | 788 // We export the JS type as if it was a Dart type. For example this allows |
759 // `dom.InputElement` to actually be HTMLInputElement. | 789 // `dom.InputElement` to actually be HTMLInputElement. |
760 // TODO(jmesserly): if we had the JS name on the Element, we could just | 790 // TODO(jmesserly): if we had the JS name on the Element, we could just |
(...skipping 5276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6037 if (targetIdentifier.staticElement is! PrefixElement) return false; | 6067 if (targetIdentifier.staticElement is! PrefixElement) return false; |
6038 var prefix = targetIdentifier.staticElement as PrefixElement; | 6068 var prefix = targetIdentifier.staticElement as PrefixElement; |
6039 | 6069 |
6040 // The library the prefix is referring to must come from a deferred import. | 6070 // The library the prefix is referring to must come from a deferred import. |
6041 var containingLibrary = resolutionMap | 6071 var containingLibrary = resolutionMap |
6042 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 6072 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
6043 .library; | 6073 .library; |
6044 var imports = containingLibrary.getImportsWithPrefix(prefix); | 6074 var imports = containingLibrary.getImportsWithPrefix(prefix); |
6045 return imports.length == 1 && imports[0].isDeferred; | 6075 return imports.length == 1 && imports[0].isDeferred; |
6046 } | 6076 } |
OLD | NEW |