// Copyright (c) 2021, 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.

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../util/feature_sets.dart';
import 'parser_test_base.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(FunctionReferenceParserTest);
  });
}

/// Tests exercising the fasta parser's handling of generic instantiations.
@reflectiveTest
class FunctionReferenceParserTest extends FastaParserTestCase {
  /// Verifies that the given [node] matches `f<a, b>`.
  void expect_f_a_b(AstNode node) {
    var functionReference = node as FunctionReference;
    expect((functionReference.function as SimpleIdentifier).name, 'f');
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void expect_two_args(MethodInvocation methodInvocation) {
    var arguments = methodInvocation.argumentList.arguments;
    expect(arguments, hasLength(2));
    expect(arguments[0], TypeMatcher<BinaryExpression>());
    expect(arguments[1], TypeMatcher<BinaryExpression>());
  }

  void test_feature_disabled() {
    expect_f_a_b(
        (parseStatement('f<a, b>;', featureSet: FeatureSets.language_2_13)
                as ExpressionStatement)
            .expression);
    listener.assertErrors([
      expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 1, 6),
    ]);
  }

  void test_followingToken_accepted_closeBrace() {
    expect_f_a_b((parseExpression('{f<a, b>}') as SetOrMapLiteral).elements[0]);
  }

  void test_followingToken_accepted_closeBracket() {
    expect_f_a_b((parseExpression('[f<a, b>]') as ListLiteral).elements[0]);
  }

  void test_followingToken_accepted_closeParen() {
    expect_f_a_b((parseExpression('g(f<a, b>)') as MethodInvocation)
        .argumentList
        .arguments[0]);
  }

  void test_followingToken_accepted_colon() {
    expect_f_a_b(((parseExpression('{f<a, b>: null}') as SetOrMapLiteral)
            .elements[0] as MapLiteralEntry)
        .key);
  }

  void test_followingToken_accepted_comma() {
    expect_f_a_b(
        (parseExpression('[f<a, b>, null]') as ListLiteral).elements[0]);
  }

  void test_followingToken_accepted_equals() {
    expect_f_a_b(
        (parseExpression('f<a, b> == null') as BinaryExpression).leftOperand);
  }

  void test_followingToken_accepted_not_equals() {
    expect_f_a_b(
        (parseExpression('f<a, b> != null') as BinaryExpression).leftOperand);
  }

  void test_followingToken_accepted_openParen() {
    // This is a special case because when a `(` follows `<typeArguments>` it is
    // parsed as a MethodInvocation rather than a GenericInstantiation.
    var methodInvocation = parseExpression('f<a, b>()') as MethodInvocation;
    expect(methodInvocation.methodName.name, 'f');
    var typeArgs = methodInvocation.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
    expect(methodInvocation.argumentList.arguments, isEmpty);
  }

  void test_followingToken_accepted_period_methodInvocation() {
    // This is a special case because `f<a, b>.methodName(...)` is parsed as an
    // InstanceCreationExpression.
    var instanceCreationExpression =
        parseExpression('f<a, b>.toString()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.name2.lexeme, 'f');
    var typeArgs = type.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
    expect(constructorName.name!.name, 'toString');
    expect(instanceCreationExpression.argumentList.arguments, isEmpty);
  }

  void test_followingToken_accepted_period_methodInvocation_generic() {
    expect_f_a_b(
        (parseExpression('f<a, b>.foo<c>()') as MethodInvocation).target!);
  }

  void test_followingToken_accepted_period_propertyAccess() {
    expect_f_a_b(
        (parseExpression('f<a, b>.hashCode') as PropertyAccess).target!);
  }

  void test_followingToken_accepted_semicolon() {
    expect_f_a_b(
        (parseStatement('f<a, b>;') as ExpressionStatement).expression);
    listener.assertNoErrors();
  }

  void test_followingToken_rejected_ampersand() {
    expect_two_args(parseExpression('f(a<b,c>&d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_as() {
    expect_two_args(parseExpression('f(a<b,c>as)') as MethodInvocation);
  }

  void test_followingToken_rejected_asterisk() {
    expect_two_args(parseExpression('f(a<b,c>*d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_bang_openBracket() {
    expect_two_args(parseExpression('f(a<b,c>![d])') as MethodInvocation);
  }

  void test_followingToken_rejected_bang_paren() {
    expect_two_args(parseExpression('f(a<b,c>!(d))') as MethodInvocation);
  }

  void test_followingToken_rejected_bar() {
    expect_two_args(parseExpression('f(a<b,c>|d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_caret() {
    expect_two_args(parseExpression('f(a<b,c>^d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_is() {
    var methodInvocation = parseExpression('f(a<b,c> is int)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
    ]) as MethodInvocation;
    var arguments = methodInvocation.argumentList.arguments;
    expect(arguments, hasLength(2));
    expect(arguments[0], TypeMatcher<BinaryExpression>());
    expect(arguments[1], TypeMatcher<IsExpression>());
  }

  void test_followingToken_rejected_lessThan() {
    // Note: in principle we could parse this as a generic instantiation of a
    // generic instantiation, but such an expression would be meaningless so we
    // reject it at the parser level.
    parseExpression('f<a><b>', errors: [
      expectedError(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, 3, 1),
      expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 0),
    ]);
  }

  void test_followingToken_rejected_minus() {
    expect_two_args(parseExpression('f(a<b,c>-d)') as MethodInvocation);
  }

  void test_followingToken_rejected_openBracket() {
    expect_two_args(parseExpression('f(a<b,c>[d])') as MethodInvocation);
  }

  void test_followingToken_rejected_openBracket_error() {
    // Note that theoretically this could be successfully parsed by interpreting
    // `<` and `>` as delimiting type arguments, but the parser doesn't have
    // enough lookahead to see that this is the only possible error-free parse;
    // it commits to interpreting `<` and `>` as operators when it sees the `[`.
    expect_two_args(parseExpression('f(a<b,c>[d]>e)', errors: [
      expectedError(ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND, 11, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_openBracket_unambiguous() {
    expect_two_args(parseExpression('f(a<b,c>[d, e])') as MethodInvocation);
  }

  void test_followingToken_rejected_percent() {
    expect_two_args(parseExpression('f(a<b,c>%d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_period_period() {
    var methodInvocation = parseExpression('f(a<b,c>..toString())', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
    ]) as MethodInvocation;
    var arguments = methodInvocation.argumentList.arguments;
    expect(arguments, hasLength(2));
    expect(arguments[0], TypeMatcher<BinaryExpression>());
    expect(arguments[1], TypeMatcher<CascadeExpression>());
  }

  void test_followingToken_rejected_plus() {
    expect_two_args(parseExpression('f(a<b,c>+d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_question() {
    var methodInvocation = parseExpression('f(a<b,c> ? null : null)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 1),
    ]) as MethodInvocation;
    var arguments = methodInvocation.argumentList.arguments;
    expect(arguments, hasLength(2));
    expect(arguments[0], TypeMatcher<BinaryExpression>());
    expect(arguments[1], TypeMatcher<ConditionalExpression>());
  }

  void test_followingToken_rejected_question_period_methodInvocation() {
    expect_two_args(parseExpression('f(a<b,c>?.toString())', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_question_period_methodInvocation_generic() {
    expect_two_args(parseExpression('f(a<b,c>?.foo<c>())', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_question_period_period() {
    var methodInvocation = parseExpression('f(a<b,c>?..toString())', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 3),
      expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 8),
    ]) as MethodInvocation;
    var arguments = methodInvocation.argumentList.arguments;
    expect(arguments, hasLength(3));
    expect(arguments[0], TypeMatcher<BinaryExpression>());
    expect(arguments[1], TypeMatcher<BinaryExpression>());
    expect(arguments[2], TypeMatcher<MethodInvocation>());
  }

  void test_followingToken_rejected_question_period_propertyAccess() {
    expect_two_args(parseExpression('f(a<b,c>?.hashCode)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_question_question() {
    expect_two_args(parseExpression('f(a<b,c> ?? d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 2),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_slash() {
    expect_two_args(parseExpression('f(a<b,c>/d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
    ]) as MethodInvocation);
  }

  void test_followingToken_rejected_tilde_slash() {
    expect_two_args(parseExpression('f(a<b,c>~/d)', errors: [
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 2),
    ]) as MethodInvocation);
  }

  void test_functionReference_after_indexExpression() {
    // Note: this is not legal Dart, but it's important that we do error
    // recovery and don't crash the parser.
    var functionReference = parseExpression('x[0]<a, b>') as FunctionReference;
    expect(functionReference.function, TypeMatcher<IndexExpression>());
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_functionReference_after_indexExpression_bang() {
    // Note: this is not legal Dart, but it's important that we do error
    // recovery and don't crash the parser.
    var functionReference = parseExpression('x[0]!<a, b>') as FunctionReference;
    expect(functionReference.function, TypeMatcher<PostfixExpression>());
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_functionReference_after_indexExpression_functionCall() {
    // Note: this is not legal Dart, but it's important that we do error
    // recovery and don't crash the parser.
    var functionReference =
        parseExpression('x[0]()<a, b>') as FunctionReference;
    expect(functionReference.function,
        TypeMatcher<FunctionExpressionInvocation>());
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_functionReference_after_indexExpression_nullAware() {
    // Note: this is not legal Dart, but it's important that we do error
    // recovery and don't crash the parser.
    var functionReference = parseExpression('x?[0]<a, b>') as FunctionReference;
    expect(functionReference.function, TypeMatcher<IndexExpression>());
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_methodTearoff() {
    var functionReference = parseExpression('f().m<a, b>') as FunctionReference;
    var function = functionReference.function as PropertyAccess;
    var target = function.target as MethodInvocation;
    expect(target.methodName.name, 'f');
    expect(function.propertyName.name, 'm');
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_methodTearoff_cascaded() {
    var cascadeExpression =
        parseExpression('f()..m<a, b>') as CascadeExpression;
    var functionReference =
        cascadeExpression.cascadeSections[0] as FunctionReference;
    var function = functionReference.function as PropertyAccess;
    expect(function.target, isNull);
    expect(function.propertyName.name, 'm');
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_prefixedIdentifier() {
    var functionReference =
        parseExpression('prefix.f<a, b>') as FunctionReference;
    var function = functionReference.function as PrefixedIdentifier;
    expect(function.prefix.name, 'prefix');
    expect(function.identifier.name, 'f');
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }

  void test_three_identifiers() {
    var functionReference =
        parseExpression('prefix.ClassName.m<a, b>') as FunctionReference;
    var function = functionReference.function as PropertyAccess;
    var target = function.target as PrefixedIdentifier;
    expect(target.prefix.name, 'prefix');
    expect(target.identifier.name, 'ClassName');
    expect(function.propertyName.name, 'm');
    var typeArgs = functionReference.typeArguments!.arguments;
    expect(typeArgs, hasLength(2));
    expect((typeArgs[0] as NamedType).name2.lexeme, 'a');
    expect((typeArgs[1] as NamedType).name2.lexeme, 'b');
  }
}
