Make function delegated to sam adapter synthetic

This commit is contained in:
Natalia Ukhorskaya
2016-02-12 15:54:57 +03:00
parent 7fb1848bd5
commit 42927bb078
8 changed files with 77 additions and 2 deletions
@@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.constants.ArrayValue;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.KClassValue;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
@@ -155,6 +156,11 @@ public class FunctionCodegen {
Method asmMethod = jvmSignature.getAsmMethod();
int flags = getMethodAsmFlags(functionDescriptor, contextKind);
if (origin.getOriginKind() == JvmDeclarationOriginKind.SAM_DELEGATION) {
flags |= ACC_SYNTHETIC;
}
boolean isNative = NativeKt.hasNativeAnnotation(functionDescriptor);
if (isNative && owner instanceof MultifileClassFacadeContext) {
@@ -923,19 +929,42 @@ public class FunctionCodegen {
iv.visitLabel(afterBarrier);
}
public void genSamDelegate(@NotNull FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {
FunctionDescriptor delegatedTo = overriddenDescriptor.getOriginal();
JvmDeclarationOrigin declarationOrigin =
JvmDeclarationOriginKt.SamDelegation(functionDescriptor);
genDelegate(
functionDescriptor, delegatedTo,
declarationOrigin,
(ClassDescriptor) overriddenDescriptor.getContainingDeclaration(),
field);
}
public void genDelegate(@NotNull FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenDescriptor, StackValue field) {
genDelegate(functionDescriptor, overriddenDescriptor.getOriginal(),
(ClassDescriptor) overriddenDescriptor.getContainingDeclaration(), field);
}
public void genDelegate(
@NotNull FunctionDescriptor delegateFunction,
FunctionDescriptor delegatedTo,
ClassDescriptor toClass,
StackValue field
) {
JvmDeclarationOrigin declarationOrigin =
JvmDeclarationOriginKt.Delegation(DescriptorToSourceUtils.descriptorToDeclaration(delegatedTo), delegateFunction);
genDelegate(delegateFunction, delegatedTo, declarationOrigin, toClass, field);
}
private void genDelegate(
@NotNull final FunctionDescriptor delegateFunction,
final FunctionDescriptor delegatedTo,
@NotNull JvmDeclarationOrigin declarationOrigin,
final ClassDescriptor toClass,
final StackValue field
) {
generateMethod(
JvmDeclarationOriginKt.Delegation(DescriptorToSourceUtils.descriptorToDeclaration(delegatedTo), delegateFunction), delegateFunction,
declarationOrigin, delegateFunction,
new FunctionGenerationStrategy() {
@Override
public void generateBody(
@@ -152,7 +152,7 @@ public class SamWrapperCodegen {
FunctionDescriptor invokeFunction =
functionJetType.getMemberScope().getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND).iterator().next().getOriginal();
StackValue functionField = StackValue.field(functionType, ownerType, FUNCTION_FIELD_NAME, false, StackValue.none());
codegen.genDelegate(erasedInterfaceFunction, invokeFunction, functionField);
codegen.genSamDelegate(erasedInterfaceFunction, invokeFunction, functionField);
// generate sam bridges
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
@@ -34,6 +34,7 @@ enum class JvmDeclarationOriginKind {
INTERFACE_DEFAULT_IMPL,
DELEGATION_TO_DEFAULT_IMPLS,
DELEGATION,
SAM_DELEGATION,
BRIDGE,
MULTIFILE_CLASS,
MULTIFILE_CLASS_PART,
@@ -78,4 +79,6 @@ fun DelegationToTraitImpl(element: PsiElement?, descriptor: FunctionDescriptor):
fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(DELEGATION, element, descriptor)
fun SamDelegation(descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SAM_DELEGATION, null, descriptor)
fun Synthetic(element: PsiElement?, descriptor: CallableMemberDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(SYNTHETIC, element, descriptor)
+15
View File
@@ -0,0 +1,15 @@
LineBreakpoint created at samAdapter.kt:5
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! samAdapter.SamAdapterKt
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
samAdapter.kt:5
samAdapter.kt:6
samAdapter.kt:10
MyJavaClass.java:20
samAdapter.kt:6
MyJavaClass.java:20
samAdapter.kt:10
samAdapter.kt:6
samAdapter.kt:7
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
Process finished with exit code 0
@@ -0,0 +1,5 @@
package forTests;
public interface Computable <T> {
T compute();
}
@@ -15,4 +15,8 @@ public class MyJavaClass {
public static int staticFun(Object s) {
return 1;
}
public static <T> T runReadAction(@NotNull Computable<T> computation) {
return computation.compute();
}
}
@@ -0,0 +1,13 @@
package samAdapter
fun main(args: Array<String>) {
//Breakpoint!
val a = 1
runReadAction { 1 }
}
fun runReadAction(action: () -> Int): Int {
return forTests.MyJavaClass.runReadAction<Int>(action)
}
// STEP_INTO: 8
@@ -241,6 +241,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
doStepIntoTest(fileName);
}
@TestMetadata("samAdapter.kt")
public void testSamAdapter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepInto/samAdapter.kt");
doStepIntoTest(fileName);
}
@TestMetadata("skipSimpleGetter.kt")
public void testSkipSimpleGetter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/stepInto/skipSimpleGetter.kt");