Chromium Code Reviews| 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 |