| Index: pkg/analyzer/lib/src/summary/fasta/stack_listener.dart
|
| diff --git a/pkg/analyzer/lib/src/summary/fasta/stack_listener.dart b/pkg/analyzer/lib/src/summary/fasta/stack_listener.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f7e0bbd13472ed57f6758141490c1c2e27c1a8f2
|
| --- /dev/null
|
| +++ b/pkg/analyzer/lib/src/summary/fasta/stack_listener.dart
|
| @@ -0,0 +1,139 @@
|
| +// 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 fe.stack_listener;
|
| +
|
| +import 'dart:collection' show
|
| + Queue;
|
| +
|
| +import 'package:front_end/src/fasta/parser/identifier_context.dart';
|
| +import 'package:front_end/src/fasta/parser/listener.dart';
|
| +import 'package:front_end/src/fasta/scanner/token.dart';
|
| +
|
| +enum NullValue {
|
| + Arguments,
|
| + Combinators,
|
| + FormalParameters,
|
| + FunctionBody,
|
| + IdentifierList,
|
| + Initializers,
|
| + Metadata,
|
| + Modifiers,
|
| + Type,
|
| + TypeArguments,
|
| + TypeList,
|
| + TypeVariable,
|
| + TypeVariables,
|
| +}
|
| +
|
| +abstract class StackListener extends Listener {
|
| + final Queue<Object> stack = new Queue<Object>();
|
| +
|
| + Uri get uri;
|
| +
|
| + void push(Object node) {
|
| + if (node == null) throw "null not allowed.";
|
| + stack.addLast(node);
|
| + }
|
| +
|
| + Object peek() {
|
| + Object node = stack.last;
|
| + return node is NullValue ? null : node;
|
| + }
|
| +
|
| + Object pop({NullValue expect: null}) {
|
| + Object node = stack.removeLast();
|
| + if (expect != null && expect != node) {
|
| + throw "unexpected value: $expect vs $node";
|
| + }
|
| + return node is NullValue ? null : node;
|
| + }
|
| +
|
| + Object popIfNotNull(Object value) {
|
| + return value == null ? null : pop();
|
| + }
|
| +
|
| + List popList(int n) {
|
| + if (n == 0) return null;
|
| + List list = new List(n);
|
| + for (int i = n - 1; i >= 0; i--) {
|
| + list[i] = pop();
|
| + }
|
| + return list;
|
| + }
|
| +
|
| + void debugEvent(String name) {
|
| + // print(" ${stack.join('\n ')}");
|
| + // print(name);
|
| + }
|
| +
|
| + void logEvent(String name) {
|
| + print(" ${stack.join('\n ')}");
|
| + throw "Unhandled event: $name in $runtimeType $uri.";
|
| + }
|
| +
|
| + void handleIdentifier(Token token, IdentifierContext context) {
|
| + debugEvent("handleIdentifier");
|
| + push(token.value);
|
| + }
|
| +
|
| + void checkEmpty() {
|
| + if (stack.isNotEmpty) {
|
| + throw "Stack not empty $uri:\n"
|
| + " ${stack.join('\n ')}";
|
| + }
|
| + }
|
| +
|
| + void endTopLevelDeclaration(Token token) {
|
| + debugEvent("TopLevelDeclaration");
|
| + checkEmpty();
|
| + }
|
| +
|
| + void endCompilationUnit(int count, Token token) {
|
| + debugEvent("CompilationUnit");
|
| + checkEmpty();
|
| + }
|
| +
|
| + void handleNoTypeArguments(Token token) {
|
| + debugEvent("NoTypeArguments");
|
| + push(NullValue.TypeArguments);
|
| + }
|
| +
|
| + void handleNoTypeVariables(Token token) {
|
| + debugEvent("NoTypeVariables");
|
| + push(NullValue.TypeVariables);
|
| + }
|
| +
|
| + void handleNoType(Token token) {
|
| + debugEvent("NoType");
|
| + push(NullValue.Type);
|
| + }
|
| +
|
| + void handleNoFormalParameters(Token token) {
|
| + debugEvent("NoFormalParameters");
|
| + push(NullValue.FormalParameters);
|
| + }
|
| +
|
| + void handleNoArguments(Token token) {
|
| + debugEvent("NoArguments");
|
| + var typeArguments = pop();
|
| + assert(typeArguments == null);
|
| + push(NullValue.Arguments);
|
| + }
|
| +
|
| + void handleNoFunctionBody(Token token) {
|
| + debugEvent("NoFunctionBody");
|
| + push(NullValue.FunctionBody);
|
| + }
|
| +
|
| + void handleNoInitializers() {
|
| + debugEvent("NoInitializers");
|
| + push(NullValue.Initializers);
|
| + }
|
| +
|
| + void handleParenthesizedExpression(BeginGroupToken token) {
|
| + debugEvent("ParenthesizedExpression");
|
| + }
|
| +}
|
| +
|
|
|