// 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.parser.type_info_impl;

import '../../scanner/token.dart' show SyntheticToken, Token, TokenType;

import '../fasta_codes.dart' as fasta;

import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN;

import '../util/link.dart' show Link;

import 'forwarding_listener.dart' show ForwardingListener;

import 'identifier_context.dart' show IdentifierContext;

import 'member_kind.dart' show MemberKind;

import 'listener.dart' show Listener;

import 'parser.dart' show Parser;

import 'type_info.dart';

import 'util.dart'
    show
        optional,
        skipMetadata,
        splitGtEq,
        splitGtFromGtGtEq,
        splitGtGt,
        syntheticGt;

/// [SimpleType] is a specialized [TypeInfo] returned by [computeType]
/// when there is a single identifier as the type reference.
const TypeInfo simpleType = const SimpleType();

/// [PrefixedType] is a specialized [TypeInfo] returned by [computeType]
/// when the type reference is of the form: identifier `.` identifier.
const TypeInfo prefixedType = const PrefixedType();

/// [SimpleTypeWith1Argument] is a specialized [TypeInfo] returned by
/// [computeType] when the type reference is of the form:
/// identifier `<` identifier `>`.
const TypeInfo simpleTypeWith1Argument =
    const SimpleTypeWith1Argument(simpleTypeArgument1);

/// [SimpleTypeWith1Argument] is a specialized [TypeInfo] returned by
/// [computeType] when the type reference is of the form:
/// identifier `<` identifier `>=`.
const TypeInfo simpleTypeWith1ArgumentGtEq =
    const SimpleTypeWith1Argument(simpleTypeArgument1GtEq);

/// [SimpleTypeWith1Argument] is a specialized [TypeInfo] returned by
/// [computeType] when the type reference is of the form:
/// identifier `<` identifier `>>`.
const TypeInfo simpleTypeWith1ArgumentGtGt =
    const SimpleTypeWith1Argument(simpleTypeArgument1GtGt);

/// [SimpleTypeArgument1] is a specialized [TypeParamOrArgInfo] returned by
/// [computeTypeParamOrArg] when the type reference is of the form:
/// `<` identifier `>`.
const TypeParamOrArgInfo simpleTypeArgument1 = const SimpleTypeArgument1();

/// [SimpleTypeArgument1] is a specialized [TypeParamOrArgInfo] returned by
/// [computeTypeParamOrArg] when the type reference is of the form:
/// `<` identifier `>=`.
const TypeParamOrArgInfo simpleTypeArgument1GtEq =
    const SimpleTypeArgument1GtEq();

/// [SimpleTypeArgument1] is a specialized [TypeParamOrArgInfo] returned by
/// [computeTypeParamOrArg] when the type reference is of the form:
/// `<` identifier `>>`.
const TypeParamOrArgInfo simpleTypeArgument1GtGt =
    const SimpleTypeArgument1GtGt();

/// See documentation on the [noType] const.
class NoType implements TypeInfo {
  const NoType();

  @override
  bool get couldBeExpression => false;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) {
    parser.reportRecoverableErrorWithToken(
        token.next, fasta.templateExpectedType);
    parser.rewriter.insertSyntheticIdentifier(token);
    return simpleType.parseType(token, parser);
  }

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      ensureTypeNotVoid(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    parser.listener.handleNoType(token);
    return token;
  }

  @override
  Token skipType(Token token) {
    return token;
  }
}

/// See documentation on the [prefixedType] const.
class PrefixedType implements TypeInfo {
  const PrefixedType();

  @override
  bool get couldBeExpression => true;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    Token start = token = token.next;
    assert(token.isKeywordOrIdentifier);
    Listener listener = parser.listener;
    listener.handleIdentifier(token, IdentifierContext.prefixedTypeReference);

    Token period = token = token.next;
    assert(optional('.', token));

    token = token.next;
    assert(token.isKeywordOrIdentifier);
    listener.handleIdentifier(
        token, IdentifierContext.typeReferenceContinuation);
    listener.handleQualified(period);

    listener.handleNoTypeArguments(token.next);
    listener.handleType(start);
    return token;
  }

  @override
  Token skipType(Token token) {
    return token.next.next.next;
  }
}

/// See documentation on the [simpleTypeWith1Argument] const.
class SimpleTypeWith1Argument implements TypeInfo {
  final TypeParamOrArgInfo typeArg;

  const SimpleTypeWith1Argument(this.typeArg);

  @override
  bool get couldBeExpression => false;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    Token start = token = token.next;
    assert(token.isKeywordOrIdentifier);
    Listener listener = parser.listener;
    listener.handleIdentifier(token, IdentifierContext.typeReference);
    token = typeArg.parseArguments(token, parser);
    listener.handleType(start);
    return token;
  }

  @override
  Token skipType(Token token) {
    token = token.next;
    assert(token.isKeywordOrIdentifier);
    return typeArg.skip(token);
  }
}

/// See documentation on the [simpleType] const.
class SimpleType implements TypeInfo {
  const SimpleType();

  @override
  bool get couldBeExpression => true;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    token = token.next;
    assert(isValidTypeReference(token));
    Listener listener = parser.listener;
    listener.handleIdentifier(token, IdentifierContext.typeReference);
    token = noTypeParamOrArg.parseArguments(token, parser);
    listener.handleType(token);
    return token;
  }

  @override
  Token skipType(Token token) {
    return token.next;
  }
}

/// See documentation on the [voidType] const.
class VoidType implements TypeInfo {
  const VoidType();

  @override
  bool get couldBeExpression => false;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) {
    // Report an error, then parse `void` as if it were a type name.
    parser.reportRecoverableError(token.next, fasta.messageInvalidVoid);
    return simpleType.parseTypeNotVoid(token, parser);
  }

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      ensureTypeNotVoid(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    token = token.next;
    parser.listener.handleVoidKeyword(token);
    return token;
  }

  @override
  Token skipType(Token token) {
    return token.next;
  }
}

bool looksLikeName(Token token) =>
    token.kind == IDENTIFIER_TOKEN ||
    optional('this', token) ||
    (token.isIdentifier &&
        // Although `typedef` is a legal identifier,
        // type `typedef` identifier is not legal and in this situation
        // `typedef` is probably a separate declaration.
        (!optional('typedef', token) || !token.next.isIdentifier));

/// When missing a comma, determine if the given token looks like it should
/// be part of a collection of type parameters or arguments.
bool looksLikeTypeParamOrArg(bool inDeclaration, Token token) {
  if (inDeclaration && token.kind == IDENTIFIER_TOKEN) {
    Token next = token.next;
    if (next.kind == IDENTIFIER_TOKEN ||
        optional(',', next) ||
        isCloser(next)) {
      return true;
    }
  }
  return false;
}

/// Instances of [ComplexTypeInfo] are returned by [computeType] to represent
/// type references that cannot be represented by the constants above.
class ComplexTypeInfo implements TypeInfo {
  /// The first token in the type reference.
  Token start;

  /// Type arguments were seen during analysis.
  final TypeParamOrArgInfo typeArguments;

  /// The last token in the type reference.
  Token end;

  /// The `Function` tokens before the start of type variables of function types
  /// as seen during analysis.
  Link<Token> typeVariableStarters = const Link<Token>();

  /// If the receiver represents a generalized function type then this indicates
  /// whether it has a return type, otherwise this is `null`.
  bool gftHasReturnType;

  ComplexTypeInfo(Token beforeStart, this.typeArguments)
      : this.start = beforeStart.next;

  @override
  bool get couldBeExpression => false;

  @override
  Token ensureTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token ensureTypeOrVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseTypeNotVoid(Token token, Parser parser) =>
      parseType(token, parser);

  @override
  Token parseType(Token token, Parser parser) {
    assert(identical(token.next, start));

    if (optional('.', start)) {
      // Recovery: Insert missing identifier without sending events
      start = parser.insertSyntheticIdentifier(
          token, IdentifierContext.prefixedTypeReference);
    }

    final typeVariableEndGroups = <Token>[];
    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
      typeVariableEndGroups.add(
          computeTypeParamOrArg(t.head, true).parseVariables(t.head, parser));
      parser.listener.beginFunctionType(start);
    }

    if (gftHasReturnType == false) {
      // A function type without return type.
      // Push the non-existing return type first. The loop below will
      // generate the full type.
      noType.parseType(token, parser);
    } else {
      Token typeRefOrPrefix = token.next;
      if (optional('void', typeRefOrPrefix)) {
        token = voidType.parseType(token, parser);
      } else {
        if (!optional('.', typeRefOrPrefix) &&
            !optional('.', typeRefOrPrefix.next)) {
          token =
              parser.ensureIdentifier(token, IdentifierContext.typeReference);
        } else {
          token = parser.ensureIdentifier(
              token, IdentifierContext.prefixedTypeReference);
          token = parser.parseQualifiedRest(
              token, IdentifierContext.typeReferenceContinuation);
          if (token.isSynthetic && end == typeRefOrPrefix.next) {
            // Recovery: Update `end` if a synthetic identifier was inserted.
            end = token;
          }
        }
        token = typeArguments.parseArguments(token, parser);
        parser.listener.handleType(typeRefOrPrefix);
      }
    }

    int endGroupIndex = typeVariableEndGroups.length - 1;
    for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
      token = token.next;
      assert(optional('Function', token));
      Token functionToken = token;
      if (optional("<", token.next)) {
        // Skip type parameters, they were parsed above.
        token = typeVariableEndGroups[endGroupIndex];
        assert(optional('>', token));
      }
      --endGroupIndex;
      token = parser.parseFormalParametersRequiredOpt(
          token, MemberKind.GeneralizedFunctionType);
      parser.listener.endFunctionType(functionToken);
    }

    // There are two situations in which the [token] != [end]:
    // Valid code:    identifier `<` identifier `<` identifier `>>`
    //    where `>>` is replaced by two tokens.
    // Invalid code:  identifier `<` identifier identifier `>`
    //    where a synthetic `>` is inserted between the identifiers.
    assert(identical(token, end) || optional('>', token));

    // During recovery, [token] may be a synthetic that was inserted in the
    // middle of the type reference.
    end = token;
    return token;
  }

  @override
  Token skipType(Token token) {
    return end;
  }

  /// Given `Function` non-identifier, compute the type
  /// and return the receiver or one of the [TypeInfo] constants.
  TypeInfo computeNoTypeGFT(bool required) {
    assert(optional('Function', start));

    computeRest(start, required);
    if (gftHasReturnType == null) {
      return required ? simpleType : noType;
    }
    assert(end != null);
    return this;
  }

  /// Given void `Function` non-identifier, compute the type
  /// and return the receiver or one of the [TypeInfo] constants.
  TypeInfo computeVoidGFT(bool required) {
    assert(optional('void', start));
    assert(optional('Function', start.next));

    computeRest(start.next, required);
    if (gftHasReturnType == null) {
      return voidType;
    }
    assert(end != null);
    return this;
  }

  /// Given identifier `Function` non-identifier, compute the type
  /// and return the receiver or one of the [TypeInfo] constants.
  TypeInfo computeIdentifierGFT(bool required) {
    assert(isValidTypeReference(start));
    assert(optional('Function', start.next));

    computeRest(start.next, required);
    if (gftHasReturnType == null) {
      return simpleType;
    }
    assert(end != null);
    return this;
  }

  /// Given a builtin, return the receiver so that parseType will report
  /// an error for the builtin used as a type.
  TypeInfo computeBuiltinOrVarAsType(bool required) {
    assert(start.type.isBuiltIn || optional('var', start));

    end = typeArguments.skip(start);
    computeRest(end.next, required);
    assert(end != null);
    return this;
  }

  /// Given identifier `<` ... `>`, compute the type
  /// and return the receiver or one of the [TypeInfo] constants.
  TypeInfo computeSimpleWithTypeArguments(bool required) {
    assert(isValidTypeReference(start));
    assert(optional('<', start.next));
    assert(typeArguments != noTypeParamOrArg);

    end = typeArguments.skip(start);
    computeRest(end.next, required);

    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
      return noType;
    }
    assert(end != null);
    return this;
  }

  /// Given identifier `.` identifier (or `.` identifier or identifier `.`
  /// for recovery), compute the type and return the receiver or one of the
  /// [TypeInfo] constants.
  TypeInfo computePrefixedType(bool required) {
    Token token = start;
    if (!optional('.', token)) {
      assert(token.isKeywordOrIdentifier);
      token = token.next;
    }
    assert(optional('.', token));
    if (token.next.isKeywordOrIdentifier) {
      token = token.next;
    }

    end = typeArguments.skip(token);
    computeRest(end.next, required);
    if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
      return noType;
    }
    assert(end != null);
    return this;
  }

  void computeRest(Token token, bool required) {
    while (optional('Function', token)) {
      Token typeVariableStart = token;
      // TODO(danrubel): Consider caching TypeParamOrArgInfo
      token = computeTypeParamOrArg(token, true).skip(token);
      token = token.next;
      if (!optional('(', token)) {
        break; // Not a function type.
      }
      token = token.endGroup;
      if (token == null) {
        break; // Not a function type.
      }
      if (!required) {
        if (!(token.next.isIdentifier || optional('this', token.next))) {
          break; // `Function` used as the name in a function declaration.
        }
      }
      assert(optional(')', token));
      gftHasReturnType ??= typeVariableStart != start;
      typeVariableStarters = typeVariableStarters.prepend(typeVariableStart);
      end = token;
      token = token.next;
    }
  }
}

/// See [noTypeParamOrArg].
class NoTypeParamOrArg extends TypeParamOrArgInfo {
  const NoTypeParamOrArg();

  @override
  Token parseArguments(Token token, Parser parser) {
    parser.listener.handleNoTypeArguments(token.next);
    return token;
  }

  @override
  Token parseVariables(Token token, Parser parser) {
    parser.listener.handleNoTypeVariables(token.next);
    return token;
  }

  @override
  Token skip(Token token) => token;
}

class SimpleTypeArgument1 extends TypeParamOrArgInfo {
  const SimpleTypeArgument1();

  @override
  bool get isSimpleTypeArgument => true;

  @override
  TypeInfo get typeInfo => simpleTypeWith1Argument;

  @override
  Token parseArguments(Token token, Parser parser) {
    Token beginGroup = token.next;
    assert(optional('<', beginGroup));
    Token endGroup = parseEndGroup(beginGroup, beginGroup.next);
    Listener listener = parser.listener;
    listener.beginTypeArguments(beginGroup);
    simpleType.parseType(beginGroup, parser);
    parser.listener.endTypeArguments(1, beginGroup, endGroup);
    return endGroup;
  }

  @override
  Token parseVariables(Token token, Parser parser) {
    Token beginGroup = token.next;
    assert(optional('<', beginGroup));
    token = beginGroup.next;
    Token endGroup = parseEndGroup(beginGroup, token);
    Listener listener = parser.listener;
    listener.beginTypeVariables(beginGroup);
    listener.beginMetadataStar(token);
    listener.endMetadataStar(0);
    listener.handleIdentifier(token, IdentifierContext.typeVariableDeclaration);
    listener.beginTypeVariable(token);
    listener.handleTypeVariablesDefined(token, 1);
    listener.handleNoType(token);
    listener.endTypeVariable(endGroup, 0, null);
    listener.endTypeVariables(beginGroup, endGroup);
    return endGroup;
  }

  @override
  Token skip(Token token) {
    token = token.next;
    assert(optional('<', token));
    token = token.next;
    assert(token.isKeywordOrIdentifier);
    return skipEndGroup(token);
  }

  Token skipEndGroup(Token token) {
    token = token.next;
    assert(optional('>', token));
    return token;
  }

  Token parseEndGroup(Token beginGroup, Token token) {
    token = token.next;
    assert(optional('>', token));
    return token;
  }
}

class SimpleTypeArgument1GtEq extends SimpleTypeArgument1 {
  const SimpleTypeArgument1GtEq();

  @override
  TypeInfo get typeInfo => simpleTypeWith1ArgumentGtEq;

  Token skipEndGroup(Token token) {
    token = token.next;
    assert(optional('>=', token));
    return splitGtEq(token);
  }

  Token parseEndGroup(Token beginGroup, Token beforeEndGroup) {
    Token endGroup = beforeEndGroup.next;
    if (!optional('>', endGroup)) {
      endGroup = splitGtEq(endGroup);
      endGroup.next.setNext(endGroup.next.next);
    }
    beforeEndGroup.setNext(endGroup);
    return endGroup;
  }
}

class SimpleTypeArgument1GtGt extends SimpleTypeArgument1 {
  const SimpleTypeArgument1GtGt();

  @override
  TypeInfo get typeInfo => simpleTypeWith1ArgumentGtGt;

  Token skipEndGroup(Token token) {
    token = token.next;
    assert(optional('>>', token));
    return splitGtGt(token);
  }

  Token parseEndGroup(Token beginGroup, Token beforeEndGroup) {
    Token endGroup = beforeEndGroup.next;
    if (!optional('>', endGroup)) {
      endGroup = splitGtGt(endGroup);
      endGroup.next.setNext(endGroup.next.next);
    }
    beforeEndGroup.setNext(endGroup);
    return endGroup;
  }
}

class ComplexTypeParamOrArgInfo extends TypeParamOrArgInfo {
  /// The first token in the type var.
  final Token start;

  /// If [inDeclaration] is `true`, then this will more aggressively recover
  /// given unbalanced `<` `>` and invalid parameters or arguments.
  final bool inDeclaration;

  /// The `>` token which ends the type parameter or argument.
  /// This closer may be synthetic, points to the next token in the stream,
  /// is only used when skipping over the type parameters or arguments,
  /// and may not be part of the token stream.
  Token skipEnd;

  ComplexTypeParamOrArgInfo(Token token, this.inDeclaration)
      : assert(optional('<', token.next)),
        assert(inDeclaration != null),
        start = token.next;

  /// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
  /// are no type parameters or arguments. This does not modify the token
  /// stream.
  TypeParamOrArgInfo compute() {
    Token token;
    Token next = start;
    while (true) {
      TypeInfo typeInfo = computeType(next, true, inDeclaration);
      if (typeInfo == noType) {
        while (typeInfo == noType && optional('@', next.next)) {
          next = skipMetadata(next);
          typeInfo = computeType(next, true, inDeclaration);
        }
        if (typeInfo == noType) {
          if (next == start && !inDeclaration && !isCloser(next.next)) {
            return noTypeParamOrArg;
          }
          if (!optional(',', next.next)) {
            token = next;
            next = token.next;
            break;
          }
        }
        assert(typeInfo != noType || optional(',', next.next));
        // Fall through to process type (if any) and consume `,`
      }
      token = typeInfo.skipType(next);
      next = token.next;
      if (optional('extends', next)) {
        token = computeType(next, true, inDeclaration).skipType(next);
        next = token.next;
      }
      if (!optional(',', next)) {
        skipEnd = splitCloser(next);
        if (skipEnd != null) {
          return this;
        }
        if (!inDeclaration) {
          return noTypeParamOrArg;
        }

        // Recovery
        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
          break;
        }
        // Looks like missing comma. Continue looping.
        next = token;
      }
    }

    // Recovery
    skipEnd = splitCloser(next);
    if (skipEnd == null) {
      if (optional('(', next)) {
        token = next.endGroup;
        next = token.next;
      }
      skipEnd = splitCloser(next);
      if (skipEnd == null) {
        skipEnd = splitCloser(next.next);
      }
      if (skipEnd == null) {
        skipEnd = syntheticGt(next);
      }
    }
    return this;
  }

  @override
  Token parseArguments(Token token, Parser parser) {
    assert(identical(token.next, start));
    Token next = start;
    parser.listener.beginTypeArguments(start);
    int count = 0;
    while (true) {
      TypeInfo typeInfo = computeType(next, true, inDeclaration);
      if (typeInfo == noType) {
        // Recovery
        while (typeInfo == noType && optional('@', next.next)) {
          parser.reportRecoverableErrorWithToken(
              next.next, fasta.templateUnexpectedToken);
          next = skipMetadata(next);
          typeInfo = computeType(next, true, inDeclaration);
        }
        // Fall through to process type (if any) and consume `,`
      }
      token = typeInfo.ensureTypeOrVoid(next, parser);
      next = token.next;
      ++count;
      if (!optional(',', next)) {
        if (parseCloser(token)) {
          break;
        }

        // Recovery
        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
          token = parseUnexpectedEnd(token, true, parser);
          break;
        }
        // Missing comma. Report error, insert comma, and continue looping.
        next = parseMissingComma(token, parser);
      }
    }
    Token endGroup = token.next;
    parser.listener.endTypeArguments(count, start, endGroup);
    return endGroup;
  }

  @override
  Token parseVariables(Token token, Parser parser) {
    assert(identical(token.next, start));
    Token next = start;
    Listener listener = parser.listener;
    listener.beginTypeVariables(start);
    int count = 0;

    Link<Token> typeStarts = const Link<Token>();
    Link<TypeInfo> superTypeInfos = const Link<TypeInfo>();

    while (true) {
      token = parser.parseMetadataStar(next);
      next = parser.ensureIdentifier(
          token, IdentifierContext.typeVariableDeclaration);
      token = next;
      listener.beginTypeVariable(token);
      typeStarts = typeStarts.prepend(token);

      next = token.next;
      if (optional('extends', next)) {
        TypeInfo typeInfo = computeType(next, true, inDeclaration);
        token = typeInfo.skipType(next);
        next = token.next;
        superTypeInfos = superTypeInfos.prepend(typeInfo);
      } else {
        superTypeInfos = superTypeInfos.prepend(null);
      }

      ++count;
      if (!optional(',', next)) {
        if (isCloser(token)) {
          break;
        }

        // Recovery
        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
          break;
        }
        // Missing comma. Report error, insert comma, and continue looping.
        next = parseMissingComma(token, parser);
      }
    }

    assert(count > 0);
    assert(typeStarts.slowLength() == count);
    assert(superTypeInfos.slowLength() == count);
    listener.handleTypeVariablesDefined(token, count);

    token = null;
    while (typeStarts.isNotEmpty) {
      Token token2 = typeStarts.head;
      TypeInfo typeInfo = superTypeInfos.head;

      Token extendsOrSuper = null;
      Token next2 = token2.next;
      if (typeInfo != null) {
        assert(optional('extends', next2));
        extendsOrSuper = next2;
        token2 = typeInfo.ensureTypeNotVoid(next2, parser);
        next2 = token2.next;
      } else {
        assert(!optional('extends', next2));
        listener.handleNoType(token2);
      }
      // Type variables are "completed" in reverse order, so capture the last
      // consumed token from the first "completed" type variable.
      token ??= token2;
      listener.endTypeVariable(next2, --count, extendsOrSuper);

      typeStarts = typeStarts.tail;
      superTypeInfos = superTypeInfos.tail;
    }

    if (!parseCloser(token)) {
      token = parseUnexpectedEnd(token, false, parser);
    }
    Token endGroup = token.next;
    listener.endTypeVariables(start, endGroup);
    return endGroup;
  }

  Token parseMissingComma(Token token, Parser parser) {
    Token next = token.next;
    parser.reportRecoverableError(
        next, fasta.templateExpectedButGot.withArguments(','));
    return parser.rewriter.insertToken(
        token, new SyntheticToken(TokenType.COMMA, next.charOffset));
  }

  Token parseUnexpectedEnd(Token token, bool isArguments, Parser parser) {
    Token next = token.next;
    bool errorReported = token.isSynthetic || (next.isSynthetic && !next.isEof);

    bool typeFollowsExtends = false;
    if (optional('extends', next)) {
      if (!errorReported) {
        parser.reportRecoverableError(
            token, fasta.templateExpectedAfterButGot.withArguments('>'));
        errorReported = true;
      }
      token = next;
      next = token.next;
      typeFollowsExtends = isValidTypeReference(next);

      if (parseCloser(token)) {
        return token;
      }
    }

    if (typeFollowsExtends ||
        optional('dynamic', next) ||
        optional('void', next) ||
        optional('Function', next)) {
      TypeInfo invalidType = computeType(token, true);
      if (invalidType != noType) {
        if (!errorReported) {
          parser.reportRecoverableError(
              token, fasta.templateExpectedAfterButGot.withArguments('>'));
          errorReported = true;
        }

        // Parse the type so that the token stream is properly modified,
        // but ensure that parser events are ignored by replacing the listener.
        final originalListener = parser.listener;
        parser.listener = new ForwardingListener();
        token = invalidType.parseType(token, parser);
        next = token.next;
        parser.listener = originalListener;

        if (parseCloser(token)) {
          return token;
        }
      }
    }

    TypeParamOrArgInfo invalidTypeVar =
        computeTypeParamOrArg(token, inDeclaration);
    if (invalidTypeVar != noTypeParamOrArg) {
      if (!errorReported) {
        parser.reportRecoverableError(
            token, fasta.templateExpectedAfterButGot.withArguments('>'));
        errorReported = true;
      }

      // Parse the type so that the token stream is properly modified,
      // but ensure that parser events are ignored by replacing the listener.
      final originalListener = parser.listener;
      parser.listener = new ForwardingListener();
      token = isArguments
          ? invalidTypeVar.parseArguments(token, parser)
          : invalidTypeVar.parseVariables(token, parser);
      next = token.next;
      parser.listener = originalListener;

      if (parseCloser(token)) {
        return token;
      }
    }

    if (optional('(', next) && next.endGroup != null) {
      if (!errorReported) {
        // Only report an error if one has not already been reported.
        parser.reportRecoverableError(
            token, fasta.templateExpectedAfterButGot.withArguments('>'));
        errorReported = true;
      }
      token = next.endGroup;
      next = token.next;

      if (parseCloser(token)) {
        return token;
      }
    }

    if (!errorReported) {
      // Only report an error if one has not already been reported.
      parser.reportRecoverableError(
          token, fasta.templateExpectedAfterButGot.withArguments('>'));
    }
    if (parseCloser(next)) {
      return next;
    }
    Token endGroup = syntheticGt(next);
    endGroup.setNext(next);
    token.setNext(endGroup);
    return token;
  }

  @override
  Token skip(Token token) {
    assert(skipEnd != null);
    return skipEnd;
  }
}

/// Return `true` if [token] is one of `>`, `>>`, `>=', or `>>=`.
bool isCloser(Token token) {
  final value = token.stringValue;
  return identical(value, '>') ||
      identical(value, '>>') ||
      identical(value, '>=') ||
      identical(value, '>>=');
}

/// If [beforeCloser].next is one of `>`, `>>`, `>=', or `>>=`,
/// then update the token stream and return `true`.
bool parseCloser(Token beforeCloser) {
  Token unsplit = beforeCloser.next;
  Token split = splitCloser(unsplit);
  if (split == unsplit) {
    return true;
  } else if (split == null) {
    return false;
  }
  split.next.setNext(unsplit.next);
  beforeCloser.setNext(split);
  return true;
}

/// If [closer] is `>` then return it.
/// If [closer] is one of `>>`, `>=', or `>>=` then split then token
/// and return the leading `>` without updating the token stream.
/// If [closer] is none of the above, then return null;
Token splitCloser(Token closer) {
  String value = closer.stringValue;
  if (identical(value, '>')) {
    return closer;
  } else if (identical(value, '>>')) {
    return splitGtGt(closer);
  } else if (identical(value, '>=')) {
    return splitGtEq(closer);
  } else if (identical(value, '>>=')) {
    return splitGtFromGtGtEq(closer);
  }
  return null;
}
