Fix SAM detection algorithm for case of default overrides

#KT-22652 Fixed
This commit is contained in:
Denis Zharkov
2018-03-12 12:14:18 +03:00
parent b4fb0e0305
commit a7854bc0ce
5 changed files with 57 additions and 0 deletions
@@ -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");
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")
@@ -13230,6 +13230,12 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/sam/typeInferenceOnSamAdapters.kt");
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")
@@ -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.
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
return typeConstructor.supertypes.any {
it.constructor.declarationDescriptor.safeAs<LazyJavaClassDescriptor>()?.isDefinitelyNotSamInterface == true