// 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 '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;
}
''',
        featureSet: constructorTearoffs,
        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()', featureSet: constructorTearoffs)
            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 typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'C');
    expect(typeName.identifier.name, 'new');
    expect(constructorName.type2.typeArguments, isNull);
    expect(constructorName.name, isNull);
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_const_generic() {
    var instanceCreationExpression =
        parseExpression('const C<int>.new()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as SimpleIdentifier;
    expect(typeName.name, 'C');
    expect(constructorName.type2.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()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'C');
    expect(constructorName.type2.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()',
        featureSet: constructorTearoffs) as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'C');
    expect(constructorName.type2.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit() {
    var instanceCreationExpression =
        parseExpression('new C.new()', featureSet: constructorTearoffs)
            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 typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'C');
    expect(typeName.identifier.name, 'new');
    expect(constructorName.type2.typeArguments, isNull);
    expect(constructorName.name, isNull);
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_explicit_generic() {
    var instanceCreationExpression =
        parseExpression('new C<int>.new()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as SimpleIdentifier;
    expect(typeName.name, 'C');
    expect(constructorName.type2.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()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'C');
    expect(constructorName.type2.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()',
        featureSet: constructorTearoffs) as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'C');
    expect(constructorName.type2.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

  void test_constructor_invocation_implicit() {
    var methodInvocation =
        parseExpression('C.new()', featureSet: constructorTearoffs)
            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()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as SimpleIdentifier;
    expect(typeName.name, 'C');
    expect(constructorName.type2.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()', featureSet: constructorTearoffs)
            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()', featureSet: constructorTearoffs)
            as InstanceCreationExpression;
    var constructorName = instanceCreationExpression.constructorName;
    var typeName = constructorName.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'C');
    expect(constructorName.type2.typeArguments!.arguments, hasLength(1));
    expect(constructorName.name!.name, 'new');
    expect(instanceCreationExpression.argumentList, isNotNull);
  }

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

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

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

  void test_constructor_tearoff_generic() {
    var propertyAccess =
        parseExpression('C<int>.new', featureSet: constructorTearoffs)
            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()',
        featureSet: constructorTearoffs) 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()', featureSet: constructorTearoffs)
            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', featureSet: constructorTearoffs)
            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', featureSet: constructorTearoffs)
            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()',
        featureSet: constructorTearoffs) 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()',
        featureSet: constructorTearoffs) 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: preConstructorTearoffs,
        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!.name, 'new');
  }

  void test_factory_redirection() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = D.new;
}
''', featureSet: constructorTearoffs);
    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 typeName = redirectedConstructor.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'D');
    expect(typeName.identifier.name, 'new');
    expect(redirectedConstructor.type2.typeArguments, isNull);
    expect(redirectedConstructor.name, isNull);
  }

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

  void test_factory_redirection_prefixed() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = prefix.D.new;
}
''', featureSet: constructorTearoffs);
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var typeName = redirectedConstructor.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'D');
    expect(redirectedConstructor.type2.typeArguments, isNull);
    expect(redirectedConstructor.name!.name, 'new');
  }

  void test_factory_redirection_prefixed_generic() {
    var unit = parseCompilationUnit('''
class C {
  factory C() = prefix.D<int>.new;
}
''', featureSet: constructorTearoffs);
    var classDeclaration = unit.declarations.single as ClassDeclaration;
    var constructorDeclaration =
        classDeclaration.members.single as ConstructorDeclaration;
    expect(constructorDeclaration.initializers, isEmpty);
    var redirectedConstructor = constructorDeclaration.redirectedConstructor!;
    var typeName = redirectedConstructor.type2.name as PrefixedIdentifier;
    expect(typeName.prefix.name, 'prefix');
    expect(typeName.identifier.name, 'D');
    expect(redirectedConstructor.type2.typeArguments!.arguments, hasLength(1));
    expect(redirectedConstructor.name!.name, 'new');
  }

  void test_super_invocation() {
    var unit = parseCompilationUnit('''
class C extends B {
  C() : super.new();
}
''', featureSet: constructorTearoffs);
    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();
}
''', featureSet: constructorTearoffs);
    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');
  }
}
