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}) { | |
3030 var parameterTypes = type.normalParameterTypes; | 2995 var parameterTypes = type.normalParameterTypes; |
3031 var optionalTypes = type.optionalParameterTypes; | 2996 var optionalTypes = type.optionalParameterTypes; |
3032 var namedTypes = type.namedParameterTypes; | 2997 var namedTypes = type.namedParameterTypes; |
3033 var rt = | 2998 var rt = |
3034 _emitType(type.returnType, nameType: nameType, hoistType: hoistType); | 2999 _emitType(type.returnType, nameType: nameType, hoistType: hoistType); |
3035 | 3000 |
3036 var ra = _emitTypeNames(parameterTypes, parameters, | 3001 var ra = _emitTypeNames(parameterTypes, parameters, |
3037 nameType: nameType, hoistType: hoistType); | 3002 nameType: nameType, hoistType: hoistType); |
3038 | 3003 |
3039 List<JS.Expression> typeParts; | 3004 List<JS.Expression> typeParts; |
3040 if (namedTypes.isNotEmpty) { | 3005 if (namedTypes.isNotEmpty) { |
3041 assert(optionalTypes.isEmpty); | 3006 assert(optionalTypes.isEmpty); |
3042 // TODO(vsm): Pass in annotations here as well. | 3007 // TODO(vsm): Pass in annotations here as well. |
3043 var na = _emitTypeProperties(namedTypes); | 3008 var na = _emitTypeProperties(namedTypes); |
3044 typeParts = [rt, ra, na]; | 3009 typeParts = [rt, ra, na]; |
3045 } else if (optionalTypes.isNotEmpty) { | 3010 } else if (optionalTypes.isNotEmpty) { |
3046 assert(namedTypes.isEmpty); | 3011 assert(namedTypes.isEmpty); |
3047 var oa = _emitTypeNames( | 3012 var oa = _emitTypeNames( |
3048 optionalTypes, parameters?.sublist(parameterTypes.length), | 3013 optionalTypes, parameters?.sublist(parameterTypes.length), |
3049 nameType: nameType, hoistType: hoistType); | 3014 nameType: nameType, hoistType: hoistType); |
3050 typeParts = [rt, ra, oa]; | 3015 typeParts = [rt, ra, oa]; |
3051 } else { | 3016 } else { |
3052 typeParts = [rt, ra]; | 3017 typeParts = [rt, ra]; |
3053 } | 3018 } |
3054 | 3019 |
| 3020 JS.Expression fullType; |
3055 var typeFormals = type.typeFormals; | 3021 var typeFormals = type.typeFormals; |
| 3022 String helperCall; |
3056 if (typeFormals.isNotEmpty) { | 3023 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 | |
3060 var tf = _emitTypeFormals(typeFormals); | 3024 var tf = _emitTypeFormals(typeFormals); |
3061 var names = _typeTable.discharge(typeFormals); | 3025 |
3062 var parts = new JS.ArrayInitializer(typeParts); | 3026 addTypeFormalsAsParameters(List<JS.Expression> elements) { |
3063 if (names.isEmpty) { | 3027 var names = _typeTable.discharge(typeFormals); |
3064 typeParts = [ | 3028 var array = new JS.ArrayInitializer(elements); |
3065 js.call('(#) => #', [tf, parts]) | 3029 return names.isEmpty |
3066 ]; | 3030 ? js.call('(#) => #', [tf, array]) |
3067 } else { | 3031 : js.call('(#) => {#; return #;}', [tf, names, array]); |
3068 typeParts = [ | |
3069 js.call('(#) => {#; return #;}', [tf, names, parts]) | |
3070 ]; | |
3071 } | 3032 } |
| 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(#)'; |
3072 } | 3044 } |
3073 return typeParts; | 3045 fullType = _callHelper(helperCall, [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); |
3074 } | 3065 } |
3075 | 3066 |
3076 /// Emits an expression that lets you access statics on a [type] from code. | 3067 /// Emits an expression that lets you access statics on a [type] from code. |
3077 /// | 3068 /// |
3078 /// If [nameType] is true, then the type will be named. In addition, | 3069 /// If [nameType] is true, then the type will be named. In addition, |
3079 /// if [hoistType] is true, then the named type will be hoisted. | 3070 /// if [hoistType] is true, then the named type will be hoisted. |
3080 JS.Expression _emitConstructorAccess(DartType type, | 3071 JS.Expression _emitConstructorAccess(DartType type, |
3081 {bool nameType: true, bool hoistType: true}) { | 3072 {bool nameType: true, bool hoistType: true}) { |
3082 return _emitJSInterop(type.element) ?? | 3073 return _emitJSInterop(type.element) ?? |
3083 _emitType(type, nameType: nameType, hoistType: hoistType); | 3074 _emitType(type, nameType: nameType, hoistType: hoistType); |
(...skipping 3053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6137 if (targetIdentifier.staticElement is! PrefixElement) return false; | 6128 if (targetIdentifier.staticElement is! PrefixElement) return false; |
6138 var prefix = targetIdentifier.staticElement as PrefixElement; | 6129 var prefix = targetIdentifier.staticElement as PrefixElement; |
6139 | 6130 |
6140 // 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. |
6141 var containingLibrary = resolutionMap | 6132 var containingLibrary = resolutionMap |
6142 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) | 6133 .elementDeclaredByCompilationUnit(target.root as CompilationUnit) |
6143 .library; | 6134 .library; |
6144 var imports = containingLibrary.getImportsWithPrefix(prefix); | 6135 var imports = containingLibrary.getImportsWithPrefix(prefix); |
6145 return imports.length == 1 && imports[0].isDeferred; | 6136 return imports.length == 1 && imports[0].isDeferred; |
6146 } | 6137 } |
OLD | NEW |