// Copyright (c) 2018, 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.type_promotion_look_ahead_listener;

import '../builder/builder.dart' show Builder;

import '../messages.dart' show LocatedMessage, Message, MessageCode;

import '../parser.dart'
    show
        Assert,
        DeclarationKind,
        FormalParameterKind,
        IdentifierContext,
        Listener,
        MemberKind;

import '../problems.dart' as problems show unhandled;

import '../scanner.dart' show Token;

import '../scope.dart' show Scope;

import '../severity.dart' show Severity;

final NoArguments noArgumentsSentinel = new NoArguments();

abstract class TypePromotionState {
  final Uri uri;

  final List<Scope> scopes = <Scope>[new Scope.top(isModifiable: true)];

  final List<Builder> stack = <Builder>[];

  TypePromotionState(this.uri);

  Scope get currentScope => scopes.last;

  void enterScope(String debugName) {
    scopes.add(new Scope.nested(currentScope, "block"));
  }

  Scope exitScope(Token token) {
    return scopes.removeLast();
  }

  void declareIdentifier(Token token) {
    String name = token.lexeme;
    LocatedMessage error = currentScope.declare(
        name, new UnspecifiedDeclaration(name, uri, token.charOffset), uri);
    if (error != null) {
      report(error, Severity.error);
    }
    pushNull(token.lexeme, token);
  }

  void registerWrite(UnspecifiedDeclaration declaration, Token token) {}

  void registerPromotionCandidate(
      UnspecifiedDeclaration declaration, Token token) {}

  void pushReference(Token token) {
    String name = token.lexeme;
    Builder declaration = currentScope.lookup(name, token.charOffset, uri);
    stack.add(declaration);
  }

  Builder pop() => stack.removeLast();

  void push(Builder declaration) {
    stack.add(declaration);
  }

  Builder popPushNull(String name, Token token) {
    int last = stack.length - 1;
    Builder declaration = stack[last];
    stack[last] = nullValue(name, token);
    return declaration;
  }

  void discard(int count) {
    stack.length = stack.length - count;
  }

  void pushNull(String name, Token token) {
    stack.add(nullValue(name, token));
  }

  Builder nullValue(String name, Token token) => null;

  void report(LocatedMessage message, Severity severity,
      {List<LocatedMessage> context});

  void trace(String message, Token token) {}

  void checkEmpty(Token token) {}
}

class UnspecifiedDeclaration extends Builder {
  final String name;

  @override
  final Uri fileUri;

  @override
  int charOffset;

  UnspecifiedDeclaration(this.name, this.fileUri, this.charOffset);

  @override
  Builder get parent => null;

  @override
  String get fullNameForErrors => name;

  @override
  String toString() => "UnspecifiedDeclaration($name)";
}

class NoArguments extends Builder {
  NoArguments();

  @override
  Uri get fileUri => null;

  @override
  int get charOffset => -1;

  @override
  Builder get parent => null;

  @override
  String get fullNameForErrors => "<<no arguments>>";

  @override
  String toString() => fullNameForErrors;
}

class TypePromotionLookAheadListener extends Listener {
  final TypePromotionState state;

  TypePromotionLookAheadListener(this.state);

  Uri get uri => state.uri;

  void logEvent(String name) {
    throw new UnimplementedError(name);
  }

  void debugEvent(String name, Token token) {
    // state.trace(name, token);
  }

  @override
  void endArguments(int count, Token beginToken, Token endToken) {
    debugEvent("Arguments", beginToken);
    state.discard(count);
    state.pushNull("%Arguments%", endToken);
  }

  @override
  void handleNoArguments(Token token) {
    debugEvent("NoArguments", token);
    state.push(noArgumentsSentinel);
  }

  @override
  void handleAsOperator(Token operator) {
    debugEvent("AsOperator", operator);
    state.popPushNull(operator.lexeme, operator);
  }

  @override
  void endAssert(Token assertKeyword, Assert kind, Token leftParenthesis,
      Token commaToken, Token semicolonToken) {
    debugEvent("Assert", assertKeyword);
    if (commaToken != null) {
      state.pop(); // Message.
    }
    state.pop(); // Condition.
    switch (kind) {
      case Assert.Expression:
        state.pushNull("%AssertExpression%", assertKeyword);
        break;

      case Assert.Initializer:
        state.pushNull("%AssertInitializer%", assertKeyword);
        break;

      case Assert.Statement:
        break;
    }
  }

  @override
  void handleAssignmentExpression(Token token) {
    debugEvent("AssignmentExpression", token);
    state.pop(); // Right-hand side.
    Builder lhs = state.popPushNull(token.lexeme, token);
    if (lhs is UnspecifiedDeclaration) {
      state.registerWrite(lhs, token);
    }
  }

  @override
  void handleAsyncModifier(Token asyncToken, Token starToken) {
    debugEvent("AsyncModifier", asyncToken);
  }

  @override
  void endAwaitExpression(Token beginToken, Token endToken) {
    debugEvent("AwaitExpression", beginToken);
    state.popPushNull(beginToken.lexeme, beginToken); // Expression.
  }

  @override
  void endInvalidAwaitExpression(
      Token beginToken, Token endToken, MessageCode errorCode) {
    debugEvent("InvalidAwaitExpression", beginToken);
    state.popPushNull(beginToken.lexeme, beginToken); // Expression.
  }

  @override
  void endBinaryExpression(Token token) {
    debugEvent("BinaryExpression", token);
    state.pop(); // Right-hand side.
    state.popPushNull(token.lexeme, token); // Left-hand side.
  }

  @override
  void beginBlock(Token token) {
    debugEvent("beginBlock", token);
    state.enterScope("block");
  }

  @override
  void endBlock(int count, Token beginToken, Token endToken) {
    debugEvent("Block", beginToken);
    state.exitScope(endToken);
  }

  @override
  void beginBlockFunctionBody(Token token) {
    debugEvent("beginBlockFunctionBody", token);
    state.enterScope("block-function-body");
  }

  @override
  void endBlockFunctionBody(int count, Token beginToken, Token endToken) {
    debugEvent("BlockFunctionBody", beginToken);
    state.exitScope(endToken);
  }

  @override
  void handleBreakStatement(
      bool hasTarget, Token breakKeyword, Token endToken) {
    debugEvent("BreakStatement", breakKeyword);
    if (hasTarget) {
      state.pop(); // Target.
    }
  }

  @override
  void endCascade() {
    debugEvent("Cascade", null);
    state.popPushNull("%Cascade%", null);
  }

  @override
  void endCaseExpression(Token colon) {
    debugEvent("CaseExpression", colon);
    state.pop(); // Expression.
  }

  @override
  void handleCaseMatch(Token caseKeyword, Token colon) {
    debugEvent("CaseMatch", caseKeyword);
  }

  @override
  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
    debugEvent("CatchBlock", catchKeyword);
  }

  @override
  void endCatchClause(Token token) {
    debugEvent("CatchClause", token);
  }

  @override
  void endClassDeclaration(Token beginToken, Token endToken) {
    debugEvent("ClassDeclaration", beginToken);
    state.checkEmpty(endToken);
  }

  @override
  void handleClassExtends(Token extendsKeyword) {
    debugEvent("ClassExtends", extendsKeyword);
  }

  @override
  void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
    debugEvent("ClassHeader", begin);
    state.pop(); // Class name.
    state.checkEmpty(classKeyword);
  }

  @override
  void handleClassNoWithClause() {
    debugEvent("ClassNoWithClause", null);
  }

  @override
  void endClassOrMixinBody(
      DeclarationKind kind, int memberCount, Token beginToken, Token endToken) {
    debugEvent("ClassOrMixinBody", beginToken);
    state.checkEmpty(endToken);
  }

  @override
  void handleClassOrMixinImplements(
      Token implementsKeyword, int interfacesCount) {
    debugEvent("ClassOrMixinImplements", implementsKeyword);
  }

  @override
  void handleClassWithClause(Token withKeyword) {
    debugEvent("ClassWithClause", withKeyword);
  }

  @override
  void endCombinators(int count) {
    debugEvent("Combinators", null);
  }

  @override
  void handleCommentReference(
      Token newKeyword, Token prefix, Token period, Token token) {
    debugEvent("CommentReference", newKeyword);
    unhandled("CommentReference", newKeyword);
  }

  @override
  void handleNoCommentReference() {
    debugEvent("NoCommentReference", null);
    unhandled("NoCommentReference", null);
  }

  @override
  void handleCommentReferenceText(String referenceSource, int referenceOffset) {
    debugEvent("CommentReferenceText", null);
    unhandled("CommentReferenceText", null);
  }

  @override
  void endCompilationUnit(int count, Token token) {
    debugEvent("CompilationUnit", token);
    print(state.stack);
  }

  @override
  void endConditionalExpression(Token question, Token colon) {
    debugEvent("ConditionalExpression", question);
    state.pop(); // Otherwise expression.
    state.pop(); // Then expression.
    state.popPushNull(question.lexeme, question); // Condition.
  }

  @override
  void handleConditionalExpressionColon() {
    debugEvent("ConditionalExpressionColon", null);
    // TODO(ahe): Rename this event. This is not handling any colons as it
    // isn't being passed a colon. One alternative is
    // handleConditionalThenExpression, but check the specification for naming
    // conventions. Kernel uses "then" and "otherwise".
  }

  @override
  void endConditionalUri(Token ifKeyword, Token leftParen, Token equalSign) {
    debugEvent("ConditionalUri", ifKeyword);
    unhandled("ConditionalUri", ifKeyword);
  }

  @override
  void endConditionalUris(int count) {
    debugEvent("ConditionalUris", null);
  }

  @override
  void endConstExpression(Token token) {
    debugEvent("ConstExpression", token);
    doConstuctorInvocation(token, true);
  }

  @override
  void endForControlFlow(Token token) {
    // TODO(danrubel) add support for for control flow collection entries
    // but for now this is ignored and an error reported in the body builder.
  }

  @override
  void endForInControlFlow(Token token) {
    // TODO(danrubel) add support for for control flow collection entries
    // but for now this is ignored and an error reported in the body builder.
  }

  @override
  void handleElseControlFlow(Token token) {}

  @override
  void endIfControlFlow(Token token) {
    state.pop(); // Element.
    state.pop(); // Condition.
    state.pushNull("%IfControlFlow%", token);
  }

  @override
  void endIfElseControlFlow(Token token) {
    state.pop(); // Else element.
    state.pop(); // Then element.
    state.pop(); // Condition.
    state.pushNull("%IfElseControlFlow%", token);
  }

  @override
  void handleSpreadExpression(Token spreadToken) {
    // TODO(danrubel) add support for spread collections
    // but for now this is ignored and an error reported in the body builder.
    // The top of stack is the spread collection expression.
  }

  void doConstuctorInvocation(Token token, bool isConst) {
    state.pop(); // Arguments.
    state.popPushNull(token.lexeme, token); // Constructor reference.
  }

  @override
  void endConstLiteral(Token token) {
    debugEvent("ConstLiteral", token);
    state.popPushNull("%ConstLiteral%", token);
  }

  @override
  void endConstructorReference(
      Token start, Token periodBeforeName, Token endToken) {
    debugEvent("ConstructorReference", start);
    if (periodBeforeName != null) {
      state.pop(); // Prefix.
    }
    state.popPushNull("%ConstructorReference%", start);
  }

  @override
  void handleNoConstructorReferenceContinuationAfterTypeArguments(Token token) {
    debugEvent("NoConstructorReferenceContinuationAfterTypeArguments", token);
  }

  @override
  void handleContinueStatement(
      bool hasTarget, Token continueKeyword, Token endToken) {
    debugEvent("ContinueStatement", continueKeyword);
    if (hasTarget) {
      state.pop(); // Target.
    }
  }

  @override
  void handleDirectivesOnly() {
    debugEvent("DirectivesOnly", null);
    unhandled("DirectivesOnly", null);
  }

  @override
  void endDoWhileStatement(
      Token doKeyword, Token whileKeyword, Token endToken) {
    debugEvent("DoWhileStatement", doKeyword);
    state.pop(); // Condition.
  }

  @override
  void endDoWhileStatementBody(Token token) {
    debugEvent("DoWhileStatementBody", token);
  }

  @override
  void handleDottedName(int count, Token firstIdentifier) {
    debugEvent("DottedName", firstIdentifier);
    unhandled("DottedName", firstIdentifier);
  }

  @override
  void endElseStatement(Token token) {
    debugEvent("ElseStatement", token);
  }

  @override
  void handleEmptyFunctionBody(Token semicolon) {
    debugEvent("EmptyFunctionBody", semicolon);
  }

  @override
  void handleEmptyStatement(Token token) {
    debugEvent("EmptyStatement", token);
  }

  @override
  void beginEnum(Token enumKeyword) {
    debugEvent("beginEnum", enumKeyword);
    state.checkEmpty(enumKeyword);
  }

  @override
  void endEnum(Token enumKeyword, Token leftBrace, int count) {
    debugEvent("endEnum", enumKeyword);
    state.discard(count); // Enum values.
    state.pop(); // Enum name.
    state.checkEmpty(enumKeyword);
  }

  @override
  void endExport(Token exportKeyword, Token semicolon) {
    debugEvent("Export", exportKeyword);
    state.pop(); // Export URI.
    state.checkEmpty(semicolon);
  }

  @override
  void handleExpressionFunctionBody(Token arrowToken, Token endToken) {
    debugEvent("ExpressionFunctionBody", arrowToken);
    state.pop();
  }

  @override
  void handleExpressionStatement(Token token) {
    debugEvent("ExpressionStatement", token);
    state.pop();
  }

  @override
  void handleExtraneousExpression(Token token, Message message) {
    debugEvent("ExtraneousExpression", token);
    unhandled("ExtraneousExpression", token);
  }

  @override
  void endClassFactoryMethod(
      Token beginToken, Token factoryKeyword, Token endToken) {
    debugEvent("ClassFactoryMethod", beginToken);
    state.pop(); // Name.
    state.checkEmpty(endToken);
  }

  @override
  void endFieldInitializer(Token assignment, Token token) {
    debugEvent("FieldInitializer", assignment);
    state.pop(); // Initializer.
  }

  @override
  void handleNoFieldInitializer(Token token) {
    debugEvent("NoFieldInitializer", token);
  }

  @override
  void endClassFields(Token staticToken, Token covariantToken, Token lateToken,
      Token varFinalOrConst, int count, Token beginToken, Token endToken) {
    debugEvent("Fields", staticToken);
    state.discard(count); // Field names.
    state.checkEmpty(endToken);
  }

  @override
  void handleFinallyBlock(Token finallyKeyword) {
    debugEvent("FinallyBlock", finallyKeyword);
  }

  @override
  void endForIn(Token endToken) {
    debugEvent("ForIn", endToken);
  }

  @override
  void endForInBody(Token token) {
    debugEvent("ForInBody", token);
  }

  @override
  void endForInExpression(Token token) {
    debugEvent("ForInExpression", token);
    state.pop(); // Expression.
  }

  @override
  void handleForInitializerEmptyStatement(Token token) {
    debugEvent("ForInitializerEmptyStatement", token);
  }

  @override
  void handleForInitializerExpressionStatement(Token token) {
    debugEvent("ForInitializerExpressionStatement", token);
    state.pop(); // Expression.
  }

  @override
  void handleForInitializerLocalVariableDeclaration(Token token) {
    debugEvent("ForInitializerLocalVariableDeclaration", token);
  }

  @override
  void handleForLoopParts(Token forKeyword, Token leftParen,
      Token leftSeparator, int updateExpressionCount) {
    debugEvent("handleForLoopParts", forKeyword);
    state.discard(updateExpressionCount);
  }

  @override
  void endForStatement(Token endToken) {
    debugEvent("ForStatement", endToken);
  }

  @override
  void endForStatementBody(Token token) {
    debugEvent("ForStatementBody", token);
  }

  @override
  void endFormalParameter(
      Token thisKeyword,
      Token periodAfterThis,
      Token nameToken,
      Token initializerStart,
      Token initializerEnd,
      FormalParameterKind kind,
      MemberKind memberKind) {
    debugEvent("FormalParameter", thisKeyword);
    state.pop(); // Parameter name.
  }

  @override
  void endFormalParameterDefaultValueExpression() {
    debugEvent("FormalParameterDefaultValueExpression", null);
    state.pop();
  }

  @override
  void handleFormalParameterWithoutValue(Token token) {
    debugEvent("FormalParameterWithoutValue", token);
  }

  @override
  void endFormalParameters(
      int count, Token beginToken, Token endToken, MemberKind kind) {
    debugEvent("FormalParameters", beginToken);
  }

  @override
  void handleNoFormalParameters(Token token, MemberKind kind) {
    debugEvent("NoFormalParameters", token);
  }

  @override
  void handleNoFunctionBody(Token token) {
    debugEvent("NoFunctionBody", token);
    unhandled("NoFunctionBody", token);
  }

  @override
  void handleFunctionBodySkipped(Token token, bool isExpressionBody) {
    debugEvent("FunctionBodySkipped", token);
    unhandled("FunctionBodySkipped", token);
  }

  @override
  void endFunctionExpression(Token beginToken, Token token) {
    debugEvent("FunctionExpression", beginToken);
    state.pushNull("%function%", token);
  }

  @override
  void endFunctionName(Token beginToken, Token token) {
    debugEvent("FunctionName", beginToken);
  }

  @override
  void endFunctionType(Token functionToken, Token questionMark) {
    debugEvent("FunctionType", functionToken);
  }

  @override
  void endFunctionTypeAlias(
      Token typedefKeyword, Token equals, Token endToken) {
    debugEvent("FunctionTypeAlias", typedefKeyword);
    state.pop(); // Name.
    state.checkEmpty(endToken);
  }

  @override
  void endFunctionTypedFormalParameter(Token nameToken, Token question) {
    debugEvent("FunctionTypedFormalParameter", nameToken);
  }

  @override
  void endHide(Token hideKeyword) {
    debugEvent("Hide", hideKeyword);
  }

  @override
  void handleIdentifier(Token token, IdentifierContext context) {
    debugEvent("Identifier ${context}", token);
    if (context.inSymbol) {
      // Do nothing.
    } else if (context.inDeclaration) {
      if (identical(IdentifierContext.localVariableDeclaration, context) ||
          identical(IdentifierContext.formalParameterDeclaration, context)) {
        state.declareIdentifier(token);
      } else {
        state.pushNull(token.lexeme, token);
      }
    } else if (context.isContinuation) {
      state.pushNull(token.lexeme, token);
    } else if (context.isScopeReference) {
      state.pushReference(token);
    } else {
      state.pushNull(token.lexeme, token);
    }
  }

  @override
  void handleIdentifierList(int count) {
    debugEvent("IdentifierList", null);
    state.discard(count);
  }

  @override
  void endIfStatement(Token ifToken, Token elseToken) {
    debugEvent("IfStatement", ifToken);
    state.pop(); // Condition.
  }

  @override
  void endImplicitCreationExpression(Token token) {
    debugEvent("ImplicitCreationExpression", token);
    doConstuctorInvocation(token, false);
  }

  @override
  void endImport(Token importKeyword, Token semicolon) {
    debugEvent("Import", importKeyword);
    state.pop(); // Import URI.
    state.checkEmpty(semicolon);
  }

  @override
  void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
    debugEvent("ImportPrefix", deferredKeyword);
    if (asKeyword != null) {
      state.pop(); // Prefix name.
    }
  }

  @override
  void handleIndexedExpression(
      Token openSquareBracket, Token closeSquareBracket) {
    debugEvent("IndexedExpression", openSquareBracket);
    state.pop(); // Index.
    state.popPushNull("%indexed%", closeSquareBracket); // Expression.
  }

  @override
  void endInitializedIdentifier(Token nameToken) {
    debugEvent("InitializedIdentifier", nameToken);
  }

  @override
  void endInitializer(Token token) {
    debugEvent("Initializer", token);
    state.pop(); // Initializer.
  }

  @override
  void endInitializers(int count, Token beginToken, Token endToken) {
    debugEvent("Initializers", beginToken);
  }

  @override
  void handleNoInitializers() {
    debugEvent("NoInitializers", null);
  }

  @override
  void handleInterpolationExpression(Token leftBracket, Token rightBracket) {
    debugEvent("InterpolationExpression", leftBracket);
    state.popPushNull(r"$", leftBracket);
  }

  @override
  void handleInvalidExpression(Token token) {
    // TODO(ahe): The parser doesn't generate this event anymore.
    debugEvent("InvalidExpression", token);
    unhandled("InvalidExpression", token);
  }

  @override
  void handleInvalidFunctionBody(Token token) {
    debugEvent("InvalidFunctionBody", token);
  }

  @override
  void handleInvalidMember(Token endToken) {
    debugEvent("InvalidMember", endToken);
    state.checkEmpty(endToken);
  }

  @override
  void handleInvalidOperatorName(Token operatorKeyword, Token token) {
    debugEvent("InvalidOperatorName", operatorKeyword);
    state.checkEmpty(operatorKeyword);
  }

  @override
  void handleInvalidStatement(Token token, Message message) {
    debugEvent("InvalidStatement", token);
  }

  @override
  void handleInvalidTopLevelBlock(Token token) {
    debugEvent("InvalidTopLevelBlock", token);
    state.checkEmpty(token);
  }

  @override
  void handleInvalidTopLevelDeclaration(Token endToken) {
    debugEvent("InvalidTopLevelDeclaration", endToken);
    state.checkEmpty(endToken);
  }

  @override
  void handleInvalidTypeArguments(Token token) {
    debugEvent("InvalidTypeArguments", token);
  }

  @override
  void handleInvalidTypeReference(Token token) {
    debugEvent("InvalidTypeReference", token);
    unhandled("InvalidTypeReference", token);
  }

  @override
  void handleIsOperator(Token isOperator, Token not) {
    debugEvent("IsOperator", isOperator);
    Builder lhs = state.popPushNull(isOperator.lexeme, isOperator);
    if (not == null && lhs is UnspecifiedDeclaration) {
      state.registerPromotionCandidate(lhs, isOperator);
    }
  }

  @override
  void handleLabel(Token token) {
    debugEvent("Label", token);
    state.pop(); // Label.
  }

  @override
  void endLabeledStatement(int labelCount) {
    debugEvent("LabeledStatement", null);
  }

  @override
  void endLibraryName(Token libraryKeyword, Token semicolon) {
    debugEvent("LibraryName", libraryKeyword);
    state.pop(); // Library name.
    state.checkEmpty(semicolon);
  }

  @override
  void handleLiteralBool(Token token) {
    debugEvent("LiteralBool", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void handleLiteralDouble(Token token) {
    debugEvent("LiteralDouble", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void handleLiteralInt(Token token) {
    debugEvent("LiteralInt", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void handleLiteralList(
      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
    debugEvent("LiteralList", leftBracket);
    state.discard(count);
    state.pushNull("[]", leftBracket);
  }

  @override
  void handleLiteralSetOrMap(
    int count,
    Token leftBrace,
    Token constKeyword,
    Token rightBrace,
    // TODO(danrubel): hasSetEntry parameter exists for replicating existing
    // behavior and will be removed once unified collection has been enabled
    bool hasSetEntry,
  ) {
    debugEvent("LiteralSetOrMap", leftBrace);
    state.discard(count);
    state.pushNull("{}", leftBrace);
  }

  @override
  void handleLiteralMapEntry(Token colon, Token endToken) {
    debugEvent("LiteralMapEntry", colon);
    state.pop(); // Value.
    state.popPushNull("%LiteralMapEntry%", colon); // Key.
  }

  @override
  void handleLiteralNull(Token token) {
    debugEvent("LiteralNull", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void beginLiteralString(Token token) {
    debugEvent("beginLiteralString", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void endLiteralString(int interpolationCount, Token endToken) {
    debugEvent("LiteralString", endToken);
    state.discard(interpolationCount * 2);
    state.popPushNull("%string%", endToken);
  }

  @override
  void endLiteralSymbol(Token hashToken, int identifierCount) {
    debugEvent("LiteralSymbol", hashToken);
    state.pushNull(hashToken.lexeme, hashToken);
  }

  @override
  void endLocalFunctionDeclaration(Token endToken) {
    debugEvent("LocalFunctionDeclaration", endToken);
    state.pop(); // Function name.
  }

  @override
  void endMember() {
    debugEvent("Member", null);
    state.checkEmpty(null);
  }

  @override
  void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
    debugEvent("Metadata", beginToken);
    state.pop(); // Arguments.
    if (periodBeforeName != null) {
      state.pop(); // Suffix.
    }
    state.pop(); // Qualifier.
  }

  @override
  void endMetadataStar(int count) {
    debugEvent("MetadataStar", null);
  }

  @override
  void beginMethod(Token externalToken, Token staticToken, Token covariantToken,
      Token varFinalOrConst, Token getOrSet, Token name) {
    debugEvent("beginMethod", name);
    state.checkEmpty(name);
  }

  @override
  void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
      Token beginInitializers, Token endToken) {
    debugEvent("endMethod", endToken);
    state.pop(); // Method name.
    state.checkEmpty(endToken);
  }

  @override
  void endMixinDeclaration(Token mixinKeyword, Token endToken) {
    debugEvent("MixinDeclaration", mixinKeyword);
    state.checkEmpty(endToken);
  }

  @override
  void handleMixinHeader(Token mixinKeyword) {
    debugEvent("MixinHeader", mixinKeyword);
    state.pop(); // Mixin name.
    state.checkEmpty(mixinKeyword);
  }

  @override
  void handleMixinOn(Token onKeyword, int typeCount) {
    debugEvent("MixinOn", onKeyword);
  }

  @override
  void handleNoName(Token token) {
    debugEvent("NoName", token);
    state.pushNull("%NoName%", token);
  }

  @override
  void handleNamedArgument(Token colon) {
    debugEvent("NamedArgument", colon);
    state.pop(); // Expression.
    state.popPushNull("%NamedArgument%", colon); // Identifier.
  }

  @override
  void endNamedFunctionExpression(Token endToken) {
    debugEvent("NamedFunctionExpression", endToken);
    state.popPushNull(
        "%named function expression%", endToken); // Function name.
  }

  @override
  void endNamedMixinApplication(Token begin, Token classKeyword, Token equals,
      Token implementsKeyword, Token endToken) {
    debugEvent("NamedMixinApplication", begin);
    state.pop(); // Mixin application name.
    state.checkEmpty(endToken);
  }

  @override
  void handleNamedMixinApplicationWithClause(Token withKeyword) {
    debugEvent("NamedMixinApplicationWithClause", withKeyword);
  }

  @override
  void handleNativeClause(Token nativeToken, bool hasName) {
    debugEvent("NativeClause", nativeToken);
    if (hasName) {
      state.pop(); // Name.
    }
  }

  @override
  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBody", nativeToken);
  }

  @override
  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodyIgnored", nativeToken);
  }

  @override
  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
    debugEvent("NativeFunctionBodySkipped", nativeToken);
  }

  @override
  void endNewExpression(Token token) {
    debugEvent("NewExpression", token);
    doConstuctorInvocation(token, false);
  }

  @override
  void handleOperator(Token token) {
    debugEvent("Operator", token);
    unhandled("Operator", token);
  }

  @override
  void handleOperatorName(Token operatorKeyword, Token token) {
    debugEvent("OperatorName", operatorKeyword);
    state.pushNull(token.lexeme, token);
  }

  @override
  void endOptionalFormalParameters(
      int count, Token beginToken, Token endToken) {
    debugEvent("OptionalFormalParameters", beginToken);
  }

  @override
  void handleParenthesizedCondition(Token token) {
    debugEvent("ParenthesizedCondition", token);
  }

  @override
  void handleParenthesizedExpression(Token token) {
    debugEvent("ParenthesizedExpression", token);
    state.popPushNull("%(expr)%", token);
  }

  @override
  void endPart(Token partKeyword, Token semicolon) {
    debugEvent("Part", partKeyword);
    state.pop(); // URI.
    state.checkEmpty(semicolon);
  }

  @override
  void endPartOf(
      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
    debugEvent("PartOf", partKeyword);
    state.pop(); // Name or URI.
    state.checkEmpty(semicolon);
  }

  @override
  void handleQualified(Token period) {
    debugEvent("Qualified", period);
    state.pop(); // Suffix.
    state.popPushNull("%Qualified%", period); // Qualifier.
  }

  @override
  void handleRecoverClassHeader() {
    debugEvent("RecoverClassHeader", null);
    state.checkEmpty(null);
  }

  @override
  void handleRecoverImport(Token semicolon) {
    debugEvent("RecoverImport", semicolon);
    unhandled("RecoverImport", semicolon);
  }

  @override
  void handleRecoverMixinHeader() {
    debugEvent("RecoverMixinHeader", null);
    state.checkEmpty(null);
  }

  @override
  void handleRecoverableError(
      Message message, Token startToken, Token endToken) {
    debugEvent("RecoverableError ${message.message}", startToken);
  }

  @override
  void endRedirectingFactoryBody(Token beginToken, Token endToken) {
    debugEvent("RedirectingFactoryBody", beginToken);
    state.pop(); // Constructor reference.
  }

  @override
  void endRethrowStatement(Token rethrowToken, Token endToken) {
    debugEvent("RethrowStatement", rethrowToken);
  }

  @override
  void endReturnStatement(
      bool hasExpression, Token beginToken, Token endToken) {
    debugEvent("ReturnStatement", beginToken);
    if (hasExpression) {
      state.pop(); // Expression.
    }
  }

  @override
  void handleScript(Token token) {
    debugEvent("Script", token);
    unhandled("Script", token);
  }

  @override
  void handleSend(Token beginToken, Token endToken) {
    debugEvent("Send", beginToken);
    Builder arguments = state.pop();
    if (identical(arguments, noArgumentsSentinel)) {
      // Leave the receiver on the stack.
    } else {
      state.popPushNull("%send%", beginToken);
    }
  }

  @override
  void endShow(Token showKeyword) {
    debugEvent("Show", showKeyword);
  }

  @override
  void handleStringJuxtaposition(int literalCount) {
    debugEvent("StringJuxtaposition", null);
    state.discard(literalCount);
    state.pushNull("%StringJuxtaposition%", null);
  }

  @override
  void handleStringPart(Token token) {
    debugEvent("StringPart", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void handleSuperExpression(Token token, IdentifierContext context) {
    debugEvent("SuperExpression", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
    debugEvent("SwitchBlock", beginToken);
    state.pop(); // Expression.
  }

  @override
  void endSwitchCase(
      int labelCount,
      int expressionCount,
      Token defaultKeyword,
      Token colonAfterDefault,
      int statementCount,
      Token firstToken,
      Token endToken) {
    debugEvent("SwitchCase", defaultKeyword);
  }

  @override
  void endSwitchStatement(Token switchKeyword, Token endToken) {
    debugEvent("SwitchStatement", switchKeyword);
  }

  @override
  void handleSymbolVoid(Token token) {
    debugEvent("SymbolVoid", token);
    unhandled("SymbolVoid", token);
  }

  @override
  void endThenStatement(Token token) {
    debugEvent("ThenStatement", token);
  }

  @override
  void handleThisExpression(Token token, IdentifierContext context) {
    debugEvent("ThisExpression", token);
    state.pushNull(token.lexeme, token);
  }

  @override
  void handleThrowExpression(Token throwToken, Token endToken) {
    debugEvent("ThrowExpression", throwToken);
    state.popPushNull(throwToken.lexeme, throwToken);
  }

  @override
  void endTopLevelDeclaration(Token token) {
    debugEvent("TopLevelDeclaration", token);
    state.checkEmpty(token);
  }

  @override
  void endTopLevelFields(
      Token staticToken,
      Token covariantToken,
      Token lateToken,
      Token varFinalOrConst,
      int count,
      Token beginToken,
      Token endToken) {
    debugEvent("TopLevelFields", staticToken);
    state.discard(count); // Field names.
    state.checkEmpty(endToken);
  }

  @override
  void beginTopLevelMethod(Token lastConsumed, Token externalToken) {
    debugEvent("beginTopLevelMethod", lastConsumed.next);
    state.checkEmpty(lastConsumed.next);
  }

  @override
  void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
    debugEvent("endTopLevelMethod", beginToken);
    state.pop(); // Method name.
    state.checkEmpty(endToken);
  }

  @override
  void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
    debugEvent("TryStatement", tryKeyword);
  }

  @override
  void handleType(Token beginToken, Token questionMark) {
    debugEvent("Type", beginToken);
    state.pop();
  }

  @override
  void handleNoType(Token lastConsumed) {
    debugEvent("NoType", lastConsumed);
  }

  @override
  void endTypeArguments(int count, Token beginToken, Token endToken) {
    debugEvent("TypeArguments", beginToken);
  }

  @override
  void handleNoTypeArguments(Token token) {
    debugEvent("NoTypeArguments", token);
  }

  @override
  void endTypeList(int count) {
    debugEvent("TypeList", null);
  }

  @override
  void endTypeVariable(
      Token token, int index, Token extendsOrSuper, Token variance) {
    debugEvent("TypeVariable", token);
    state.pop(); // Name.
  }

  @override
  void endTypeVariables(Token beginToken, Token endToken) {
    debugEvent("TypeVariables", beginToken);
  }

  @override
  void handleVarianceModifier(Token variance) {
    debugEvent("VarianceModifier", variance);
  }

  @override
  void handleNoTypeVariables(Token token) {
    debugEvent("NoTypeVariables", token);
  }

  @override
  void handleTypeVariablesDefined(Token token, int count) {
    debugEvent("TypeVariablesDefined", token);
  }

  @override
  void handleUnaryPostfixAssignmentExpression(Token token) {
    debugEvent("UnaryPostfixAssignmentExpression", token);
    Builder expr = state.popPushNull(token.lexeme, token);
    if (expr is UnspecifiedDeclaration) {
      state.registerWrite(expr, token);
    }
  }

  @override
  void handleUnaryPrefixAssignmentExpression(Token token) {
    debugEvent("UnaryPrefixAssignmentExpression", token);
    Builder expr = state.popPushNull(token.lexeme, token);
    if (expr is UnspecifiedDeclaration) {
      state.registerWrite(expr, token);
    }
  }

  @override
  void handleUnaryPrefixExpression(Token token) {
    debugEvent("UnaryPrefixExpression", token);
    state.popPushNull("%UnaryPrefixExpression%", token);
  }

  @override
  void handleNonNullAssertExpression(Token token) {
    debugEvent("NonNullAssertExpression", token);
    state.popPushNull("%NonNullAssertExpression%", token);
  }

  @override
  void handleUnescapeError(
      Message message, Token location, int stringOffset, int length) {
    debugEvent("UnescapeError", location);
    unhandled("UnescapeError", location);
  }

  @override
  void handleValuedFormalParameter(Token equals, Token token) {
    debugEvent("ValuedFormalParameter", equals);
  }

  @override
  void endVariableInitializer(Token assignmentOperator) {
    debugEvent("VariableInitializer", assignmentOperator);
    state.pop(); // Initializer.
  }

  @override
  void handleNoVariableInitializer(Token token) {
    debugEvent("NoVariableInitializer", token);
  }

  @override
  void endVariablesDeclaration(int count, Token endToken) {
    debugEvent("VariablesDeclaration", endToken);
    state.discard(count); // Variable names.
  }

  @override
  void handleVoidKeyword(Token token) {
    debugEvent("VoidKeyword", token);
  }

  @override
  void endWhileStatement(Token whileKeyword, Token endToken) {
    debugEvent("WhileStatement", whileKeyword);
    state.pop(); // Condition.
  }

  @override
  void endWhileStatementBody(Token token) {
    debugEvent("WhileStatementBody", token);
  }

  @override
  void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
    debugEvent("YieldStatement", yieldToken);
    state.pop(); // Expression.
  }

  void unhandled(String event, Token token) {
    problems.unhandled(
        event, "TypePromotionLookAheadListener", token?.charOffset ?? -1, uri);
  }
}
