// 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 Declaration;

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

import '../parser.dart'
    show Assert, IdentifierContext, FormalParameterKind, 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<Declaration> stack = <Declaration>[];

  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;
    Declaration declaration = currentScope.lookup(name, token.charOffset, uri);
    stack.add(declaration);
  }

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

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

  Declaration popPushNull(String name, Token token) {
    int last = stack.length - 1;
    Declaration 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));
  }

  Declaration 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 Declaration {
  final String name;

  @override
  final Uri fileUri;

  @override
  int charOffset;

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

  @override
  Declaration get parent => null;

  @override
  String get fullNameForErrors => name;

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

class NoArguments extends Declaration {
  NoArguments();

  @override
  Uri get fileUri => null;

  @override
  int get charOffset => -1;

  @override
  Declaration 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 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.
    Declaration 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 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(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);
  }

  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 endExpressionStatement(Token token) {
    debugEvent("ExpressionStatement", token);
    state.pop();
  }

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

  @override
  void endFactoryMethod(
      Token beginToken, Token factoryKeyword, Token endToken) {
    debugEvent("FactoryMethod", 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 endFields(Token staticToken, Token covariantToken, 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 awaitToken, Token forToken, Token leftParenthesis,
      Token inKeyword, Token endToken) {
    debugEvent("ForIn", awaitToken);
  }

  @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 endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
      int updateExpressionCount, Token endToken) {
    debugEvent("ForStatement", forKeyword);
    state.discard(updateExpressionCount);
  }

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

  @override
  void endFormalParameter(Token thisKeyword, Token periodAfterThis,
      Token nameToken, 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) {
    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) {
    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);
    Declaration 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 handleLiteralMap(
      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
    debugEvent("LiteralMap", 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 endMethod(
      Token getOrSet, Token beginToken, Token beginParam, 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);
    Declaration 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 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) {
    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) {
    debugEvent("TypeVariable", token);
    state.pop(); // Name.
  }

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

  @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);
    Declaration expr = state.popPushNull(token.lexeme, token);
    if (expr is UnspecifiedDeclaration) {
      state.registerWrite(expr, token);
    }
  }

  @override
  void handleUnaryPrefixAssignmentExpression(Token token) {
    debugEvent("UnaryPrefixAssignmentExpression", token);
    Declaration 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 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);
  }
}
