Kapt: Preserve parameter names for abstract methods

This commit is contained in:
Yan Zhulanow
2017-05-19 18:16:26 +03:00
committed by Yan Zhulanow
parent 18e17a4400
commit 5ec16167bc
7 changed files with 71 additions and 10 deletions
@@ -70,7 +70,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor {
// So we just do it here // So we just do it here
if (methodNode.instructions.size() == 0 if (methodNode.instructions.size() == 0
// MethodNode does not create a list of variables for abstract methods, so we would get NPE in accept() instead // MethodNode does not create a list of variables for abstract methods, so we would get NPE in accept() instead
&& (!(delegate instanceof MethodNode) || (methodNode.access & Opcodes.ACC_ABSTRACT) == 0) && (!(delegate instanceof MethodNode) || methodNode.localVariables != null)
) { ) {
List<LocalVariableNode> localVariables = methodNode.localVariables; List<LocalVariableNode> localVariables = methodNode.localVariables;
// visits local variables // visits local variables
@@ -21,12 +21,8 @@ import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.ClassBuilderFactory import org.jetbrains.kotlin.codegen.ClassBuilderFactory
import org.jetbrains.kotlin.codegen.ClassBuilderMode import org.jetbrains.kotlin.codegen.ClassBuilderMode
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.org.objectweb.asm.ClassWriter import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.FieldVisitor import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.tree.ClassNode
import org.jetbrains.org.objectweb.asm.tree.FieldNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
internal class Kapt3BuilderFactory : ClassBuilderFactory { internal class Kapt3BuilderFactory : ClassBuilderFactory {
internal val compiledClasses = mutableListOf<ClassNode>() internal val compiledClasses = mutableListOf<ClassNode>()
@@ -65,6 +61,12 @@ internal class Kapt3BuilderFactory : ClassBuilderFactory {
): MethodVisitor { ): MethodVisitor {
val methodNode = super.newMethod(origin, access, name, desc, signature, exceptions) as MethodNode val methodNode = super.newMethod(origin, access, name, desc, signature, exceptions) as MethodNode
origins.put(methodNode, origin) origins.put(methodNode, origin)
// ASM doesn't read information about local variables for the `abstract` methods so we need to get it manually
if ((access and Opcodes.ACC_ABSTRACT) != 0 && methodNode.localVariables == null) {
methodNode.localVariables = mutableListOf<LocalVariableNode>()
}
return methodNode return methodNode
} }
} }
@@ -186,6 +186,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
doTest(fileName); doTest(fileName);
} }
@TestMetadata("methodParameterNames.kt")
public void testMethodParameterNames() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/methodParameterNames.kt");
doTest(fileName);
}
@TestMetadata("methodPropertySignatureClash.kt") @TestMetadata("methodPropertySignatureClash.kt")
public void testMethodPropertySignatureClash() throws Exception { public void testMethodPropertySignatureClash() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/methodPropertySignatureClash.kt"); String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/methodPropertySignatureClash.kt");
+2 -2
View File
@@ -1,10 +1,10 @@
public abstract class Base { public abstract class Base {
protected abstract void doJob(@org.jetbrains.annotations.NotNull() protected abstract void doJob(@org.jetbrains.annotations.NotNull()
java.lang.String p0, int p1); java.lang.String job, int delay);
protected abstract <T extends java.lang.CharSequence>void doJobGeneric(@org.jetbrains.annotations.NotNull() protected abstract <T extends java.lang.CharSequence>void doJobGeneric(@org.jetbrains.annotations.NotNull()
T p0, int p1); T job, int delay);
public Base() { public Base() {
super(); super();
+1 -1
View File
@@ -2,7 +2,7 @@ public abstract interface EntryHolder {
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public abstract java.util.Map.Entry<java.lang.String, java.lang.Object> entry(@org.jetbrains.annotations.NotNull() public abstract java.util.Map.Entry<java.lang.String, java.lang.Object> entry(@org.jetbrains.annotations.NotNull()
java.util.Map.Entry<? extends java.lang.CharSequence, ? extends java.util.Map.Entry<java.lang.String, java.lang.Integer>> p0); java.util.Map.Entry<? extends java.lang.CharSequence, ? extends java.util.Map.Entry<java.lang.String, java.lang.Integer>> p);
@org.jetbrains.annotations.NotNull() @org.jetbrains.annotations.NotNull()
public abstract java.util.Map.Entry<java.lang.String, java.lang.Object> getEntryProperty(); public abstract java.util.Map.Entry<java.lang.String, java.lang.Object> getEntryProperty();
@@ -0,0 +1,15 @@
interface Intf {
fun foo(abc: String)
fun bar(bcd: Int): String {
return ""
}
}
abstract class Cls {
abstract fun foo(abc: String)
fun bar(bcd: Int): String {
return ""
}
}
@@ -0,0 +1,38 @@
public abstract class Cls {
public abstract void foo(@org.jetbrains.annotations.NotNull()
java.lang.String abc);
@org.jetbrains.annotations.NotNull()
public final java.lang.String bar(int bcd) {
return null;
}
public Cls() {
super();
}
}
////////////////////
public abstract interface Intf {
public abstract void foo(@org.jetbrains.annotations.NotNull()
java.lang.String abc);
@org.jetbrains.annotations.NotNull()
public abstract java.lang.String bar(int bcd);
public static final class DefaultImpls {
public DefaultImpls() {
super();
}
@org.jetbrains.annotations.NotNull()
public static java.lang.String bar(Intf $this, int bcd) {
return null;
}
}
}