// Copyright (c) 2014, 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:expect/expect.dart";

// Test for type checks against tear-off closures generated in different
// optimization contexts.
//
// The type of a tear-off closure depends on the receiver when the method
// signature uses a type parameter of the method's class.  This means that type
// checking needs to reference the receiver correctly, either during closure
// creation or during the type test.

class A<T> {
  const A();
  void add(T x) { }
  T elementAt(int index) => index == 0 ? 42 : 'string';

  // This call get:elementAt has a known receiver type, so is is potentially
  // eligible for a dummy receiver optimization.
  getElementAt() => this.elementAt;
  // Same for get:add.
  getAdd() => this.add;

  toString() => 'A<$T>';
}

var getAddOfA = (a) => a.getAdd();
var getElementAtOfA = (a) => a.getElementAt();

var getAdd1 = (a) => a.add;  // receiver has unknown type here.

var getAdd2 = (a) {
  // Call needs to be indirect to avoid inlining.
  if (a is A) return getAddOfA(a);
  return a.add;
};

var getElementAt1 = (a) => a.elementAt;  // receiver has unknown type here.

var getElementAt2 = (a) {
  // Call needs to be indirect to avoid inlining.
  if (a is A) return getElementAtOfA(a);
  return a.elementAt;
};


typedef void IntToVoid(int x);
typedef void StringToVoid(String x);

typedef int IntToInt(int x);
typedef String IntToString(int x);
typedef T IntToT<T>(int x);

var inscrutable;

var checkers = {
  'IntToVoid': (x) => x is IntToVoid,
  'StringToVoid': (x) => x is StringToVoid,
  'IntToInt': (x) => x is IntToInt,
  'IntToString': (x) => x is IntToString,
  'IntToT<int>': (x) => x is IntToT<int>,
  'IntToT<String>': (x) => x is IntToT<String>,
};

var methods = {
  'getAdd1': (x) => getAdd1(x),
  'getAdd2': (x) => getAdd2(x),
  'getElementAt1': (x) => getElementAt1(x),
  'getElementAt2': (x) => getElementAt2(x),
};


main() {
  inscrutable = (x) => x;

  getAdd1 = inscrutable(getAdd1);
  getAdd2 = inscrutable(getAdd2);
  getElementAt1 = inscrutable(getElementAt1);
  getElementAt2 = inscrutable(getElementAt2);
  getAddOfA = inscrutable(getAddOfA);
  getElementAtOfA = inscrutable(getElementAtOfA);

  check(methodNames, objects, trueCheckNames) {
    for (var trueCheckName in trueCheckNames) {
      if (!checkers.containsKey(trueCheckName)) {
        Expect.fail("unknown check '$trueCheckName'");
      }
    }

    for (var object in objects) {
      for (var methodName in methodNames) {
        var methodFn = methods[methodName];
        var description = '$object';
        checkers.forEach((checkName, checkFn) {
          bool answer = trueCheckNames.contains(checkName);
          Expect.equals(
              answer,
              checkFn(methodFn(object)),
              '$methodName($description) is $checkName');
        });
      }
    }
  }

  var objectsDyn = [[], new A(), new A<dynamic>()];
  var objectsInt = [<int>[], new A<int>()];
  var objectsStr = [<String>[], new A<String>()];
  var objectsLst = [<List>[], new A<List>()];

  var m = ['getAdd1', 'getAdd2'];
  check(m, objectsDyn, ['IntToVoid', 'StringToVoid']);
  check(m, objectsInt, ['IntToVoid']);
  check(m, objectsStr, ['StringToVoid']);
  check(m, objectsLst, []);

  m = ['getElementAt1', 'getElementAt2'];
  check(m, objectsDyn, ['IntToInt', 'IntToString', 'IntToVoid', 'IntToT<int>',
          'IntToT<String>']);
  check(m, objectsInt, ['IntToInt', 'IntToVoid', 'IntToT<int>']);
  check(m, objectsStr, ['IntToString', 'IntToVoid', 'IntToT<String>']);
  check(m, objectsLst, ['IntToVoid']);
}
