[KAPT] Some optimizations for stubs generation

* Add index to resolve compiled class by name
* Disable full property resolution
This commit is contained in:
Andrey Zinovyev
2021-03-03 12:05:49 +03:00
committed by GitHub
parent 08446e2371
commit b128577508
10 changed files with 99 additions and 10 deletions
@@ -85,7 +85,12 @@ open class PartialAnalysisHandlerExtension : AnalysisHandlerExtension {
if (declaration is KtProperty) {
/* TODO Now we analyse body with anonymous object initializers. Check if we can't avoid it
* val a: Runnable = object : Runnable { ... } */
bodyResolver.resolveProperty(topDownAnalysisContext, declaration, descriptor)
//resolve property in case it has delegate expression or explicit accessor, otherwise just infer type
if (declaration.delegateExpression != null || declaration.accessors.isNotEmpty()) {
bodyResolver.resolveProperty(topDownAnalysisContext, declaration, descriptor)
} else {
BodyResolver.computeDeferredType(descriptor.returnType)
}
}
}
is FunctionDescriptor -> {
@@ -138,4 +143,4 @@ open class PartialAnalysisHandlerExtension : AnalysisHandlerExtension {
}
}
}
}
@@ -1018,7 +1018,7 @@ public class BodyResolver {
valueParameterResolver.resolveValueParameters(valueParameters, valueParameterDescriptors, scope, outerDataFlowInfo, trace);
}
private static void computeDeferredType(KotlinType type) {
public static void computeDeferredType(KotlinType type) {
// handle type inference loop: function or property body contains a reference to itself
// fun f() = { f() }
// val x = x
@@ -134,6 +134,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
private val importsFromRoot by lazy(::collectImportsFromRootPackage)
private val compiledClassByName = kaptContext.compiledClasses.associateBy { it.name!! }
private var done = false
fun convert(): List<KaptStub> {
@@ -364,7 +366,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
for (innerClass in clazz.innerClasses) {
// Class should have the same name as enum value
if (innerClass.innerName != field.name) continue
val classNode = kaptContext.compiledClasses.firstOrNull { it.name == innerClass.name } ?: continue
val classNode = compiledClassByName[innerClass.name] ?: continue
// Super class name of the class should be our enum class
if (classNode.superName != clazz.name) continue
@@ -423,7 +425,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
val nestedClasses = mapJList<InnerClassNode, JCTree>(clazz.innerClasses) { innerClass ->
if (enumValuesData.any { it.innerClass == innerClass }) return@mapJList null
if (innerClass.outerName != clazz.name) return@mapJList null
val innerClassNode = kaptContext.compiledClasses.firstOrNull { it.name == innerClass.name } ?: return@mapJList null
val innerClassNode = compiledClassByName[innerClass.name] ?: return@mapJList null
convertClass(innerClassNode, lineMappings, packageFqName, false)
}
@@ -613,7 +615,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
return false
}
val clazz = kaptContext.compiledClasses.firstOrNull { it.name == internalName } ?: return true
val clazz = compiledClassByName[internalName] ?: return true
if (doesInnerClassNameConflictWithOuter(clazz)) {
if (strictMode) {
@@ -634,7 +636,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati
private fun findContainingClassNode(clazz: ClassNode): ClassNode? {
val innerClassForOuter = clazz.innerClasses.firstOrNull { it.name == clazz.name } ?: return null
return kaptContext.compiledClasses.firstOrNull { it.name == innerClassForOuter.outerName }
return compiledClassByName[innerClassForOuter.outerName]
}
// Java forbids outer and inner class names to be the same. Check if the names are different
@@ -434,6 +434,11 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
runTest("plugins/kapt3/kapt3-compiler/testData/converter/primitiveTypes.kt");
}
@TestMetadata("properties.kt")
public void testProperties() throws Exception {
runTest("plugins/kapt3/kapt3-compiler/testData/converter/properties.kt");
}
@TestMetadata("propertyAnnotations.kt")
public void testPropertyAnnotations() throws Exception {
runTest("plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt");
@@ -435,6 +435,11 @@ public class IrClassFileToSourceStubConverterTestGenerated extends AbstractIrCla
runTest("plugins/kapt3/kapt3-compiler/testData/converter/primitiveTypes.kt");
}
@TestMetadata("properties.kt")
public void testProperties() throws Exception {
runTest("plugins/kapt3/kapt3-compiler/testData/converter/properties.kt");
}
@TestMetadata("propertyAnnotations.kt")
public void testPropertyAnnotations() throws Exception {
runTest("plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt");
@@ -1,5 +1,12 @@
// CORRECT_ERROR_TYPES
import kotlin.reflect.KProperty
class ConcreteDelegate {
operator fun getValue(t: Any?, p: KProperty<*>): Int = 1
}
class Test {
var broken by object {
@@ -24,6 +31,8 @@ class Test {
}
}
val concreteDelegate: Int by ConcreteDelegate()
}
var delegate by object {
@@ -1,4 +1,4 @@
import java.lang.System;
import kotlin.reflect.KProperty;
@kotlin.Metadata()
public final class AnonymousDelegateKt {
@@ -22,7 +22,26 @@ public final class AnonymousDelegateKt {
////////////////////
import java.lang.System;
import kotlin.reflect.KProperty;
@kotlin.Metadata()
public final class ConcreteDelegate {
public ConcreteDelegate() {
super();
}
public final int getValue(@org.jetbrains.annotations.Nullable()
java.lang.Object t, @org.jetbrains.annotations.NotNull()
kotlin.reflect.KProperty<?> p) {
return 0;
}
}
////////////////////
import kotlin.reflect.KProperty;
@kotlin.Metadata()
public final class Test {
@@ -31,6 +50,8 @@ public final class Test {
@org.jetbrains.annotations.NotNull()
private final java.io.Serializable overridden$delegate = null;
private final kotlin.Lazy lazyProp$delegate = null;
@org.jetbrains.annotations.NotNull()
private final ConcreteDelegate concreteDelegate$delegate = null;
public Test() {
super();
@@ -57,4 +78,8 @@ public final class Test {
private final java.lang.Runnable getLazyProp() {
return null;
}
public final int getConcreteDelegate() {
return 0;
}
}
@@ -0,0 +1,8 @@
class Test {
val simple: String = "123"
val inferType = simple.length.toString() + "4891"
val getter: String = "O"
get() = { field }() + "K"
}
@@ -0,0 +1,30 @@
import java.lang.System;
@kotlin.Metadata()
public final class Test {
@org.jetbrains.annotations.NotNull()
private final java.lang.String simple = "123";
@org.jetbrains.annotations.NotNull()
private final java.lang.String inferType = null;
@org.jetbrains.annotations.NotNull()
private final java.lang.String getter = "O";
public Test() {
super();
}
@org.jetbrains.annotations.NotNull()
public final java.lang.String getSimple() {
return null;
}
@org.jetbrains.annotations.NotNull()
public final java.lang.String getInferType() {
return null;
}
@org.jetbrains.annotations.NotNull()
public final java.lang.String getGetter() {
return null;
}
}
@@ -6,4 +6,4 @@ annotation class Anno2
class Test {
@property:[Anno Anno2]
val prop = "A"
}
}