// Generated from "innerclassinitorder/InnerClassInitOrder.java"
@file:Suppress(
 "ALWAYS_NULL",
 "PARAMETER_NAME_CHANGED_ON_OVERRIDE",
 "SENSELESS_COMPARISON",
 "UNCHECKED_CAST",
 "UNNECESSARY_LATEINIT",
 "UNNECESSARY_NOT_NULL_ASSERTION",
 "UNREACHABLE_CODE",
 "UNUSED_ANONYMOUS_PARAMETER",
 "UNUSED_PARAMETER",
 "UNUSED_VARIABLE",
 "USELESS_CAST",
 "VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL",
 "VARIABLE_WITH_REDUNDANT_INITIALIZER",
 "REDUNDANT_ELSE_IN_WHEN")

package innerclassinitorder

import javaemul.lang.*
import kotlin.Any
import kotlin.Array
import kotlin.Int
import kotlin.Suppress
import kotlin.arrayOfNulls
import kotlin.assert
import kotlin.jvm.JvmField

open class InnerClassInitOrder {
 @JvmField
 var number: Int = 0

 open fun testOuterThisFromSuperCall() {
  OuterRefFromSuperCtorCall()
  assert(this.number == 100)
 }

 open fun testOuterThisFromThisCall() {
  OuterRefFromThisCtorCall()
  assert(this.number == 1100)
 }

 open fun testInnerClassCtors() {
  val p1: P1<*> = P1<Any?>()
  assert(1 == p1.value_pp_innerclassinitorder)
  assert(2 == P1<Any?>(2).value_pp_innerclassinitorder)
  val p2: P1<*>.P2<*> = p1.P2<Any?>()
  assert(1 == p2.value_pp_innerclassinitorder)
  assert(2 == p1.P2<Any?>(2).value_pp_innerclassinitorder)
  assert(1 == p2.P3<Any?>().value_pp_innerclassinitorder)
  assert(2 == p2.P3<Any?>(2).value_pp_innerclassinitorder)
 }

 open fun testInnerClassInitialization() {
  InnerClass()
  assert(this.number == 1111)
 }

 open fun testInnerClassLoop() {
  abstract class AddNumber {
   @JvmField
   internal var num_pp_innerclassinitorder: Int = 0

   constructor(i: Int) {
    this.num_pp_innerclassinitorder = i
   }

   abstract fun act()
  }
  val results: Array<AddNumber?> = arrayOfNulls<AddNumber>(10)
  var i: Int = 0
  while (i < 10) {
   val ap: AddNumber = object : AddNumber(i) {
    override fun act() {
     this@InnerClassInitOrder.number = this@InnerClassInitOrder.number + num_pp_innerclassinitorder
    }
   }
   results[i] = ap
   i = i + 1
  }
  for (theAp in results) {
   theAp!!.act()
  }
  assert(this.number == 1156)
 }

 private val outer: Outer? = Outer(1)

 private val outerIsSuper: Outer.OuterIsSuper? = this.outer!!.OuterIsSuper(2)

 open fun testOuterIsNotSuper() {
  val x: Outer.OuterIsNotSuper = this.outerIsSuper!!.OuterIsNotSuper()
  assert(2 == x.getValue())
 }

 open fun testSuperDispatch() {
  assert(1 == this.outerIsSuper!!.checkDispatchFromSub1())
  assert(1 == this.outerIsSuper!!.checkDispatchFromSub2())
 }

 open fun testUnqualifiedAlloc() {
  val x: Outer.OuterIsNotSuper? = this.outerIsSuper!!.unqualifiedAlloc()
  assert(2 == x!!.getValue())
 }

 open fun testUnqualifiedSuperCall() {
  val x: Outer.TestUnqualifiedSuperCall = this.outerIsSuper!!.TestUnqualifiedSuperCall()
  assert(2 == x.getValue())
 }

 open class OuterRefFromSuperCtorBase {
  internal constructor(o: Any?) {
   o!!.hashCode()
  }
 }

 open inner class OuterRefFromSuperCtorCall constructor(): OuterRefFromSuperCtorBase(
  object : Any() {
   override fun hashCode(): Int {
    this@InnerClassInitOrder.number = this@InnerClassInitOrder.number + 100
    return 0
   }
  },
 )

 open inner class OuterRefFromThisCtorCall: OuterRefFromSuperCtorBase {
  constructor(`object`: Any?): super(`object`)

  constructor(): this(
   object : Any() {
    override fun hashCode(): Int {
     this@InnerClassInitOrder.number = this@InnerClassInitOrder.number + 1000
     return 0
    }
   },
  )
 }

 open inner class InnerClass internal constructor() {
  init {
   this.callInner_pp_innerclassinitorder()
  }

  internal open fun callInner_pp_innerclassinitorder() {
   this@InnerClassInitOrder.number = this@InnerClassInitOrder.number + 1
   open class ReallyInnerClass internal constructor() {
    init {
     this.callReallyInner_pp_innerclassinitorder()
    }

    internal open fun callReallyInner_pp_innerclassinitorder() {
     this@InnerClassInitOrder.number = this@InnerClassInitOrder.number + 10
    }
   }
   ReallyInnerClass()
  }
 }

 open class P1<T1> {
  @JvmField
  internal val value_pp_innerclassinitorder: Int

  internal constructor(): this(1)

  internal constructor(i: Int) {
   this.value_pp_innerclassinitorder = i
  }

  open inner class P2<T2>: P1<T1> {
   internal constructor(): this(1)

   internal constructor(i: Int): super(i)

   open inner class P3<T3>: P1<T1>.P2<T2> {
    internal constructor(): this(1)

    internal constructor(i: Int): super(i)
   }
  }
 }

 open class ESOuter internal constructor() {
  open fun newESInner(): ESOuter.ESInner? {
   return ESInner()
  }

  open inner class ESInner {
   @JvmField
   var value: Int = 0

   constructor() {
    this.value = 1
   }

   constructor(value: Int) {
    this.value = value
   }
  }
 }

 open class ESWGOuter<T> internal constructor() {
  open fun newESWGInner(): ESWGOuter<T>.ESWGInner? {
   return ESWGInner()
  }

  open inner class ESWGInner {
   @JvmField
   var value: Int = 0

   constructor() {
    this.value = 1
   }

   constructor(value: Int) {
    this.value = value
   }
  }
 }

 open class Outer {
  @JvmField
  val value: Int

  constructor(i: Int) {
   this.value = i
  }

  open fun checkDispatch(): Int {
   return 1
  }

  open inner class OuterIsNotSuper {
   open fun getValue(): Int {
    return this@Outer.value
   }
  }

  open inner class OuterIsSuper constructor(i: Int): Outer(i) {
   override fun checkDispatch(): Int {
    return 2
   }

   open fun checkDispatchFromSub1(): Int {
    return super<Outer>.checkDispatch()
   }

   open fun checkDispatchFromSub2(): Int {
    return object : Outer(1) {
     fun go(): Int {
      return super<Outer>@OuterIsSuper.checkDispatch()
     }
    }.go()
   }

   open fun unqualifiedAlloc(): Outer.OuterIsNotSuper? {
    return OuterIsNotSuper()
   }
  }

  open inner class TestUnqualifiedSuperCall: Outer.OuterIsNotSuper()
 }
}
