library test;
import self as self;
import "dart:core" as core;

class Index extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
}
class A extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  operator +(self::F v) → self::C
    return null;
  operator -(core::int i) → self::C
    return null;
}
class B extends self::A {
  synthetic constructor •() → void
    : super self::A::•()
    ;
  operator +(self::E v) → self::D
    return null;
  operator -(core::int i) → self::D
    return null;
}
class C extends self::B {
  synthetic constructor •() → void
    : super self::B::•()
    ;
}
class D extends self::C {
  synthetic constructor •() → void
    : super self::C::•()
    ;
}
class E extends self::D {
  synthetic constructor •() → void
    : super self::D::•()
    ;
}
class F extends self::E {
  synthetic constructor •() → void
    : super self::E::•()
    ;
}
class Test extends core::Object {
  synthetic constructor •() → void
    : super core::Object::•()
    ;
  operator [](self::Index i) → self::B
    return null;
  operator []=(self::Index i, self::A v) → void {}
  method test() → void {
    self::Test t = self::f<dynamic>();
    t.[]=(self::f<dynamic>(), self::f<dynamic>());
    let final dynamic #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.[](#t2).==(null) ? let final dynamic #t3 = self::f<dynamic>() in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3 : null;
    let final dynamic #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.[]=(#t6, #t5.[](#t6).+(self::f<dynamic>()));
    let final dynamic #t7 = t in let final dynamic #t8 = self::f<dynamic>() in let final dynamic #t9 = #t7.[](#t8).-(1) in let final dynamic #t10 = #t7.[]=(#t8, #t9) in #t9;
    let final dynamic #t11 = t in let final dynamic #t12 = self::f<dynamic>() in #t11.[]=(#t12, #t11.[](#t12).-(1));
    dynamic v1 = let final dynamic #t13 = t in let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = self::f<dynamic>() in let final dynamic #t16 = #t13.[]=(#t14, #t15) in #t15;
    dynamic v2 = let final dynamic #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = #t17.[](#t18) in #t19.==(null) ? let final dynamic #t20 = self::f<dynamic>() in let final dynamic #t21 = #t17.[]=(#t18, #t20) in #t20 : #t19;
    dynamic v3 = let final dynamic #t22 = t in let final dynamic #t23 = self::f<dynamic>() in let final dynamic #t24 = #t22.[](#t23).+(self::f<dynamic>()) in let final dynamic #t25 = #t22.[]=(#t23, #t24) in #t24;
    dynamic v4 = let final dynamic #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = #t26.[](#t27).-(1) in let final dynamic #t29 = #t26.[]=(#t27, #t28) in #t28;
    dynamic v5 = let final dynamic #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final dynamic #t32 = #t30.[](#t31) in let final dynamic #t33 = #t30.[]=(#t31, #t32.-(1)) in #t32;
  }
}
static method f<T extends core::Object = dynamic>() → self::f::T
  return null;
static method main() → dynamic {}
