Minor. Extract computation of collection mutable stub list
It's necessary in the next commits to obtain these signatures without actually emitting any code
This commit is contained in:
+31
-14
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.FAKE_OVERRIDE
|
||||||
@@ -49,20 +49,27 @@ import java.util.*
|
|||||||
* Kotlin's read-only collections. This is required on JVM because Kotlin's read-only collections are mapped to mutable JDK collections
|
* Kotlin's read-only collections. This is required on JVM because Kotlin's read-only collections are mapped to mutable JDK collections
|
||||||
*/
|
*/
|
||||||
class CollectionStubMethodGenerator(
|
class CollectionStubMethodGenerator(
|
||||||
state: GenerationState,
|
private val typeMapper: KotlinTypeMapper,
|
||||||
private val descriptor: ClassDescriptor,
|
private val descriptor: ClassDescriptor
|
||||||
private val functionCodegen: FunctionCodegen,
|
|
||||||
private val v: ClassBuilder
|
|
||||||
) {
|
) {
|
||||||
private val typeMapper = state.typeMapper
|
private data class TasksToGenerate(
|
||||||
|
val methodStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||||
|
val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>,
|
||||||
|
val bridgesToGenerate: Set<FunctionDescriptor>
|
||||||
|
)
|
||||||
|
|
||||||
fun generate() {
|
companion object {
|
||||||
if (descriptor.kind == ClassKind.INTERFACE) return
|
private val NO_TASKS = TasksToGenerate(emptySet(), emptySet(), emptySet())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun computeTasksToGenerate(): TasksToGenerate {
|
||||||
|
if (descriptor.kind == ClassKind.INTERFACE) return NO_TASKS
|
||||||
val superCollectionClasses = findRelevantSuperCollectionClasses()
|
val superCollectionClasses = findRelevantSuperCollectionClasses()
|
||||||
if (superCollectionClasses.isEmpty()) return
|
if (superCollectionClasses.isEmpty()) return NO_TASKS
|
||||||
|
|
||||||
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
||||||
val syntheticStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
val syntheticStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
|
||||||
|
val bridgesToGenerate = LinkedHashSet<FunctionDescriptor>()
|
||||||
|
|
||||||
for ((readOnlyClass, mutableClass) in superCollectionClasses) {
|
for ((readOnlyClass, mutableClass) in superCollectionClasses) {
|
||||||
// To determine which method stubs we need to generate, we create a synthetic class (named 'child' here) which inherits from
|
// To determine which method stubs we need to generate, we create a synthetic class (named 'child' here) which inherits from
|
||||||
@@ -144,24 +151,34 @@ class CollectionStubMethodGenerator(
|
|||||||
// If the fake override is non-abstract, its implementation is already present in the class or inherited from one of its
|
// If the fake override is non-abstract, its implementation is already present in the class or inherited from one of its
|
||||||
// super classes, but is not related to the MutableCollection hierarchy. So maybe it uses more specific return types
|
// super classes, but is not related to the MutableCollection hierarchy. So maybe it uses more specific return types
|
||||||
// and we may need to generate some bridges
|
// and we may need to generate some bridges
|
||||||
functionCodegen.generateBridges(method)
|
bridgesToGenerate.add(method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TasksToGenerate(methodStubsToGenerate, syntheticStubsToGenerate, bridgesToGenerate)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun generate(functionCodegen: FunctionCodegen, v: ClassBuilder) {
|
||||||
|
val (methodStubsToGenerate, syntheticStubsToGenerate, bridgesToGenerate) = computeTasksToGenerate()
|
||||||
|
|
||||||
for (signature in methodStubsToGenerate) {
|
for (signature in methodStubsToGenerate) {
|
||||||
generateMethodStub(signature, synthetic = false)
|
generateMethodStub(v, signature, synthetic = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (signature in syntheticStubsToGenerate) {
|
for (signature in syntheticStubsToGenerate) {
|
||||||
generateMethodStub(signature, synthetic = true)
|
generateMethodStub(v, signature, synthetic = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (method in bridgesToGenerate) {
|
||||||
|
functionCodegen.generateBridges(method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isDefaultInJdk(method: FunctionDescriptor) =
|
private fun isDefaultInJdk(method: FunctionDescriptor) =
|
||||||
method.modality != Modality.ABSTRACT &&
|
method.modality != Modality.ABSTRACT &&
|
||||||
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
|
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
|
||||||
(it as FunctionDescriptor).kind == FAKE_OVERRIDE || it.isFromBuiltins()
|
it.kind == FAKE_OVERRIDE || it.isFromBuiltins()
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class CollectionClassPair(
|
private data class CollectionClassPair(
|
||||||
@@ -300,7 +317,7 @@ class CollectionStubMethodGenerator(
|
|||||||
|
|
||||||
private fun FunctionDescriptor.signature(): JvmMethodGenericSignature = typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
|
private fun FunctionDescriptor.signature(): JvmMethodGenericSignature = typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
|
||||||
|
|
||||||
private fun generateMethodStub(signature: JvmMethodGenericSignature, synthetic: Boolean) {
|
private fun generateMethodStub(v: ClassBuilder, signature: JvmMethodGenericSignature, synthetic: Boolean) {
|
||||||
assert(descriptor.kind != ClassKind.INTERFACE) { "No stubs should be generated for interface ${descriptor.fqNameUnsafe}" }
|
assert(descriptor.kind != ClassKind.INTERFACE) { "No stubs should be generated for interface ${descriptor.fqNameUnsafe}" }
|
||||||
|
|
||||||
val access = ACC_PUBLIC or (if (synthetic) ACC_SYNTHETIC else 0)
|
val access = ACC_PUBLIC or (if (synthetic) ACC_SYNTHETIC else 0)
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument;
|
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm;
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
|
||||||
@@ -64,7 +63,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.kotlin.types.KotlinType;
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||||
import org.jetbrains.kotlin.utils.StringsKt;
|
|
||||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
@@ -369,7 +367,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
generateFunctionsForDataClasses();
|
generateFunctionsForDataClasses();
|
||||||
|
|
||||||
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
|
new CollectionStubMethodGenerator(typeMapper, descriptor).generate(functionCodegen, v);
|
||||||
|
|
||||||
generateToArray();
|
generateToArray();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user