// Copyright (c) 2012, 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";

// Invocation and noSuchMethod testing.

Map<Symbol, dynamic> listToNamedArguments(list) {
  var iterator = list.iterator;
  var result = new Map<Symbol, dynamic>();
  while (iterator.moveNext()) {
    Symbol key = iterator.current;
    Expect.isTrue(iterator.moveNext());
    result[key] = iterator.current;
  }
  return result;
}


/** Class with noSuchMethod that returns the mirror */
class N {
  // Storage for the last argument to noSuchMethod.
  // Needed for setters, which don't evaluate to the return value.
  var last;
  noSuchMethod(Invocation m) => last = m;

  flif(int x) { Expect.fail("never get here"); }
  flaf([int x]) { Expect.fail("never get here"); }
  flof({int y}) { Expect.fail("never get here"); }

  get wut => this;
  final int plif = 99;
  int get plaf { Expect.fail("never get here"); return 0; }
}

/** As [N] but also implements 'call', so we can call it with wrong arguments.*/
class C extends N {
  call(int x) { Expect.fail("never get here"); }
}

/**
 * Checks the data of an Invocation.
 *
 * Call without optionals for getters, with only positional for setters,
 * and with both optionals for everything else.
 */
testInvocationMirror(Invocation im, Symbol name,
                     [List positional, List named]) {
  Expect.isTrue(im is Invocation, "is Invocation");
  Expect.equals(name, im.memberName, "name");
  if (named == null) {
    Expect.isTrue(im.isAccessor, "$name:isAccessor");
    Expect.isFalse(im.isMethod, "$name:isMethod");
    if (positional == null) {
      Expect.isTrue(im.isGetter, "$name:isGetter");
      Expect.isFalse(im.isSetter, "$name:isSetter");
      Expect.equals(0, im.positionalArguments.length, "$name:#positional");
      Expect.equals(0, im.namedArguments.length, "$name:#named");
      return;
    }
    Expect.isTrue(im.isSetter, "$name:isSetter");
    Expect.isFalse(im.isGetter, "$name:isGetter");
    Expect.equals(1, im.positionalArguments.length, "$name:#positional");
    Expect.equals(positional[0], im.positionalArguments[0],
                  "$name:positional[0]");
    Expect.equals(0, im.namedArguments.length, "$name:#named");
    return;
  }
  Map<Symbol, dynamic> namedArguments = listToNamedArguments(named);
  Expect.isTrue(im.isMethod, "$name:isMethod");
  Expect.isFalse(im.isAccessor, "$name:isAccessor");
  Expect.isFalse(im.isSetter, "$name:isSetter");
  Expect.isFalse(im.isGetter, "$name:isGetter");

  Expect.listEquals(positional, im.positionalArguments);

  Expect.equals(namedArguments.length, im.namedArguments.length,
                "$name:#named");
  namedArguments.forEach((k, v) {
    Expect.isTrue(im.namedArguments.containsKey(k),
                  "$name:?namedArguments[$k]");
    Expect.equals(v, im.namedArguments[k], "$name:namedArguments[$k]");
  });
}


// Test different ways that noSuchMethod can be called.
testInvocationMirrors() {
  var n = new N();
  var c = new C();

  // Missing property/method access.
  testInvocationMirror(n.bar, const Symbol('bar'));
  testInvocationMirror((n..bar = 42).last, const Symbol('bar='), [42]);
  testInvocationMirror(n.bar(), const Symbol('bar'), [], []);
  testInvocationMirror(n.bar(42), const Symbol('bar'), [42], []);
  testInvocationMirror(n.bar(x: 42), const Symbol('bar'), [],
                       [const Symbol("x"),  42]);
  testInvocationMirror(n.bar(37, x: 42), const Symbol('bar'), [37],
                       [const Symbol("x"), 42]);

  // Missing operator access.
  testInvocationMirror(n + 4, const Symbol('+'), [4], []);
  testInvocationMirror(n - 4, const Symbol('-'), [4], []);
  testInvocationMirror(-n, const Symbol('unary-'), [], []);
  testInvocationMirror(n[42], const Symbol('[]'), [42], []);
  testInvocationMirror((n..[37] = 42).last, const Symbol('[]='), [37, 42], []);

  // Calling as function when it's not.
  testInvocationMirror(n(), const Symbol('call'), [], []);
  testInvocationMirror(n(42), const Symbol('call'), [42], []);
  testInvocationMirror(n(x: 42), const Symbol('call'), [],
                       [const Symbol("x"), 42]);
  testInvocationMirror(n(37, x: 42), const Symbol('call'), [37],
                       [const Symbol("x"), 42]);

  // Calling with arguments not matching existing call method.
  testInvocationMirror(c(), const Symbol('call'), [], []);
  testInvocationMirror(c(37, 42), const Symbol('call'), [37, 42], []);
  testInvocationMirror(c(x: 42), const Symbol('call'), [],
                       [const Symbol("x"), 42]);
  testInvocationMirror(c(37, x: 42), const Symbol('call'), [37],
                       [const Symbol("x"), 42]);

  // Wrong arguments to existing function.
  testInvocationMirror(n.flif(), const Symbol("flif"), [], []);
  testInvocationMirror(n.flif(37, 42), const Symbol("flif"), [37, 42], []);
  testInvocationMirror(n.flif(x: 42), const Symbol("flif"), [],
                       [const Symbol("x"), 42]);
  testInvocationMirror(n.flif(37, x: 42), const Symbol("flif"), [37],
                       [const Symbol("x"), 42]);
  testInvocationMirror((n..flif = 42).last, const Symbol("flif="), [42]);

  testInvocationMirror(n.flaf(37, 42), const Symbol("flaf"), [37, 42], []);
  testInvocationMirror(n.flaf(x: 42), const Symbol("flaf"), [],
                       [const Symbol("x"), 42]);
  testInvocationMirror(n.flaf(37, x: 42), const Symbol("flaf"), [37],
                       [const Symbol("x"), 42]);
  testInvocationMirror((n..flaf = 42).last, const Symbol("flaf="), [42]);

  testInvocationMirror(n.flof(37, 42), const Symbol("flof"), [37, 42], []);
  testInvocationMirror(n.flof(x: 42), const Symbol("flof"), [],
                       [const Symbol("x"), 42]);
  testInvocationMirror(n.flof(37, y: 42), const Symbol("flof"), [37],
                       [const Symbol("y"), 42]);
  testInvocationMirror((n..flof = 42).last, const Symbol("flof="), [42]);

  // Reading works.
  Expect.isTrue(n.flif is Function);
  Expect.isTrue(n.flaf is Function);
  Expect.isTrue(n.flof is Function);

  // Writing to read-only fields.
  testInvocationMirror((n..wut = 42).last, const Symbol("wut="), [42]);
  testInvocationMirror((n..plif = 42).last, const Symbol("plif="), [42]);
  testInvocationMirror((n..plaf = 42).last, const Symbol("plaf="), [42]);

  // Trick call to n.call - wut is a getter returning n again.
  testInvocationMirror(n.wut(42), const Symbol("call"), [42], []);

  // Calling noSuchMethod itself, badly.
  testInvocationMirror(n.noSuchMethod(), const Symbol("noSuchMethod"), [], []);
  testInvocationMirror(n.noSuchMethod(37, 42), const Symbol("noSuchMethod"),
                       [37, 42], []);
  testInvocationMirror(n.noSuchMethod(37, x:42),
                       const Symbol("noSuchMethod"), [37],
                       [const Symbol("x"), 42]);
  testInvocationMirror(n.noSuchMethod(x:42), const Symbol("noSuchMethod"), [],
                       [const Symbol("x"), 42]);

  // Closurizing a method means that calling it badly will not hit the
  // original receivers noSuchMethod, only the one inherited from Object
  // by the closure object.
  Expect.throws(() { var x = n.flif; x(37, 42); },
                (e) => e is NoSuchMethodError);
  Expect.throws(() { var x = c.call; x(37, 42); },
                (e) => e is NoSuchMethodError);
}

class M extends N {
  noSuchMethod(Invocation m) { throw "never get here"; }

  testSuperCalls() {
    // Missing property/method access.
    testInvocationMirror(super.bar, const Symbol('bar'));
    testInvocationMirror((){super.bar = 42; return last;}(),
                         const Symbol('bar='), [42]);
    testInvocationMirror(super.bar(), const Symbol('bar'), [], []);
    testInvocationMirror(super.bar(42), const Symbol('bar'), [42], []);
    testInvocationMirror(super.bar(x: 42), const Symbol('bar'), [],
                         [const Symbol("x"), 42]);
    testInvocationMirror(super.bar(37, x: 42), const Symbol('bar'), [37],
                         [const Symbol("x"), 42]);

    // Missing operator access.
    testInvocationMirror(super + 4, const Symbol('+'), [4], []);
    testInvocationMirror(super - 4, const Symbol('-'), [4], []);
    testInvocationMirror(-super, const Symbol('unary-'), [], []);
    testInvocationMirror(super[42], const Symbol('[]'), [42], []);
    testInvocationMirror((){super[37] = 42; return last;}(),
                         const Symbol('[]='), [37, 42], []);

    // Wrong arguments to existing function.
    testInvocationMirror(super.flif(), const Symbol("flif"), [], []);
    testInvocationMirror(super.flif(37, 42), const Symbol("flif"), [37, 42],
                         []);
    testInvocationMirror(super.flif(x: 42), const Symbol("flif"), [],
                         [const Symbol("x"), 42]);
    testInvocationMirror(super.flif(37, x: 42), const Symbol("flif"), [37],
                         [const Symbol("x"), 42]);
    testInvocationMirror((){super.flif = 42; return last;}(),
                         const Symbol("flif="), [42]);

    testInvocationMirror(super.flaf(37, 42), const Symbol("flaf"), [37, 42],
                         []);
    testInvocationMirror(super.flaf(x: 42), const Symbol("flaf"), [],
                         [const Symbol("x"), 42]);
    testInvocationMirror(super.flaf(37, x: 42), const Symbol("flaf"), [37],
                         [const Symbol("x"), 42]);
    testInvocationMirror((){super.flaf = 42; return last;}(),
                         const Symbol("flaf="), [42]);

    testInvocationMirror(super.flof(37, 42), const Symbol("flof"), [37, 42],
                         []);
    testInvocationMirror(super.flof(x: 42), const Symbol("flof"), [],
                         [const Symbol("x"), 42]);
    testInvocationMirror(super.flof(37, y: 42), const Symbol("flof"), [37],
                         [const Symbol("y"), 42]);
    testInvocationMirror((){super.flof = 42; return last;}(),
                         const Symbol("flof="), [42]);

    // Reading works.
    Expect.isTrue(super.flif is Function);
    Expect.isTrue(super.flaf is Function);
    Expect.isTrue(super.flof is Function);

    // Writing to read-only fields.
    testInvocationMirror((){super.wut = 42; return last;}(),
                         const Symbol("wut="), [42]);
    testInvocationMirror((){super.plif = 42; return last;}(),
                         const Symbol("plif="), [42]);
    testInvocationMirror((){super.plaf = 42; return last;}(),
                         const Symbol("plaf="), [42]);

    // Calling noSuchMethod itself, badly.
    testInvocationMirror(super.noSuchMethod(), const Symbol("noSuchMethod"), [],
                         []);
    testInvocationMirror(super.noSuchMethod(37, 42),
                         const Symbol("noSuchMethod"), [37, 42], []);
    testInvocationMirror(super.noSuchMethod(37, x:42),
                         const Symbol("noSuchMethod"), [37],
                         [const Symbol("x"), 42]);
    testInvocationMirror(super.noSuchMethod(x:42),
                         const Symbol("noSuchMethod"), [],
                         [const Symbol("x"), 42]);

    // Closurizing a method means that calling it badly will not hit the
    // original receivers noSuchMethod, only the one inherited from Object
    // by the closure object.
    Expect.throws(() { var x = super.flif; x(37, 42); },
                  (e) => e is NoSuchMethodError);
  }
}



// Test the NoSuchMethodError thrown by different incorrect calls.
testNoSuchMethodErrors() {
  test(Function block) {
    Expect.throws(block, (e) => e is NoSuchMethodError);
  }
  var n = new N();
  var o = new Object();
  test(() => o.bar);
  test(() => o.bar = 42);
  test(() => o.bar());
  test(() => o + 2);
  test(() => -o);
  test(() => o[0]);
  test(() => o[0] = 42);
  test(() => o());
  test(() => o.toString = 42);
  test(() => o.toString(42));
  test(() => o.toString(x: 37));
  test(() => o.hashCode = 42);
  test(() => o.hashCode());  // Thrown by int.noSuchMethod.
  test(() => (n.flif)());  // Extracted method has no noSuchMethod.
}

main() {
  testInvocationMirrors();
  testNoSuchMethodErrors();
  new M().testSuperCalls();
}
