// 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.
// VMOptions=--no_show_internal_names
// Dart test program testing type casts.

// @dart = 2.9
import "package:expect/expect.dart";

checkSecondFunction(String expected, StackTrace stacktrace) {
  var topLine = stacktrace.toString().split("\n")[1];
  int startPos = topLine.lastIndexOf("/");
  int endPos = topLine.lastIndexOf(")");
  String subs = topLine.substring(startPos + 1, endPos);
  Expect.equals(expected, subs);
}

// Test that the initializer expression gets properly skipped.
bool b = "foo" as bool;

class TypeTest {
  static test() {
    int result = 0;
    try {
      var i = "hello" as int; // Throws a TypeError
    } catch (error) {
      result = 1;
      Expect.type<TypeError>(error);
      var msg = error.toString();
      Expect.isTrue(msg.contains("int")); // dstType
      Expect.isTrue(msg.contains("String")); // srcType
      checkSecondFunction("type_cast_vm_test.dart:23:23", error.stackTrace);
    }
    return result;
  }

  static testSideEffect() {
    int result = 0;
    int index() {
      result++;
      return 0;
    }

    try {
      var a = new List<int>(1) as List<int>;
      a[0] = 0;
      a[index()]++; // Type check succeeds, but does not create side effects.
      Expect.equals(1, a[0]);
    } catch (error) {
      result = 100;
    }
    return result;
  }

  static testArgument() {
    int result = 0;
    int f(int i) {
      return i;
    }

    try {
      int i = f("hello" as int); // Throws a TypeError
    } catch (error) {
      result = 1;
      Expect.type<TypeError>(error);
      var msg = error.toString();
      Expect.isTrue(msg.contains("int")); // dstType
      Expect.isTrue(msg.contains("String")); // srcType
      checkSecondFunction("type_cast_vm_test.dart:60:25", error.stackTrace);
    }
    return result;
  }

  static testReturn() {
    int result = 0;
    int f(String s) {
      return s as int; // Throws a TypeError
    }

    try {
      int i = f("hello");
    } catch (error) {
      result = 1;
      Expect.type<TypeError>(error);
      var msg = error.toString();
      Expect.isTrue(msg.contains("int")); // dstType
      Expect.isTrue(msg.contains("String")); // srcType
      checkSecondFunction("type_cast_vm_test.dart:75:16", error.stackTrace);
    }
    return result;
  }

  static var field = "hello";

  static testField() {
    int result = 0;
    Expect.equals(5, (field as String).length);
    try {
      field as int; // Throws a TypeError
    } catch (error) {
      result = 1;
      var msg = error.toString();
      Expect.isTrue(msg.contains("int")); // dstType
      Expect.isTrue(msg.contains("String")); // srcType
      checkSecondFunction("type_cast_vm_test.dart:97:13", error.stackTrace);
    }
    return result;
  }

  static testAnyFunction() {
    int result = 0;
    Function anyFunction;
    f() {}
    ;
    anyFunction = f as Function; // No error.
    anyFunction = null as Function; // No error.
    try {
      var i = f as int; // Throws a TypeError if type checks are enabled.
    } catch (error) {
      result = 1;
      var msg = error.toString();
      Expect.isTrue(msg.contains("int")); // dstType
      Expect.isTrue(msg.contains("() => dynamic")); // srcType
      checkSecondFunction("type_cast_vm_test.dart:116:17", error.stackTrace);
    }
    return result;
  }

  static testMain() {
    Expect.equals(1, test());
    Expect.equals(1, testSideEffect());
    Expect.equals(1, testArgument());
    Expect.equals(1, testReturn());
    Expect.equals(1, testField());
    Expect.equals(1, testAnyFunction());
  }
}

main() {
  TypeTest.testMain();
}
