| Index: pkg/kernel/lib/transformations/closure/converter.dart
|
| diff --git a/pkg/kernel/lib/transformations/closure/converter.dart b/pkg/kernel/lib/transformations/closure/converter.dart
|
| index 5ee224172f0006729dda2786a0733ec62dadfdff..713ab38cdc6995e812fabb5dad3932f2fabd491d 100644
|
| --- a/pkg/kernel/lib/transformations/closure/converter.dart
|
| +++ b/pkg/kernel/lib/transformations/closure/converter.dart
|
| @@ -13,7 +13,6 @@ import '../../ast.dart'
|
| ClosureCreation,
|
| Constructor,
|
| DartType,
|
| - DynamicType,
|
| EmptyStatement,
|
| Expression,
|
| ExpressionStatement,
|
| @@ -260,39 +259,12 @@ class ClosureConverter extends Transformer {
|
| context = context.toNestedContext(
|
| new VariableAccessor(contextVariable, null, TreeNode.noOffset));
|
|
|
| - Set<TypeParameter> captured = capturedTypeVariables[currentFunction];
|
| - if (captured != null) {
|
| - typeSubstitution = copyTypeVariables(captured);
|
| - } else {
|
| - typeSubstitution = const <TypeParameter, DartType>{};
|
| - }
|
| + Set<TypeParameter> captured =
|
| + capturedTypeVariables[currentFunction] ?? new Set<TypeParameter>();
|
| + typeSubstitution = copyTypeVariables(captured);
|
|
|
| - // TODO(29181): remove replacementTypeSubstitution variable and its usages.
|
| - // All the type variables used in this function body are replaced with
|
| - // either dynamic or their bounds. This is to temporarily remove the type
|
| - // variables from closure conversion. They should be returned after the VM
|
| - // changes are done to support vectors and closure creation. See #29181.
|
| - Map<TypeParameter, DartType> replacementTypeSubstitution =
|
| - <TypeParameter, DartType>{};
|
| - for (TypeParameter parameter in typeSubstitution.keys) {
|
| - replacementTypeSubstitution[parameter] = const DynamicType();
|
| - }
|
| - for (TypeParameter parameter in typeSubstitution.keys) {
|
| - if (!isObject(parameter.bound)) {
|
| - replacementTypeSubstitution[parameter] =
|
| - substitute(parameter.bound, replacementTypeSubstitution);
|
| - }
|
| - }
|
| - typeSubstitution = replacementTypeSubstitution;
|
| function.transformChildren(this);
|
|
|
| - // TODO(29181): don't replace typeSubstitution with an empty map.
|
| - // Information about captured type variables is deleted from the closure
|
| - // class, because the type variables in this function body are already
|
| - // replaced with either dynamic or their bounds. This change should be
|
| - // undone after the VM support for vectors and closure creation is
|
| - // implemented. See #29181.
|
| - typeSubstitution = <TypeParameter, DartType>{};
|
| Expression result = addClosure(function, contextVariable, parent.expression,
|
| typeSubstitution, enclosingTypeSubstitution);
|
| currentFunction = enclosingFunction;
|
| @@ -322,9 +294,7 @@ class ClosureConverter extends Transformer {
|
| }
|
|
|
| TreeNode visitFunctionExpression(FunctionExpression node) {
|
| - return saveContext(() {
|
| - return handleLocalFunction(node.function);
|
| - });
|
| + return saveContext(() => handleLocalFunction(node.function));
|
| }
|
|
|
| /// Add a new procedure to the current library that looks like this:
|
| @@ -346,6 +316,16 @@ class ClosureConverter extends Transformer {
|
| Expression accessContext,
|
| Map<TypeParameter, DartType> substitution,
|
| Map<TypeParameter, DartType> enclosingTypeSubstitution) {
|
| + var fnTypeParams = <TypeParameter>[];
|
| + var fnTypeArgs = <TypeParameterType>[];
|
| + for (TypeParameter t in substitution.keys) {
|
| + var fnTypeParam = (substitution[t] as TypeParameterType).parameter;
|
| + fnTypeParams.add(fnTypeParam);
|
| + fnTypeArgs
|
| + .add(substitute(new TypeParameterType(t), enclosingTypeSubstitution));
|
| + }
|
| +
|
| + function.typeParameters.insertAll(0, fnTypeParams);
|
| function.positionalParameters.insert(0, contextVariable);
|
| ++function.requiredParameterCount;
|
| Procedure closedTopLevelFunction = new Procedure(
|
| @@ -356,21 +336,29 @@ class ClosureConverter extends Transformer {
|
| fileUri: currentFileUri);
|
| newLibraryMembers.add(closedTopLevelFunction);
|
|
|
| + // We need to again make new type parameters for the function's function
|
| + // type, and substitute them into the function type's arguments' types.
|
| + var closureTypeParams = <TypeParameter>[];
|
| + var closureTypeSubstitutionMap = copyTypeVariables(function.typeParameters);
|
| + for (DartType d in closureTypeSubstitutionMap.values)
|
| + closureTypeParams.add((d as TypeParameterType).parameter);
|
| +
|
| FunctionType closureType = new FunctionType(
|
| function.positionalParameters
|
| .skip(1)
|
| - .map((VariableDeclaration decl) => decl.type)
|
| + .map((VariableDeclaration decl) =>
|
| + substitute(decl.type, closureTypeSubstitutionMap))
|
| .toList(),
|
| - function.returnType,
|
| + substitute(function.returnType, closureTypeSubstitutionMap),
|
| namedParameters: function.namedParameters
|
| - .map((VariableDeclaration decl) =>
|
| - new NamedType(decl.name, decl.type))
|
| + .map((VariableDeclaration decl) => new NamedType(
|
| + decl.name, substitute(decl.type, closureTypeSubstitutionMap)))
|
| .toList(),
|
| - typeParameters: function.typeParameters,
|
| + typeParameters: closureTypeParams,
|
| requiredParameterCount: function.requiredParameterCount - 1);
|
|
|
| return new ClosureCreation(
|
| - closedTopLevelFunction, accessContext, closureType);
|
| + closedTopLevelFunction, accessContext, closureType, fnTypeArgs);
|
| }
|
|
|
| TreeNode visitProcedure(Procedure node) {
|
| @@ -664,14 +652,19 @@ class ClosureConverter extends Transformer {
|
|
|
| /// Creates copies of the type variables in [original] and returns a
|
| /// substitution that can be passed to [substitute] to substitute all uses of
|
| - /// [original] with their copies.
|
| + /// [original] with their copies. Additionally returns a list of new type
|
| + /// parameters to prefix to the enclosing function's type parameters and the
|
| + /// arguments to be passed for those parameters.
|
| + ///
|
| Map<TypeParameter, DartType> copyTypeVariables(
|
| Iterable<TypeParameter> original) {
|
| if (original.isEmpty) return const <TypeParameter, DartType>{};
|
| +
|
| Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
|
| for (TypeParameter t in original) {
|
| substitution[t] = new TypeParameterType(new TypeParameter(t.name));
|
| }
|
| +
|
| substitution.forEach((TypeParameter t, DartType copy) {
|
| if (copy is TypeParameterType) {
|
| copy.parameter.bound = substitute(t.bound, substitution);
|
|
|