Kapt3: Call super class constructor with some default parameters.
Allow interface, annotation, enum modifiers on class.
This commit is contained in:
committed by
Yan Zhulanow
parent
edaadb0d48
commit
10cfde4ab9
@@ -58,6 +58,10 @@ public class ClassFileFactory implements OutputFileCollection {
|
||||
this.builderFactory = builderFactory;
|
||||
}
|
||||
|
||||
public GenerationState getGenerationState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ClassBuilder newVisitor(
|
||||
@NotNull JvmDeclarationOrigin origin,
|
||||
|
||||
@@ -23,8 +23,10 @@ import com.sun.tools.javac.util.Context
|
||||
import com.sun.tools.javac.util.Name
|
||||
import com.sun.tools.javac.util.Names
|
||||
import com.sun.tools.javac.util.SharedNameTable
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -32,12 +34,18 @@ import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import javax.lang.model.element.ElementKind
|
||||
import com.sun.tools.javac.util.List as JavacList
|
||||
|
||||
class JCTreeConverter(context: Context, val classes: List<ClassNode>, val origins: Map<Any, JvmDeclarationOrigin>) {
|
||||
class JCTreeConverter(
|
||||
context: Context,
|
||||
val typeMapper: KotlinTypeMapper,
|
||||
val classes: List<ClassNode>,
|
||||
val origins: Map<Any, JvmDeclarationOrigin>
|
||||
) {
|
||||
private companion object {
|
||||
private val VISIBILITY_MODIFIERS = Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED
|
||||
private val MODALITY_MODIFIERS = Opcodes.ACC_FINAL or Opcodes.ACC_ABSTRACT
|
||||
|
||||
private val CLASS_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or Opcodes.ACC_DEPRECATED
|
||||
private val CLASS_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
|
||||
Opcodes.ACC_DEPRECATED or Opcodes.ACC_INTERFACE or Opcodes.ACC_ANNOTATION or Opcodes.ACC_ENUM
|
||||
|
||||
private val METHOD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
|
||||
Opcodes.ACC_SYNCHRONIZED or Opcodes.ACC_STATIC or Opcodes.ACC_NATIVE or Opcodes.ACC_DEPRECATED
|
||||
@@ -72,7 +80,7 @@ class JCTreeConverter(context: Context, val classes: List<ClassNode>, val origin
|
||||
// Nested classes will be processed during the outer classes conversion
|
||||
if (descriptor.containingDeclaration is ClassDescriptor) return null
|
||||
|
||||
val classDeclaration = convert(clazz)
|
||||
val classDeclaration = convertClass(clazz)
|
||||
|
||||
val packageAnnotations = JavacList.nil<JCAnnotation>()
|
||||
val packageName = ktFile.packageFqName.asString()
|
||||
@@ -87,7 +95,7 @@ class JCTreeConverter(context: Context, val classes: List<ClassNode>, val origin
|
||||
/**
|
||||
* Returns false for the inner classe or if the origin for the class was not found.
|
||||
*/
|
||||
private fun convert(clazz: ClassNode): JCClassDecl? {
|
||||
private fun convertClass(clazz: ClassNode): JCClassDecl? {
|
||||
if (isSynthetic(clazz.access)) return null
|
||||
|
||||
val descriptor = origins[clazz]?.descriptor as? ClassDescriptor ?: return null
|
||||
@@ -102,7 +110,7 @@ class JCTreeConverter(context: Context, val classes: List<ClassNode>, val origin
|
||||
val nestedClasses = mapValues<InnerClassNode, JCTree>(clazz.innerClasses) { innerClass ->
|
||||
if (innerClass.outerName != clazz.name) return@mapValues null
|
||||
val innerClassNode = classes.firstOrNull { it.name == innerClass.name } ?: return@mapValues null
|
||||
convert(innerClassNode)
|
||||
convertClass(innerClassNode)
|
||||
}
|
||||
|
||||
return treeMaker.ClassDef(modifiers, simpleName, typeParams, extending, implementing, fields + methods + nestedClasses)
|
||||
@@ -150,7 +158,20 @@ class JCTreeConverter(context: Context, val classes: List<ClassNode>, val origin
|
||||
val body = if (defaultValue != null) {
|
||||
null
|
||||
} else if (isConstructor) {
|
||||
var statements = JavacList.nil<JCStatement>()
|
||||
// We already checked it in convertClass()
|
||||
val declaration = origins[containingClass]?.descriptor as ClassDescriptor
|
||||
val superClass = declaration.getSuperClassOrAny()
|
||||
val superClassConstructor = superClass.constructors.firstOrNull { it.visibility.isVisible(null, it, declaration) }
|
||||
|
||||
var statements = if (superClassConstructor != null) {
|
||||
val args = mapValues(superClassConstructor.valueParameters) { param ->
|
||||
convertLiteralExpression(getDefaultValue(typeMapper.mapType(param.type)))
|
||||
}
|
||||
val call = treeMaker.Apply(JavacList.nil(), convertSimpleName("super"), args)
|
||||
JavacList.of<JCStatement>(treeMaker.Exec(call))
|
||||
} else {
|
||||
JavacList.nil<JCStatement>()
|
||||
}
|
||||
|
||||
for (field in containingClass.fields) {
|
||||
if ((field.access and Opcodes.ACC_FINAL) == 0) continue
|
||||
|
||||
@@ -34,10 +34,11 @@ abstract class AbstractJCTreeConverterTest : CodegenTestCase() {
|
||||
|
||||
val txtFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
|
||||
val classBuilderFactory = Kapt3BuilderFactory()
|
||||
CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||
val factory = CodegenTestUtil.generateFiles(myEnvironment, myFiles, classBuilderFactory)
|
||||
val typeMapper = factory.generationState.typeMapper
|
||||
|
||||
val kaptRunner = KaptRunner()
|
||||
val converter = JCTreeConverter(kaptRunner.context, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||
val converter = JCTreeConverter(kaptRunner.context, typeMapper, classBuilderFactory.compiledClasses, classBuilderFactory.origins)
|
||||
val javaFiles = converter.convert()
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(txtFile, javaFiles.joinToString("\n\n////////////////////\n\n"))
|
||||
|
||||
@@ -40,4 +40,10 @@ public class JCTreeConverterTestGenerated extends AbstractJCTreeConverterTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/dataClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("inheritanceSimple.kt")
|
||||
public void testInheritanceSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/inheritanceSimple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
interface Context
|
||||
|
||||
enum class Result {
|
||||
SUCCESS, ERROR
|
||||
}
|
||||
|
||||
abstract class BaseClass(context: Context, num: Int, bool: Boolean) {
|
||||
abstract fun doJob(): Result
|
||||
}
|
||||
|
||||
class Inheritor(context: Context) : BaseClass(context, 5, true) {
|
||||
override fun doJob() = Result.SUCCESS
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
public abstract interface Context {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
public final class Context {
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
public enum Result extends java.lang.Enum {
|
||||
;
|
||||
public static final Result SUCCESS;
|
||||
public static final Result ERROR;
|
||||
|
||||
protected /*missing*/ Result(@java.lang.Synthetic()
|
||||
java.lang.String $enum_name_or_ordinal$0, @java.lang.Synthetic()
|
||||
int $enum_name_or_ordinal$1) {
|
||||
super(null, 0);
|
||||
this.SUCCESS = null;
|
||||
this.ERROR = null;
|
||||
}
|
||||
|
||||
public static Result[] values() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Result valueOf(java.lang.String p0) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
public abstract class BaseClass {
|
||||
|
||||
public abstract Result doJob() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public /*missing*/ BaseClass(Context context, int num, boolean bool) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
public final class Inheritor extends BaseClass {
|
||||
|
||||
public Result doJob() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public /*missing*/ Inheritor(Context context) {
|
||||
super(null, 0, false);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user