// 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(NewAsIdentifierParserTest);
  });
}

/// Tests exercising the fasta parser's handling of generic instantiations.
@reflectiveTest
class NewAsIdentifierParserTest extends FastaParserTestCase {
  void test_constructor_field_initializer() {
    // Even though `C() : this.new();` is allowed, `C() : this.new = ...;`
    // should not be.
    parseCompilationUnit('''
class C {
  C() : this.new = null;
}
''', errors: [
      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 18, 4),
      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 23, 3),
      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 23, 3),
      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 23, 3),
      expectedError(ParserErrorCode.MISSING_KEYWORD_OPERATOR, 27, 1),
      expectedError(ParserErrorCode.INVALID_OPERATOR, 27, 1),
      expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 27, 1),
      expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 29, 4),
      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 29, 4),
      expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 33, 1),
    ]);
  }

  void test_constructor_invocation_const() {
    var instanceCreationExpression =
        parseExpression('const C.new()') as InstanceCreationExpression;
    // Parsing treats `new` as an identifier, so `D.new` is classified as a
    // type.  Resolution will change the type to `D` and the name to `new` if
    // appropriate.
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'C');
    expect(type.name2.lexeme, 'new');
    expect(constructorName.type.typeArguments, isNull);
    expect(constructorName.name, isNull);
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_const_generic() {
    var instanceCreationExpression =
        parseExpression('const C<int>.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_const_prefixed() {
    var instanceCreationExpression =
        parseExpression('const prefix.C.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments, isNull);
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_const_prefixed_generic() {
    var instanceCreationExpression = parseExpression(
      'const prefix.C<int>.new()',
    ) as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit() {
    var instanceCreationExpression =
        parseExpression('new C.new()') as InstanceCreationExpression;
    // Parsing treats `new` as an identifier, so `D.new` is classified as a
    // type.  Resolution will change the type to `D` and the name to `new` if
    // appropriate.
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'C');
    expect(type.name2.lexeme, 'new');
    expect(constructorName.type.typeArguments, isNull);
    expect(constructorName.name, isNull);
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit_generic() {
    var instanceCreationExpression =
        parseExpression('new C<int>.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit_prefixed() {
    var instanceCreationExpression =
        parseExpression('new prefix.C.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments, isNull);
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit_prefixed_generic() {
    var instanceCreationExpression = parseExpression(
      'new prefix.C<int>.new()',
    ) as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_implicit() {
    var methodInvocation = parseExpression('C.new()') as MethodInvocation;
    var target = methodInvocation.target as SimpleIdentifier;
    expect(target.name, 'C');
    expect(methodInvocation.methodName.name, 'new');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_constructor_invocation_implicit_generic() {
    var instanceCreationExpression =
        parseExpression('C<int>.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_implicit_prefixed() {
    var methodInvocation =
        parseExpression('prefix.C.new()') as MethodInvocation;
    var target = methodInvocation.target as PrefixedIdentifier;
    expect(target.prefix.name, 'prefix');
    expect(target.identifier.name, 'C');
    expect(methodInvocation.methodName.name, 'new');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_constructor_invocation_implicit_prefixed_generic() {
    var instanceCreationExpression =
        parseExpression('prefix.C<int>.new()') as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var type = constructorName.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'C');
    expect(constructorName.type.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_name() {
    var unit = parseCompilationUnit('''
class C {
  C.new();
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.name!.lexeme, 'new');
  }

  void test_constructor_name_factory() {
    var unit = parseCompilationUnit('''
class C {
  factory C.new() => C._();
  C._();
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members[0] as ConstructorDeclaration;
    expect(constructorDeclaration.name!.lexeme, 'new');
  }

  void test_constructor_tearoff() {
    var prefixedIdentifier = parseExpression('C.new') as PrefixedIdentifier;
    expect(prefixedIdentifier.prefix.name, 'C');
    expect(prefixedIdentifier.identifier.name, 'new');
  }

  void test_constructor_tearoff_generic() {
    var propertyAccess = parseExpression('C<int>.new') as PropertyAccess;
    var target = propertyAccess.target as FunctionReference;
    var className = target.function as SimpleIdentifier;
    expect(className.name, 'C');
    expect(target.typeArguments, isNotNull);
    expect(propertyAccess.propertyName.name, 'new');
  }

  void test_constructor_tearoff_generic_method_invocation() {
    var methodInvocation =
        parseExpression('C<int>.new.toString()') as MethodInvocation;
    var target = methodInvocation.target as PropertyAccess;
    var functionReference = target.target as FunctionReference;
    var className = functionReference.function as SimpleIdentifier;
    expect(className.name, 'C');
    expect(functionReference.typeArguments, isNotNull);
    expect(target.propertyName.name, 'new');
    expect(methodInvocation.methodName.name, 'toString');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_constructor_tearoff_in_comment_reference() {
    createParser('');
    var commentReference = parseCommentReference('C.new', 5)!;
    var identifier = commentReference.expression as PrefixedIdentifier;
    expect(identifier.prefix.name, 'C');
    expect(identifier.identifier.name, 'new');
  }

  void test_constructor_tearoff_method_invocation() {
    var methodInvocation =
        parseExpression('C.new.toString()') as MethodInvocation;
    var target = methodInvocation.target as PrefixedIdentifier;
    expect(target.prefix.name, 'C');
    expect(target.identifier.name, 'new');
    expect(methodInvocation.methodName.name, 'toString');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_constructor_tearoff_prefixed() {
    var propertyAccess = parseExpression('prefix.C.new') as PropertyAccess;
    var target = propertyAccess.target as PrefixedIdentifier;
    expect(target.prefix.name, 'prefix');
    expect(target.identifier.name, 'C');
    expect(propertyAccess.propertyName.name, 'new');
  }

  void test_constructor_tearoff_prefixed_generic() {
    var propertyAccess = parseExpression('prefix.C<int>.new') as PropertyAccess;
    var target = propertyAccess.target as FunctionReference;
    var className = target.function as PrefixedIdentifier;
    expect(className.prefix.name, 'prefix');
    expect(className.identifier.name, 'C');
    expect(target.typeArguments, isNotNull);
    expect(propertyAccess.propertyName.name, 'new');
  }

  void test_constructor_tearoff_prefixed_generic_method_invocation() {
    var methodInvocation = parseExpression(
      'prefix.C<int>.new.toString()',
    ) as MethodInvocation;
    var target = methodInvocation.target as PropertyAccess;
    var functionReference = target.target as FunctionReference;
    var className = functionReference.function as PrefixedIdentifier;
    expect(className.prefix.name, 'prefix');
    expect(className.identifier.name, 'C');
    expect(functionReference.typeArguments, isNotNull);
    expect(target.propertyName.name, 'new');
    expect(methodInvocation.methodName.name, 'toString');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_constructor_tearoff_prefixed_method_invocation() {
    var methodInvocation = parseExpression(
      'prefix.C.new.toString()',
    ) as MethodInvocation;
    var target = methodInvocation.target as PropertyAccess;
    var prefixedIdentifier = target.target as PrefixedIdentifier;
    expect(prefixedIdentifier.prefix.name, 'prefix');
    expect(prefixedIdentifier.identifier.name, 'C');
    expect(target.propertyName.name, 'new');
    expect(methodInvocation.methodName.name, 'toString');
    expect(methodInvocation.typeArguments, isNull);
    expect(methodInvocation.argumentList, isNotNull);
  }

  void test_disabled() {
    var unit = parseCompilationUnit(
        '''
class C {
  C.new();
}
''',
        featureSet: FeatureSets.language_2_13,
        errors: [
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 3),
        ]);
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.name!.lexeme, 'new');
  }

  void test_factory_redirection() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = D.new;
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    // Parsing treats `new` as an identifier, so `D.new` is classified as a
    // type.  Resolution will change the type to `D` and the name to `new` if
    // appropriate.
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var type = redirectedConstructor.type;
    expect(type.importPrefix!.name.lexeme, 'D');
    expect(type.name2.lexeme, 'new');
    expect(redirectedConstructor.type.typeArguments, isNull);
    expect(redirectedConstructor.name, isNull);
  }

  void test_factory_redirection_generic() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = D<int>.new;
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var type = redirectedConstructor.type;
    expect(type.name2.lexeme, 'D');
    expect(redirectedConstructor.type.typeArguments!.arguments, hasLength(1));
    expect(redirectedConstructor.name!.name, 'new');
  }

  void test_factory_redirection_prefixed() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = prefix.D.new;
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var type = redirectedConstructor.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'D');
    expect(redirectedConstructor.type.typeArguments, isNull);
    expect(redirectedConstructor.name!.name, 'new');
  }

  void test_factory_redirection_prefixed_generic() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = prefix.D<int>.new;
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var type = redirectedConstructor.type;
    expect(type.importPrefix!.name.lexeme, 'prefix');
    expect(type.name2.lexeme, 'D');
    expect(redirectedConstructor.type.typeArguments!.arguments, hasLength(1));
    expect(redirectedConstructor.name!.name, 'new');
  }

  void test_super_invocation() {
    var unit = parseCompilationUnit('''
class C extends B {
  C() : super.new();
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.redirectedConstructor, isNull);
    var superConstructorInvocation = constructorDeclaration.initializers.single
        as SuperConstructorInvocation;
    expect(superConstructorInvocation.constructorName!.name, 'new');
  }

  void test_this_redirection() {
    var unit = parseCompilationUnit('''
class C {
  C.named() : this.new();
  C();
}
''');
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members[0] as ConstructorDeclaration;
    expect(constructorDeclaration.redirectedConstructor, isNull);
    var redirectingConstructorInvocation = constructorDeclaration
        .initializers.single as RedirectingConstructorInvocation;
    expect(redirectingConstructorInvocation.constructorName!.name, 'new');
  }
}
