Optimize isDefinitelyNotSamInterface

Do not generate intermediate garbage and no reason to iterate over
all non-SAM candidates when more than one found

#KTIJ-23032
This commit is contained in:
Vladimir Dolzhenko
2023-01-03 14:08:18 +01:00
committed by teamcity
parent 397cafcbe8
commit d6e587171e
@@ -105,7 +105,6 @@ class SyntheticJavaClassDescriptor(
override fun isDefinitelyNotSamInterface(): Boolean {
if (classKind != ClassKind.INTERFACE) return true
val candidates = jClass.methods.filter { it.isAbstract && it.typeParameters.isEmpty() }
// From the definition of function interfaces in the Java specification (pt. 9.8):
// "methods that are members of I that do not have the same signature as any public instance method of the class Object"
// It means that if an interface declares `int hashCode()` then the method won't be taken into account when
@@ -113,7 +112,18 @@ class SyntheticJavaClassDescriptor(
// We make here a conservative check just filtering out methods by name.
// If we ignore a method with wrong signature (different from one in Object) it's not very bad,
// we'll just say that the interface MAY BE a SAM when it's not and then more detailed check will be applied.
if (candidates.count { it.name.identifier !in PUBLIC_METHOD_NAMES_IN_OBJECT } > 1) return true
var foundSamMethod = false
for (method in jClass.methods) {
if (method.isAbstract && method.typeParameters.isEmpty() &&
method.name.identifier !in PUBLIC_METHOD_NAMES_IN_OBJECT
) {
// found 2nd method candidate
if (foundSamMethod) {
return true
}
foundSamMethod = true
}
}
// If we have default methods the interface could be a SAM even while a super interface has more than one abstract method
if (jClass.methods.any { !it.isAbstract && it.typeParameters.isEmpty() }) return false