Index: pkg/fasta/lib/src/kernel/kernel_function_type_alias_builder.dart |
diff --git a/pkg/fasta/lib/src/kernel/kernel_function_type_alias_builder.dart b/pkg/fasta/lib/src/kernel/kernel_function_type_alias_builder.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ac709f084d0b10d68692a71ba02f47abbdd66df2 |
--- /dev/null |
+++ b/pkg/fasta/lib/src/kernel/kernel_function_type_alias_builder.dart |
@@ -0,0 +1,113 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library fasta.kernel_function_type_alias_builder; |
+ |
+import 'package:kernel/ast.dart' show |
+ DartType, |
+ DynamicType, |
+ FunctionType, |
+ InvalidType, |
+ NamedType, |
+ TypeParameter; |
+ |
+import 'package:kernel/type_algebra.dart' show |
+ substitute; |
+ |
+import 'kernel_builder.dart' show |
+ FormalParameterBuilder, |
+ FunctionTypeAliasBuilder, |
+ KernelFormalParameterBuilder, |
+ KernelTypeBuilder, |
+ KernelTypeVariableBuilder, |
+ LibraryBuilder, |
+ MetadataBuilder, |
+ TypeVariableBuilder, |
+ computeDefaultTypeArguments; |
+ |
+class KernelFunctionTypeAliasBuilder |
+ extends FunctionTypeAliasBuilder<KernelTypeBuilder, DartType> { |
+ DartType thisType; |
+ |
+ DartType type; |
+ |
+ KernelFunctionTypeAliasBuilder(List<MetadataBuilder> metadata, |
+ KernelTypeBuilder returnType, String name, |
+ List<TypeVariableBuilder> typeVariables, |
+ List<FormalParameterBuilder> formals, List<KernelTypeBuilder> types, |
+ LibraryBuilder parent) |
+ : super(metadata, returnType, name, typeVariables, formals, types, |
+ parent); |
+ |
+ DartType buildThisType() { |
+ if (thisType != null) { |
+ if (thisType == const InvalidType()) { |
+ thisType = const DynamicType(); |
+ // TODO(ahe): Build an error somehow. |
+ print("${parent.uri}: Cyclic typedef: $name."); |
+ } |
+ return thisType; |
+ } |
+ thisType = const InvalidType(); |
+ DartType returnType = this.returnType?.build() ?? const DynamicType(); |
+ List<DartType> positionalParameters = <DartType>[]; |
+ List<NamedType> namedParameters; |
+ int requiredParameterCount = 0; |
+ if (formals != null) { |
+ for (KernelFormalParameterBuilder formal in formals) { |
+ DartType type = formal.type?.build() ?? const DynamicType(); |
+ if (formal.isPositional) { |
+ positionalParameters.add(type); |
+ if (formal.isRequired) requiredParameterCount++; |
+ } else if (formal.isNamed) { |
+ namedParameters ??= <NamedType>[]; |
+ namedParameters.add(new NamedType(formal.name, type)); |
+ } |
+ } |
+ if (namedParameters != null) { |
+ namedParameters.sort(); |
+ } |
+ } |
+ List<TypeParameter> typeParameters; |
+ if (typeVariables != null) { |
+ typeParameters = <TypeParameter>[]; |
+ for (KernelTypeVariableBuilder t in typeVariables) { |
+ typeParameters.add(t.parameter); |
+ } |
+ } |
+ return thisType = new FunctionType(positionalParameters, returnType, |
+ namedParameters: namedParameters ?? const <NamedType>[], |
+ typeParameters: typeParameters ?? const <TypeParameter>[], |
+ requiredParameterCount: requiredParameterCount); |
+ } |
+ |
+ /// [arguments] have already been built. |
+ DartType buildTypesWithBuiltArguments(List<DartType> arguments) { |
+ var thisType = buildThisType(); |
+ if (thisType is DynamicType) return thisType; |
+ FunctionType result = thisType; |
+ if (result.typeParameters.isEmpty && arguments == null) return result; |
+ arguments = computeDefaultTypeArguments(result.typeParameters, arguments); |
+ Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{}; |
+ for (int i = 0; i < result.typeParameters.length; i++) { |
+ substitution[result.typeParameters[i]] = arguments[i]; |
+ } |
+ return substitute(result.withoutTypeParameters, substitution); |
+ } |
+ |
+ DartType buildType(List<KernelTypeBuilder> arguments) { |
+ var thisType = buildThisType(); |
+ if (thisType is DynamicType) return thisType; |
+ FunctionType result = thisType; |
+ if (result.typeParameters.isEmpty && arguments == null) return result; |
+ // Otherwise, substitute. |
+ List<DartType> builtArguments = <DartType>[]; |
+ if (arguments != null) { |
+ for (int i = 0; i < arguments.length; i++) { |
+ builtArguments.add(arguments[i].build()); |
+ } |
+ } |
+ return buildTypesWithBuiltArguments(builtArguments); |
+ } |
+} |