// Copyright (c) 2020, 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/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'parser_test_base.dart';
import 'test_support.dart';

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

@reflectiveTest
class VarianceParserTest extends FastaParserTestCase {
  @override
  CompilationUnit parseCompilationUnit(String content,
      {List<ErrorCode> codes,
      List<ExpectedError> errors,
      FeatureSet featureSet}) {
    return super.parseCompilationUnit(content,
        codes: codes,
        errors: errors,
        featureSet: featureSet ??
            FeatureSet.forTesting(
              sdkVersion: '2.5.0',
              additionalFeatures: [Feature.variance],
            ));
  }

  void test_class_disabled_multiple() {
    parseCompilationUnit('class A<in T, inout U, out V> { }',
        errors: [
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_class_disabled_single() {
    parseCompilationUnit('class A<out T> { }',
        errors: [
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_class_enabled_multiple() {
    var unit = parseCompilationUnit('class A<in T, inout U, out V, W> { }');
    expect(unit.declarations, hasLength(1));
    var classDecl = unit.declarations[0] as ClassDeclaration;
    expect(classDecl.name.name, 'A');

    expect(classDecl.typeParameters.typeParameters, hasLength(4));
    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
    expect(classDecl.typeParameters.typeParameters[1].name.name, 'U');
    expect(classDecl.typeParameters.typeParameters[2].name.name, 'V');
    expect(classDecl.typeParameters.typeParameters[3].name.name, 'W');

    var typeParameterImplList = classDecl.typeParameters.typeParameters;
    expect((typeParameterImplList[0] as TypeParameterImpl).varianceKeyword,
        isNotNull);
    expect(
        (typeParameterImplList[0] as TypeParameterImpl).varianceKeyword.lexeme,
        "in");
    expect((typeParameterImplList[1] as TypeParameterImpl).varianceKeyword,
        isNotNull);
    expect(
        (typeParameterImplList[1] as TypeParameterImpl).varianceKeyword.lexeme,
        "inout");
    expect((typeParameterImplList[2] as TypeParameterImpl).varianceKeyword,
        isNotNull);
    expect(
        (typeParameterImplList[2] as TypeParameterImpl).varianceKeyword.lexeme,
        "out");
    expect((typeParameterImplList[3] as TypeParameterImpl).varianceKeyword,
        isNull);
  }

  void test_class_enabled_multipleVariances() {
    var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
    ]);
    expect(unit.declarations, hasLength(1));
    var classDecl = unit.declarations[0] as ClassDeclaration;
    expect(classDecl.name.name, 'A');
    expect(classDecl.typeParameters.typeParameters, hasLength(1));
    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
  }

  void test_class_enabled_single() {
    var unit = parseCompilationUnit('class A<in T> { }');
    expect(unit.declarations, hasLength(1));
    var classDecl = unit.declarations[0] as ClassDeclaration;
    expect(classDecl.name.name, 'A');
    expect(classDecl.typeParameters.typeParameters, hasLength(1));
    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');

    var typeParameterImpl =
        classDecl.typeParameters.typeParameters[0] as TypeParameterImpl;
    expect(typeParameterImpl.varianceKeyword, isNotNull);
    expect(typeParameterImpl.varianceKeyword.lexeme, "in");
  }

  void test_function_disabled() {
    parseCompilationUnit('void A(in int value) {}',
        errors: [
          expectedError(
              ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 2),
          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_function_enabled() {
    parseCompilationUnit('void A(in int value) {}', errors: [
      expectedError(ParserErrorCode.EXPECTED_IDENTIFIER_BUT_GOT_KEYWORD, 7, 2),
      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
    ]);
  }

  void test_list_disabled() {
    parseCompilationUnit('List<out String> stringList = [];',
        errors: [
          expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_list_enabled() {
    parseCompilationUnit('List<out String> stringList = [];', errors: [
      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
    ]);
  }

  void test_mixin_disabled_multiple() {
    parseCompilationUnit('mixin A<inout T, out U> { }',
        errors: [
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_mixin_disabled_single() {
    parseCompilationUnit('mixin A<inout T> { }',
        errors: [
          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_mixin_enabled_single() {
    var unit = parseCompilationUnit('mixin A<inout T> { }');
    expect(unit.declarations, hasLength(1));
    var mixinDecl = unit.declarations[0] as MixinDeclaration;
    expect(mixinDecl.name.name, 'A');
    expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
    expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
  }

  void test_typedef_disabled() {
    parseCompilationUnit('typedef A<inout X> = X Function(X);',
        errors: [
          expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
        ],
        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
  }

  void test_typedef_enabled() {
    parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
    ]);
  }
}
