Optimize isDefinitelyNotSamInterface
Do not generate intermediate garbage and no reason to iterate over
all non-SAM candidates when more than one found
#KTIJ-23032
diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/SyntheticJavaClassDescriptor.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/SyntheticJavaClassDescriptor.kt
index 875d91a..22a6566 100644
--- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/SyntheticJavaClassDescriptor.kt
+++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/SyntheticJavaClassDescriptor.kt
@@ -105,7 +105,6 @@
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 @@
// 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