// Copyright (c) 2018, 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 'context_collection_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(ForEachStatementResolutionTest);
    defineReflectiveTests(ForLoopStatementResolutionTest);
  });
}

/// TODO(scheglov) Move other for-in tests here.
@reflectiveTest
class ForEachStatementResolutionTest extends PubPackageResolutionTest {
  test_iterable_missing() async {
    await assertErrorsInCode(r'''
void f() {
  for (var v in) {
    v;
  }
}
''', [
      error(ParserErrorCode.MISSING_IDENTIFIER, 26, 1),
    ]);

    assertType(findElement.localVar('v').type, 'dynamic');
    assertType(findNode.simple('v;'), 'dynamic');
  }

  /// Test that the parameter `x` is in the scope of the iterable.
  /// But the declared identifier `x` is in the scope of the body.
  test_scope() async {
    await assertNoErrorsInCode('''
void f(List<List<int>> x) {
  for (int x in x.first) {
    x.isEven;
  }
}
''');

    assertElement(
      findNode.simple('x) {'),
      findElement.parameter('x'),
    );

    assertElement(
      findNode.simple('x.isEven'),
      findElement.localVar('x'),
    );
  }

  test_type_genericFunctionType() async {
    await assertNoErrorsInCode(r'''
void f() {
  for (Null Function<T>(T, Null) e in <dynamic>[]) {
    e;
  }
}
''');
  }

  test_type_inferred() async {
    await assertNoErrorsInCode(r'''
void f(List<int> a) {
  for (var v in a) {
    v;
  }
}
''');

    assertType(findElement.localVar('v').type, 'int');
    assertType(findNode.simple('v;'), 'int');
  }
}

@reflectiveTest
class ForLoopStatementResolutionTest extends PubPackageResolutionTest {
  test_condition_rewrite() async {
    await assertNoErrorsInCode(r'''
f(bool Function() b) {
  for (; b(); ) {
    print(0);
  }
}
''');

    assertFunctionExpressionInvocation(
      findNode.functionExpressionInvocation('b()'),
      element: null,
      typeArgumentTypes: [],
      invokeType: 'bool Function()',
      type: 'bool',
    );
  }
}
