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:
Denis Zharkov
2016-10-05 11:08:36 +03:00
parent 56ecbe52b2
commit d2de4579de
2 changed files with 32 additions and 17 deletions
@@ -16,7 +16,7 @@
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.CallableMemberDescriptor.Kind.DECLARATION
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
*/
class CollectionStubMethodGenerator(
state: GenerationState,
private val descriptor: ClassDescriptor,
private val functionCodegen: FunctionCodegen,
private val v: ClassBuilder
private val typeMapper: KotlinTypeMapper,
private val descriptor: ClassDescriptor
) {
private val typeMapper = state.typeMapper
private data class TasksToGenerate(
val methodStubsToGenerate: Set<JvmMethodGenericSignature>,
val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>,
val bridgesToGenerate: Set<FunctionDescriptor>
)
fun generate() {
if (descriptor.kind == ClassKind.INTERFACE) return
companion object {
private val NO_TASKS = TasksToGenerate(emptySet(), emptySet(), emptySet())
}
private fun computeTasksToGenerate(): TasksToGenerate {
if (descriptor.kind == ClassKind.INTERFACE) return NO_TASKS
val superCollectionClasses = findRelevantSuperCollectionClasses()
if (superCollectionClasses.isEmpty()) return
if (superCollectionClasses.isEmpty()) return NO_TASKS
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
val syntheticStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
val bridgesToGenerate = LinkedHashSet<FunctionDescriptor>()
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
@@ -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
// 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
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) {
generateMethodStub(signature, synthetic = false)
generateMethodStub(v, signature, synthetic = false)
}
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) =
method.modality != Modality.ABSTRACT &&
method.original.overriddenTreeUniqueAsSequence(useOriginal = true).all {
(it as FunctionDescriptor).kind == FAKE_OVERRIDE || it.isFromBuiltins()
it.kind == FAKE_OVERRIDE || it.isFromBuiltins()
}
private data class CollectionClassPair(
@@ -300,7 +317,7 @@ class CollectionStubMethodGenerator(
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}" }
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.VarargValueArgument;
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.JvmDeclarationOriginKt;
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.types.KotlinType;
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.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
@@ -369,7 +367,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
generateFunctionsForDataClasses();
new CollectionStubMethodGenerator(state, descriptor, functionCodegen, v).generate();
new CollectionStubMethodGenerator(typeMapper, descriptor).generate(functionCodegen, v);
generateToArray();