// Copyright (c) 2019, 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/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../dart/resolution/driver_resolution.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(InferenceFailureOnFunctionReturnTypeTest);
    defineReflectiveTests(InferenceFailureOnFunctionReturnType_InExtensionTest);
  });
}

@reflectiveTest
class InferenceFailureOnFunctionReturnType_InExtensionTest
    extends DriverResolutionTest {
  @override
  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
    ..contextFeatures = new FeatureSet.forTesting(
        sdkVersion: '2.3.0', additionalFeatures: [Feature.extension_methods])
    ..strictInference = true;

  test_extensionMethod() async {
    await assertErrorsInCode(r'''
extension E on List {
  e() {
    return 7;
  }
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 24, 23)]);
  }
}

/// Tests of HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE with the
/// "strict-inference" static analysis option.
@reflectiveTest
class InferenceFailureOnFunctionReturnTypeTest extends DriverResolutionTest {
  @override
  AnalysisOptionsImpl get analysisOptions =>
      AnalysisOptionsImpl()..strictInference = true;

  test_classInstanceGetter() async {
    await assertErrorsInCode(r'''
class C {
  get f => 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 11)]);
  }

  test_classInstanceMethod() async {
    await assertErrorsInCode(r'''
class C {
  f() => 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 9)]);
  }

  test_classInstanceMethod_withReturnType() async {
    await assertNoErrorsInCode(r'''
class C {
  Object f() => 7;
}
''');
  }

  test_classInstanceOperator() async {
    await assertErrorsInCode(r'''
class C {
  operator +(int x) => print(x);
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 30)]);
  }

  test_classInstanceSetter() async {
    await assertErrorsInCode(r'''
class C {
  set f(int x) => print(x);
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 25)]);
  }

  test_classStaticMethod() async {
    await assertErrorsInCode(r'''
class C {
  static f() => 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 16)]);
  }

  test_classStaticMethod_withType() async {
    await assertNoErrorsInCode(r'''
class C {
  static int f() => 7;
}
''');
  }

  test_functionTypedParameter() async {
    await assertErrorsInCode(r'''
void f(callback()) {
  callback();
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 7, 10)]);
  }

  test_functionTypedParameter_nested() async {
    await assertErrorsInCode(r'''
void f(void callback(callback2())) {
  callback(() => print('hey'));
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 21, 11)]);
  }

  test_functionTypedParameter_withReturnType() async {
    await assertNoErrorsInCode(r'''
void f(int callback()) {
  callback();
}
''');
  }

  test_localFunction() async {
    await assertNoErrorsInCode(r'''
class C {
  void f() {
    g() => 7;
  }
}
''');
  }

  test_mixinInstanceMethod() async {
    await assertErrorsInCode(r'''
mixin C {
  f() => 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 12, 9)]);
  }

  test_topLevelArrowFunction() async {
    await assertErrorsInCode(r'''
f() => 7;
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 9)]);
  }

  test_topLevelFunction() async {
    await assertErrorsInCode(r'''
f() {
  return 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 19)]);
  }

  test_topLevelFunction_async() async {
    await assertErrorsInCode(r'''
f() {
  return 7;
}
''', [error(HintCode.INFERENCE_FAILURE_ON_FUNCTION_RETURN_TYPE, 0, 19)]);
  }

  test_topLevelFunction_withReturnType() async {
    await assertNoErrorsInCode(r'''
dynamic f() => 7;
''');
  }
}
