| 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 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 } | 743 } |
| 744 | 744 |
| 745 String _jsTypeofName(DartType t) { | 745 String _jsTypeofName(DartType t) { |
| 746 if (_isNumberInJS(t)) return 'number'; | 746 if (_isNumberInJS(t)) return 'number'; |
| 747 if (t == types.stringType) return 'string'; | 747 if (t == types.stringType) return 'string'; |
| 748 if (t == types.boolType) return 'boolean'; | 748 if (t == types.boolType) return 'boolean'; |
| 749 return null; | 749 return null; |
| 750 } | 750 } |
| 751 | 751 |
| 752 @override | 752 @override |
| 753 visitFunctionTypeAlias(FunctionTypeAlias node) { | 753 visitFunctionTypeAlias(FunctionTypeAlias node) => _emitTypedef(node); |
| 754 FunctionTypeAliasElement element = node.element; | 754 |
| 755 @override |
| 756 visitGenericTypeAlias(GenericTypeAlias node) => _emitTypedef(node); |
| 757 |
| 758 JS.Statement _emitTypedef(TypeAlias node) { |
| 759 var element = node.element as FunctionTypeAliasElement; |
| 760 FunctionType type; |
| 761 var typeFormals = element.typeParameters; |
| 762 if (element is GenericTypeAliasElement) { |
| 763 type = element.function.type; |
| 764 } else { |
| 765 type = element.type; |
| 766 if (typeFormals.isNotEmpty) { |
| 767 // Skip past the type formals, we'll add them back below, so these |
| 768 // type parameter names will end up in scope in the generated JS. |
| 769 type = type.instantiate(typeFormals.map((f) => f.type).toList()); |
| 770 } |
| 771 } |
| 755 | 772 |
| 756 JS.Expression body = annotate( | 773 JS.Expression body = annotate( |
| 757 _callHelper('typedef(#, () => #)', [ | 774 _callHelper('typedef(#, () => #)', [ |
| 758 js.string(element.name, "'"), | 775 js.string(element.name, "'"), |
| 759 _emitType(element.type, nameType: false, lowerTypedef: true) | 776 _emitType(type, nameType: false, lowerTypedef: true) |
| 760 ]), | 777 ]), |
| 761 node, | 778 node, |
| 762 element); | 779 element); |
| 763 | 780 |
| 764 var typeFormals = element.typeParameters; | |
| 765 if (typeFormals.isNotEmpty) { | 781 if (typeFormals.isNotEmpty) { |
| 766 return _defineClassTypeArguments(element, typeFormals, | 782 return _defineClassTypeArguments(element, typeFormals, |
| 767 js.statement('const # = #;', [element.name, body])); | 783 js.statement('const # = #;', [element.name, body])); |
| 768 } else { | 784 } else { |
| 769 return js.statement('# = #;', [_emitTopLevelName(element), body]); | 785 return js.statement('# = #;', [_emitTopLevelName(element), body]); |
| 770 } | 786 } |
| 771 } | 787 } |
| 772 | 788 |
| 773 @override | 789 @override |
| 774 visitGenericTypeAlias(GenericTypeAlias node) { | |
| 775 throw new UnimplementedError('Generic type aliases are not implemented. ' | |
| 776 'See https://github.com/dart-lang/sdk/issues/27971'); | |
| 777 } | |
| 778 | |
| 779 @override | |
| 780 JS.Expression visitTypeName(TypeName node) { | 790 JS.Expression visitTypeName(TypeName node) { |
| 781 if (node.type == null) { | 791 if (node.type == null) { |
| 782 // TODO(jmesserly): if the type fails to resolve, should we generate code | 792 // TODO(jmesserly): if the type fails to resolve, should we generate code |
| 783 // that throws instead? | 793 // that throws instead? |
| 784 assert(options.unsafeForceCompile || options.replCompile); | 794 assert(options.unsafeForceCompile || options.replCompile); |
| 785 return _callHelper('dynamic'); | 795 return _callHelper('dynamic'); |
| 786 } | 796 } |
| 787 return _emitType(node.type); | 797 return _emitType(node.type); |
| 788 } | 798 } |
| 789 | 799 |
| (...skipping 2240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3030 assert(namedTypes.isEmpty); | 3040 assert(namedTypes.isEmpty); |
| 3031 var oa = _emitTypeNames( | 3041 var oa = _emitTypeNames( |
| 3032 optionalTypes, parameters?.sublist(parameterTypes.length), | 3042 optionalTypes, parameters?.sublist(parameterTypes.length), |
| 3033 nameType: nameType, hoistType: hoistType); | 3043 nameType: nameType, hoistType: hoistType); |
| 3034 typeParts = [rt, ra, oa]; | 3044 typeParts = [rt, ra, oa]; |
| 3035 } else { | 3045 } else { |
| 3036 typeParts = [rt, ra]; | 3046 typeParts = [rt, ra]; |
| 3037 } | 3047 } |
| 3038 | 3048 |
| 3039 var typeFormals = type.typeFormals; | 3049 var typeFormals = type.typeFormals; |
| 3040 if (typeFormals.isNotEmpty && !lowerTypedef) { | 3050 if (typeFormals.isNotEmpty) { |
| 3041 // TODO(jmesserly): this is a suboptimal representation for universal | 3051 // TODO(jmesserly): this is a suboptimal representation for universal |
| 3042 // function types (as callable functions). See discussion at | 3052 // function types (as callable functions). See discussion at |
| 3043 // https://github.com/dart-lang/sdk/issues/27333 | 3053 // https://github.com/dart-lang/sdk/issues/27333 |
| 3044 var tf = _emitTypeFormals(typeFormals); | 3054 var tf = _emitTypeFormals(typeFormals); |
| 3045 var names = _typeTable.discharge(typeFormals); | 3055 var names = _typeTable.discharge(typeFormals); |
| 3046 var parts = new JS.ArrayInitializer(typeParts); | 3056 var parts = new JS.ArrayInitializer(typeParts); |
| 3047 if (names.isEmpty) { | 3057 if (names.isEmpty) { |
| 3048 typeParts = [ | 3058 typeParts = [ |
| 3049 js.call('(#) => #', [tf, parts]) | 3059 js.call('(#) => #', [tf, parts]) |
| 3050 ]; | 3060 ]; |
| (...skipping 3067 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6118 if (targetIdentifier.staticElement is! PrefixElement) return false; | 6128 if (targetIdentifier.staticElement is! PrefixElement) return false; |
| 6119 var prefix = targetIdentifier.staticElement as PrefixElement; | 6129 var prefix = targetIdentifier.staticElement as PrefixElement; |
| 6120 | 6130 |
| 6121 // The library the prefix is referring to must come from a deferred import. | 6131 // The library the prefix is referring to must come from a deferred import. |
| 6122 var containingLibrary = resolutionMap | 6132 var containingLibrary = resolutionMap |
| 6123 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 6133 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
| 6124 .library; | 6134 .library; |
| 6125 var imports = containingLibrary.getImportsWithPrefix(prefix); | 6135 var imports = containingLibrary.getImportsWithPrefix(prefix); |
| 6126 return imports.length == 1 && imports[0].isDeferred; | 6136 return imports.length == 1 && imports[0].isDeferred; |
| 6127 } | 6137 } |
| OLD | NEW |