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