Serialize secondary constructors
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
open class A {
|
||||
val prop: String
|
||||
constructor(x1: String, x2: String = "abc") {
|
||||
prop = "$x1#$x2"
|
||||
}
|
||||
constructor(x1: Long) {
|
||||
prop = "$x1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import java.lang
|
||||
|
||||
class B1() : A("123") {
|
||||
constructor(x1: Int): this() {}
|
||||
}
|
||||
|
||||
class B2 : A {
|
||||
constructor(x1: String): super(x1) {}
|
||||
constructor(): this("empty") {}
|
||||
constructor(x1: Int): super(x1.toLong()) {}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val b1 = B1()
|
||||
if (b1.prop != "123#abc") throw AssertionError("fail1: ${b1.prop}")
|
||||
val b2 = B1(456)
|
||||
if (b2.prop != "123#abc") throw AssertionError("fail2: ${b2.prop}")
|
||||
|
||||
val b3 = B2("cde")
|
||||
if (b3.prop != "cde#abc") throw AssertionError("fail3: ${b3.prop}")
|
||||
val b4 = B2()
|
||||
if (b4.prop != "empty#abc") throw AssertionError("fail4: ${b4.prop}")
|
||||
val b5 = B2(789)
|
||||
if (b5.prop != "789") throw AssertionError("fail5: ${b5.prop}")
|
||||
}
|
||||
+6
@@ -144,6 +144,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("SecondaryConstructors.A.kt")
|
||||
public void testSecondaryConstructors() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/SecondaryConstructors.A.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("Simple.A.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/Simple.A.kt");
|
||||
|
||||
@@ -201,7 +201,7 @@ message Class {
|
||||
|
||||
// This field is present if and only if the class has a primary constructor
|
||||
optional PrimaryConstructor primary_constructor = 13;
|
||||
// todo: other constructors?
|
||||
repeated Callable secondary_constructor = 14;
|
||||
|
||||
extensions 100 to 199;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,10 @@ public class DescriptorSerializer {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: other constructors
|
||||
for (ConstructorDescriptor constructorDescriptor : classDescriptor.getConstructors()) {
|
||||
if (constructorDescriptor.isPrimary()) continue;
|
||||
builder.addSecondaryConstructor(callableProto(constructorDescriptor));
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : sort(classDescriptor.getDefaultType().getMemberScope().getAllDescriptors())) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
|
||||
+3
-4
@@ -31,7 +31,6 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
return when (callableKind) {
|
||||
FUN -> loadFunction(proto)
|
||||
VAL, VAR -> loadProperty(proto)
|
||||
CONSTRUCTOR -> loadConstructor(proto)
|
||||
else -> throw IllegalArgumentException("Unsupported callable kind: $callableKind")
|
||||
}
|
||||
}
|
||||
@@ -143,11 +142,11 @@ public class MemberDeserializer(private val c: DeserializationContext) {
|
||||
return (c.containingDeclaration as? ClassDescriptor)?.getThisAsReceiverParameter()
|
||||
}
|
||||
|
||||
private fun loadConstructor(proto: Callable): CallableMemberDescriptor {
|
||||
public fun loadConstructor(proto: Callable, isPrimary: Boolean): ConstructorDescriptor {
|
||||
val classDescriptor = c.containingDeclaration as ClassDescriptor
|
||||
val descriptor = ConstructorDescriptorImpl.create(
|
||||
classDescriptor, getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION), // TODO: primary
|
||||
true, SourceElement.NO_SOURCE
|
||||
classDescriptor, getAnnotations(proto, proto.getFlags(), AnnotatedCallableKind.FUNCTION),
|
||||
isPrimary, SourceElement.NO_SOURCE
|
||||
)
|
||||
val local = c.childContext(descriptor, listOf())
|
||||
descriptor.initialize(
|
||||
|
||||
+12
-6
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.serialization.deserialization
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.utils.singletonOrEmptyList
|
||||
import java.util.*
|
||||
|
||||
public class DeserializedClassDescriptor(
|
||||
@@ -62,6 +63,7 @@ public class DeserializedClassDescriptor(
|
||||
|
||||
private val containingDeclaration = outerContext.containingDeclaration
|
||||
private val primaryConstructor = c.storageManager.createNullableLazyValue { computePrimaryConstructor() }
|
||||
private val constructors = c.storageManager.createLazyValue { computeConstructors() }
|
||||
private val defaultObjectDescriptor = c.storageManager.createNullableLazyValue { computeDefaultObjectDescriptor() }
|
||||
|
||||
private val annotations =
|
||||
@@ -102,16 +104,20 @@ public class DeserializedClassDescriptor(
|
||||
return descriptor
|
||||
}
|
||||
|
||||
return c.memberDeserializer.loadCallable(constructorProto.getData()) as ConstructorDescriptor
|
||||
return c.memberDeserializer.loadConstructor(constructorProto.getData(), true)
|
||||
}
|
||||
|
||||
override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = primaryConstructor()
|
||||
|
||||
override fun getConstructors(): Collection<ConstructorDescriptor> {
|
||||
val constructor = getUnsubstitutedPrimaryConstructor() ?: return listOf()
|
||||
// TODO: other constructors
|
||||
return listOf(constructor)
|
||||
}
|
||||
private fun computeConstructors(): Collection<ConstructorDescriptor> =
|
||||
computeSecondaryConstructors() + getUnsubstitutedPrimaryConstructor().singletonOrEmptyList()
|
||||
|
||||
private fun computeSecondaryConstructors(): List<ConstructorDescriptor> =
|
||||
classProto.getSecondaryConstructorList().map {
|
||||
c.memberDeserializer.loadConstructor(it, false)
|
||||
}
|
||||
|
||||
override fun getConstructors() = constructors()
|
||||
|
||||
private fun computeDefaultObjectDescriptor(): ClassDescriptor? {
|
||||
if (!classProto.hasDefaultObjectName()) return null
|
||||
|
||||
@@ -103,3 +103,5 @@ public fun <E> newHashSetWithExpectedSize(expectedSize: Int): HashSet<E> {
|
||||
|
||||
public fun <T> Collection<T>.toReadOnlyList(): List<T> =
|
||||
if (isEmpty()) Collections.emptyList() else ArrayList(this)
|
||||
|
||||
public fun <T: Any> T?.singletonOrEmptyList(): List<T> = if (this != null) Collections.singletonList(this) else Collections.emptyList()
|
||||
|
||||
Reference in New Issue
Block a user