// Copyright (c) 2015, 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 'dart:async';

import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/strong_mode.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../generated/resolver_test_case.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(InstanceMemberInferrerTest);
    defineReflectiveTests(SetFieldTypeTest);
    defineReflectiveTests(VariableGathererTest);
  });
}

@reflectiveTest
class InstanceMemberInferrerTest extends ResolverTestCase {
  InstanceMemberInferrer createInferrer(LibraryElement library) {
    AnalysisContext context = library.context;
    var inheritanceManager = new InheritanceManager(library);
    return new InstanceMemberInferrer(
        context.typeProvider, (_) => inheritanceManager,
        typeSystem: context.typeSystem);
  }

  /**
   * Add a source with the given [content] and return the result of resolving
   * the source.
   */
  Future<CompilationUnitElement> resolve(String content) async {
    Source source = addNamedSource('/test.dart', content);
    if (enableNewAnalysisDriver) {
      var analysisResult = await computeAnalysisResult(source);
      return analysisResult.unit.declaredElement;
    } else {
      return analysisContext
          .resolveCompilationUnit2(source, source)
          .declaredElement;
    }
  }

  test_inferCompilationUnit_invalid_inheritanceCycle() async {
    CompilationUnitElement unit = await resolve('''
class A extends C {}
class B extends A {}
class C extends B {}
''');
    _runInferrer(unit);
  }

  test_inferCompilationUnit_method_parameter_multiple_different() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  $methodName(int p) => 0;
}
class B {
  $methodName(double p) => 0;
}
class C implements A, B {
  $methodName(p) => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    expect(parameterC.type.isDynamic, isTrue);

    _runInferrer(unit);

    expect(parameterC.type.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_parameter_multiple_named_different() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  $methodName({int p}) => 0;
}
class B {
  $methodName({int q}) => 0;
}
class C implements A, B {
  $methodName({p}) => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    expect(parameterC.type.isDynamic, isTrue);

    _runInferrer(unit);

    expect(parameterC.type.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_parameter_multiple_named_same() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  $methodName({int p}) => 0;
}
class B {
  $methodName({int p}) => 0;
}
class C implements A, B {
  $methodName({p}) => 0;
}
''');
    ClassElement classA = unit.getType('A');
    MethodElement methodA = classA.getMethod(methodName);
    ParameterElement parameterA = methodA.parameters[0];
    DartType expectedType = parameterA.type;
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    if (previewDart2) {
      expect(parameterC.type.isDynamic, isFalse);
    } else {
      expect(parameterC.type.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(parameterC.type, expectedType);
  }

  test_inferCompilationUnit_method_parameter_multiple_namedAndRequired() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  $methodName({int p}) => 0;
}
class B {
  $methodName(int p) => 0;
}
class C implements A, B {
  $methodName(p) => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    expect(parameterC.type.isDynamic, isTrue);

    _runInferrer(unit);

    expect(parameterC.type.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  $methodName(int p) => 0;
}
class B {
  $methodName([int p]) => 0;
}
class C implements A, B {
  $methodName(p) => 0;
}
''');
    ClassElement classA = unit.getType('A');
    MethodElement methodA = classA.getMethod(methodName);
    ParameterElement parameterA = methodA.parameters[0];
    DartType expectedType = parameterA.type;
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    if (previewDart2) {
      expect(parameterC.type.isDynamic, isFalse);
    } else {
      expect(parameterC.type.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(parameterC.type, expectedType);
  }

  test_inferCompilationUnit_method_parameter_single_generic() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A<E> {
  $methodName(E p) => 0;
}
class C<E> implements A<E> {
  $methodName(p) => 0;
}
''');
    ClassElement classC = unit.getType('C');
    DartType typeCE = classC.typeParameters[0].type;
    MethodElement methodC = classC.getMethod(methodName);
    ParameterElement parameterC = methodC.parameters[0];
    if (previewDart2) {
      expect(parameterC.type.isDynamic, isFalse);
    } else {
      expect(parameterC.type.isDynamic, isTrue);
    }
    expect(methodC.type.typeArguments, [typeCE]);

    _runInferrer(unit);

    expect(parameterC.type, classC.typeParameters[0].type);
    expect(methodC.type.typeArguments, [typeCE],
        reason: 'function type should still have type arguments');
  }

  test_inferCompilationUnit_method_return_multiple_different() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  int $methodName() => 0;
}
class B {
  double $methodName() => 0.0;
}
class C implements A, B {
  $methodName() => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    expect(methodC.returnType.isDynamic, isTrue);

    _runInferrer(unit);

    expect(methodC.returnType.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_return_multiple_different_generic() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A<E> {
  E $methodName() => null;
}
class B<E> {
  E $methodName() => null;
}
class C implements A<int>, B<double> {
  $methodName() => null;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    expect(methodC.returnType.isDynamic, isTrue);

    _runInferrer(unit);

    expect(methodC.returnType.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_return_multiple_dynamic() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  int $methodName() => 0;
}
class B {
  $methodName() => 0;
}
class C implements A, B {
  $methodName() => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    expect(methodC.returnType.isDynamic, isTrue);

    _runInferrer(unit);

    expect(methodC.returnType.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_return_multiple_same_generic() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A<E> {
  E $methodName() => 0;
}
class B<E> {
  E $methodName() => 0;
}
class C<E> implements A<E>, B<E> {
  $methodName() => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    if (previewDart2) {
      expect(methodC.returnType.isDynamic, isFalse);
    } else {
      expect(methodC.returnType.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(methodC.returnType, classC.typeParameters[0].type);
  }

  test_inferCompilationUnit_method_return_multiple_same_nonVoid() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  int $methodName() => 0;
}
class B {
  int $methodName() => 0;
}
class C implements A, B {
  $methodName() => 0;
}
''');
    ClassElement classA = unit.getType('A');
    MethodElement methodA = classA.getMethod(methodName);
    DartType expectedType = methodA.returnType;
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    if (previewDart2) {
      expect(methodC.returnType.isDynamic, isFalse);
    } else {
      expect(methodC.returnType.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(methodC.returnType, expectedType);
  }

  test_inferCompilationUnit_method_return_multiple_same_void() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  void $methodName() {};
}
class B {
  void $methodName() {};
}
class C implements A, B {
  $methodName() {};
}
''');
    ClassElement classA = unit.getType('A');
    MethodElement methodA = classA.getMethod(methodName);
    DartType expectedType = methodA.returnType;
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    if (previewDart2) {
      expect(methodC.returnType.isDynamic, isFalse);
    } else {
      expect(methodC.returnType.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(methodC.returnType, expectedType);
  }

  test_inferCompilationUnit_method_return_multiple_void() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  int $methodName() => 0;
}
class B {
  void $methodName() => 0;
}
class C implements A, B {
  $methodName() => 0;
}
''');
    ClassElement classC = unit.getType('C');
    MethodElement methodC = classC.getMethod(methodName);
    expect(methodC.returnType.isDynamic, isTrue);

    _runInferrer(unit);

    expect(methodC.returnType.isDynamic, isTrue);
  }

  test_inferCompilationUnit_method_return_single() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A {
  int $methodName() => 0;
}
class B extends A {
  $methodName() => 0;
}
''');
    ClassElement classA = unit.getType('A');
    MethodElement methodA = classA.getMethod(methodName);
    ClassElement classB = unit.getType('B');
    MethodElement methodB = classB.getMethod(methodName);
    if (previewDart2) {
      expect(methodB.returnType.isDynamic, isFalse);
    } else {
      expect(methodB.returnType.isDynamic, isTrue);
    }

    _runInferrer(unit);

    expect(methodB.returnType, methodA.returnType);
  }

  test_inferCompilationUnit_method_return_single_generic() async {
    String methodName = 'm';
    CompilationUnitElement unit = await resolve('''
class A<E> {
  E $methodName() => 0;
}
class B<E> extends A<E> {
  $methodName() => 0;
}
''');
    ClassElement classB = unit.getType('B');
    DartType typeBE = classB.typeParameters[0].type;
    MethodElement methodB = classB.getMethod(methodName);
    if (previewDart2) {
      expect(methodB.returnType.isDynamic, isFalse);
    } else {
      expect(methodB.returnType.isDynamic, isTrue);
    }
    expect(methodB.type.typeArguments, [typeBE]);

    _runInferrer(unit);

    expect(methodB.returnType, classB.typeParameters[0].type);
    expect(methodB.type.typeArguments, [typeBE],
        reason: 'function type should still have type arguments');
  }

  InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) {
    InstanceMemberInferrer inferrer = createInferrer(unit.library);
    inferrer.inferCompilationUnit(unit);
    return inferrer;
  }
}

@reflectiveTest
class SetFieldTypeTest extends ResolverTestCase {
  test_setter_withoutParameter() async {
    Source source = addSource('''
var x = 0;
set x() {}
''');
    var analysisResult = await computeAnalysisResult(source);
    CompilationUnitElement unit = analysisResult.unit.declaredElement;
    TopLevelVariableElement variable = unit.topLevelVariables.single;
    setFieldType(variable, unit.context.typeProvider.intType);
  }
}

@reflectiveTest
class VariableGathererTest extends ResolverTestCase {
  test_creation_withFilter() async {
    VariableFilter filter = (variable) => true;
    VariableGatherer gatherer = new VariableGatherer(filter);
    expect(gatherer, isNotNull);
    expect(gatherer.filter, same(filter));
  }

  test_creation_withoutFilter() async {
    VariableGatherer gatherer = new VariableGatherer();
    expect(gatherer, isNotNull);
    expect(gatherer.filter, isNull);
  }

  test_visit_noReferences() async {
    Source source = addNamedSource('/test.dart', '''
library lib;
import 'dart:math';
int zero = 0;
class C {
  void m() => null;
}
typedef void F();
''');
    var analysisResult = await computeAnalysisResult(source);
    VariableGatherer gatherer = new VariableGatherer();
    analysisResult.unit.accept(gatherer);
    expect(gatherer.results, hasLength(0));
  }

  test_visit_withFilter() async {
    VariableFilter filter = (VariableElement variable) => variable.isStatic;
    Set<VariableElement> variables = await _gather(filter);
    expect(variables, hasLength(1));
  }

  test_visit_withoutFilter() async {
    Set<VariableElement> variables = await _gather();
    expect(variables, hasLength(4));
  }

  Future<Set<VariableElement>> _gather([VariableFilter filter = null]) async {
    Source source = addNamedSource('/test.dart', '''
const int zero = 0;
class Counter {
  int value = zero;
  void inc() {
    value++;
  }
  void dec() {
    value = value - 1;
  }
  void fromZero(f(int index)) {
    for (int i = zero; i < value; i++) {
      f(i);
    }
  }
}
''');
    var analysisResult = await computeAnalysisResult(source);
    VariableGatherer gatherer = new VariableGatherer(filter);
    analysisResult.unit.accept(gatherer);
    return gatherer.results;
  }
}
