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

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

Issue 2994973002: Implement type variables on local function declarations and expressions. (Closed)
Patch Set: Created 3 years, 4 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 'package:kernel/ast.dart' 7 import 'package:kernel/ast.dart'
8 hide InvalidExpression, InvalidInitializer, InvalidStatement; 8 hide InvalidExpression, InvalidInitializer, InvalidStatement;
9 9
10 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; 10 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 if (outerSwitchScope == null) { 310 if (outerSwitchScope == null) {
311 deprecated_addCompileTimeError(-1, "Label not found: '$name'."); 311 deprecated_addCompileTimeError(-1, "Label not found: '$name'.");
312 } else { 312 } else {
313 outerSwitchScope.forwardDeclareLabel(name, builder); 313 outerSwitchScope.forwardDeclareLabel(name, builder);
314 } 314 }
315 }); 315 });
316 } 316 }
317 switchScope = outerSwitchScope; 317 switchScope = outerSwitchScope;
318 } 318 }
319 319
320 void declareVariable(VariableDeclaration variable) { 320 void declareVariable(VariableDeclaration variable, Scope scope) {
321 // ignore: UNUSED_LOCAL_VARIABLE 321 // ignore: UNUSED_LOCAL_VARIABLE
322 Statement discardedStatement; 322 Statement discardedStatement;
323 String name = variable.name; 323 String name = variable.name;
324 int offset = variable.fileOffset; 324 int offset = variable.fileOffset;
325 if (scope.local[name] != null) { 325 if (scope.local[name] != null) {
326 // This reports an error for duplicated declarations in the same scope: 326 // This reports an error for duplicated declarations in the same scope:
327 // `{ var x; var x; }` 327 // `{ var x; var x; }`
328 discardedStatement = pop(); // TODO(ahe): Issue 29717. 328 discardedStatement = pop(); // TODO(ahe): Issue 29717.
329 push(deprecated_buildCompileTimeErrorStatement( 329 push(deprecated_buildCompileTimeErrorStatement(
330 "'$name' already declared in this scope.", offset)); 330 "'$name' already declared in this scope.", offset));
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 } 1054 }
1055 push(new Identifier(token)); 1055 push(new Identifier(token));
1056 } 1056 }
1057 1057
1058 /// Look up [name] in [scope] using [token] as location information (both to 1058 /// Look up [name] in [scope] using [token] as location information (both to
1059 /// report problems and as the file offset in the generated kernel code). 1059 /// report problems and as the file offset in the generated kernel code).
1060 /// [isQualified] should be true if [name] is a qualified access 1060 /// [isQualified] should be true if [name] is a qualified access
1061 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor] 1061 /// (which implies that it shouldn't be turned into a [ThisPropertyAccessor]
1062 /// if the name doesn't resolve in the scope). 1062 /// if the name doesn't resolve in the scope).
1063 @override 1063 @override
1064 scopeLookup(Scope scope, String name, Token token, 1064 scopeLookup(Scope scope, String name, Token token,
danrubel 2017/08/14 14:08:04 It is confusing to have a field and a parameter bo
ahe 2017/08/15 08:59:28 Yeah. I'll address this in a follow-up.
1065 {bool isQualified: false, PrefixBuilder prefix}) { 1065 {bool isQualified: false, PrefixBuilder prefix}) {
1066 Builder builder = scope.lookup(name, offsetForToken(token), uri); 1066 Builder builder = scope.lookup(name, offsetForToken(token), uri);
1067 if (builder != null && member.isField && builder.isInstanceMember) { 1067 if (builder != null && member.isField && builder.isInstanceMember) {
1068 return new IncompleteError(this, token, 1068 return new IncompleteError(this, token,
1069 fasta.templateThisAccessInFieldInitializer.withArguments(name)); 1069 fasta.templateThisAccessInFieldInitializer.withArguments(name));
1070 } 1070 }
1071 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) { 1071 if (builder == null || (!isInstanceContext && builder.isInstanceMember)) {
1072 Name n = new Name(name, library.library); 1072 Name n = new Name(name, library.library);
1073 if (prefix != null && 1073 if (prefix != null &&
1074 prefix.deferred && 1074 prefix.deferred &&
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 } 1387 }
1388 } 1388 }
1389 1389
1390 @override 1390 @override
1391 void endInitializedIdentifier(Token nameToken) { 1391 void endInitializedIdentifier(Token nameToken) {
1392 // TODO(ahe): Use [InitializedIdentifier] here? 1392 // TODO(ahe): Use [InitializedIdentifier] here?
1393 debugEvent("InitializedIdentifier"); 1393 debugEvent("InitializedIdentifier");
1394 VariableDeclaration variable = pop(); 1394 VariableDeclaration variable = pop();
1395 variable.fileOffset = nameToken.charOffset; 1395 variable.fileOffset = nameToken.charOffset;
1396 push(variable); 1396 push(variable);
1397 declareVariable(variable); 1397 declareVariable(variable, scope);
1398 } 1398 }
1399 1399
1400 @override 1400 @override
1401 void beginVariablesDeclaration(Token token) { 1401 void beginVariablesDeclaration(Token token) {
1402 debugEvent("beginVariablesDeclaration"); 1402 debugEvent("beginVariablesDeclaration");
1403 DartType type = pop(); 1403 DartType type = pop();
1404 int modifiers = Modifier.validate(pop()); 1404 int modifiers = Modifier.validate(pop());
1405 super.push(currentLocalVariableModifiers); 1405 super.push(currentLocalVariableModifiers);
1406 super.push(currentLocalVariableType ?? NullValue.Type); 1406 super.push(currentLocalVariableType ?? NullValue.Type);
1407 currentLocalVariableType = type; 1407 currentLocalVariableType = type;
(...skipping 1002 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 ..fileOffset = offsetForToken(name.token); 2410 ..fileOffset = offsetForToken(name.token);
2411 if (scope.local[variable.name] != null) { 2411 if (scope.local[variable.name] != null) {
2412 deprecated_addCompileTimeError(offsetForToken(name.token), 2412 deprecated_addCompileTimeError(offsetForToken(name.token),
2413 "'${variable.name}' already declared in this scope."); 2413 "'${variable.name}' already declared in this scope.");
2414 } 2414 }
2415 push(new KernelFunctionDeclaration( 2415 push(new KernelFunctionDeclaration(
2416 variable, 2416 variable,
2417 // The function node is created later. 2417 // The function node is created later.
2418 null) 2418 null)
2419 ..fileOffset = beginToken.charOffset); 2419 ..fileOffset = beginToken.charOffset);
2420 declareVariable(variable); 2420 declareVariable(variable, scope.parent);
2421 enterLocalScope();
2422 } 2421 }
2423 2422
2424 void enterFunction() { 2423 void enterFunction() {
2425 debugEvent("enterFunction"); 2424 debugEvent("enterFunction");
2425 enterFunctionTypeScope();
2426 functionNestingLevel++; 2426 functionNestingLevel++;
2427 push(switchScope ?? NullValue.SwitchScope); 2427 push(switchScope ?? NullValue.SwitchScope);
2428 switchScope = null; 2428 switchScope = null;
2429 push(inCatchBlock); 2429 push(inCatchBlock);
2430 inCatchBlock = false; 2430 inCatchBlock = false;
2431 } 2431 }
2432 2432
2433 void exitFunction() { 2433 void exitFunction() {
2434 debugEvent("exitFunction"); 2434 debugEvent("exitFunction");
2435 functionNestingLevel--; 2435 functionNestingLevel--;
2436 inCatchBlock = pop(); 2436 inCatchBlock = pop();
2437 switchScope = pop(); 2437 switchScope = pop();
2438 List typeVariables = pop();
2439 exitLocalScope();
2440 push(typeVariables ?? NullValue.TypeVariables);
2438 } 2441 }
2439 2442
2440 @override 2443 @override
2441 void beginLocalFunctionDeclaration(Token token) { 2444 void beginLocalFunctionDeclaration(Token token) {
2442 debugEvent("beginLocalFunctionDeclaration"); 2445 debugEvent("beginLocalFunctionDeclaration");
2443 enterFunction(); 2446 enterFunction();
2444 } 2447 }
2445 2448
2446 @override 2449 @override
2447 void beginNamedFunctionExpression(Token token) { 2450 void beginNamedFunctionExpression(Token token) {
2448 debugEvent("beginNamedFunctionExpression"); 2451 debugEvent("beginNamedFunctionExpression");
2452 List typeVariables = pop();
2453 // Create an additional scope in which the named function expression is
2454 // declared.
2455 enterLocalScope();
2456 push(typeVariables ?? NullValue.TypeVariables);
2449 enterFunction(); 2457 enterFunction();
2450 } 2458 }
2451 2459
2452 @override 2460 @override
2453 void beginFunctionExpression(Token token) { 2461 void beginFunctionExpression(Token token) {
2454 debugEvent("beginFunctionExpression"); 2462 debugEvent("beginFunctionExpression");
2455 enterFunction(); 2463 enterFunction();
2456 } 2464 }
2457 2465
2458 @override 2466 void pushNamedFunction(Token token, bool isFunctionExpression) {
2459 void endNamedFunctionExpression(Token endToken) {
2460 debugEvent("NamedFunctionExpression");
2461 Statement body = popStatement(); 2467 Statement body = popStatement();
2462 AsyncMarker asyncModifier = pop(); 2468 AsyncMarker asyncModifier = pop();
2463 if (functionNestingLevel != 0) { 2469 exitLocalScope();
2464 exitLocalScope();
2465 }
2466 FormalParameters formals = pop(); 2470 FormalParameters formals = pop();
2467 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
2468
2469 exitLocalScope();
2470 KernelFunctionDeclaration declaration = pop();
2471 VariableDeclaration variable = declaration.variable;
2472 var returnType = pop();
2473 returnType ??= const DynamicType();
2474 pop(); // Modifiers.
2475 exitFunction();
2476
2477 variable.initializer = new KernelFunctionExpression(formals.addToFunction(
2478 new FunctionNode(body,
2479 typeParameters: typeParameters, asyncMarker: asyncModifier)
2480 ..fileOffset = formals.charOffset
2481 ..fileEndOffset = endToken.charOffset))
2482 ..parent = variable
2483 ..fileOffset = formals.charOffset;
2484 push(
2485 new KernelNamedFunctionExpression(variable, new VariableGet(variable)));
2486 }
2487
2488 @override
2489 void endLocalFunctionDeclaration(Token token) {
2490 debugEvent("LocalFunctionDeclaration");
2491 Statement body = popStatement();
2492 AsyncMarker asyncModifier = pop();
2493 if (functionNestingLevel != 0) {
2494 exitLocalScope();
2495 }
2496 FormalParameters formals = pop();
2497 exitLocalScope();
2498 var declaration = pop(); 2471 var declaration = pop();
2499 var returnType = pop(); 2472 var returnType = pop();
2500 var hasImplicitReturnType = returnType == null; 2473 var hasImplicitReturnType = returnType == null;
2501 returnType ??= const DynamicType(); 2474 returnType ??= const DynamicType();
2502 pop(); // Modifiers. 2475 pop(); // Modifiers.
2503 exitFunction(); 2476 exitFunction();
2504 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop()); 2477 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
2505 FunctionNode function = formals.addToFunction(new FunctionNode(body, 2478 FunctionNode function = formals.addToFunction(new FunctionNode(body,
2506 typeParameters: typeParameters, asyncMarker: asyncModifier) 2479 typeParameters: typeParameters,
2480 asyncMarker: asyncModifier,
2481 returnType: returnType)
2507 ..fileOffset = formals.charOffset 2482 ..fileOffset = formals.charOffset
2508 ..fileEndOffset = token.charOffset); 2483 ..fileEndOffset = token.charOffset);
2484
2509 if (declaration is FunctionDeclaration) { 2485 if (declaration is FunctionDeclaration) {
2486 VariableDeclaration variable = declaration.variable;
2510 KernelFunctionDeclaration.setHasImplicitReturnType( 2487 KernelFunctionDeclaration.setHasImplicitReturnType(
2511 declaration, hasImplicitReturnType); 2488 declaration, hasImplicitReturnType);
2512 function.returnType = returnType; 2489
2513 declaration.variable.type = function.functionType; 2490 variable.type = function.functionType;
2514 declaration.function = function; 2491 if (isFunctionExpression) {
2515 function.parent = declaration; 2492 variable.initializer = new KernelFunctionExpression(function)
2516 } else { 2493 ..parent = variable
2494 ..fileOffset = formals.charOffset;
2495 exitLocalScope();
2496 push(new KernelNamedFunctionExpression(variable));
2497 } else {
2498 declaration.function = function;
2499 function.parent = declaration;
2500 push(declaration);
2501 }
2502 } else if (declaration is ExpressionStatement) {
2517 // If [declaration] isn't a [FunctionDeclaration], it must be because 2503 // If [declaration] isn't a [FunctionDeclaration], it must be because
2518 // there was a compile-time error. 2504 // there was a compile-time error.
2505 assert(library.hasCompileTimeErrors);
2519 2506
2520 // TODO(paulberry): ensure that when integrating with analyzer, type 2507 // TODO(paulberry,ahe): ensure that when integrating with analyzer, type
2521 // inference is still performed for the dropped declaration. 2508 // inference is still performed for the dropped declaration.
2522 assert(library.hasCompileTimeErrors); 2509 if (isFunctionExpression) {
2510 push(declaration.expression);
2511 } else {
2512 push(declaration);
2513 }
2514 } else {
2515 return unhandled("${declaration.runtimeType}", "pushNamedFunction",
2516 token.charOffset, uri);
2523 } 2517 }
2524 push(declaration);
2525 } 2518 }
2526 2519
2527 @override 2520 @override
2521 void endNamedFunctionExpression(Token endToken) {
2522 debugEvent("NamedFunctionExpression");
2523 pushNamedFunction(endToken, true);
2524 }
2525
2526 @override
2527 void endLocalFunctionDeclaration(Token token) {
2528 debugEvent("LocalFunctionDeclaration");
2529 pushNamedFunction(token, false);
2530 }
2531
2532 @override
2528 void endFunctionExpression(Token beginToken, Token token) { 2533 void endFunctionExpression(Token beginToken, Token token) {
2529 debugEvent("FunctionExpression"); 2534 debugEvent("FunctionExpression");
2530 Statement body = popStatement(); 2535 Statement body = popStatement();
2531 AsyncMarker asyncModifier = pop(); 2536 AsyncMarker asyncModifier = pop();
2532 exitLocalScope(); 2537 exitLocalScope();
2533 FormalParameters formals = pop(); 2538 FormalParameters formals = pop();
2534 exitFunction(); 2539 exitFunction();
2535 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop()); 2540 List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
2536 FunctionNode function = formals.addToFunction(new FunctionNode(body, 2541 FunctionNode function = formals.addToFunction(new FunctionNode(body,
2537 typeParameters: typeParameters, asyncMarker: asyncModifier) 2542 typeParameters: typeParameters, asyncMarker: asyncModifier)
(...skipping 1269 matching lines...) Expand 10 before | Expand all | Expand 10 after
3807 return AsyncMarker.Async; 3812 return AsyncMarker.Async;
3808 } else { 3813 } else {
3809 assert(identical(starToken.stringValue, "*")); 3814 assert(identical(starToken.stringValue, "*"));
3810 return AsyncMarker.AsyncStar; 3815 return AsyncMarker.AsyncStar;
3811 } 3816 }
3812 } else { 3817 } else {
3813 return unhandled(asyncToken.lexeme, "asyncMarkerFromTokens", 3818 return unhandled(asyncToken.lexeme, "asyncMarkerFromTokens",
3814 asyncToken.charOffset, null); 3819 asyncToken.charOffset, null);
3815 } 3820 }
3816 } 3821 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/node_listener.dart ('k') | pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698