// Copyright (c) 2018, 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.

/*member: X.:[exact=X]*/
class X {}

/*member: returnDyn1:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn1() {
  var a;
  ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
      ((a = 'foo') /*invoke: Value([exact=JSString], value: "foo")*/ == true);
  return a;
}

/*member: returnDyn2:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn2() {
  var a;
  ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
      ((a = 'foo') /*invoke: Value([exact=JSString], value: "foo")*/ == true);
  return a;
}

/*member: returnDyn3:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn3() {
  var a;
  a = a == 54 ? 'foo' : 31;
  return a;
}

/*member: returnDyn4:Union([exact=JSUInt31], [exact=X])*/
returnDyn4() {
  var a;
  ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) ||
      ((a = new X()) /*invoke: [exact=X]*/ == true);
  return a;
}

/*member: returnDyn5:Union([exact=JSUInt31], [exact=X])*/
returnDyn5() {
  var a;
  ((a = 52) /*invoke: [exact=JSUInt31]*/ == true) &&
      ((a = new X()) /*invoke: [exact=X]*/ == true);
  return a;
}

/*member: returnDyn6:Union([exact=JSString], [exact=X])*/
returnDyn6() {
  var a;
  a = a == 54 ? 'foo' : new X();
  return a;
}

/*member: returnDyn7b:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn7b(
    /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
  return x;
}

/*member: returnDyn7:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn7() {
  dynamic a = "foo";
  if (a. /*Value([exact=JSString], value: "foo")*/ length
      /*invoke: [subclass=JSInt]*/ ==
      3) {
    a = 52;
  }
  if ((a is int) || (a is String && true)) returnDyn7b(a);
  return a;
}

/*member: returnDyn8:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn8(
    /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
  return x;
}

/*member: test8:Union([exact=JSUInt31], [null|exact=JSString])*/ test8() {
  dynamic a = "foo";
  if (a. /*Value([exact=JSString], value: "foo")*/ length
      /*invoke: [subclass=JSInt]*/ ==
      3) {
    a = 52;
  }
  // ignore: dead_code
  if ((false && a is! String) || returnDyn8(a)) return a;
}

/*member: returnDyn9:Union([exact=JSString], [exact=JSUInt31])*/
returnDyn9(
    /*Union([exact=JSString], [exact=JSUInt31])*/ x) {
  return x;
}

/*member: test9:[null]*/
test9() {
  dynamic a = "foo";
  if (a. /*Value([exact=JSString], value: "foo")*/ length
      /*invoke: [subclass=JSInt]*/ ==
      3) {
    a = 52;
  }
  if (!(a is bool && a is bool)) returnDyn9(a);
}

/*member: returnString:[exact=JSString]*/ returnString(
        /*[exact=JSString]*/ x) =>
    x;

/*member: test10:[null]*/
test10() {
  dynamic a = "foo";
  if (a. /*Value([exact=JSString], value: "foo")*/ length
      /*invoke: [subclass=JSInt]*/ ==
      3) {
    a = 52;
  }
  if (!(a is num) && a is String) returnString(a);
}

/*member: main:[null]*/
main() {
  returnDyn1();
  returnDyn2();
  returnDyn3();
  returnDyn4();
  returnDyn5();
  returnDyn6();
  returnDyn7();
  test8();
  test9();
  test10();
}
