Fix SAM detection algorithm for case of default overrides
#KT-22652 Fixed
This commit is contained in:
@@ -0,0 +1,22 @@
|
|||||||
|
// FILE: ALambda.java
|
||||||
|
|
||||||
|
public interface ALambda {
|
||||||
|
ALambda curried();
|
||||||
|
|
||||||
|
ALambda tupled();
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: ACheckedFunction0.java
|
||||||
|
|
||||||
|
public interface ACheckedFunction0 extends ALambda {
|
||||||
|
|
||||||
|
Integer apply();
|
||||||
|
|
||||||
|
default ALambda curried() { return null; }
|
||||||
|
default ALambda tupled() { return null; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: main.kt
|
||||||
|
fun test() {
|
||||||
|
ACheckedFunction0 { 2 } // error: Interface ACheckedFunction0 does not have constructors
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
|
public interface ACheckedFunction0 : ALambda {
|
||||||
|
public abstract fun apply(): kotlin.Int!
|
||||||
|
public open override /*1*/ fun curried(): ALambda!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public open override /*1*/ fun tupled(): ALambda!
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ALambda {
|
||||||
|
public abstract fun curried(): ALambda!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public abstract fun tupled(): ALambda!
|
||||||
|
}
|
||||||
@@ -13230,6 +13230,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withDefaultMethods.kt")
|
||||||
|
public void testWithDefaultMethods() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/withDefaultMethods.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
||||||
|
|||||||
Generated
+6
@@ -13230,6 +13230,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("withDefaultMethods.kt")
|
||||||
|
public void testWithDefaultMethods() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/withDefaultMethods.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
@TestMetadata("compiler/testData/diagnostics/tests/j+k/samByProjectedType")
|
||||||
|
|||||||
+3
@@ -140,6 +140,9 @@ class LazyJavaClassDescriptor(
|
|||||||
// we'll just say that the interface MAY BE a SAM when it's not and then more detailed check will be applied.
|
// 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
|
if (candidates.count { it.name.identifier !in PUBLIC_METHOD_NAMES_IN_OBJECT } > 1) return 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
|
||||||
|
|
||||||
// Check if any of the super-interfaces contain too many methods to be a SAM
|
// Check if any of the super-interfaces contain too many methods to be a SAM
|
||||||
return typeConstructor.supertypes.any {
|
return typeConstructor.supertypes.any {
|
||||||
it.constructor.declarationDescriptor.safeAs<LazyJavaClassDescriptor>()?.isDefinitelyNotSamInterface == true
|
it.constructor.declarationDescriptor.safeAs<LazyJavaClassDescriptor>()?.isDefinitelyNotSamInterface == true
|
||||||
|
|||||||
Reference in New Issue
Block a user