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 2974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2985 } | 2985 } |
2986 | 2986 |
2987 /// Emit the pieces of a function type, as an array of return type, | 2987 /// Emit the pieces of a function type, as an array of return type, |
2988 /// regular args, and optional/named args. | 2988 /// regular args, and optional/named args. |
2989 JS.Expression _emitFunctionType(FunctionType type, | 2989 JS.Expression _emitFunctionType(FunctionType type, |
2990 {List<FormalParameter> parameters, | 2990 {List<FormalParameter> parameters, |
2991 bool lowerTypedef: false, | 2991 bool lowerTypedef: false, |
2992 bool nameType: true, | 2992 bool nameType: true, |
2993 bool hoistType: true, | 2993 bool hoistType: true, |
2994 definite: false}) { | 2994 definite: false}) { |
| 2995 var parts = _emitFunctionTypeParts(type, |
| 2996 parameters: parameters, |
| 2997 lowerTypedef: lowerTypedef, |
| 2998 nameType: nameType, |
| 2999 hoistType: hoistType); |
| 3000 var helper = definite ? 'definiteFunctionType' : 'functionType'; |
| 3001 var fullType = _callHelper('${helper}(#)', [parts]); |
| 3002 if (!nameType) return fullType; |
| 3003 return _typeTable.nameType(type, fullType, |
| 3004 hoistType: hoistType, definite: definite); |
| 3005 } |
| 3006 |
| 3007 JS.Expression _emitAnnotatedFunctionType( |
| 3008 FunctionType type, List<Annotation> metadata, |
| 3009 {List<FormalParameter> parameters, |
| 3010 bool lowerTypedef: false, |
| 3011 bool nameType: true, |
| 3012 bool hoistType: true, |
| 3013 bool definite: false}) { |
| 3014 var result = _emitFunctionType(type, |
| 3015 parameters: parameters, |
| 3016 lowerTypedef: lowerTypedef, |
| 3017 nameType: nameType, |
| 3018 hoistType: hoistType, |
| 3019 definite: definite); |
| 3020 return _emitAnnotatedResult(result, metadata); |
| 3021 } |
| 3022 |
| 3023 /// Emit the pieces of a function type, as an array of return type, |
| 3024 /// regular args, and optional/named args. |
| 3025 List<JS.Expression> _emitFunctionTypeParts(FunctionType type, |
| 3026 {List<FormalParameter> parameters, |
| 3027 bool lowerTypedef: false, |
| 3028 bool nameType: true, |
| 3029 bool hoistType: true}) { |
2995 var parameterTypes = type.normalParameterTypes; | 3030 var parameterTypes = type.normalParameterTypes; |
2996 var optionalTypes = type.optionalParameterTypes; | 3031 var optionalTypes = type.optionalParameterTypes; |
2997 var namedTypes = type.namedParameterTypes; | 3032 var namedTypes = type.namedParameterTypes; |
2998 var rt = | 3033 var rt = |
2999 _emitType(type.returnType, nameType: nameType, hoistType: hoistType); | 3034 _emitType(type.returnType, nameType: nameType, hoistType: hoistType); |
3000 | 3035 |
3001 var ra = _emitTypeNames(parameterTypes, parameters, | 3036 var ra = _emitTypeNames(parameterTypes, parameters, |
3002 nameType: nameType, hoistType: hoistType); | 3037 nameType: nameType, hoistType: hoistType); |
3003 | 3038 |
3004 List<JS.Expression> typeParts; | 3039 List<JS.Expression> typeParts; |
3005 if (namedTypes.isNotEmpty) { | 3040 if (namedTypes.isNotEmpty) { |
3006 assert(optionalTypes.isEmpty); | 3041 assert(optionalTypes.isEmpty); |
3007 // TODO(vsm): Pass in annotations here as well. | 3042 // TODO(vsm): Pass in annotations here as well. |
3008 var na = _emitTypeProperties(namedTypes); | 3043 var na = _emitTypeProperties(namedTypes); |
3009 typeParts = [rt, ra, na]; | 3044 typeParts = [rt, ra, na]; |
3010 } else if (optionalTypes.isNotEmpty) { | 3045 } else if (optionalTypes.isNotEmpty) { |
3011 assert(namedTypes.isEmpty); | 3046 assert(namedTypes.isEmpty); |
3012 var oa = _emitTypeNames( | 3047 var oa = _emitTypeNames( |
3013 optionalTypes, parameters?.sublist(parameterTypes.length), | 3048 optionalTypes, parameters?.sublist(parameterTypes.length), |
3014 nameType: nameType, hoistType: hoistType); | 3049 nameType: nameType, hoistType: hoistType); |
3015 typeParts = [rt, ra, oa]; | 3050 typeParts = [rt, ra, oa]; |
3016 } else { | 3051 } else { |
3017 typeParts = [rt, ra]; | 3052 typeParts = [rt, ra]; |
3018 } | 3053 } |
3019 | 3054 |
3020 JS.Expression fullType; | |
3021 var typeFormals = type.typeFormals; | 3055 var typeFormals = type.typeFormals; |
3022 String helperCall; | |
3023 if (typeFormals.isNotEmpty) { | 3056 if (typeFormals.isNotEmpty) { |
| 3057 // TODO(jmesserly): this is a suboptimal representation for universal |
| 3058 // function types (as callable functions). See discussion at |
| 3059 // https://github.com/dart-lang/sdk/issues/27333 |
3024 var tf = _emitTypeFormals(typeFormals); | 3060 var tf = _emitTypeFormals(typeFormals); |
3025 | 3061 var names = _typeTable.discharge(typeFormals); |
3026 addTypeFormalsAsParameters(List<JS.Expression> elements) { | 3062 var parts = new JS.ArrayInitializer(typeParts); |
3027 var names = _typeTable.discharge(typeFormals); | 3063 if (names.isEmpty) { |
3028 var array = new JS.ArrayInitializer(elements); | 3064 typeParts = [ |
3029 return names.isEmpty | 3065 js.call('(#) => #', [tf, parts]) |
3030 ? js.call('(#) => #', [tf, array]) | 3066 ]; |
3031 : js.call('(#) => {#; return #;}', [tf, names, array]); | 3067 } else { |
| 3068 typeParts = [ |
| 3069 js.call('(#) => {#; return #;}', [tf, names, parts]) |
| 3070 ]; |
3032 } | 3071 } |
3033 | |
3034 typeParts = [addTypeFormalsAsParameters(typeParts)]; | |
3035 | |
3036 helperCall = definite ? 'gFnType(#)' : 'gFnTypeFuzzy(#)'; | |
3037 // If any explicit bounds were passed, emit them. | |
3038 if (typeFormals.any((t) => t.bound != null)) { | |
3039 var bounds = typeFormals.map((t) => _emitType(t.type.bound)).toList(); | |
3040 typeParts.add(addTypeFormalsAsParameters(bounds)); | |
3041 } | |
3042 } else { | |
3043 helperCall = definite ? 'fnType(#)' : 'fnTypeFuzzy(#)'; | |
3044 } | 3072 } |
3045 fullType = _callHelper(helperCall, [typeParts]); | 3073 return typeParts; |
3046 if (!nameType) return fullType; | |
3047 return _typeTable.nameType(type, fullType, | |
3048 hoistType: hoistType, definite: definite); | |
3049 } | |
3050 | |
3051 JS.Expression _emitAnnotatedFunctionType( | |
3052 FunctionType type, List<Annotation> metadata, | |
3053 {List<FormalParameter> parameters, | |
3054 bool lowerTypedef: false, | |
3055 bool nameType: true, | |
3056 bool hoistType: true, | |
3057 bool definite: false}) { | |
3058 var result = _emitFunctionType(type, | |
3059 parameters: parameters, | |
3060 lowerTypedef: lowerTypedef, | |
3061 nameType: nameType, | |
3062 hoistType: hoistType, | |
3063 definite: definite); | |
3064 return _emitAnnotatedResult(result, metadata); | |
3065 } | 3074 } |
3066 | 3075 |
3067 /// Emits an expression that lets you access statics on a [type] from code. | 3076 /// Emits an expression that lets you access statics on a [type] from code. |
3068 /// | 3077 /// |
3069 /// If [nameType] is true, then the type will be named. In addition, | 3078 /// If [nameType] is true, then the type will be named. In addition, |
3070 /// if [hoistType] is true, then the named type will be hoisted. | 3079 /// if [hoistType] is true, then the named type will be hoisted. |
3071 JS.Expression _emitConstructorAccess(DartType type, | 3080 JS.Expression _emitConstructorAccess(DartType type, |
3072 {bool nameType: true, bool hoistType: true}) { | 3081 {bool nameType: true, bool hoistType: true}) { |
3073 return _emitJSInterop(type.element) ?? | 3082 return _emitJSInterop(type.element) ?? |
3074 _emitType(type, nameType: nameType, hoistType: hoistType); | 3083 _emitType(type, nameType: nameType, hoistType: hoistType); |
(...skipping 3053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6128 if (targetIdentifier.staticElement is! PrefixElement) return false; | 6137 if (targetIdentifier.staticElement is! PrefixElement) return false; |
6129 var prefix = targetIdentifier.staticElement as PrefixElement; | 6138 var prefix = targetIdentifier.staticElement as PrefixElement; |
6130 | 6139 |
6131 // The library the prefix is referring to must come from a deferred import. | 6140 // The library the prefix is referring to must come from a deferred import. |
6132 var containingLibrary = resolutionMap | 6141 var containingLibrary = resolutionMap |
6133 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 6142 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
6134 .library; | 6143 .library; |
6135 var imports = containingLibrary.getImportsWithPrefix(prefix); | 6144 var imports = containingLibrary.getImportsWithPrefix(prefix); |
6136 return imports.length == 1 && imports[0].isDeferred; | 6145 return imports.length == 1 && imports[0].isDeferred; |
6137 } | 6146 } |
OLD | NEW |