| 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 '../parser/parser.dart' show FormalParameterType, optional; | 7 import '../parser/parser.dart' show FormalParameterType, optional; |
| 8 | 8 |
| 9 import '../parser/error_kind.dart' show ErrorKind; | 9 import '../parser/error_kind.dart' show ErrorKind; |
| 10 | 10 |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 push(switchScope ?? NullValue.SwitchScope); | 264 push(switchScope ?? NullValue.SwitchScope); |
| 265 switchScope = scope; | 265 switchScope = scope; |
| 266 } | 266 } |
| 267 | 267 |
| 268 void exitSwitchScope() { | 268 void exitSwitchScope() { |
| 269 switchScope = pop(); | 269 switchScope = pop(); |
| 270 } | 270 } |
| 271 | 271 |
| 272 @override | 272 @override |
| 273 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { | 273 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { |
| 274 return new JumpTarget(kind, member, charOffset); | 274 return new JumpTarget(kind, functionNestingLevel, member, charOffset); |
| 275 } | 275 } |
| 276 | 276 |
| 277 @override | 277 @override |
| 278 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 278 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| 279 debugEvent("Metadata"); | 279 debugEvent("Metadata"); |
| 280 pop(); // Arguments. | 280 pop(); // Arguments. |
| 281 popIfNotNull(periodBeforeName); // Postfix. | 281 popIfNotNull(periodBeforeName); // Postfix. |
| 282 pop(); // Type arguments. | 282 pop(); // Type arguments. |
| 283 pop(); // Expression or type name (depends on arguments). | 283 pop(); // Expression or type name (depends on arguments). |
| 284 // TODO(ahe): Implement metadata on local declarations. | 284 // TODO(ahe): Implement metadata on local declarations. |
| (...skipping 1633 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 debugEvent("Label"); | 1918 debugEvent("Label"); |
| 1919 Identifier identifier = pop(); | 1919 Identifier identifier = pop(); |
| 1920 push(new Label(identifier.name)); | 1920 push(new Label(identifier.name)); |
| 1921 } | 1921 } |
| 1922 | 1922 |
| 1923 @override | 1923 @override |
| 1924 void beginLabeledStatement(Token token, int labelCount) { | 1924 void beginLabeledStatement(Token token, int labelCount) { |
| 1925 debugEvent("beginLabeledStatement"); | 1925 debugEvent("beginLabeledStatement"); |
| 1926 List<Label> labels = popList(labelCount); | 1926 List<Label> labels = popList(labelCount); |
| 1927 enterLocalScope(); | 1927 enterLocalScope(); |
| 1928 LabelTarget target = new LabelTarget(member, token.charOffset); | 1928 LabelTarget target = |
| 1929 new LabelTarget(member, functionNestingLevel, token.charOffset); |
| 1929 for (Label label in labels) { | 1930 for (Label label in labels) { |
| 1930 scope.declareLabel(label.name, target); | 1931 scope.declareLabel(label.name, target); |
| 1931 } | 1932 } |
| 1932 push(target); | 1933 push(target); |
| 1933 } | 1934 } |
| 1934 | 1935 |
| 1935 @override | 1936 @override |
| 1936 void endLabeledStatement(int labelCount) { | 1937 void endLabeledStatement(int labelCount) { |
| 1937 debugEvent("LabeledStatement"); | 1938 debugEvent("LabeledStatement"); |
| 1938 Statement statement = popStatement(); | 1939 Statement statement = popStatement(); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2110 target = scope.lookupLabel(identifier.name); | 2111 target = scope.lookupLabel(identifier.name); |
| 2111 } | 2112 } |
| 2112 if (target == null && name == null) { | 2113 if (target == null && name == null) { |
| 2113 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2114 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2114 "No target of break.", breakKeyword.charOffset)); | 2115 "No target of break.", breakKeyword.charOffset)); |
| 2115 } else if (target == null || | 2116 } else if (target == null || |
| 2116 target is! JumpTarget || | 2117 target is! JumpTarget || |
| 2117 !target.isBreakTarget) { | 2118 !target.isBreakTarget) { |
| 2118 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2119 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2119 "Can't break to '$name'.", breakKeyword.next.charOffset)); | 2120 "Can't break to '$name'.", breakKeyword.next.charOffset)); |
| 2121 } else if (target.functionNestingLevel != functionNestingLevel) { |
| 2122 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2123 "Can't break to '$name' in a different function.", |
| 2124 breakKeyword.next.charOffset)); |
| 2120 } else { | 2125 } else { |
| 2121 BreakStatement statement = new BreakStatement(null) | 2126 BreakStatement statement = new BreakStatement(null) |
| 2122 ..fileOffset = breakKeyword.charOffset; | 2127 ..fileOffset = breakKeyword.charOffset; |
| 2123 target.addBreak(statement); | 2128 target.addBreak(statement); |
| 2124 push(statement); | 2129 push(statement); |
| 2125 } | 2130 } |
| 2126 } | 2131 } |
| 2127 | 2132 |
| 2128 @override | 2133 @override |
| 2129 void handleContinueStatement( | 2134 void handleContinueStatement( |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2155 push(statement); | 2160 push(statement); |
| 2156 return; | 2161 return; |
| 2157 } | 2162 } |
| 2158 } | 2163 } |
| 2159 if (target == null) { | 2164 if (target == null) { |
| 2160 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2165 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2161 "No target of continue.", continueKeyword.charOffset)); | 2166 "No target of continue.", continueKeyword.charOffset)); |
| 2162 } else if (!target.isContinueTarget) { | 2167 } else if (!target.isContinueTarget) { |
| 2163 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2168 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2164 "Can't continue at '$name'.", continueKeyword.next.charOffset)); | 2169 "Can't continue at '$name'.", continueKeyword.next.charOffset)); |
| 2170 } else if (target.functionNestingLevel != functionNestingLevel) { |
| 2171 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2172 "Can't continue at '$name' in a different function.", |
| 2173 continueKeyword.next.charOffset)); |
| 2165 } else { | 2174 } else { |
| 2166 BreakStatement statement = new BreakStatement(null) | 2175 BreakStatement statement = new BreakStatement(null) |
| 2167 ..fileOffset = continueKeyword.charOffset; | 2176 ..fileOffset = continueKeyword.charOffset; |
| 2168 target.addContinue(statement); | 2177 target.addContinue(statement); |
| 2169 push(statement); | 2178 push(statement); |
| 2170 } | 2179 } |
| 2171 } | 2180 } |
| 2172 | 2181 |
| 2173 @override | 2182 @override |
| 2174 void endTypeVariable(Token token, Token extendsOrSuper) { | 2183 void endTypeVariable(Token token, Token extendsOrSuper) { |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2510 return accessor.buildPostfixIncrement(binaryOperator, charOffset, | 2519 return accessor.buildPostfixIncrement(binaryOperator, charOffset, |
| 2511 voidContext: true, interfaceTarget: interfaceTarget); | 2520 voidContext: true, interfaceTarget: interfaceTarget); |
| 2512 } | 2521 } |
| 2513 } | 2522 } |
| 2514 | 2523 |
| 2515 class JumpTarget extends Builder { | 2524 class JumpTarget extends Builder { |
| 2516 final List<Statement> users = <Statement>[]; | 2525 final List<Statement> users = <Statement>[]; |
| 2517 | 2526 |
| 2518 final JumpTargetKind kind; | 2527 final JumpTargetKind kind; |
| 2519 | 2528 |
| 2520 JumpTarget(this.kind, MemberBuilder member, int charOffset) | 2529 final int functionNestingLevel; |
| 2530 |
| 2531 JumpTarget(this.kind, this.functionNestingLevel, MemberBuilder member, |
| 2532 int charOffset) |
| 2521 : super(member, charOffset, member.fileUri); | 2533 : super(member, charOffset, member.fileUri); |
| 2522 | 2534 |
| 2523 bool get isBreakTarget => kind == JumpTargetKind.Break; | 2535 bool get isBreakTarget => kind == JumpTargetKind.Break; |
| 2524 | 2536 |
| 2525 bool get isContinueTarget => kind == JumpTargetKind.Continue; | 2537 bool get isContinueTarget => kind == JumpTargetKind.Continue; |
| 2526 | 2538 |
| 2527 bool get isGotoTarget => kind == JumpTargetKind.Goto; | 2539 bool get isGotoTarget => kind == JumpTargetKind.Goto; |
| 2528 | 2540 |
| 2529 bool get hasUsers => users.isNotEmpty; | 2541 bool get hasUsers => users.isNotEmpty; |
| 2530 | 2542 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2566 } | 2578 } |
| 2567 users.clear(); | 2579 users.clear(); |
| 2568 } | 2580 } |
| 2569 } | 2581 } |
| 2570 | 2582 |
| 2571 class LabelTarget extends Builder implements JumpTarget { | 2583 class LabelTarget extends Builder implements JumpTarget { |
| 2572 final JumpTarget breakTarget; | 2584 final JumpTarget breakTarget; |
| 2573 | 2585 |
| 2574 final JumpTarget continueTarget; | 2586 final JumpTarget continueTarget; |
| 2575 | 2587 |
| 2576 LabelTarget(MemberBuilder member, int charOffset) | 2588 final int functionNestingLevel; |
| 2577 : breakTarget = new JumpTarget(JumpTargetKind.Break, member, charOffset), | 2589 |
| 2578 continueTarget = | 2590 LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset) |
| 2579 new JumpTarget(JumpTargetKind.Continue, member, charOffset), | 2591 : breakTarget = new JumpTarget( |
| 2592 JumpTargetKind.Break, functionNestingLevel, member, charOffset), |
| 2593 continueTarget = new JumpTarget( |
| 2594 JumpTargetKind.Continue, functionNestingLevel, member, charOffset), |
| 2580 super(member, charOffset, member.fileUri); | 2595 super(member, charOffset, member.fileUri); |
| 2581 | 2596 |
| 2582 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers; | 2597 bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers; |
| 2583 | 2598 |
| 2584 List<Statement> get users => internalError("Unsupported operation."); | 2599 List<Statement> get users => internalError("Unsupported operation."); |
| 2585 | 2600 |
| 2586 JumpTargetKind get kind => internalError("Unsupported operation."); | 2601 JumpTargetKind get kind => internalError("Unsupported operation."); |
| 2587 | 2602 |
| 2588 bool get isBreakTarget => true; | 2603 bool get isBreakTarget => true; |
| 2589 | 2604 |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2721 } else if (node is PrefixBuilder) { | 2736 } else if (node is PrefixBuilder) { |
| 2722 return node.name; | 2737 return node.name; |
| 2723 } else if (node is ThisAccessor) { | 2738 } else if (node is ThisAccessor) { |
| 2724 return node.isSuper ? "super" : "this"; | 2739 return node.isSuper ? "super" : "this"; |
| 2725 } else if (node is BuilderAccessor) { | 2740 } else if (node is BuilderAccessor) { |
| 2726 return node.plainNameForRead; | 2741 return node.plainNameForRead; |
| 2727 } else { | 2742 } else { |
| 2728 return internalError("Unhandled: ${node.runtimeType}"); | 2743 return internalError("Unhandled: ${node.runtimeType}"); |
| 2729 } | 2744 } |
| 2730 } | 2745 } |
| OLD | NEW |