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

Side by Side 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, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.body_builder; 5 library fasta.body_builder;
6 6
7 import '../fasta_codes.dart' 7 import '../fasta_codes.dart'
8 show 8 show
9 FastaMessage, 9 FastaMessage,
10 codeConstFieldWithoutInitializer, 10 codeConstFieldWithoutInitializer,
(...skipping 1680 matching lines...) Expand 10 before | Expand all | Expand 10 after
1691 } else if (name is Builder) { 1691 } else if (name is Builder) {
1692 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset)); 1692 push(kernelTypeFromBuilder(name, arguments, beginToken.charOffset));
1693 } else if (name is String) { 1693 } else if (name is String) {
1694 push(kernelTypeFromString(name, arguments, beginToken.charOffset)); 1694 push(kernelTypeFromString(name, arguments, beginToken.charOffset));
1695 } else { 1695 } else {
1696 internalError("Unhandled: '${name.runtimeType}'."); 1696 internalError("Unhandled: '${name.runtimeType}'.");
1697 } 1697 }
1698 } 1698 }
1699 1699
1700 @override 1700 @override
1701 void beginFunctionType(Token beginToken) {
1702 debugEvent("beginFunctionType");
1703 List typeVariables = pop();
1704 enterLocalScope(scope.createNestedScope(isModifiable: false));
1705 push(typeVariables ?? NullValue.TypeVariables);
1706 if (typeVariables != null) {
1707 ScopeBuilder scopeBuilder = new ScopeBuilder(scope);
1708 for (KernelTypeVariableBuilder builder in typeVariables) {
1709 String name = builder.name;
1710 KernelTypeVariableBuilder existing = scopeBuilder[name];
1711 if (existing == null) {
1712 scopeBuilder.addMember(name, builder);
1713 } else {
1714 addCompileTimeError(
1715 builder.charOffset, "'$name' already declared in this scope.");
1716 addCompileTimeError(
1717 existing.charOffset, "Previous definition of '$name'.");
1718 }
1719 }
1720 }
1721 }
1722
1723 @override
1701 void endFunctionType(Token functionToken, Token endToken) { 1724 void endFunctionType(Token functionToken, Token endToken) {
1702 debugEvent("FunctionType"); 1725 debugEvent("FunctionType");
1703 FormalParameters formals = pop(); 1726 FormalParameters formals = pop();
1704 DartType returnType = pop(); 1727 DartType returnType = pop();
1705 ignore(Unhandled.TypeVariables); 1728 List<TypeParameter> typeVariables = typeVariableBuildersToKernel(pop());
1706 push(formals.toFunctionType(returnType)); 1729 FunctionType type = formals.toFunctionType(returnType, typeVariables);
1730 exitLocalScope();
1731 push(type);
1707 } 1732 }
1708 1733
1709 @override 1734 @override
1710 void handleVoidKeyword(Token token) { 1735 void handleVoidKeyword(Token token) {
1711 debugEvent("VoidKeyword"); 1736 debugEvent("VoidKeyword");
1712 push(const VoidType()); 1737 push(const VoidType());
1713 } 1738 }
1714 1739
1715 @override 1740 @override
1716 void handleAsOperator(Token operator, Token endToken) { 1741 void handleAsOperator(Token operator, Token endToken) {
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
2396 2421
2397 @override 2422 @override
2398 void endFunction(Token getOrSet, Token endToken) { 2423 void endFunction(Token getOrSet, Token endToken) {
2399 debugEvent("Function"); 2424 debugEvent("Function");
2400 Statement body = popStatement(); 2425 Statement body = popStatement();
2401 AsyncMarker asyncModifier = pop(); 2426 AsyncMarker asyncModifier = pop();
2402 if (functionNestingLevel != 0) { 2427 if (functionNestingLevel != 0) {
2403 exitLocalScope(); 2428 exitLocalScope();
2404 } 2429 }
2405 FormalParameters formals = pop(); 2430 FormalParameters formals = pop();
2406 List<TypeParameter> typeParameters = pop(); 2431 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
2407 push(formals.addToFunction(new FunctionNode(body, 2432 push(formals.addToFunction(new FunctionNode(body,
2408 typeParameters: typeParameters, asyncMarker: asyncModifier) 2433 typeParameters: typeParameters, asyncMarker: asyncModifier)
2409 ..fileOffset = formals.charOffset 2434 ..fileOffset = formals.charOffset
2410 ..fileEndOffset = endToken.charOffset)); 2435 ..fileEndOffset = endToken.charOffset));
2411 } 2436 }
2412 2437
2413 @override 2438 @override
2414 void endFunctionDeclaration(Token token) { 2439 void endFunctionDeclaration(Token token) {
2415 debugEvent("FunctionDeclaration"); 2440 debugEvent("FunctionDeclaration");
2416 FunctionNode function = pop(); 2441 FunctionNode function = pop();
(...skipping 23 matching lines...) Expand all
2440 } 2465 }
2441 2466
2442 @override 2467 @override
2443 void endUnnamedFunction(Token beginToken, Token token) { 2468 void endUnnamedFunction(Token beginToken, Token token) {
2444 debugEvent("UnnamedFunction"); 2469 debugEvent("UnnamedFunction");
2445 Statement body = popStatement(); 2470 Statement body = popStatement();
2446 AsyncMarker asyncModifier = pop(); 2471 AsyncMarker asyncModifier = pop();
2447 exitLocalScope(); 2472 exitLocalScope();
2448 FormalParameters formals = pop(); 2473 FormalParameters formals = pop();
2449 exitFunction(); 2474 exitFunction();
2450 List<TypeParameter> typeParameters = pop(); 2475 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
2451 FunctionNode function = formals.addToFunction(new FunctionNode(body, 2476 FunctionNode function = formals.addToFunction(new FunctionNode(body,
2452 typeParameters: typeParameters, asyncMarker: asyncModifier) 2477 typeParameters: typeParameters, asyncMarker: asyncModifier)
2453 ..fileOffset = beginToken.charOffset 2478 ..fileOffset = beginToken.charOffset
2454 ..fileEndOffset = token.charOffset); 2479 ..fileEndOffset = token.charOffset);
2455 if (constantExpressionRequired) { 2480 if (constantExpressionRequired) {
2456 push(buildCompileTimeError( 2481 push(buildCompileTimeError(
2457 "Not a constant expression.", formals.charOffset)); 2482 "Not a constant expression.", formals.charOffset));
2458 } else { 2483 } else {
2459 push(new KernelFunctionExpression(function) 2484 push(new KernelFunctionExpression(function)
2460 ..fileOffset = offsetForToken(beginToken)); 2485 ..fileOffset = offsetForToken(beginToken));
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
2908 BreakStatement statement = new KernelBreakStatement(null) 2933 BreakStatement statement = new KernelBreakStatement(null)
2909 ..fileOffset = continueKeyword.charOffset; 2934 ..fileOffset = continueKeyword.charOffset;
2910 target.addContinue(statement); 2935 target.addContinue(statement);
2911 push(statement); 2936 push(statement);
2912 } 2937 }
2913 } 2938 }
2914 2939
2915 @override 2940 @override
2916 void endTypeVariable(Token token, Token extendsOrSuper) { 2941 void endTypeVariable(Token token, Token extendsOrSuper) {
2917 debugEvent("TypeVariable"); 2942 debugEvent("TypeVariable");
2918 // TODO(ahe): Do not discard these when enabling generic method syntax. 2943 DartType bound = pop();
2919 pop(); // Bound. 2944 if (bound != null) {
2920 pop(); // Name. 2945 // TODO(ahe): To handle F-bounded types, this needs to be a TypeBuilder.
2946 warningNotError("Type variable bounds not implemented yet.",
2947 offsetForToken(extendsOrSuper.next));
2948 }
2949 Identifier name = pop();
2950 // TODO(ahe): Do not discard metadata.
2921 pop(); // Metadata. 2951 pop(); // Metadata.
2952 push(new KernelTypeVariableBuilder(
2953 name.name, library, offsetForToken(name.token), null)
2954 ..finish(library, library.loader.coreLibrary["Object"]));
2922 } 2955 }
2923 2956
2924 @override 2957 @override
2925 void endTypeVariables(int count, Token beginToken, Token endToken) { 2958 void endTypeVariables(int count, Token beginToken, Token endToken) {
2926 debugEvent("TypeVariables"); 2959 debugEvent("TypeVariables");
2927 // TODO(ahe): Implement this when enabling generic method syntax. 2960 push(popList(count) ?? NullValue.TypeVariables);
2928 push(NullValue.TypeVariables); 2961 }
2962
2963 List<TypeParameter> typeVariableBuildersToKernel(List typeVariableBuilders) {
2964 if (typeVariableBuilders == null) return null;
2965 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
2966 typeVariableBuilders.length, null,
2967 growable: true);
2968 int i = 0;
2969 for (KernelTypeVariableBuilder builder in typeVariableBuilders) {
2970 typeParameters[i++] = builder.target;
2971 }
2972 return typeParameters;
2929 } 2973 }
2930 2974
2931 @override 2975 @override
2932 void handleModifier(Token token) { 2976 void handleModifier(Token token) {
2933 debugEvent("Modifier"); 2977 debugEvent("Modifier");
2934 // TODO(ahe): Copied from outline_builder.dart. 2978 // TODO(ahe): Copied from outline_builder.dart.
2935 push(new Modifier.fromString(token.stringValue)); 2979 push(new Modifier.fromString(token.stringValue));
2936 } 2980 }
2937 2981
2938 @override 2982 @override
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
3564 function.positionalParameters.addAll(optional.formals); 3608 function.positionalParameters.addAll(optional.formals);
3565 } else { 3609 } else {
3566 function.namedParameters.addAll(optional.formals); 3610 function.namedParameters.addAll(optional.formals);
3567 setParents(function.namedParameters, function); 3611 setParents(function.namedParameters, function);
3568 } 3612 }
3569 } 3613 }
3570 setParents(function.positionalParameters, function); 3614 setParents(function.positionalParameters, function);
3571 return function; 3615 return function;
3572 } 3616 }
3573 3617
3574 FunctionType toFunctionType(DartType returnType) { 3618 FunctionType toFunctionType(DartType returnType,
3619 [List<TypeParameter> typeParameters]) {
3575 returnType ??= const DynamicType(); 3620 returnType ??= const DynamicType();
3621 typeParameters ??= const <TypeParameter>[];
3576 int requiredParameterCount = required.length; 3622 int requiredParameterCount = required.length;
3577 List<DartType> positionalParameters = <DartType>[]; 3623 List<DartType> positionalParameters = <DartType>[];
3578 List<NamedType> namedParameters = const <NamedType>[]; 3624 List<NamedType> namedParameters = const <NamedType>[];
3579 for (VariableDeclaration parameter in required) { 3625 for (VariableDeclaration parameter in required) {
3580 positionalParameters.add(parameter.type); 3626 positionalParameters.add(parameter.type);
3581 } 3627 }
3582 if (optional != null) { 3628 if (optional != null) {
3583 if (optional.kind.isPositional) { 3629 if (optional.kind.isPositional) {
3584 for (VariableDeclaration parameter in optional.formals) { 3630 for (VariableDeclaration parameter in optional.formals) {
3585 positionalParameters.add(parameter.type); 3631 positionalParameters.add(parameter.type);
3586 } 3632 }
3587 } else { 3633 } else {
3588 namedParameters = <NamedType>[]; 3634 namedParameters = <NamedType>[];
3589 for (VariableDeclaration parameter in optional.formals) { 3635 for (VariableDeclaration parameter in optional.formals) {
3590 namedParameters.add(new NamedType(parameter.name, parameter.type)); 3636 namedParameters.add(new NamedType(parameter.name, parameter.type));
3591 } 3637 }
3592 namedParameters.sort(); 3638 namedParameters.sort();
3593 } 3639 }
3594 } 3640 }
3595 return new FunctionType(positionalParameters, returnType, 3641 return new FunctionType(positionalParameters, returnType,
3596 namedParameters: namedParameters, 3642 namedParameters: namedParameters,
3597 requiredParameterCount: requiredParameterCount); 3643 requiredParameterCount: requiredParameterCount,
3644 typeParameters: typeParameters);
3598 } 3645 }
3599 3646
3600 Scope computeFormalParameterScope( 3647 Scope computeFormalParameterScope(
3601 Scope parent, Builder builder, BuilderHelper helper) { 3648 Scope parent, Builder builder, BuilderHelper helper) {
3602 if (required.length == 0 && optional == null) return parent; 3649 if (required.length == 0 && optional == null) return parent;
3603 Map<String, Builder> local = <String, Builder>{}; 3650 Map<String, Builder> local = <String, Builder>{};
3604 3651
3605 for (VariableDeclaration parameter in required) { 3652 for (VariableDeclaration parameter in required) {
3606 if (local[parameter.name] != null) { 3653 if (local[parameter.name] != null) {
3607 helper.addCompileTimeError(parameter.fileOffset, "Duplicated name."); 3654 helper.addCompileTimeError(parameter.fileOffset, "Duplicated name.");
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3671 if (starToken == null) { 3718 if (starToken == null) {
3672 return AsyncMarker.Async; 3719 return AsyncMarker.Async;
3673 } else { 3720 } else {
3674 assert(identical(starToken.stringValue, "*")); 3721 assert(identical(starToken.stringValue, "*"));
3675 return AsyncMarker.AsyncStar; 3722 return AsyncMarker.AsyncStar;
3676 } 3723 }
3677 } else { 3724 } else {
3678 return internalError("Unknown async modifier: $asyncToken"); 3725 return internalError("Unknown async modifier: $asyncToken");
3679 } 3726 }
3680 } 3727 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698