Index: pkg/fasta/lib/src/source/scope_listener.dart |
diff --git a/pkg/fasta/lib/src/source/scope_listener.dart b/pkg/fasta/lib/src/source/scope_listener.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..814883f4a3421127d0b00d45742e30186e2ed35e |
--- /dev/null |
+++ b/pkg/fasta/lib/src/source/scope_listener.dart |
@@ -0,0 +1,195 @@ |
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library fasta.scope_listener; |
+ |
+import 'package:dart_scanner/src/token.dart' show |
+ Token; |
+ |
+import 'package:dart_parser/src/error_kind.dart' show |
+ ErrorKind; |
+ |
+import 'unhandled_listener.dart' show |
+ NullValue, |
+ UnhandledListener; |
+ |
+import '../builder/scope.dart' show |
+ Scope; |
+ |
+export '../builder/scope.dart' show |
+ Scope; |
+ |
+export 'unhandled_listener.dart' show |
+ NullValue, |
+ Unhandled; |
+ |
+enum JumpTargetKind { |
+ Break, |
+ Continue, |
+ Goto, // Continue label in switch. |
+} |
+ |
+abstract class ScopeListener<J> extends UnhandledListener { |
+ Scope scope; |
+ |
+ J breakTarget; |
+ |
+ J continueTarget; |
+ |
+ ScopeListener(this.scope); |
+ |
+ J createJumpTarget(JumpTargetKind kind); |
+ |
+ J createBreakTarget() => createJumpTarget(JumpTargetKind.Break); |
+ |
+ J createContinueTarget() => createJumpTarget(JumpTargetKind.Continue); |
+ |
+ J createGotoTarget() => createJumpTarget(JumpTargetKind.Goto); |
+ |
+ void enterLocalScope([Scope newScope]) { |
+ push(scope); |
+ scope = newScope ?? scope.createNestedScope(); |
+ } |
+ |
+ void exitLocalScope() { |
+ scope = pop(); |
+ assert(scope != null); |
+ } |
+ |
+ void enterBreakTarget([J target]) { |
+ push(breakTarget ?? NullValue.BreakTarget); |
+ breakTarget = target ?? createBreakTarget(); |
+ } |
+ |
+ void enterContinueTarget([J target]) { |
+ push(continueTarget ?? NullValue.ContinueTarget); |
+ continueTarget = target ?? createContinueTarget(); |
+ } |
+ |
+ J exitBreakTarget() { |
+ J current = breakTarget; |
+ breakTarget = pop(); |
+ return current; |
+ } |
+ |
+ J exitContinueTarget() { |
+ J current = continueTarget; |
+ continueTarget = pop(); |
+ return current; |
+ } |
+ |
+ void enterLoop() { |
+ enterBreakTarget(); |
+ enterContinueTarget(); |
+ } |
+ |
+ void beginFunctionBody(Token begin) { |
+ debugEvent("beginFunctionBody"); |
+ enterLocalScope(); |
+ } |
+ |
+ void beginForStatement(Token token) { |
+ debugEvent("beginForStatement"); |
+ enterLoop(); |
+ enterLocalScope(); |
+ } |
+ |
+ void beginBlock(Token token) { |
+ debugEvent("beginBlock"); |
+ enterLocalScope(); |
+ } |
+ |
+ void beginSwitchBlock(Token token) { |
+ debugEvent("beginSwitchBlock"); |
+ enterLocalScope(); |
+ enterBreakTarget(); |
+ } |
+ |
+ void beginDoWhileStatement(Token token) { |
+ debugEvent("beginDoWhileStatement"); |
+ enterLoop(); |
+ } |
+ |
+ void beginWhileStatement(Token token) { |
+ debugEvent("beginWhileStatement"); |
+ enterLoop(); |
+ } |
+ |
+ void beginDoWhileStatementBody(Token token) { |
+ debugEvent("beginDoWhileStatementBody"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endDoWhileStatementBody(Token token) { |
+ debugEvent("endDoWhileStatementBody"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void beginWhileStatementBody(Token token) { |
+ debugEvent("beginWhileStatementBody"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endWhileStatementBody(Token token) { |
+ debugEvent("endWhileStatementBody"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void beginForStatementBody(Token token) { |
+ debugEvent("beginForStatementBody"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endForStatementBody(Token token) { |
+ debugEvent("endForStatementBody"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void beginForInBody(Token token) { |
+ debugEvent("beginForInBody"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endForInBody(Token token) { |
+ debugEvent("endForInBody"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void beginThenStatement(Token token) { |
+ debugEvent("beginThenStatement"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endThenStatement(Token token) { |
+ debugEvent("endThenStatement"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void beginElseStatement(Token token) { |
+ debugEvent("beginElseStatement"); |
+ enterLocalScope(); |
+ } |
+ |
+ void endElseStatement(Token token) { |
+ debugEvent("endElseStatement"); |
+ var body = pop(); |
+ exitLocalScope(); |
+ push(body); |
+ } |
+ |
+ void reportErrorHelper(Token token, ErrorKind kind, Map arguments) { |
+ super.reportErrorHelper(token, kind, arguments); |
+ debugEvent("error: ${recoverableErrors.last}"); |
+ } |
+} |