JVM: Rewrite companion object accessor generation

Old version handled only private companions correctly.
Some situations require multiple companion object accessors
(including accessors for protected companion objects from supertypes)
to be generated in the corresponding class.
This commit is contained in:
Dmitry Petrov
2020-01-11 00:56:04 +03:00
parent 04a6f4d92b
commit 6ad159bb01
23 changed files with 1009 additions and 101 deletions
@@ -0,0 +1,37 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: accessFromInlineLambda.kt
import c.C
fun box() = C().test()
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
open class B : A() {
protected companion object {
fun getK() = "K"
}
}
// FILE: c.kt
package c
import b.B
inline fun runStr(fn: () -> String) = fn()
class C : B() {
val test = { runStr { getO() + getK() } }
}
@@ -0,0 +1,37 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: anonymousObjectInPropertyInitializer.kt
import c.C
fun box() = C().test.toString()
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
open class B : A() {
protected companion object {
fun getK() = "K"
}
}
// FILE: c.kt
package c
import b.B
class C {
val test = object : B() {
override fun toString() = getO() + getK()
}
}
@@ -0,0 +1,34 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: fromAnonymousObjectInNestedClass.kt
import outer.*
fun box() = Outer().test()
// FILE: Outer.kt
package outer
import a.A
class Outer : A() {
private companion object {
fun getK() = "K"
}
class Nested {
fun foo() = object {
override fun toString() = getO() + getK()
}
}
fun test() = Nested().foo().toString()
}
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
@@ -0,0 +1,31 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// FILE: fromInitBlock.kt
import outer.*
fun box() = Outer().test
// FILE: Outer.kt
package outer
import a.*
class Outer : A() {
private companion object {
fun getK() = "K"
}
val test: String
init {
test = getO() + getK()
}
}
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
@@ -0,0 +1,33 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// FILE: fromInitBlockOfNestedClass.kt
import b.*
fun box() = Outer.Nested().test
// FILE: b.kt
package b
import a.*
class Outer : A() {
private companion object {
fun getK() = "K"
}
class Nested {
val test: String
init {
test = getO() + getK()
}
}
}
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
@@ -0,0 +1,35 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: fromInlineLambdaInNestedClass.kt
import b.*
fun box() = Outer().test()
// FILE: a.kt
package a
open class A {
protected companion object {
val vo = "O"
}
}
// FILE: b.kt
package b
import a.*
inline fun <T> run(fn: () -> T) = fn()
class Outer : A() {
private companion object {
val vk = "K"
}
class Nested {
fun foo() = run { vo + vk }
}
fun test() = Nested().foo()
}
@@ -0,0 +1,28 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: inheritedProtectedCompanionAndOwnPrivateCompanion.kt
import b.B
fun box() = B().test()()
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
class B : A() {
fun test() = { getO() + getK() }
private companion object {
fun getK() = "K"
}
}
@@ -0,0 +1,36 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: twoInheritedProtectedCompanions.kt
import c.C
fun box() = C().test()()
// FILE: a.kt
package a
open class A {
protected companion object AC {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
open class B : A() {
protected companion object BC {
fun getK() = "K"
}
}
// FILE: c.kt
package c
import a.A
import b.B
class C : B() {
fun test() = { A.AC.getO() + B.BC.getK() }
}
@@ -0,0 +1,35 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: lambdaInPropertyInitializer.kt
import c.C
fun box() = C().test()
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
open class B : A() {
protected companion object {
fun getK() = "K"
}
}
// FILE: c.kt
package c
import b.B
class C : B() {
val test = { getO() + getK() }
}
@@ -0,0 +1,35 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: twoInheritedProtectedCompanions.kt
import c.C
fun box() = C().test()()
// FILE: a.kt
package a
open class A {
protected companion object {
fun getO() = "O"
}
}
// FILE: b.kt
package b
import a.A
open class B : A() {
protected companion object {
fun getK() = "K"
}
}
// FILE: c.kt
package c
import b.B
class C : B() {
fun test() = { getO() + getK() }
}
@@ -0,0 +1,26 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: withCompanionObjectBase.kt
import b.*
fun box() = B.ok
// FILE: a.kt
package a
open class A {
protected companion object {
fun getOK() = "OK"
}
}
// FILE: b.kt
package b
import a.*
class B {
companion object : A() {
val ok = getOK()
}
}
@@ -0,0 +1,44 @@
// !LANGUAGE: +ProperVisibilityForCompanionObjectInstanceField
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: withCompanionObjectBase.kt
import b.*
fun box() = B.vok
// FILE: a.kt
package a
open class A1 {
protected companion object {
fun getO() = "O"
}
}
open class A2 {
protected companion object {
fun getK() = "K"
}
}
// FILE: b.kt
package b
import a.*
class B {
class B1 {
companion object : A1() {
val vo = getO()
}
class B2 {
companion object : A2() {
val vk = getK()
}
}
}
companion object {
val vok = B1.vo + B1.B2.vk
}
}