Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(537)

Unified Diff: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Issue 2964013002: Implement type variables on generalized function types. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/front_end/lib/src/fasta/kernel/body_builder.dart
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 37d5f8c7345f878bcfd7f6358d90f026ef76ebe2..bdd87d8e9d5f4132504a1bf2d079aab5e079ec68 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1697,13 +1697,38 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
}
}
+ @override
+ void beginFunctionType(Token beginToken) {
+ debugEvent("beginFunctionType");
+ List typeVariables = pop();
+ enterLocalScope(scope.createNestedScope(isModifiable: false));
+ push(typeVariables ?? NullValue.TypeVariables);
+ if (typeVariables != null) {
+ ScopeBuilder scopeBuilder = new ScopeBuilder(scope);
+ for (KernelTypeVariableBuilder builder in typeVariables) {
+ String name = builder.name;
+ KernelTypeVariableBuilder existing = scopeBuilder[name];
+ if (existing == null) {
+ scopeBuilder.addMember(name, builder);
+ } else {
+ addCompileTimeError(
+ builder.charOffset, "'$name' already declared in this scope.");
+ addCompileTimeError(
+ existing.charOffset, "Previous definition of '$name'.");
+ }
+ }
+ }
+ }
+
@override
void endFunctionType(Token functionToken, Token endToken) {
debugEvent("FunctionType");
FormalParameters formals = pop();
DartType returnType = pop();
- ignore(Unhandled.TypeVariables);
- push(formals.toFunctionType(returnType));
+ List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
+ FunctionType type = formals.toFunctionType(returnType, typeVariables);
+ exitLocalScope();
+ push(type);
}
@override
@@ -2403,7 +2428,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
exitLocalScope();
}
FormalParameters formals = pop();
- List<TypeParameter> typeParameters = pop();
+ List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
push(formals.addToFunction(new FunctionNode(body,
typeParameters: typeParameters, asyncMarker: asyncModifier)
..fileOffset = formals.charOffset
@@ -2447,7 +2472,7 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
exitLocalScope();
FormalParameters formals = pop();
exitFunction();
- List<TypeParameter> typeParameters = pop();
+ List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
FunctionNode function = formals.addToFunction(new FunctionNode(body,
typeParameters: typeParameters, asyncMarker: asyncModifier)
..fileOffset = beginToken.charOffset
@@ -2915,17 +2940,36 @@ class BodyBuilder extends ScopeListener<JumpTarget> implements BuilderHelper {
@override
void endTypeVariable(Token token, Token extendsOrSuper) {
debugEvent("TypeVariable");
- // TODO(ahe): Do not discard these when enabling generic method syntax.
- pop(); // Bound.
- pop(); // Name.
+ DartType bound = pop();
+ if (bound != null) {
+ // TODO(ahe): To handle F-bounded types, this needs to be a TypeBuilder.
+ warningNotError("Type variable bounds not implemented yet.",
+ offsetForToken(extendsOrSuper.next));
+ }
+ Identifier name = pop();
+ // TODO(ahe): Do not discard metadata.
pop(); // Metadata.
+ push(new KernelTypeVariableBuilder(
+ name.name, library, offsetForToken(name.token), null)
+ ..finish(library, library.loader.coreLibrary["Object"]));
}
@override
void endTypeVariables(int count, Token beginToken, Token endToken) {
debugEvent("TypeVariables");
- // TODO(ahe): Implement this when enabling generic method syntax.
- push(NullValue.TypeVariables);
+ push(popList(count) ?? NullValue.TypeVariables);
+ }
+
+ List<TypeParameter> typeVariableBuildersToKernel(List typeVariableBuilders) {
+ if (typeVariableBuilders == null) return null;
+ List<TypeParameter> typeParameters = new List<TypeParameter>.filled(
Paul Berry 2017/06/29 17:45:40 Nit: why not use map()?
ahe 2017/07/04 11:07:45 I try to avoid methods like that because they aren
+ typeVariableBuilders.length, null,
+ growable: true);
+ int i = 0;
+ for (KernelTypeVariableBuilder builder in typeVariableBuilders) {
+ typeParameters[i++] = builder.target;
+ }
+ return typeParameters;
}
@override
@@ -3571,8 +3615,10 @@ class FormalParameters {
return function;
}
- FunctionType toFunctionType(DartType returnType) {
+ FunctionType toFunctionType(DartType returnType,
+ [List<TypeParameter> typeParameters]) {
returnType ??= const DynamicType();
+ typeParameters ??= const <TypeParameter>[];
int requiredParameterCount = required.length;
List<DartType> positionalParameters = <DartType>[];
List<NamedType> namedParameters = const <NamedType>[];
@@ -3594,7 +3640,8 @@ class FormalParameters {
}
return new FunctionType(positionalParameters, returnType,
namedParameters: namedParameters,
- requiredParameterCount: requiredParameterCount);
+ requiredParameterCount: requiredParameterCount,
+ typeParameters: typeParameters);
}
Scope computeFormalParameterScope(

Powered by Google App Engine
This is Rietveld 408576698