Generate delegates to DefaultImpls in fun interface wrappers
#KT-37436 Fixed
This commit is contained in:
@@ -93,20 +93,18 @@ object CodegenUtil {
|
||||
private fun mapMembers(
|
||||
inherited: CallableMemberDescriptor,
|
||||
traitMember: CallableMemberDescriptor
|
||||
): LinkedHashMap<FunctionDescriptor, FunctionDescriptor> {
|
||||
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
|
||||
if (traitMember is SimpleFunctionDescriptor) {
|
||||
result[traitMember] = inherited as FunctionDescriptor
|
||||
} else if (traitMember is PropertyDescriptor) {
|
||||
): Map<FunctionDescriptor, FunctionDescriptor> = when (traitMember) {
|
||||
is SimpleFunctionDescriptor -> mapOf(traitMember to inherited as FunctionDescriptor)
|
||||
is PropertyDescriptor -> linkedMapOf<FunctionDescriptor, FunctionDescriptor>().also { result ->
|
||||
for (traitAccessor in traitMember.accessors) {
|
||||
for (inheritedAccessor in (inherited as PropertyDescriptor).accessors) {
|
||||
if (inheritedAccessor::class.java == traitAccessor::class.java) { // same accessor kind
|
||||
result.put(traitAccessor, inheritedAccessor)
|
||||
if ((inheritedAccessor is PropertyGetterDescriptor) == (traitAccessor is PropertyGetterDescriptor)) {
|
||||
result[traitAccessor] = inheritedAccessor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
else -> error("Unexpected member: $inherited")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.common.bridges.ImplKt;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
|
||||
@@ -219,21 +220,32 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
protected void generateDelegatesToDefaultImpl() {
|
||||
if (isJvmInterface(descriptor)) return;
|
||||
|
||||
boolean isErasedInlineClass = InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
JvmKotlinType receiverType = new JvmKotlinType(typeMapper.mapType(descriptor), descriptor.getDefaultType());
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
|
||||
FunctionDescriptor interfaceFun = entry.getKey();
|
||||
//skip java 8 default methods
|
||||
if (!CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) &&
|
||||
!JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(
|
||||
DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(interfaceFun), state.getJvmDefaultMode()
|
||||
)
|
||||
) {
|
||||
generateDelegationToDefaultImpl(interfaceFun, entry.getValue());
|
||||
}
|
||||
generateDelegationToDefaultImpl(entry.getKey(), entry.getValue(), receiverType, functionCodegen, state, isErasedInlineClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDelegationToDefaultImpl(@NotNull FunctionDescriptor interfaceFun, @NotNull FunctionDescriptor inheritedFun) {
|
||||
public static void generateDelegationToDefaultImpl(
|
||||
@NotNull FunctionDescriptor interfaceFun,
|
||||
@NotNull FunctionDescriptor inheritedFun,
|
||||
@NotNull JvmKotlinType receiverType,
|
||||
@NotNull FunctionCodegen functionCodegen,
|
||||
@NotNull GenerationState state,
|
||||
boolean isErasedInlineClass
|
||||
) {
|
||||
// Skip Java 8 default methods
|
||||
if (CodegenUtilKt.isDefinitelyNotDefaultImplsMethod(interfaceFun) ||
|
||||
JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(
|
||||
DescriptorUtils.unwrapFakeOverrideToAnyDeclaration(interfaceFun), state.getJvmDefaultMode()
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
KotlinTypeMapper typeMapper = state.getTypeMapper();
|
||||
functionCodegen.generateMethod(
|
||||
new JvmDeclarationOrigin(
|
||||
CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun, null
|
||||
@@ -248,7 +260,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
|
||||
PsiElement classForInheritedFun = descriptorToDeclaration(declarationInheritedFun);
|
||||
if (classForInheritedFun instanceof KtDeclaration) {
|
||||
codegen.markLineNumber((KtElement) classForInheritedFun, false);
|
||||
codegen.markLineNumber(classForInheritedFun, false);
|
||||
}
|
||||
|
||||
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
|
||||
@@ -282,18 +294,15 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
InstructionAdapter iv = codegen.v;
|
||||
Type[] myArgTypes = signature.getAsmMethod().getArgumentTypes();
|
||||
Type[] toArgTypes = defaultImplsMethod.getArgumentTypes();
|
||||
boolean isErasedInlineClass =
|
||||
InlineClassesUtilsKt.isInlineClass(descriptor) && kind == OwnerKind.ERASED_INLINE_CLASS;
|
||||
|
||||
int myArgI = 0;
|
||||
int argVar = 0;
|
||||
|
||||
Type receiverType = typeMapper.mapType(descriptor);
|
||||
KotlinType interfaceKotlinType = ((ClassDescriptor) inheritedFun.getContainingDeclaration()).getDefaultType();
|
||||
StackValue.local(argVar, receiverType, descriptor.getDefaultType())
|
||||
StackValue.local(argVar, receiverType.getType(), receiverType.getKotlinType())
|
||||
.put(OBJECT_TYPE, interfaceKotlinType, iv);
|
||||
if (isErasedInlineClass) myArgI++;
|
||||
argVar += receiverType.getSize();
|
||||
argVar += receiverType.getType().getSize();
|
||||
|
||||
int toArgI = 1;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader;
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf;
|
||||
import org.jetbrains.kotlin.psi.KtElement;
|
||||
@@ -185,6 +186,13 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
|
||||
generateBridges();
|
||||
generateClosureBody();
|
||||
|
||||
if (samType != null) {
|
||||
ClassDescriptor funInterface = samType.getClassDescriptor();
|
||||
if (!(funInterface instanceof JavaClassDescriptor)) {
|
||||
SamWrapperCodegen.generateDelegatesToDefaultImpl(asmType, classDescriptor, funInterface, functionCodegen, state);
|
||||
}
|
||||
}
|
||||
|
||||
this.constructor = generateConstructor();
|
||||
|
||||
if (isConst(closure)) {
|
||||
|
||||
@@ -70,7 +70,6 @@ import java.io.StringWriter;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.generateBridgeForMainFunctionIfNecessary;
|
||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
|
||||
@@ -1064,18 +1063,6 @@ public class FunctionCodegen {
|
||||
);
|
||||
}
|
||||
|
||||
public static boolean isMethodOfAny(@NotNull FunctionDescriptor descriptor) {
|
||||
String name = descriptor.getName().asString();
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
||||
if (parameters.isEmpty()) {
|
||||
return name.equals("hashCode") || name.equals("toString");
|
||||
}
|
||||
else if (parameters.size() == 1 && name.equals("equals")) {
|
||||
return isNullableAny(parameters.get(0).getType());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String[] getThrownExceptions(@NotNull FunctionDescriptor function, @NotNull KotlinTypeMapper typeMapper) {
|
||||
return ArrayUtil.toStringArray(CollectionsKt.map(
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
@@ -42,6 +44,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
@@ -87,7 +90,7 @@ public class SamWrapperCodegen {
|
||||
|
||||
boolean isKotlinFunInterface = !(samType.getClassDescriptor() instanceof JavaClassDescriptor);
|
||||
|
||||
ClassDescriptor classDescriptor = new ClassDescriptorImpl(
|
||||
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
||||
samType.getClassDescriptor().getContainingDeclaration(),
|
||||
fqName.shortName(),
|
||||
Modality.FINAL,
|
||||
@@ -97,6 +100,8 @@ public class SamWrapperCodegen {
|
||||
/* isExternal = */ false,
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
);
|
||||
classDescriptor.initialize(MemberScope.Empty.INSTANCE, Collections.emptySet(), null);
|
||||
|
||||
// e.g. compare(T, T)
|
||||
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getOriginalAbstractMethod().copy(
|
||||
classDescriptor,
|
||||
@@ -135,12 +140,17 @@ public class SamWrapperCodegen {
|
||||
null);
|
||||
|
||||
generateConstructor(asmType, functionAsmType, cv);
|
||||
generateMethod(asmType, functionAsmType, cv, erasedInterfaceFunction, functionType);
|
||||
|
||||
ClassContext context = state.getRootContext().intoClass(classDescriptor, OwnerKind.IMPLEMENTATION, state);
|
||||
FunctionCodegen functionCodegen = new FunctionCodegen(context, cv, state, parentCodegen);
|
||||
generateMethod(asmType, functionAsmType, erasedInterfaceFunction, functionType, functionCodegen);
|
||||
|
||||
if (isKotlinFunInterface) {
|
||||
generateGetFunctionDelegate(cv, asmType, functionAsmType);
|
||||
generateEquals(cv, asmType, functionAsmType, samAsmType);
|
||||
generateHashCode(cv, asmType, functionAsmType);
|
||||
|
||||
generateDelegatesToDefaultImpl(asmType, classDescriptor, samType.getClassDescriptor(), functionCodegen, state);
|
||||
}
|
||||
|
||||
cv.done();
|
||||
@@ -171,25 +181,22 @@ public class SamWrapperCodegen {
|
||||
}
|
||||
|
||||
private void generateMethod(
|
||||
Type ownerType,
|
||||
Type functionType,
|
||||
ClassBuilder cv,
|
||||
SimpleFunctionDescriptor erasedInterfaceFunction,
|
||||
KotlinType functionJetType
|
||||
@NotNull Type ownerType,
|
||||
@NotNull Type functionType,
|
||||
@NotNull SimpleFunctionDescriptor erasedInterfaceFunction,
|
||||
@NotNull KotlinType functionKotlinType,
|
||||
@NotNull FunctionCodegen functionCodegen
|
||||
) {
|
||||
// using root context to avoid creating ClassDescriptor and everything else
|
||||
FunctionCodegen codegen = new FunctionCodegen(state.getRootContext().intoClass(
|
||||
(ClassDescriptor) erasedInterfaceFunction.getContainingDeclaration(), OwnerKind.IMPLEMENTATION, state), cv, state, parentCodegen);
|
||||
|
||||
FunctionDescriptor invokeFunction =
|
||||
functionJetType.getMemberScope().getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).iterator().next().getOriginal();
|
||||
FunctionDescriptor invokeFunction = functionKotlinType.getMemberScope().getContributedFunctions(
|
||||
OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND
|
||||
).iterator().next().getOriginal();
|
||||
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none());
|
||||
codegen.genSamDelegate(erasedInterfaceFunction, invokeFunction, functionField);
|
||||
functionCodegen.genSamDelegate(erasedInterfaceFunction, invokeFunction, functionField);
|
||||
|
||||
// generate sam bridges
|
||||
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
|
||||
SimpleFunctionDescriptor originalInterfaceErased = samType.getOriginalAbstractMethod();
|
||||
ClosureCodegen.generateBridgesForSAM(originalInterfaceErased, erasedInterfaceFunction, codegen);
|
||||
ClosureCodegen.generateBridgesForSAM(originalInterfaceErased, erasedInterfaceFunction, functionCodegen);
|
||||
}
|
||||
|
||||
private static void generateEquals(
|
||||
@@ -248,6 +255,31 @@ public class SamWrapperCodegen {
|
||||
FunctionCodegen.endVisit(iv, "getFunctionDelegate of SAM wrapper");
|
||||
}
|
||||
|
||||
public static void generateDelegatesToDefaultImpl(
|
||||
@NotNull Type asmType,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull ClassDescriptor funInterface,
|
||||
@NotNull FunctionCodegen functionCodegen,
|
||||
@NotNull GenerationState state
|
||||
) {
|
||||
JvmKotlinType receiverType = new JvmKotlinType(asmType, classDescriptor.getDefaultType());
|
||||
|
||||
for (DeclarationDescriptor descriptor : DescriptorUtils.getAllDescriptors(funInterface.getDefaultType().getMemberScope())) {
|
||||
if (!(descriptor instanceof CallableMemberDescriptor)) continue;
|
||||
CallableMemberDescriptor member = (CallableMemberDescriptor) descriptor;
|
||||
if (member.getModality() == Modality.ABSTRACT ||
|
||||
Visibilities.isPrivate(member.getVisibility()) ||
|
||||
member.getVisibility() == Visibilities.INVISIBLE_FAKE ||
|
||||
DescriptorUtils.isMethodOfAny(member)) continue;
|
||||
|
||||
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.INSTANCE.copyFunctions(
|
||||
member, member, classDescriptor, Modality.OPEN, Visibilities.PUBLIC, CallableMemberDescriptor.Kind.DECLARATION, false
|
||||
).entrySet()) {
|
||||
ClassBodyCodegen.generateDelegationToDefaultImpl(entry.getKey(), entry.getValue(), receiverType, functionCodegen, state, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private FqName getWrapperName(
|
||||
@NotNull KtFile containingFile,
|
||||
|
||||
Generated
+15
@@ -11244,6 +11244,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
@@ -15419,6 +15424,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/inheritedFunctionWithDefaultParameters.kt");
|
||||
@@ -15676,6 +15686,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/inheritedFunctionWithDefaultParameters.kt");
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// !LANGUAGE: +NewInference +FunctionalInterfaceConversion +SamConversionPerArgument +SamConversionForKotlinFunctions
|
||||
|
||||
// IGNORE_BACKEND: JVM, JVM_IR
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// SKIP_DCE_DRIVEN
|
||||
|
||||
@@ -30,4 +29,4 @@ fun box(): String {
|
||||
if (runProxy { 10 } != "10") return "fail2"
|
||||
|
||||
return runBase { "OK" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// IGNORE_BACKEND: JVM_IR, JS_IR
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
|
||||
interface I {
|
||||
fun inherited(s: String): String = privateInherited(s)
|
||||
|
||||
private fun privateInherited(s: String): String = s
|
||||
}
|
||||
|
||||
fun interface F : I {
|
||||
fun invoke(o: String): String
|
||||
|
||||
fun result(): String = inherited(privateFun("O"))
|
||||
|
||||
private fun privateFun(s: String): String = invoke(s)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (F { o -> o + "K" }.result() != "OK") return "Fail"
|
||||
|
||||
val lambda: (String) -> String = { o -> o + "K" }
|
||||
return F(lambda).result()
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// !JVM_DEFAULT_MODE: all-compatibility
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Base {
|
||||
fun f(o: String): String = g(o)
|
||||
|
||||
private fun g(o: String): String = o
|
||||
}
|
||||
|
||||
fun interface F : Base {
|
||||
fun invoke(o: String): String
|
||||
|
||||
fun result(): String = invoke(f("O"))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (F { o -> o + "K" }.result() != "OK") return "Fail"
|
||||
|
||||
val lambda: (String) -> String = { o -> o + "K" }
|
||||
return F(lambda).result()
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// !JVM_DEFAULT_MODE: all
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
interface Base {
|
||||
fun f(o: String): String = g(o)
|
||||
|
||||
private fun g(o: String): String = o
|
||||
}
|
||||
|
||||
fun interface F : Base {
|
||||
fun invoke(o: String): String
|
||||
|
||||
fun result(): String = invoke(f("O"))
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
if (F { o -> o + "K" }.result() != "OK") return "Fail"
|
||||
|
||||
val lambda: (String) -> String = { o -> o + "K" }
|
||||
return F(lambda).result()
|
||||
}
|
||||
+3
@@ -26,5 +26,8 @@ interface Test {
|
||||
// FILE: sam.kt
|
||||
|
||||
fun box(): String {
|
||||
val lambda = { "X" }
|
||||
if (JavaCall().call(lambda) != "X") return "Fail"
|
||||
|
||||
return JavaCall().call {"OK"}
|
||||
}
|
||||
|
||||
+15
@@ -12464,6 +12464,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
@@ -16639,6 +16644,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/inheritedFunctionWithDefaultParameters.kt");
|
||||
@@ -16896,6 +16906,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/inheritedFunctionWithDefaultParameters.kt");
|
||||
|
||||
+20
-5
@@ -12411,11 +12411,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunInterface extends AbstractLightAnalysisModeTest {
|
||||
@TestMetadata("funInterfaceInheritance.kt")
|
||||
public void ignoreFunInterfaceInheritance() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/funInterfaceInheritance.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
@@ -12444,6 +12439,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/funInterface/funConversionInVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterfaceInheritance.kt")
|
||||
public void testFunInterfaceInheritance() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/funInterfaceInheritance.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterfaceWithReceiver.kt")
|
||||
public void testFunInterfaceWithReceiver() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/funInterfaceWithReceiver.kt");
|
||||
@@ -12464,6 +12464,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
@@ -16639,6 +16644,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/inheritedFunctionWithDefaultParameters.kt");
|
||||
@@ -16896,6 +16906,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/inheritedFunctionWithDefaultParameters.kt");
|
||||
|
||||
+15
@@ -11244,6 +11244,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
@@ -15419,6 +15424,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/inheritedFunctionWithDefaultParameters.kt");
|
||||
@@ -15676,6 +15686,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/defaultArgsViaAnonymousObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("funInterface.kt")
|
||||
public void testFunInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/funInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedFunctionWithDefaultParameters.kt")
|
||||
public void testInheritedFunctionWithDefaultParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/inheritedFunctionWithDefaultParameters.kt");
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve;
|
||||
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
@@ -631,7 +629,9 @@ public class DescriptorUtils {
|
||||
: descriptor;
|
||||
}
|
||||
|
||||
public static boolean isMethodOfAny(@NotNull FunctionDescriptor descriptor) {
|
||||
public static boolean isMethodOfAny(@NotNull CallableMemberDescriptor descriptor) {
|
||||
if (!(descriptor instanceof FunctionDescriptor)) return false;
|
||||
|
||||
String name = descriptor.getName().asString();
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
||||
if (parameters.isEmpty()) {
|
||||
|
||||
Generated
+5
@@ -9654,6 +9654,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
|
||||
+5
@@ -9654,6 +9654,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/funInterface/multimodule.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonAbstractMethod.kt")
|
||||
public void testNonAbstractMethod() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nonAbstractMethod.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableSam.kt")
|
||||
public void testNullableSam() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/funInterface/nullableSam.kt");
|
||||
|
||||
Reference in New Issue
Block a user