// 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.
// Dart test for type checks involving the void type.

isCheckedMode() {
  try {
    var i = 1;
    String s = i;
    return false;
  } catch (e) {
    return true;
  }
}

void f() { return; }

void f_null() { return null; }

void f_1() { return 1; }

void f_dyn_null() {
  var x = null;
  return x;
}

void f_dyn_1() {
  var x = 1;
  return x;
}

void f_f() { return f(); }

void test(int n, void func(), bool must_get_error) {
  // Test as closure call.
  {
    bool got_type_error = false;
    try {
      var x = func();
    } on TypeError catch (error) {
      got_type_error = true;
    }
    // Never a type error in production mode.
    if (isCheckedMode()) {
      Expect.isTrue(got_type_error == must_get_error);
    } else {
      Expect.isFalse(got_type_error);
    }
  }
  // Test as direct call.
  {
    bool got_type_error = false;
    try {
      var x;
      switch (n) {
        case 0: x = f(); break;
        case 1: x = f_null(); break;
        case 2: x = f_1(); break;
        case 3: x = f_dyn_null(); break;
        case 4: x = f_dyn_1(); break;
        case 5: x = f_f(); break;
      }
    } on TypeError catch (error) {
      got_type_error = true;
    }
    // Never a type error in production mode.
    if (isCheckedMode()) {
      Expect.isTrue(got_type_error == must_get_error);
    } else {
      Expect.isFalse(got_type_error);
    }
  }
}

main() {
  test(0, f, false);
  test(1, f_null, false);
  test(2, f_1, true);
  test(3, f_dyn_null, false);
  test(4, f_dyn_1, true);
  test(5, f_f, false);
}


