OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |