// 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 as dynamic : '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] as dynamic;
        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']);
}
