// Copyright (c) 2017, 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/src/dart/error/syntactic_errors.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import 'recovery_test_support.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnnotationTest);
    defineReflectiveTests(MiscellaneousTest);
    defineReflectiveTests(ModifiersTest);
    defineReflectiveTests(MultipleTypeTest);
    defineReflectiveTests(PunctuationTest);
  });
}

/**
 * Test how well the parser recovers when annotations are included in places
 * where they are not allowed.
 */
@reflectiveTest
class AnnotationTest extends AbstractRecoveryTest {
  void test_typeArgument() {
    testRecovery('''
const annotation = null;
class A<E> {}
class C {
  m() => new A<@annotation C>();
}
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
const annotation = null;
class A<E> {}
class C {
  m() => new A<C>();
}
''');
  }
}

/**
 * Test how well the parser recovers in other cases.
 */
@reflectiveTest
class MiscellaneousTest extends AbstractRecoveryTest {
  void test_classTypeAlias_withBody() {
    testRecovery('''
class B = Object with A {}
''',
        // TODO(danrubel): Consolidate and improve error message.
        [ParserErrorCode.EXPECTED_EXECUTABLE, ParserErrorCode.EXPECTED_TOKEN],
        '''
class B = Object with A;
''');
  }

  void test_getter_parameters() {
    testRecovery('''
int get g() => 0;
''', [ParserErrorCode.GETTER_WITH_PARAMETERS], '''
int get g => 0;
''');
  }

  @failingTest
  void test_identifier_afterNamedArgument() {
    // https://github.com/dart-lang/sdk/issues/30370
    testRecovery('''
a() {
  b(c: c(d: d(e: null f,),),);
}
''', [], '''
a() {
  b(c: c(d: d(e: null,),),);
}
''');
  }

  void test_invalidRangeCheck() {
    parseCompilationUnit('''
f(x) {
  while (1 < x < 3) {}
}
''', codes: [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
  }

  @failingTest
  void test_listLiteralType() {
    // https://github.com/dart-lang/sdk/issues/4348
    testRecovery('''
List<int> ints = List<int>[];
''', [], '''
List<int> ints = <int>[];
''');
  }

  @failingTest
  void test_mapLiteralType() {
    // https://github.com/dart-lang/sdk/issues/4348
    testRecovery('''
Map<int, int> map = Map<int, int>{};
''', [], '''
Map<int, int> map = <int, int>{};
''');
  }

  void test_multipleRedirectingInitializers() {
    testRecovery('''
class A {
  A() : this.a(), this.b();
  A.a() {}
  A.b() {}
}
''', [], '''
class A {
  A() : this.a(), this.b();
  A.a() {}
  A.b() {}
}
''');
  }

  @failingTest
  void test_parenInMapLiteral() {
    // https://github.com/dart-lang/sdk/issues/12100
    testRecovery('''
class C {}
final Map v = {
  'a': () => new C(),
  'b': () => new C()),
  'c': () => new C(),
};
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
class C {}
final Map v = {
  'a': () => new C(),
  'b': () => new C(),
  'c': () => new C(),
};
''');
  }
}

/**
 * Test how well the parser recovers when extra modifiers are provided.
 */
@reflectiveTest
class ModifiersTest extends AbstractRecoveryTest {
  @failingTest
  void test_classDeclaration_static() {
    // TODO(danrubel): Fails because compilation unit begin token is `static`
    // even after recovery.
    testRecovery('''
static class A {}
''', [ParserErrorCode.EXTRANEOUS_MODIFIER], '''
class A {}
''');
  }

  void test_methodDeclaration_const_getter() {
    testRecovery('''
main() {}
const int get foo => 499;
''', [ParserErrorCode.EXTRANEOUS_MODIFIER], '''
main() {}
int get foo => 499;
''');
  }

  void test_methodDeclaration_const_method() {
    testRecovery('''
main() {}
const int foo() => 499;
''', [ParserErrorCode.EXTRANEOUS_MODIFIER], '''
main() {}
int foo() => 499;
''');
  }

  void test_methodDeclaration_const_setter() {
    testRecovery('''
main() {}
const set foo(v) => 499;
''', [ParserErrorCode.EXTRANEOUS_MODIFIER], '''
main() {}
set foo(v) => 499;
''');
  }
}

/**
 * Test how well the parser recovers when multiple type annotations are
 * provided.
 */
@reflectiveTest
class MultipleTypeTest extends AbstractRecoveryTest {
  @failingTest
  void test_topLevelVariable() {
    // https://github.com/dart-lang/sdk/issues/25875
    // Recovers with 'void bar() {}', which seems wrong. Seems like we should
    // keep the first type, not the second.
    testRecovery('''
String void bar() { }
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
String bar() { }
''');
  }
}

/**
 * Test how well the parser recovers when there is extra punctuation.
 */
@reflectiveTest
class PunctuationTest extends AbstractRecoveryTest {
  @failingTest
  void test_extraComma_extendsClause() {
    // https://github.com/dart-lang/sdk/issues/22313
    testRecovery('''
class A { }
class B { }
class Foo extends A, B {
  Foo() { }
}
''', [ParserErrorCode.UNEXPECTED_TOKEN, ParserErrorCode.UNEXPECTED_TOKEN], '''
class A { }
class B { }
class Foo extends A {
  Foo() { }
}
''');
  }

  void test_extraSemicolon_afterLastClassMember() {
    testRecovery('''
class C {
  foo() {};
}
''', [ParserErrorCode.EXPECTED_CLASS_MEMBER], '''
class C {
  foo() {}
}
''');
  }

  void test_extraSemicolon_afterLastTopLevelMember() {
    testRecovery('''
foo() {};
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
foo() {}
''');
  }

  void test_extraSemicolon_beforeFirstClassMember() {
    testRecovery('''
class C {
  ;foo() {}
}
''', [ParserErrorCode.EXPECTED_CLASS_MEMBER], '''
class C {
  foo() {}
}
''');
  }

  @failingTest
  void test_extraSemicolon_beforeFirstTopLevelMember() {
    // This test fails because the beginning token for the invalid unit is the
    // semicolon, despite the fact that it was skipped.
    testRecovery('''
;foo() {}
''', [ParserErrorCode.EXPECTED_EXECUTABLE], '''
foo() {}
''');
  }

  void test_extraSemicolon_betweenClassMembers() {
    testRecovery('''
class C {
  foo() {};
  bar() {}
}
''', [ParserErrorCode.EXPECTED_CLASS_MEMBER], '''
class C {
  foo() {}
  bar() {}
}
''');
  }

  void test_extraSemicolon_betweenTopLevelMembers() {
    testRecovery('''
foo() {};
bar() {}
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
foo() {}
bar() {}
''');
  }
}
