library #lib;
import self as self;
import "dart:core" as core;

class A extends core::Object {
  synthetic constructor •() → self::A*
    : super core::Object::•()
    ;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:1]  get foo() → core::String*
    return "foo";
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:2,getterSelectorId:3]  method getBar() → core::String*
    return "bar";
}
class B extends core::Object /*isEnum*/  {
[@vm.inferred-type.metadata=dart.core::_Smi (value: 1)] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:4] [@vm.unboxing-info.metadata=()->i]  final field core::int* index;
[@vm.inferred-type.metadata=dart.core::_OneByteString (value: "B.b2")] [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,getterSelectorId:5]  final field core::String* _name;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:6,getterSelectorId:7]  method toString() → core::String*
    return [@vm.direct-call.metadata=#lib::B._name] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "B.b2")] this.{self::B::_name};
}
static method test0() → void {
  core::print(#C1);
}
static method test1() → void {
  core::print(#C2);
}
static method test2() → void {
  core::print(#C3);
}
[@vm.unboxing-info.metadata=()->d]static get getD() → dynamic
  return 100.0;
static method testDouble() → void {
  core::print(#C4);
  core::print([@vm.inferred-type.metadata=dart.core::_Double (value: 100.0)] self::getD);
}
static method testStrings([@vm.inferred-type.metadata=#lib::A] self::A* a0) → void {
  core::print([@vm.direct-call.metadata=#lib::A.foo] [@vm.inferred-type.metadata=dart.core::_OneByteString (value: "foo")] a0.{self::A::foo}{core::String*});
  core::print([@vm.direct-call.metadata=#lib::A.getBar] [@vm.inferred-type.metadata=dart.core::_OneByteString (skip check) (value: "bar")] a0.{self::A::getBar}(){() →* core::String*});
  core::print(#C5);
}
static method testPassEnum() → void {
  self::testPassEnum2();
}
static method testPassEnum2() → void {
  core::print(#C8);
}
static method getList() → dynamic
  return #C11;
static method testList() → void {
  core::print(#C11);
  core::print(#C14);
}
static method main() → dynamic {
  self::test0();
  self::test1();
  self::test2();
  self::testDouble();
  self::testStrings(new self::A::•());
  self::testPassEnum();
  let final dynamic #t1 = [@vm.inferred-type.metadata=dart.core::_ImmutableList (value: const <dart.core::int*>[1, 2, 3])] self::getList() in self::testList();
}
