Private constructors are now accessed via synthetic constructor with DEFAULT_CONSTRUCTOR_MARKER as an additional argument #KT-6299 Fixed
A set of tests provided. Some external tests fixed accordingly. Companion object creation changed accordingly. Derived classes now can use base class with the private constructor. Refactoring of AccessorForFunctionDescriptor.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor() {
|
||||
class Inner: Outer()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.Inner()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor() {
|
||||
companion object {
|
||||
fun foo() = Outer()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.foo()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor() {
|
||||
companion object {
|
||||
inline fun foo() = Outer()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.foo()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val s: String) {
|
||||
inner class Inner: Outer("O") {
|
||||
fun foo(): String {
|
||||
return this.s + this@Outer.s
|
||||
}
|
||||
}
|
||||
class Nested: Outer("K")
|
||||
fun bar() = Inner()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val inner = Outer.Nested().bar()
|
||||
return inner.foo()
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val x: Int) {
|
||||
constructor(): this(42)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val s: String, val f: Boolean = true) {
|
||||
class Inner: Outer("xyz")
|
||||
class Other: Outer("abc", true)
|
||||
class Another: Outer("", false)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.Inner()
|
||||
val other = Outer.Other()
|
||||
val another = Outer.Another()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val x: Int = 0) {
|
||||
class Inner: Outer()
|
||||
class Other: Outer(42)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.Inner()
|
||||
val other = Outer.Other()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val p: Outer?) {
|
||||
object First: Outer(null)
|
||||
class Other(p: Outer = First): Outer(p)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val second = Outer.Other()
|
||||
val third = Outer.Other(second)
|
||||
val fourth = Outer.Other(third)
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val p: Outer?) {
|
||||
object Inner: Outer(null)
|
||||
object Other: Outer(Inner)
|
||||
object Another: Outer(Other)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.Inner
|
||||
val other = Outer.Other
|
||||
val another = Outer.Another
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// See also KT-6299
|
||||
public open class Outer private constructor(val s: String, vararg i: Int) {
|
||||
class Inner: Outer("xyz")
|
||||
class Other: Outer("abc", 1, 2, 3)
|
||||
class Another: Outer("", 42)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val outer = Outer.Inner()
|
||||
val other = Outer.Other()
|
||||
val another = Outer.Another()
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// private constructors are transformed into synthetic
|
||||
class PrivateConstructor private constructor() {
|
||||
class Nested { val a = PrivateConstructor() }
|
||||
}
|
||||
|
||||
fun check(klass: Class<*>) {
|
||||
var hasSynthetic = false
|
||||
var hasSimple = false
|
||||
for (method in klass.getDeclaredConstructors()) {
|
||||
if (method.isSynthetic()) {
|
||||
hasSynthetic = true
|
||||
}
|
||||
else {
|
||||
hasSimple = true
|
||||
}
|
||||
}
|
||||
if (hasSynthetic && hasSimple) return
|
||||
throw AssertionError("Class should have both synthetic and non-synthetic constructor: ($hasSynthetic, $hasSimple)")
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
check(javaClass<PrivateConstructor>())
|
||||
// Also check that synthetic accessors really work
|
||||
PrivateConstructor.Nested()
|
||||
return "OK"
|
||||
}
|
||||
@@ -2,10 +2,6 @@
|
||||
// This is crucial for some JVM frameworks like Quasar which rely on the bytecode being similar to the one generated by javac
|
||||
// See https://youtrack.jetbrains.com/issue/KT-6870
|
||||
|
||||
class PrivateConstructor private constructor() {
|
||||
class Nested { val a = PrivateConstructor() }
|
||||
}
|
||||
|
||||
class PrivatePropertyGet {
|
||||
private val x = 42
|
||||
|
||||
@@ -33,13 +29,11 @@ fun check(klass: Class<*>) {
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
check(javaClass<PrivateConstructor>())
|
||||
check(javaClass<PrivatePropertyGet>())
|
||||
check(javaClass<PrivatePropertySet>())
|
||||
check(javaClass<PrivateMethod>())
|
||||
|
||||
// Also check that synthetic accessors really work
|
||||
PrivateConstructor.Nested()
|
||||
PrivatePropertyGet().Inner()
|
||||
PrivatePropertySet().Inner()
|
||||
PrivateMethod().Inner()
|
||||
|
||||
@@ -4,4 +4,4 @@ class A {
|
||||
}
|
||||
}
|
||||
// A and companion object constructor call
|
||||
// 2 ALOAD 0
|
||||
// 3 ALOAD 0
|
||||
+1
-1
@@ -4,5 +4,5 @@ class A {
|
||||
}
|
||||
}
|
||||
// A and companion object constructor call
|
||||
// 2 ALOAD 0
|
||||
// 3 ALOAD 0
|
||||
// 1 synthetic access\$getR
|
||||
|
||||
Reference in New Issue
Block a user