Minor: reformat and cleanup warnings in CollectionStubMethodGenerator.kt

This commit is contained in:
Dmitry Petrov
2020-09-28 14:02:50 +03:00
parent af1ed77d15
commit 565c156ddb
@@ -52,13 +52,13 @@ 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(
private val typeMapper: KotlinTypeMapper, private val typeMapper: KotlinTypeMapper,
private val descriptor: ClassDescriptor private val descriptor: ClassDescriptor
) { ) {
private data class TasksToGenerate( private data class TasksToGenerate(
val methodStubsToGenerate: Set<JvmMethodGenericSignature>, val methodStubsToGenerate: Set<JvmMethodGenericSignature>,
val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>, val syntheticStubsToGenerate: Set<JvmMethodGenericSignature>,
val bridgesToGenerate: Set<FunctionDescriptor> val bridgesToGenerate: Set<FunctionDescriptor>
) )
companion object { companion object {
@@ -70,9 +70,9 @@ class CollectionStubMethodGenerator(
val superCollectionClasses = findRelevantSuperCollectionClasses() val superCollectionClasses = findRelevantSuperCollectionClasses()
if (superCollectionClasses.isEmpty()) return NO_TASKS if (superCollectionClasses.isEmpty()) return NO_TASKS
val existingMethodsInSuperclasses = descriptor.getAllSuperclassesWithoutAny().flatMap { val existingMethodsInSuperclasses = descriptor.getAllSuperclassesWithoutAny().flatMap { superClass ->
val tasksFromSuperClass = CollectionStubMethodGenerator(typeMapper, it).computeTasksToGenerate() val tasksFromSuperClass = CollectionStubMethodGenerator(typeMapper, superClass).computeTasksToGenerate()
(tasksFromSuperClass.methodStubsToGenerate + tasksFromSuperClass.syntheticStubsToGenerate).map { it.asmMethod } (tasksFromSuperClass.methodStubsToGenerate + tasksFromSuperClass.syntheticStubsToGenerate).map { stub -> stub.asmMethod }
} }
val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>() val methodStubsToGenerate = LinkedHashSet<JvmMethodGenericSignature>()
@@ -126,43 +126,42 @@ class CollectionStubMethodGenerator(
val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo() val genericSignatureInfo = overriddenMethod.getSpecialSignatureInfo()
val specialGenericSignature = val specialGenericSignature =
genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature) genericSignatureInfo?.replaceValueParametersIn(overriddenMethodSignature.genericsSignature)
?: overriddenMethodSignature.genericsSignature ?: overriddenMethodSignature.genericsSignature
val (asmMethod, valueParameters) = val (asmMethod, valueParameters) =
// if current method has special generic signature, // if current method has special generic signature,
// like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)` // like `Collection.remove(E): Boolean` in Kotlin, use original signature to obtain `remove(Object)`
if (genericSignatureInfo?.isObjectReplacedWithTypeParameter ?: false) if (genericSignatureInfo?.isObjectReplacedWithTypeParameter == true)
Pair(originalSignature.asmMethod, originalSignature.valueParameters) Pair(originalSignature.asmMethod, originalSignature.valueParameters)
else else
Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters) Pair(overriddenMethodSignature.asmMethod, overriddenMethodSignature.valueParameters)
JvmMethodGenericSignature( JvmMethodGenericSignature(
asmMethod, asmMethod,
valueParameters, valueParameters,
specialGenericSignature specialGenericSignature
) )
} } else {
else {
method.signature() method.signature()
} }
if (commonSignature.asmMethod !in existingMethodsInSuperclasses && if (commonSignature.asmMethod !in existingMethodsInSuperclasses &&
// If original method already defined in a superclass we mustn't care about specialized version // If original method already defined in a superclass we mustn't care about specialized version
// The same way we do not generate specialized version in a common case like: // The same way we do not generate specialized version in a common case like:
// open class A<T> : MutableList<T> { // open class A<T> : MutableList<T> {
// fun add(x: T) = true // fun add(x: T) = true
// } // }
// class B : A<String>() // No 'B.add(String)Z' // class B : A<String>() // No 'B.add(String)Z'
originalSignature.asmMethod !in existingMethodsInSuperclasses) { originalSignature.asmMethod !in existingMethodsInSuperclasses
) {
methodStubsToGenerate.add(commonSignature) methodStubsToGenerate.add(commonSignature)
if (originalSignature.asmMethod != commonSignature.asmMethod) { if (originalSignature.asmMethod != commonSignature.asmMethod) {
syntheticStubsToGenerate.add(originalSignature) syntheticStubsToGenerate.add(originalSignature)
} }
} }
} } else {
else {
// 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
@@ -192,13 +191,13 @@ class CollectionStubMethodGenerator(
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.kind == FAKE_OVERRIDE || KotlinBuiltIns.isBuiltIn(it) it.kind == FAKE_OVERRIDE || KotlinBuiltIns.isBuiltIn(it)
} }
private data class CollectionClassPair( private data class CollectionClassPair(
val readOnlyClass: TypeConstructor, val readOnlyClass: TypeConstructor,
val mutableClass: TypeConstructor val mutableClass: TypeConstructor
) )
private fun findRelevantSuperCollectionClasses(): Collection<CollectionClassPair> { private fun findRelevantSuperCollectionClasses(): Collection<CollectionClassPair> {
@@ -206,14 +205,14 @@ class CollectionStubMethodGenerator(
val collectionClasses = with(descriptor.builtIns) { val collectionClasses = with(descriptor.builtIns) {
listOf( listOf(
collection to mutableCollection, collection to mutableCollection,
set to mutableSet, set to mutableSet,
list to mutableList, list to mutableList,
map to mutableMap, map to mutableMap,
mapEntry to mutableMapEntry, mapEntry to mutableMapEntry,
iterable to mutableIterable, iterable to mutableIterable,
iterator to mutableIterator, iterator to mutableIterator,
listIterator to mutableListIterator listIterator to mutableListIterator
).map { (readOnly, mutable) -> ).map { (readOnly, mutable) ->
pair(readOnly.typeConstructor, mutable.typeConstructor) pair(readOnly.typeConstructor, mutable.typeConstructor)
} }
@@ -234,15 +233,16 @@ class CollectionStubMethodGenerator(
} }
private fun findFakeOverridesForMethodsFromMutableCollection( private fun findFakeOverridesForMethodsFromMutableCollection(
klass: ClassDescriptor, klass: ClassDescriptor,
mutableCollectionTypeConstructor: TypeConstructor mutableCollectionTypeConstructor: TypeConstructor
): List<FunctionDescriptor> { ): List<FunctionDescriptor> {
val result = ArrayList<FunctionDescriptor>() val result = ArrayList<FunctionDescriptor>()
generateOverridesInAClass(klass, object : NonReportingOverrideStrategy() { generateOverridesInAClass(klass, object : NonReportingOverrideStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) { override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
if (fakeOverride !is FunctionDescriptor) return if (fakeOverride !is FunctionDescriptor) return
val foundOverriddenFromDirectSuperClass = fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionTypeConstructor) ?: return val foundOverriddenFromDirectSuperClass =
fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionTypeConstructor) ?: return
if (foundOverriddenFromDirectSuperClass.kind == DECLARATION) { if (foundOverriddenFromDirectSuperClass.kind == DECLARATION) {
// For regular classes there should no be fake overrides having return types incompatible with return types of their // For regular classes there should no be fake overrides having return types incompatible with return types of their
// overridden, while here it's possible to create declaration like `fun remove(e: E): ImmutableCollection<E>` // overridden, while here it's possible to create declaration like `fun remove(e: E): ImmutableCollection<E>`
@@ -254,23 +254,29 @@ class CollectionStubMethodGenerator(
// `fun iterator(): CharIterator` defined in read-only collection // `fun iterator(): CharIterator` defined in read-only collection
// The problem is that 'CharIterator' is not a subtype of 'MutableIterator' while from Java's point of view it is, // The problem is that 'CharIterator' is not a subtype of 'MutableIterator' while from Java's point of view it is,
// so we must hack our subtyping a little bit // so we must hack our subtyping a little bit
val newDescriptor = val newDescriptor =
if (READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf( if (READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(
fakeOverride.returnType!!, foundOverriddenFromDirectSuperClass.returnType!!)) fakeOverride.returnType!!,
fakeOverride foundOverriddenFromDirectSuperClass.returnType!!
else )
foundOverriddenFromDirectSuperClass.copy( )
fakeOverride.containingDeclaration, fakeOverride
foundOverriddenFromDirectSuperClass.modality, else
foundOverriddenFromDirectSuperClass.visibility, foundOverriddenFromDirectSuperClass.copy(
fakeOverride.kind, false) fakeOverride.containingDeclaration,
foundOverriddenFromDirectSuperClass.modality,
foundOverriddenFromDirectSuperClass.visibility,
fakeOverride.kind, false
)
newDescriptor.overriddenDescriptors = newDescriptor.overriddenDescriptors =
fakeOverride.overriddenDescriptors.filter { fakeOverride.overriddenDescriptors.filter { superDescriptor ->
superDescriptor -> // filter out incompatible descriptors, e.g. `fun remove(e: E): ImmutableCollection<E>` for `fun remove(e: E): Boolean`
// filter out incompatible descriptors, e.g. `fun remove(e: E): ImmutableCollection<E>` for `fun remove(e: E): Boolean` READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(
READ_ONLY_ARE_EQUAL_TO_MUTABLE_TYPE_CHECKER.isSubtypeOf(newDescriptor.returnType!!, superDescriptor.returnType!!) newDescriptor.returnType!!,
} superDescriptor.returnType!!
)
}
result.add(newDescriptor) result.add(newDescriptor)
} }
@@ -298,11 +304,11 @@ class CollectionStubMethodGenerator(
private fun generateOverridesInAClass(classDescriptor: ClassDescriptor, strategy: OverridingStrategy) { private fun generateOverridesInAClass(classDescriptor: ClassDescriptor, strategy: OverridingStrategy) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val membersFromSupertypesByName = val membersFromSupertypesByName =
classDescriptor.typeConstructor.supertypes.flatMapTo(linkedSetOf()) { type -> classDescriptor.typeConstructor.supertypes.flatMapTo(linkedSetOf()) { type ->
DescriptorUtils.getAllDescriptors(type.memberScope).filter { DescriptorUtils.getAllDescriptors(type.memberScope).filter {
it is PropertyDescriptor || it is SimpleFunctionDescriptor it is PropertyDescriptor || it is SimpleFunctionDescriptor
} as List<CallableMemberDescriptor> } as List<CallableMemberDescriptor>
}.groupBy { it.name } }.groupBy { it.name }
for ((name, fromSupertypes) in membersFromSupertypesByName) { for ((name, fromSupertypes) in membersFromSupertypesByName) {
OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(name, fromSupertypes, emptyList(), classDescriptor, strategy) OverridingUtil.DEFAULT.generateOverridesInFunctionGroup(name, fromSupertypes, emptyList(), classDescriptor, strategy)
@@ -330,15 +336,16 @@ class CollectionStubMethodGenerator(
} }
private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(typeConstructor: TypeConstructor): FunctionDescriptor? = private fun FunctionDescriptor.findOverriddenFromDirectSuperClass(typeConstructor: TypeConstructor): FunctionDescriptor? =
this.overriddenDescriptors.firstOrNull { this.overriddenDescriptors.firstOrNull {
(it.containingDeclaration as? ClassDescriptor)?.typeConstructor == typeConstructor (it.containingDeclaration as? ClassDescriptor)?.typeConstructor == typeConstructor
} }
private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType { private fun newType(classDescriptor: ClassDescriptor, typeArguments: List<TypeProjection>): KotlinType {
return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, classDescriptor, typeArguments) return KotlinTypeFactory.simpleNotNullType(Annotations.EMPTY, classDescriptor, typeArguments)
} }
private fun FunctionDescriptor.signature(): JvmMethodGenericSignature = typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION) private fun FunctionDescriptor.signature(): JvmMethodGenericSignature =
typeMapper.mapSignatureWithGeneric(this, OwnerKind.IMPLEMENTATION)
private fun generateMethodStub(v: ClassBuilder, 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}" }
@@ -349,9 +356,10 @@ class CollectionStubMethodGenerator(
val mv = v.newMethod(CollectionStub, access, asmMethod.name, asmMethod.descriptor, genericSignature, null) val mv = v.newMethod(CollectionStub, access, asmMethod.name, asmMethod.descriptor, genericSignature, null)
mv.visitCode() mv.visitCode()
AsmUtil.genThrow( AsmUtil.genThrow(
InstructionAdapter(mv), InstructionAdapter(mv),
"java/lang/UnsupportedOperationException", "java/lang/UnsupportedOperationException",
"Operation is not supported for read-only collection") "Operation is not supported for read-only collection"
)
FunctionCodegen.endVisit(mv, "built-in stub for $signature") FunctionCodegen.endVisit(mv, "built-in stub for $signature")
} }
} }