// 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(ClassDeclarationTest);
    defineReflectiveTests(CompilationUnitMemberTest);
    defineReflectiveTests(ImportDirectiveTest);
  });
}

/**
 * Test how well the parser recovers when the clauses in a class declaration are
 * out of order.
 */
@reflectiveTest
class ClassDeclarationTest extends AbstractRecoveryTest {
  @failingTest
  void test_implementsBeforeExtends() {
    // Parser crashes
    testRecovery('''
class A implements B extends C {}
''', [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS], '''
class A extends C implements B {}
''');
  }

  @failingTest
  void test_implementsBeforeWith() {
    // Parser crashes
    testRecovery('''
class A extends B implements C with D {}
''', [ParserErrorCode.IMPLEMENTS_BEFORE_WITH], '''
class A extends B with D implements C {}
''');
  }

  @failingTest
  void test_implementsBeforeWithBeforeExtends() {
    // Parser crashes
    testRecovery('''
class A implements B with C extends D {}
''', [ParserErrorCode.IMPLEMENTS_BEFORE_WITH], '''
class A extends D with C implements B {}
''');
  }

  @failingTest
  void test_multipleExtends() {
    // Parser crashes
    testRecovery('''
class A extends B extends C {}
''', [ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES], '''
class A extends B {}
''');
  }

  @failingTest
  void test_multipleImplements() {
    // Parser crashes
    testRecovery('''
class A implements B implements C, D {}
''', [ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES], '''
class A implements B, C, D {}
''');
  }

  @failingTest
  void test_multipleWith() {
    // Parser crashes
    testRecovery('''
class A extends B with C, D with E {}
''', [ParserErrorCode.MULTIPLE_WITH_CLAUSES], '''
class A extends B with C, D, E {}
''');
  }

  @failingTest
  void test_withBeforeExtends() {
    // Parser crashes
    testRecovery('''
class A with B extends C {}
''', [ParserErrorCode.WITH_BEFORE_EXTENDS], '''
class A extends C with B {}
''');
  }
}

/**
 * Test how well the parser recovers when the members of a compilation unit are
 * out of order.
 */
@reflectiveTest
class CompilationUnitMemberTest extends AbstractRecoveryTest {
  void test_declarationBeforeDirective_export() {
    testRecovery('''
class C { }
export 'bar.dart';
''', [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION], '''
export 'bar.dart';
class C { }
''');
  }

  void test_declarationBeforeDirective_import() {
    testRecovery('''
class C { }
import 'bar.dart';
''', [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION], '''
import 'bar.dart';
class C { }
''');
  }

  void test_declarationBeforeDirective_part() {
    testRecovery('''
class C { }
part 'bar.dart';
''', [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION], '''
part 'bar.dart';
class C { }
''');
  }

  void test_declarationBeforeDirective_part_of() {
    testRecovery('''
class C { }
part of foo;
''', [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION], '''
part of foo;
class C { }
''');
  }

  void test_exportBeforeLibrary() {
    testRecovery('''
export 'bar.dart';
library l;
''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
library l;
export 'bar.dart';
''');
  }

  void test_importBeforeLibrary() {
    testRecovery('''
import 'bar.dart';
library l;
''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
library l;
import 'bar.dart';
''');
  }

  void test_partBeforeExport() {
    testRecovery('''
part 'foo.dart';
export 'bar.dart';
''', [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE], '''
export 'bar.dart';
part 'foo.dart';
''');
  }

  void test_partBeforeImport() {
    testRecovery('''
part 'foo.dart';
import 'bar.dart';
''', [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE], '''
import 'bar.dart';
part 'foo.dart';
''');
  }

  void test_partBeforeLibrary() {
    testRecovery('''
part 'foo.dart';
library l;
''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
library l;
part 'foo.dart';
''');
  }
}

/**
 * Test how well the parser recovers when the members of an import directive are
 * out of order.
 */
@reflectiveTest
class ImportDirectiveTest extends AbstractRecoveryTest {
  void test_combinatorsBeforeAndAfterPrefix() {
    testRecovery('''
import 'bar.dart' show A as p show B;
''', [ParserErrorCode.PREFIX_AFTER_COMBINATOR], '''
import 'bar.dart' as p show A show B;
''');
  }

  void test_combinatorsBeforePrefix() {
    testRecovery('''
import 'bar.dart' show A as p;
''', [ParserErrorCode.PREFIX_AFTER_COMBINATOR], '''
import 'bar.dart' as p show A;
''');
  }

  void test_combinatorsBeforePrefixAfterDeferred() {
    testRecovery('''
import 'bar.dart' deferred show A as p;
''', [ParserErrorCode.PREFIX_AFTER_COMBINATOR], '''
import 'bar.dart' deferred as p show A;
''');
  }

  void test_deferredAfterPrefix() {
    // TODO(danrubel): Add a new error messages for this situation
    // indicating that `deferred` should be moved before `as`.
    testRecovery('''
import 'bar.dart' as p deferred;
''', [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT], '''
import 'bar.dart' deferred as p;
''');
  }

  void test_duplicatePrefix() {
    testRecovery('''
import 'bar.dart' as p as q;
''', [ParserErrorCode.DUPLICATE_PREFIX], '''
import 'bar.dart' as p;
''');
  }

  void test_unknownTokenBeforePrefix() {
    testRecovery('''
import 'bar.dart' d as p;
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
import 'bar.dart' as p;
''');
  }

  void test_unknownTokenBeforePrefixAfterDeferred() {
    testRecovery('''
import 'bar.dart' deferred s as p;
''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
import 'bar.dart' deferred as p;
''');
  }

  void test_unknownTokenBeforePrefixAfterCombinatorMissingSemicolon() {
    testRecovery('''
import 'bar.dart' d show A as p
import 'b.dart';
''', [
      ParserErrorCode.UNEXPECTED_TOKEN,
      ParserErrorCode.PREFIX_AFTER_COMBINATOR,
      ParserErrorCode.EXPECTED_TOKEN
    ], '''
import 'bar.dart' as p show A;
import 'b.dart';
''');
  }
}
