// 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.md file.

import 'package:kernel/ast.dart'
    show Catch, DartType, FunctionType, Node, TypeParameter;

import 'package:kernel/ast.dart' show Catch, DartType, FunctionType, Node;

import 'package:kernel/type_algebra.dart' show Substitution;

import '../../scanner/token.dart' show Token;
import '../kernel/kernel_shadow_ast.dart'
    show
        ExpressionJudgment,
        InitializerJudgment,
        LoadLibraryJudgment,
        LoadLibraryTearOffJudgment,
        StatementJudgment,
        SwitchCaseJudgment;

import '../kernel/kernel_type_variable_builder.dart'
    show KernelTypeVariableBuilder;

/// Callback interface used by [TypeInferrer] to report the results of type
/// inference to a client.
///
/// The interface is structured as a set of enter/exit methods.  The enter
/// methods are called as the inferrer recurses down through the AST, and the
/// exit methods are called on the way back up.  The enter methods take a
/// [DartType] argument representing the downwards inference context; the exit
/// methods take [DartType] argument representing the final inferred type.
///
/// The default implementation (in this base class) does nothing, however it can
/// be used to debug type inference by uncommenting the
/// "with TypeInferenceDebugging" clause below.
abstract class TypeInferenceListener<Location, Reference, PrefixInfo> {
  void asExpression(
      ExpressionJudgment judgment,
      Location location,
      void expression,
      Token asOperator,
      void literalType,
      DartType inferredType);

  void assertInitializer(
      InitializerJudgment judgment,
      Location location,
      Token assertKeyword,
      Token leftParenthesis,
      void condition,
      Token comma,
      void message,
      Token rightParenthesis);

  void assertStatement(
      StatementJudgment judgment,
      Location location,
      Token assertKeyword,
      Token leftParenthesis,
      void condition,
      Token comma,
      void message,
      Token rightParenthesis,
      Token semicolon);

  void awaitExpression(ExpressionJudgment judgment, Location location,
      Token awaitKeyword, void expression, DartType inferredType);

  Object binderForFunctionDeclaration(
      StatementJudgment judgment, Location location, String name);

  Object binderForStatementLabel(
      StatementJudgment judgment, int fileOffset, String name);

  Object binderForSwitchLabel(
      SwitchCaseJudgment judgment, int fileOffset, String name);

  Object binderForTypeVariable(
      KernelTypeVariableBuilder builder, int fileOffset, String name);

  Object binderForVariableDeclaration(
      StatementJudgment judgment, int fileOffset, String name);

  void block(StatementJudgment judgment, Location location, Token leftBracket,
      List<void> statements, Token rightBracket);

  void boolLiteral(ExpressionJudgment judgment, Location location,
      Token literal, bool value, DartType inferredType);

  void breakStatement(
      StatementJudgment judgment,
      Location location,
      Token breakKeyword,
      void label,
      Token semicolon,
      covariant Object labelBinder);

  void cascadeExpression(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void catchStatement(
      Catch judgment,
      Location location,
      Token onKeyword,
      void type,
      Token catchKeyword,
      Token leftParenthesis,
      Token exceptionParameter,
      Token comma,
      Token stackTraceParameter,
      Token rightParenthesis,
      void body,
      DartType guardType,
      covariant Object exceptionBinder,
      DartType exceptionType,
      covariant Object stackTraceBinder,
      DartType stackTraceType);

  void conditionalExpression(
      ExpressionJudgment judgment,
      Location location,
      void condition,
      Token question,
      void thenExpression,
      Token colon,
      void elseExpression,
      DartType inferredType);

  void constructorInvocation(ExpressionJudgment judgment, Location location,
      Reference expressionTarget, DartType inferredType);

  void continueStatement(
      StatementJudgment judgment,
      Location location,
      Token continueKeyword,
      void label,
      Token semicolon,
      covariant Object labelBinder);

  void continueSwitchStatement(
      StatementJudgment judgment,
      Location location,
      Token continueKeyword,
      void label,
      Token semicolon,
      covariant Object labelBinder);

  void deferredCheck(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void doStatement(
      StatementJudgment judgment,
      Location location,
      Token doKeyword,
      void body,
      Token whileKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      Token semicolon);

  void doubleLiteral(ExpressionJudgment judgment, Location location,
      Token literal, double value, DartType inferredType);

  void emptyStatement(Token semicolon);

  void expressionStatement(StatementJudgment judgment, Location location,
      void expression, Token semicolon);

  void fieldInitializer(
      InitializerJudgment judgment,
      Location location,
      Token thisKeyword,
      Token period,
      Token fieldName,
      Token equals,
      void expression,
      Reference initializerField);

  void forInStatement(
      StatementJudgment judgment,
      Location location,
      Token awaitKeyword,
      Token forKeyword,
      Token leftParenthesis,
      Object loopVariable,
      Token identifier,
      Token inKeyword,
      void iterator,
      Token rightParenthesis,
      void body,
      covariant Object loopVariableBinder,
      DartType loopVariableType,
      Location writeLocation,
      DartType writeVariableType,
      covariant Object writeVariableBinder,
      Reference writeTarget);

  void forStatement(
      StatementJudgment judgment,
      Location location,
      Token forKeyword,
      Token leftParenthesis,
      List<Object> variableList,
      void initialization,
      Token leftSeparator,
      void condition,
      Token rightSeparator,
      void updaters,
      Token rightParenthesis,
      void body);

  void functionDeclaration(covariant Object binder, FunctionType inferredType);

  void functionExpression(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void functionType(Location location, DartType type);

  void functionTypedFormalParameter(Location location, DartType type);

  void ifNull(ExpressionJudgment judgment, Location location, void leftOperand,
      Token operator, void rightOperand, DartType inferredType);

  void ifStatement(
      StatementJudgment judgment,
      Location location,
      Token ifKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      void thenStatement,
      Token elseKeyword,
      void elseStatement);

  void indexAssign(ExpressionJudgment judgment, Location location,
      Reference writeMember, Reference combiner, DartType inferredType);

  void intLiteral(ExpressionJudgment judgment, Location location, Token literal,
      num value, DartType inferredType);

  void invalidInitializer(InitializerJudgment judgment, Location location);

  void isExpression(
      ExpressionJudgment judgment,
      Location location,
      void expression,
      Token isOperator,
      void literalType,
      DartType testedType,
      DartType inferredType);

  void isNotExpression(
      ExpressionJudgment judgment,
      Location location,
      void expression,
      Token isOperator,
      Token notOperator,
      void literalType,
      DartType type,
      DartType inferredType);

  void labeledStatement(List<Object> labels, void statement);

  void listLiteral(
      ExpressionJudgment judgment,
      Location location,
      Token constKeyword,
      covariant Object typeArguments,
      Token leftBracket,
      void elements,
      Token rightBracket,
      DartType inferredType);

  void loadLibrary(LoadLibraryJudgment judgment, Location location,
      Reference library, FunctionType calleeType, DartType inferredType);

  void loadLibraryTearOff(LoadLibraryTearOffJudgment judgment,
      Location location, Reference library, DartType inferredType);

  void logicalExpression(
      ExpressionJudgment judgment,
      Location location,
      void leftOperand,
      Token operator,
      void rightOperand,
      DartType inferredType);

  void mapLiteral(
      ExpressionJudgment judgment,
      Location location,
      Token constKeyword,
      covariant Object typeArguments,
      Token leftBracket,
      List<Object> entries,
      Token rightBracket,
      DartType inferredType);

  void mapLiteralEntry(
      Object judgment, int fileOffset, void key, Token separator, void value);

  void methodInvocation(
      ExpressionJudgment judgment,
      Location resultOffset,
      List<DartType> argumentsTypes,
      bool isImplicitCall,
      Reference interfaceMember,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType);

  void methodInvocationCall(
      ExpressionJudgment judgment,
      Location resultOffset,
      List<DartType> argumentsTypes,
      bool isImplicitCall,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType);

  void namedFunctionExpression(ExpressionJudgment judgment,
      covariant Object binder, DartType inferredType);

  void not(ExpressionJudgment judgment, Location location, Token operator,
      void operand, DartType inferredType);

  void nullLiteral(ExpressionJudgment judgment, Location location,
      Token literal, bool isSynthetic, DartType inferredType);

  void propertyAssign(
      ExpressionJudgment judgment,
      Location location,
      Reference writeMember,
      DartType writeContext,
      Reference combiner,
      DartType inferredType);

  void propertyGet(ExpressionJudgment judgment, Location location,
      Reference member, DartType inferredType);

  void propertyGetCall(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void propertySet(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void redirectingInitializer(
      InitializerJudgment judgment,
      Location location,
      Token thisKeyword,
      Token period,
      Token constructorName,
      covariant Object argumentList,
      Reference initializerTarget);

  void rethrow_(ExpressionJudgment judgment, Location location,
      Token rethrowKeyword, DartType inferredType);

  void returnStatement(StatementJudgment judgment, Location location,
      Token returnKeyword, void expression, Token semicolon);

  Object statementLabel(covariant Object binder, Token label, Token colon);

  void staticAssign(
      ExpressionJudgment judgment,
      Location location,
      Reference writeMember,
      DartType writeContext,
      Reference combiner,
      DartType inferredType);

  void staticGet(ExpressionJudgment judgment, Location location,
      Reference expressionTarget, DartType inferredType);

  void staticInvocation(
      ExpressionJudgment judgment,
      Location location,
      Reference expressionTarget,
      List<DartType> expressionArgumentsTypes,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType);

  void storeClassReference(
      Location location, Reference reference, DartType rawType);

  void storePrefixInfo(Location location, PrefixInfo prefixInfo);

  void stringConcatenation(
      ExpressionJudgment judgment, Location location, DartType inferredType);

  void stringLiteral(ExpressionJudgment judgment, Location location,
      Token literal, String value, DartType inferredType);

  void superInitializer(
      InitializerJudgment judgment,
      Location location,
      Token superKeyword,
      Token period,
      Token constructorName,
      covariant Object argumentList);

  Object switchCase(SwitchCaseJudgment switchCase, List<Object> labels,
      Token keyword, void expression, Token colon, List<void> statements);

  Object switchLabel(covariant Object binder, Token label, Token colon);

  void switchStatement(
      StatementJudgment judgment,
      Location location,
      Token switchKeyword,
      Token leftParenthesis,
      void expression,
      Token rightParenthesis,
      Token leftBracket,
      void members,
      Token rightBracket);

  void symbolLiteral(
      ExpressionJudgment judgment,
      Location location,
      Token poundSign,
      List<Token> components,
      String value,
      DartType inferredType);

  void thisExpression(ExpressionJudgment judgment, Location location,
      Token thisKeyword, DartType inferredType);

  void throw_(ExpressionJudgment judgment, Location location,
      Token throwKeyword, void expression, DartType inferredType);

  void tryCatch(StatementJudgment judgment, Location location);

  void tryFinally(
      StatementJudgment judgment,
      Location location,
      Token tryKeyword,
      void body,
      void catchClauses,
      Token finallyKeyword,
      void finallyBlock);

  void typeLiteral(ExpressionJudgment judgment, Location location,
      Reference expressionType, DartType inferredType);

  void typeReference(
      Location location,
      Token leftBracket,
      List<void> typeArguments,
      Token rightBracket,
      Reference reference,
      covariant Object binder,
      DartType type);

  void typeVariableDeclaration(
      Location location, covariant Object binder, TypeParameter typeParameter);

  void variableAssign(
      ExpressionJudgment judgment,
      Location location,
      DartType writeContext,
      covariant Object writeVariableBinder,
      Reference combiner,
      DartType inferredType);

  void variableDeclaration(
      covariant Object binder, DartType statementType, DartType inferredType);

  void variableGet(ExpressionJudgment judgment, Location location,
      bool isInCascade, covariant Object variableBinder, DartType inferredType);

  void voidType(Location location, Token token, DartType type);

  void whileStatement(
      StatementJudgment judgment,
      Location location,
      Token whileKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      void body);

  void yieldStatement(StatementJudgment judgment, Location location,
      Token yieldKeyword, Token star, void expression, Token semicolon);
}

/// Kernel implementation of TypeInferenceListener; does nothing.
///
/// TODO(paulberry): fuse this with KernelFactory.
class KernelTypeInferenceListener
    implements TypeInferenceListener<int, Node, int> {
  @override
  void asExpression(ExpressionJudgment judgment, location, void expression,
      Token asOperator, void literalType, DartType inferredType) {}

  @override
  void assertInitializer(
      InitializerJudgment judgment,
      location,
      Token assertKeyword,
      Token leftParenthesis,
      void condition,
      Token comma,
      void message,
      Token rightParenthesis) {}

  @override
  void assertStatement(
      StatementJudgment judgment,
      location,
      Token assertKeyword,
      Token leftParenthesis,
      void condition,
      Token comma,
      void message,
      Token rightParenthesis,
      Token semicolon) {}

  @override
  void awaitExpression(ExpressionJudgment judgment, location,
      Token awaitKeyword, void expression, DartType inferredType) {}

  @override
  void binderForFunctionDeclaration(
      StatementJudgment judgment, location, String name) {}

  @override
  void binderForStatementLabel(
      StatementJudgment judgment, int fileOffset, String name) {}

  @override
  void binderForSwitchLabel(
      SwitchCaseJudgment judgment, int fileOffset, String name) {}

  @override
  void binderForTypeVariable(
      KernelTypeVariableBuilder builder, int fileOffset, String name) {}

  @override
  void binderForVariableDeclaration(
      StatementJudgment judgment, int fileOffset, String name) {}

  @override
  void block(StatementJudgment judgment, location, Token leftBracket,
      List<void> statements, Token rightBracket) {}

  @override
  void boolLiteral(ExpressionJudgment judgment, location, Token literal,
      bool value, DartType inferredType) {}

  @override
  void breakStatement(StatementJudgment judgment, location, Token breakKeyword,
      void label, Token semicolon, covariant void labelBinder) {}

  @override
  void cascadeExpression(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  @override
  void catchStatement(
      Catch judgment,
      location,
      Token onKeyword,
      void type,
      Token catchKeyword,
      Token leftParenthesis,
      Token exceptionParameter,
      Token comma,
      Token stackTraceParameter,
      Token rightParenthesis,
      void body,
      DartType guardType,
      covariant void exceptionBinder,
      DartType exceptionType,
      covariant void stackTraceBinder,
      DartType stackTraceType) {}

  @override
  void conditionalExpression(
      ExpressionJudgment judgment,
      location,
      void condition,
      Token question,
      void thenExpression,
      Token colon,
      void elseExpression,
      DartType inferredType) {}

  @override
  void constructorInvocation(ExpressionJudgment judgment, location,
      expressionTarget, DartType inferredType) {}

  @override
  void continueStatement(
      StatementJudgment judgment,
      location,
      Token continueKeyword,
      void label,
      Token semicolon,
      covariant void labelBinder) {}

  @override
  void continueSwitchStatement(
      StatementJudgment judgment,
      location,
      Token continueKeyword,
      void label,
      Token semicolon,
      covariant void labelBinder) {}

  @override
  void deferredCheck(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  @override
  void doStatement(
      StatementJudgment judgment,
      location,
      Token doKeyword,
      void body,
      Token whileKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      Token semicolon) {}

  @override
  void doubleLiteral(ExpressionJudgment judgment, location, Token literal,
      double value, DartType inferredType) {}

  @override
  void emptyStatement(Token semicolon) {}

  @override
  void expressionStatement(
      StatementJudgment judgment, location, void expression, Token semicolon) {}

  @override
  void fieldInitializer(
      InitializerJudgment judgment,
      location,
      Token thisKeyword,
      Token period,
      Token fieldName,
      Token equals,
      void expression,
      initializerField) {}

  @override
  void forInStatement(
      StatementJudgment judgment,
      location,
      Token awaitKeyword,
      Token forKeyword,
      Token leftParenthesis,
      covariant Object loopVariable,
      Token identifier,
      Token inKeyword,
      void iterator,
      Token rightParenthesis,
      void body,
      covariant void loopVariableBinder,
      DartType loopVariableType,
      writeLocation,
      DartType writeVariableType,
      covariant void writeVariableBinder,
      writeTarget) {}

  @override
  void forStatement(
      StatementJudgment judgment,
      location,
      Token forKeyword,
      Token leftParenthesis,
      Object variableDeclarationList,
      void initialization,
      Token leftSeparator,
      void condition,
      Token rightSeparator,
      void updaters,
      Token rightParenthesis,
      void body) {}

  @override
  void functionDeclaration(covariant void binder, FunctionType inferredType) {}

  @override
  void functionExpression(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  void functionType(int location, DartType type) {}

  void functionTypedFormalParameter(int location, DartType type) {}

  @override
  void ifNull(ExpressionJudgment judgment, location, void leftOperand,
      Token operator, void rightOperand, DartType inferredType) {}

  @override
  void ifStatement(
      StatementJudgment judgment,
      location,
      Token ifKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      void thenStatement,
      Token elseKeyword,
      void elseStatement) {}

  @override
  void indexAssign(ExpressionJudgment judgment, location, writeMember, combiner,
      DartType inferredType) {}

  @override
  void intLiteral(ExpressionJudgment judgment, location, Token literal,
      num value, DartType inferredType) {}

  @override
  void invalidInitializer(InitializerJudgment judgment, location) {}

  @override
  void isExpression(
      ExpressionJudgment judgment,
      location,
      void expression,
      Token isOperator,
      void literalType,
      DartType testedType,
      DartType inferredType) {}

  @override
  void isNotExpression(
      ExpressionJudgment judgment,
      location,
      void expression,
      Token isOperator,
      Token notOperator,
      void literalType,
      DartType type,
      DartType inferredType) {}

  @override
  void labeledStatement(List<Object> labels, void statement) {}

  @override
  void listLiteral(
      ExpressionJudgment judgment,
      location,
      Token constKeyword,
      covariant Object typeArguments,
      Token leftBracket,
      void elements,
      Token rightBracket,
      DartType inferredType) {}

  @override
  void loadLibrary(LoadLibraryJudgment judgment, location, library,
      FunctionType calleeType, DartType inferredType) {}

  @override
  void loadLibraryTearOff(LoadLibraryTearOffJudgment judgment, location,
      library, DartType inferredType) {}

  @override
  void logicalExpression(
      ExpressionJudgment judgment,
      location,
      void leftOperand,
      Token operator,
      void rightOperand,
      DartType inferredType) {}

  @override
  void mapLiteral(
      ExpressionJudgment judgment,
      location,
      Token constKeyword,
      Object typeArguments,
      Token leftBracket,
      List<Object> entries,
      Token rightBracket,
      DartType inferredType) {}

  void mapLiteralEntry(
      Object judgment, int fileOffset, void key, Token separator, void value) {}

  @override
  void methodInvocation(
      ExpressionJudgment judgment,
      resultOffset,
      List<DartType> argumentsTypes,
      bool isImplicitCall,
      interfaceMember,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType) {}

  @override
  void methodInvocationCall(
      ExpressionJudgment judgment,
      resultOffset,
      List<DartType> argumentsTypes,
      bool isImplicitCall,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType) {}

  @override
  void namedFunctionExpression(ExpressionJudgment judgment,
      covariant void binder, DartType inferredType) {}

  @override
  void not(ExpressionJudgment judgment, location, Token operator, void operand,
      DartType inferredType) {}

  @override
  void nullLiteral(ExpressionJudgment judgment, location, Token literal,
      bool isSynthetic, DartType inferredType) {}

  @override
  void propertyAssign(ExpressionJudgment judgment, location, writeMember,
      DartType writeContext, combiner, DartType inferredType) {}

  @override
  void propertyGet(
      ExpressionJudgment judgment, location, member, DartType inferredType) {}

  @override
  void propertyGetCall(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  @override
  void propertySet(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  @override
  void redirectingInitializer(
      InitializerJudgment judgment,
      location,
      Token thisKeyword,
      Token period,
      Token constructorName,
      covariant Object argumentList,
      initializerTarget) {}

  @override
  void rethrow_(ExpressionJudgment judgment, location, Token rethrowKeyword,
      DartType inferredType) {}

  @override
  void returnStatement(StatementJudgment judgment, location,
      Token returnKeyword, void expression, Token semicolon) {}

  @override
  void statementLabel(covariant void binder, Token label, Token colon) {}

  @override
  void staticAssign(ExpressionJudgment judgment, location, writeMember,
      DartType writeContext, combiner, DartType inferredType) {}

  @override
  void staticGet(ExpressionJudgment judgment, location, expressionTarget,
      DartType inferredType) {}

  @override
  void staticInvocation(
      ExpressionJudgment judgment,
      location,
      expressionTarget,
      List<DartType> expressionArgumentsTypes,
      FunctionType calleeType,
      Substitution substitution,
      DartType inferredType) {}

  @override
  void storeClassReference(location, reference, DartType rawType) {}

  @override
  void storePrefixInfo(location, prefixInfo) {}

  @override
  void stringConcatenation(
      ExpressionJudgment judgment, location, DartType inferredType) {}

  @override
  void stringLiteral(ExpressionJudgment judgment, location, Token literal,
      String value, DartType inferredType) {}

  @override
  void superInitializer(
      InitializerJudgment judgment,
      location,
      Token superKeyword,
      Token period,
      Token constructorName,
      covariant Object argumentList) {}

  @override
  void switchCase(SwitchCaseJudgment switchCase, covariant List<Object> labels,
      Token keyword, void expression, Token colon, List<void> statements) {}

  @override
  void switchLabel(covariant void binder, Token label, Token colon) {}

  @override
  void switchStatement(
      StatementJudgment judgment,
      location,
      Token switchKeyword,
      Token leftParenthesis,
      void expression,
      Token rightParenthesis,
      Token leftBracket,
      void members,
      Token rightBracket) {}

  @override
  void symbolLiteral(ExpressionJudgment judgment, location, Token poundSign,
      List<Token> components, String value, DartType inferredType) {}

  @override
  void thisExpression(ExpressionJudgment judgment, location, Token thisKeyword,
      DartType inferredType) {}

  @override
  void throw_(ExpressionJudgment judgment, location, Token throwKeyword,
      void expression, DartType inferredType) {}

  @override
  void tryCatch(StatementJudgment judgment, location) {}

  @override
  void tryFinally(StatementJudgment judgment, location, Token tryKeyword,
      void body, void catchClauses, Token finallyKeyword, void finallyBlock) {}

  @override
  void typeLiteral(ExpressionJudgment judgment, location, expressionType,
      DartType inferredType) {}

  @override
  void typeReference(location, Token leftBracket, List<void> typeArguments,
      Token rightBracket, reference, covariant void binder, DartType type) {}

  @override
  void typeVariableDeclaration(
      location, covariant void binder, TypeParameter typeParameter) {}

  @override
  void variableAssign(
      ExpressionJudgment judgment,
      location,
      DartType writeContext,
      covariant void writeVariableBinder,
      combiner,
      DartType inferredType) {}

  @override
  void variableDeclaration(
      covariant void binder, DartType statementType, DartType inferredType) {}

  @override
  void variableGet(ExpressionJudgment judgment, location, bool isInCascade,
      expressionVariable, DartType inferredType) {}

  @override
  void voidType(location, Token token, DartType type) {}

  @override
  void whileStatement(
      StatementJudgment judgment,
      location,
      Token whileKeyword,
      Token leftParenthesis,
      void condition,
      Token rightParenthesis,
      void body) {}

  @override
  void yieldStatement(StatementJudgment judgment, location, Token yieldKeyword,
      Token star, void expression, Token semicolon) {}
}
