Kapt3: Fix a number of errors in ClassFileToSourceStubConverter:
1. Support strictfp modifier for methods. 2. Support Kotlin top-level methods and properties. 3. Fix visibility modifiers on enum methods.
This commit is contained in:
committed by
Yan Zhulanow
parent
e22ce14c36
commit
1f1491f1ca
+17
-10
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.kapt3.*
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker
|
||||
import org.jetbrains.kotlin.kapt3.javac.KaptJavaFileObject
|
||||
@@ -48,7 +49,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
|
||||
(Opcodes.ACC_DEPRECATED or Opcodes.ACC_INTERFACE or Opcodes.ACC_ANNOTATION or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong()
|
||||
|
||||
private val METHOD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
|
||||
(Opcodes.ACC_DEPRECATED or Opcodes.ACC_SYNCHRONIZED or Opcodes.ACC_NATIVE or Opcodes.ACC_STATIC).toLong()
|
||||
(Opcodes.ACC_DEPRECATED or Opcodes.ACC_SYNCHRONIZED or Opcodes.ACC_NATIVE or Opcodes.ACC_STATIC or Opcodes.ACC_STRICT).toLong()
|
||||
|
||||
private val FIELD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
|
||||
(Opcodes.ACC_VOLATILE or Opcodes.ACC_TRANSIENT or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong()
|
||||
@@ -78,12 +79,11 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
|
||||
|
||||
private fun convertTopLevelClass(clazz: ClassNode): JCCompilationUnit? {
|
||||
val origin = kaptContext.origins[clazz] ?: return null
|
||||
// ?
|
||||
val ktFile = origin.element?.containingFile as? KtFile ?: return null
|
||||
val descriptor = origin.descriptor as? ClassDescriptor ?: return null
|
||||
val descriptor = origin.descriptor as? DeclarationDescriptor ?: return null
|
||||
|
||||
// Nested classes will be processed during the outer classes conversion
|
||||
if (descriptor.isNested) return null
|
||||
if ((descriptor as? ClassDescriptor)?.isNested ?: false) return null
|
||||
|
||||
val classDeclaration = convertClass(clazz) ?: return null
|
||||
|
||||
@@ -106,9 +106,12 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
|
||||
private fun convertClass(clazz: ClassNode): JCClassDecl? {
|
||||
if (isSynthetic(clazz.access)) return null
|
||||
|
||||
val descriptor = kaptContext.origins[clazz]?.descriptor as? ClassDescriptor ?: return null
|
||||
val descriptor = kaptContext.origins[clazz]?.descriptor as? DeclarationDescriptor ?: return null
|
||||
val isNested = (descriptor as? ClassDescriptor)?.isNested ?: false
|
||||
val isInner = isNested && (descriptor as? ClassDescriptor)?.isInner ?: false
|
||||
|
||||
val modifiers = convertModifiers(
|
||||
if (!descriptor.isInner && descriptor.isNested) (clazz.access or Opcodes.ACC_STATIC) else clazz.access,
|
||||
if (!isInner && isNested) (clazz.access or Opcodes.ACC_STATIC) else clazz.access,
|
||||
ElementKind.CLASS, clazz.visibleAnnotations, clazz.invisibleAnnotations)
|
||||
|
||||
val isEnum = clazz.isEnum()
|
||||
@@ -116,6 +119,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
|
||||
|
||||
val isDefaultImpls = clazz.name.endsWith("${descriptor.name.asString()}/DefaultImpls")
|
||||
&& isPublic(clazz.access) && isFinal(clazz.access)
|
||||
&& descriptor is ClassDescriptor
|
||||
&& descriptor.kind == ClassKind.INTERFACE
|
||||
|
||||
// DefaultImpls without any contents don't have INNERCLASS'es inside it (and inside the parent interface)
|
||||
@@ -195,13 +199,16 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContext, val typeMappe
|
||||
method.visibleAnnotations
|
||||
}
|
||||
|
||||
val modifiers = convertModifiers(
|
||||
if (containingClass.isEnum()) (method.access.toLong() and VISIBILITY_MODIFIERS.inv()) else method.access.toLong(),
|
||||
ElementKind.METHOD, visibleAnnotations, method.invisibleAnnotations)
|
||||
|
||||
val isConstructor = method.name == "<init>"
|
||||
val name = treeMaker.name(method.name)
|
||||
|
||||
val modifiers = convertModifiers(
|
||||
if (containingClass.isEnum() && isConstructor)
|
||||
(method.access.toLong() and VISIBILITY_MODIFIERS.inv())
|
||||
else
|
||||
method.access.toLong(),
|
||||
ElementKind.METHOD, visibleAnnotations, method.invisibleAnnotations)
|
||||
|
||||
val returnType = Type.getReturnType(method.desc)
|
||||
val jcReturnType = if (isConstructor) null else treeMaker.Type(returnType)
|
||||
|
||||
|
||||
+42
@@ -31,6 +31,12 @@ import java.util.regex.Pattern;
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFileToSourceStubConverterTest {
|
||||
@TestMetadata("abstractMethods.kt")
|
||||
public void testAbstractMethods() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/abstractMethods.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInConverter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/testData/converter"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
@@ -41,6 +47,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("annotations2.kt")
|
||||
public void testAnnotations2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/annotations2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("dataClass.kt")
|
||||
public void testDataClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/dataClass.kt");
|
||||
@@ -65,6 +77,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericRawSignatures.kt")
|
||||
public void testGenericRawSignatures() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/genericRawSignatures.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("genericSimple.kt")
|
||||
public void testGenericSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/genericSimple.kt");
|
||||
@@ -83,9 +101,33 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("jvmStaticFieldInParent.kt")
|
||||
public void testJvmStaticFieldInParent() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/jvmStaticFieldInParent.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("modifiers.kt")
|
||||
public void testModifiers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/modifiers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClasses.kt")
|
||||
public void testNestedClasses() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/nestedClasses.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("strangeNames.kt")
|
||||
public void testStrangeNames() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/strangeNames.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("topLevel.kt")
|
||||
public void testTopLevel() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/topLevel.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
abstract class Base {
|
||||
protected abstract fun doJob(job: String, delay: Int)
|
||||
protected abstract fun <T : CharSequence> doJobGeneric(job: T, delay: Int)
|
||||
}
|
||||
|
||||
class Impl : Base() {
|
||||
override fun doJob(job: String, delay: Int) {}
|
||||
override fun <T : CharSequence> doJobGeneric(job: T, delay: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
public abstract class Base {
|
||||
|
||||
protected abstract void doJob(java.lang.String job, int delay);
|
||||
|
||||
protected abstract <T extends java.lang.CharSequence>void doJobGeneric(T job, int delay);
|
||||
|
||||
public Base() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
public final class Impl extends Base {
|
||||
|
||||
@java.lang.Override()
|
||||
protected void doJob(java.lang.String job, int delay) {
|
||||
}
|
||||
|
||||
@java.lang.Override()
|
||||
protected <T extends java.lang.CharSequence>void doJobGeneric(T job, int delay) {
|
||||
}
|
||||
|
||||
public Impl() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
@file:kotlin.jvm.JvmName("AnnotationsTest")
|
||||
package test
|
||||
|
||||
@Anno("anno-class")
|
||||
annotation class Anno @Anno("anno-constructor") constructor(
|
||||
@Anno("anno-value") val value: String,
|
||||
val anno: Anno = Anno("anno-default")
|
||||
)
|
||||
|
||||
@Anno("clazz")
|
||||
abstract class Test @Anno("test-constructor") protected constructor(@param:Anno("v-param")
|
||||
@setparam:Anno("v-setparam")
|
||||
@property:Anno("v-property")
|
||||
@get:Anno("v-get")
|
||||
@set:Anno("v-set") var v: String) {
|
||||
@Anno("abstract-method")
|
||||
abstract fun abstractMethod(): String
|
||||
|
||||
@Anno("abstract-val")
|
||||
abstract val abstractVal: String
|
||||
}
|
||||
|
||||
@Anno("top-level-fun")
|
||||
fun @receiver:Anno("top-level-fun-receiver") String.topLevelFun() {}
|
||||
|
||||
@Anno("top-level-val")
|
||||
val @receiver:Anno("top-level-val-receiver") Int.topLevelVal: String
|
||||
get() = ""
|
||||
|
||||
@Anno("enum")
|
||||
enum class Enum @Anno("enum-constructor") constructor(@Anno("x") val x: Int) {
|
||||
@Anno("white") WHITE(1), @Anno("black") BLACK(2)
|
||||
}
|
||||
+3
@@ -7,4 +7,7 @@ annotation class Anno1(val value: String)
|
||||
enum class Enum2(@Anno1("first") val col: String, @Anno1("second") val col2: Int) {
|
||||
RED("red", 1), WHITE("white", 2);
|
||||
fun color() = col
|
||||
|
||||
private fun privateEnumFun() {}
|
||||
public fun publicEnumFun() {}
|
||||
}
|
||||
+9
-3
@@ -23,15 +23,21 @@ public enum Enum2 {
|
||||
private final java.lang.String col = null;
|
||||
private final int col2 = 0;
|
||||
|
||||
final java.lang.String color() {
|
||||
public final java.lang.String color() {
|
||||
return null;
|
||||
}
|
||||
|
||||
final java.lang.String getCol() {
|
||||
private final void privateEnumFun() {
|
||||
}
|
||||
|
||||
public final void publicEnumFun() {
|
||||
}
|
||||
|
||||
public final java.lang.String getCol() {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int getCol2() {
|
||||
public final int getCol2() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
class GenericRawSignatures {
|
||||
fun <T> genericFun(): T? = null
|
||||
fun nonGenericFun(): String? = null
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
public final class GenericRawSignatures {
|
||||
|
||||
public final <T extends java.lang.Object>T genericFun() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final java.lang.String nonGenericFun() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public GenericRawSignatures() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class Test {
|
||||
companion object A {
|
||||
@JvmStatic
|
||||
val test: String = ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
public final class Test {
|
||||
private static final java.lang.String test = "";
|
||||
public static final Test.A A = null;
|
||||
|
||||
public Test() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static final java.lang.String getTest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final class A {
|
||||
|
||||
public final java.lang.String getTest() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private A() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package modifiers
|
||||
|
||||
public class PublicClass public constructor()
|
||||
|
||||
public open class PublicClassProtectedConstructor protected constructor() {
|
||||
protected interface ProtectedInterface
|
||||
private interface PrivateInterface
|
||||
}
|
||||
|
||||
public abstract class PublicClassPrivateConstructor private constructor()
|
||||
internal class InternalClass
|
||||
private class PrivateClass
|
||||
|
||||
public interface PublicInterface
|
||||
internal interface InternalInterface
|
||||
private interface PrivateInterface
|
||||
|
||||
sealed class SealedClass {
|
||||
class One : SealedClass()
|
||||
open class Two : SealedClass()
|
||||
abstract class Three : Two()
|
||||
final class Four : Three()
|
||||
}
|
||||
|
||||
class Modifiers {
|
||||
@Transient
|
||||
val transientField: String = ""
|
||||
|
||||
@Volatile
|
||||
var volatileField: String = ""
|
||||
|
||||
@Strictfp
|
||||
fun strictFp() {}
|
||||
|
||||
@JvmOverloads
|
||||
fun overloads(a: String = "", n: Int = 5): String = null!!
|
||||
}
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
package modifiers;
|
||||
|
||||
public final class PublicClass {
|
||||
|
||||
public PublicClass() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public class PublicClassProtectedConstructor {
|
||||
|
||||
protected PublicClassProtectedConstructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected static abstract interface ProtectedInterface {
|
||||
}
|
||||
|
||||
private static abstract interface PrivateInterface {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public abstract class PublicClassPrivateConstructor {
|
||||
|
||||
private PublicClassPrivateConstructor() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public final class InternalClass {
|
||||
|
||||
public InternalClass() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
final class PrivateClass {
|
||||
|
||||
public PrivateClass() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public abstract interface PublicInterface {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public abstract interface InternalInterface {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
abstract interface PrivateInterface {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public abstract class SealedClass {
|
||||
|
||||
private SealedClass() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static final class One extends modifiers.SealedClass {
|
||||
|
||||
public One() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static class Two extends modifiers.SealedClass {
|
||||
|
||||
public Two() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Three extends modifiers.SealedClass.Two {
|
||||
|
||||
public Three() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Four extends modifiers.SealedClass.Three {
|
||||
|
||||
public Four() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package modifiers;
|
||||
|
||||
public final class Modifiers {
|
||||
private final transient java.lang.String transientField = "";
|
||||
private volatile java.lang.String volatileField;
|
||||
|
||||
public final java.lang.String getTransientField() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final java.lang.String getVolatileField() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void setVolatileField(java.lang.String p0) {
|
||||
}
|
||||
|
||||
public final strictfp void strictFp() {
|
||||
}
|
||||
|
||||
public final java.lang.String overloads(java.lang.String a, int n) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final java.lang.String overloads(java.lang.String p0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final java.lang.String overloads() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Modifiers() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class `My $ name` {
|
||||
fun `(^_^)`(`)))))`: Int) {}
|
||||
|
||||
// unicode symbol •
|
||||
val `(@•@)`: String = ""
|
||||
|
||||
// russian
|
||||
val `Котлин-компилятор`: String = ""
|
||||
|
||||
// japanese hiragana
|
||||
fun `こ と り ん!`() {}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
public final class My $ name {
|
||||
private final java.lang.String (@\u2022@) = "";
|
||||
private final java.lang.String \u041a\u043e\u0442\u043b\u0438\u043d-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 = "";
|
||||
|
||||
public final void (^_^)(int )))))) {
|
||||
}
|
||||
|
||||
public final java.lang.String get(@\u2022@)() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final java.lang.String get\u041a\u043e\u0442\u043b\u0438\u043d-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public final void \u3053\u3000\u3068\u3000\u308a\u3000\u3093\uff01() {
|
||||
}
|
||||
|
||||
public My $ name() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package test.another
|
||||
|
||||
annotation class Anno(val value: String)
|
||||
|
||||
fun topLevelFunction(): String? = null
|
||||
|
||||
fun <X : CharSequence, T : List<out X>> topLevelGenericFunction(): T? {
|
||||
return null!!
|
||||
}
|
||||
|
||||
val topLevelProperty = 2
|
||||
|
||||
val topLevelProperty2: String
|
||||
get() = ""
|
||||
|
||||
fun @receiver:Anno("rec") String.extensionFunction(@Anno("1") a: String, @Anno("2") b: String) {}
|
||||
|
||||
@Anno("extpr")
|
||||
var <T: Any> @receiver:Anno("propRec") T.extensionProperty: String
|
||||
get() = ""
|
||||
set(@Anno("setparam") setParamName) {}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package test.another;
|
||||
|
||||
public abstract @interface Anno {
|
||||
|
||||
public abstract java.lang.String value();
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package test.another;
|
||||
|
||||
public final class another {
|
||||
|
||||
public another() {
|
||||
super();
|
||||
}
|
||||
private static final int topLevelProperty = 2;
|
||||
|
||||
public static final java.lang.String topLevelFunction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final <X extends java.lang.CharSequence, T extends java.util.List<? extends X>>T topLevelGenericFunction() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final int getTopLevelProperty() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final java.lang.String getTopLevelProperty2() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final void extensionFunction(@test.another.Anno(value = "rec")
|
||||
java.lang.String $receiver, @test.another.Anno(value = "1")
|
||||
java.lang.String a, @test.another.Anno(value = "2")
|
||||
java.lang.String b) {
|
||||
}
|
||||
|
||||
public static final <T extends java.lang.Object>java.lang.String getExtensionProperty(@test.another.Anno(value = "propRec")
|
||||
T $receiver) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final <T extends java.lang.Object>void setExtensionProperty(@test.another.Anno(value = "propRec")
|
||||
T $receiver, @test.another.Anno(value = "setparam")
|
||||
java.lang.String setParamName) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user