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

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

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

import 'parser.dart' show Parser;

import 'type_info_impl.dart';

import 'util.dart' show isOneOf, optional;

/// [TypeInfo] provides information collected by [computeType]
/// about a particular type reference.
abstract class TypeInfo {
  /// Return type info representing the receiver without the trailing `?`
  /// or the receiver if the receiver does not represent a nullable type.
  TypeInfo get asNonNullable;

  /// Return `true` if the tokens comprising the type represented by the
  /// receiver could be interpreted as a valid standalone expression.
  /// For example, `A` or `A.b` could be interpreted as type references
  /// or expressions, while `A<T>` only looks like a type reference.
  bool get couldBeExpression;

  /// Return true if the receiver has a trailing `?`.
  bool get isNullable;

  /// Call this function when the token after [token] must be a type (not void).
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the type, inserting a synthetic type reference if
  /// necessary. This may modify the token stream when parsing `>>` or `>>>`
  /// or `>>>=` in valid code or during recovery.
  Token ensureTypeNotVoid(Token token, Parser parser);

  /// Call this function when the token after [token] must be a type or void.
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the type, inserting a synthetic type reference if
  /// necessary. This may modify the token stream when parsing `>>` or `>>>`
  /// or `>>>=` in valid code or during recovery.
  Token ensureTypeOrVoid(Token token, Parser parser);

  /// Call this function to parse an optional type (not void) after [token].
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the type. This may modify the token stream
  /// when parsing `>>` or `>>>` or `>>>=`  in valid code or during recovery.
  Token parseTypeNotVoid(Token token, Parser parser);

  /// Call this function to parse an optional type or void after [token].
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the type. This may modify the token stream
  /// when parsing `>>` or `>>>` or `>>>=` in valid code or during recovery.
  Token parseType(Token token, Parser parser);

  /// Call this function with the [token] before the type to obtain
  /// the last token in the type. If there is no type, then this method
  /// will return [token]. This does not modify the token stream.
  Token skipType(Token token);
}

/// [TypeParamOrArgInfo] provides information collected by
/// [computeTypeParamOrArg] about a particular group of type arguments
/// or type parameters.
abstract class TypeParamOrArgInfo {
  const TypeParamOrArgInfo();

  /// Return `true` if the receiver represents a single type argument
  bool get isSimpleTypeArgument => false;

  /// Return the number of type arguments
  int get typeArgumentCount;

  /// Return the simple type associated with this simple type argument
  /// or throw an exception if this is not a simple type argument.
  TypeInfo get typeInfo {
    throw "Internal error: $runtimeType is not a SimpleTypeArgument.";
  }

  /// Call this function to parse optional type arguments after [token].
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the arguments. This may modify the token stream
  /// when parsing `>>` or `>>>` or `>>>=` in valid code or during recovery.
  Token parseArguments(Token token, Parser parser);

  /// Call this function to parse optional type parameters
  /// (also known as type variables) after [token].
  /// This function will call the appropriate event methods on the [Parser]'s
  /// listener to handle the parameters. This may modify the token stream
  /// when parsing `>>` or `>>>` or `>>>=` in valid code or during recovery.
  Token parseVariables(Token token, Parser parser);

  /// Call this function with the [token] before the type var to obtain
  /// the last token in the type var. If there is no type var, then this method
  /// will return [token]. This does not modify the token stream.
  Token skip(Token token);
}

/// [NoType] is a specialized [TypeInfo] returned by [computeType] when
/// there is no type information in the source.
const TypeInfo noType = const NoType();

/// [NoTypeParamOrArg] is a specialized [TypeParamOrArgInfo] returned by
/// [computeTypeParamOrArg] when no type parameters or arguments are found.
const TypeParamOrArgInfo noTypeParamOrArg = const NoTypeParamOrArg();

/// [VoidType] is a specialized [TypeInfo] returned by [computeType] when
/// `void` appears in the source.
const TypeInfo voidType = const VoidType();

bool isGeneralizedFunctionType(Token token) {
  return optional('Function', token) &&
      (optional('<', token.next) || optional('(', token.next));
}

bool isValidTypeReference(Token token) {
  int kind = token.kind;
  if (IDENTIFIER_TOKEN == kind) return true;
  if (KEYWORD_TOKEN == kind) {
    TokenType type = token.type;
    String value = type.lexeme;
    return type.isPseudo ||
        (type.isBuiltIn && optional('.', token.next)) ||
        (identical(value, 'dynamic')) ||
        (identical(value, 'void'));
  }
  return false;
}

/// Called by the parser to obtain information about a possible type reference
/// that follows [token]. This does not modify the token stream.
///
/// If [inDeclaration] is `true`, then this will more aggressively recover
/// given unbalanced `<` `>` and invalid parameters or arguments.
TypeInfo computeType(final Token token, bool required,
    [bool inDeclaration = false]) {
  Token next = token.next;
  if (!isValidTypeReference(next)) {
    if (next.type.isBuiltIn) {
      TypeParamOrArgInfo typeParamOrArg =
          computeTypeParamOrArg(next, inDeclaration);
      if (typeParamOrArg != noTypeParamOrArg) {
        // Recovery: built-in `<` ... `>`
        if (required || looksLikeName(typeParamOrArg.skip(next).next)) {
          return new ComplexTypeInfo(token, typeParamOrArg)
              .computeBuiltinOrVarAsType(required);
        }
      } else if (required || isGeneralizedFunctionType(next.next)) {
        String value = next.stringValue;
        if ((!identical('get', value) &&
            !identical('set', value) &&
            !identical('factory', value) &&
            !identical('operator', value) &&
            !(identical('typedef', value) && next.next.isIdentifier))) {
          return new ComplexTypeInfo(token, typeParamOrArg)
              .computeBuiltinOrVarAsType(required);
        }
      }
    } else if (required) {
      // Recovery
      if (optional('.', next)) {
        // Looks like prefixed type missing the prefix
        return new ComplexTypeInfo(
                token, computeTypeParamOrArg(next, inDeclaration))
            .computePrefixedType(required);
      } else if (optional('var', next) &&
          isOneOf(next.next, const ['<', ',', '>'])) {
        return new ComplexTypeInfo(
                token, computeTypeParamOrArg(next, inDeclaration))
            .computeBuiltinOrVarAsType(required);
      }
    }
    return noType;
  }

  if (optional('void', next)) {
    next = next.next;
    if (isGeneralizedFunctionType(next)) {
      // `void` `Function` ...
      return new ComplexTypeInfo(token, noTypeParamOrArg)
          .computeVoidGFT(required);
    }
    // `void`
    return voidType;
  }

  if (isGeneralizedFunctionType(next)) {
    // `Function` ...
    return new ComplexTypeInfo(token, noTypeParamOrArg)
        .computeNoTypeGFT(token, required);
  }

  // We've seen an identifier.

  TypeParamOrArgInfo typeParamOrArg =
      computeTypeParamOrArg(next, inDeclaration);
  if (typeParamOrArg != noTypeParamOrArg) {
    if (typeParamOrArg.isSimpleTypeArgument) {
      // We've seen identifier `<` identifier `>`
      next = typeParamOrArg.skip(next).next;
      if (optional('?', next)) {
        next = next.next;
        if (!isGeneralizedFunctionType(next)) {
          if ((required || looksLikeName(next)) &&
              typeParamOrArg == simpleTypeArgument1) {
            // identifier `<` identifier `>` `?` identifier
            return simpleNullableTypeWith1Argument;
          }
          // identifier `<` identifier `>` `?` non-identifier
          return noType;
        }
      } else if (!isGeneralizedFunctionType(next)) {
        if (required || looksLikeName(next)) {
          // identifier `<` identifier `>` identifier
          return typeParamOrArg.typeInfo;
        }
        // identifier `<` identifier `>` non-identifier
        return noType;
      }
    }
    // TODO(danrubel): Consider adding a const for
    // identifier `<` identifier `,` identifier `>`
    // if that proves to be a common case.

    // identifier `<` ... `>`
    return new ComplexTypeInfo(token, typeParamOrArg)
        .computeSimpleWithTypeArguments(required);
  }

  assert(typeParamOrArg == noTypeParamOrArg);
  next = next.next;
  if (optional('.', next)) {
    next = next.next;
    if (isValidTypeReference(next)) {
      // We've seen identifier `.` identifier
      typeParamOrArg = computeTypeParamOrArg(next, inDeclaration);
      next = next.next;
      if (typeParamOrArg == noTypeParamOrArg) {
        if (optional('?', next)) {
          next = next.next;
          if (!isGeneralizedFunctionType(next)) {
            if (required || looksLikeName(next)) {
              // identifier `.` identifier `?` identifier
              // TODO(danrubel): consider adding PrefixedNullableType
              // Fall through to build complex type
            } else {
              // identifier `.` identifier `?` non-identifier
              return noType;
            }
          }
        } else {
          if (!isGeneralizedFunctionType(next)) {
            if (required || looksLikeName(next)) {
              // identifier `.` identifier identifier
              return prefixedType;
            } else {
              // identifier `.` identifier non-identifier
              return noType;
            }
          }
        }
      }
      // identifier `.` identifier
      return new ComplexTypeInfo(token, typeParamOrArg)
          .computePrefixedType(required);
    }
    // identifier `.` non-identifier
    if (required) {
      typeParamOrArg = computeTypeParamOrArg(token.next.next, inDeclaration);
      return new ComplexTypeInfo(token, typeParamOrArg)
          .computePrefixedType(required);
    }
    return noType;
  }

  assert(typeParamOrArg == noTypeParamOrArg);
  if (isGeneralizedFunctionType(next)) {
    // identifier `Function`
    return new ComplexTypeInfo(token, noTypeParamOrArg)
        .computeIdentifierGFT(required);
  }

  if (optional('?', next)) {
    next = next.next;
    if (isGeneralizedFunctionType(next)) {
      // identifier `?` Function `(`
      return new ComplexTypeInfo(token, noTypeParamOrArg)
          .computeIdentifierQuestionGFT(required);
    } else if (required || looksLikeName(next)) {
      // identifier `?`
      return simpleNullableType;
    }
  } else if (required || looksLikeName(next)) {
    // identifier identifier
    return simpleType;
  }
  return noType;
}

/// Called by the parser to obtain information about a possible group of type
/// parameters or type arguments that follow [token].
/// This does not modify the token stream.
///
/// If [inDeclaration] is `true`, then this will more aggressively recover
/// given unbalanced `<` `>` and invalid parameters or arguments.
TypeParamOrArgInfo computeTypeParamOrArg(Token token,
    [bool inDeclaration = false, bool allowsVariance = false]) {
  Token beginGroup = token.next;
  if (!optional('<', beginGroup)) {
    return noTypeParamOrArg;
  }

  // identifier `<` `void` `>` and `<` `dynamic` `>`
  // are handled by ComplexTypeInfo.
  Token next = beginGroup.next;
  if ((next.kind == IDENTIFIER_TOKEN || next.type.isPseudo)) {
    if (optional('>', next.next)) {
      return simpleTypeArgument1;
    } else if (optional('>>', next.next)) {
      return simpleTypeArgument1GtGt;
    } else if (optional('>=', next.next)) {
      return simpleTypeArgument1GtEq;
    }
  } else if (optional('(', next)) {
    return noTypeParamOrArg;
  }

  // TODO(danrubel): Consider adding additional const for common situations.
  return new ComplexTypeParamOrArgInfo(token, inDeclaration, allowsVariance)
      .compute();
}

/// Called by the parser to obtain information about a possible group of type
/// type arguments that follow [token] and that are followed by '('.
/// Returns the type arguments if [token] matches '<' type (',' type)* '>' '(',
/// and otherwise returns [noTypeParamOrArg]. The final '(' is not part of the
/// grammar construct `typeArguments`, but it is required here such that type
/// arguments in generic method invocations can be recognized, and as few as
/// possible other constructs will pass (e.g., 'a < C, D > 3').
TypeParamOrArgInfo computeMethodTypeArguments(Token token) {
  TypeParamOrArgInfo typeArg = computeTypeParamOrArg(token);
  return optional('(', typeArg.skip(token).next) ? typeArg : noTypeParamOrArg;
}
