diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/extensions/PartialAnalysisHandlerExtension.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/extensions/PartialAnalysisHandlerExtension.kt index bd65e356fd9..2b44ebb8fda 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/extensions/PartialAnalysisHandlerExtension.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/extensions/PartialAnalysisHandlerExtension.kt @@ -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 { } } -} \ No newline at end of file +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index fcc9a8a3208..b2d85f35233 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -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 diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index feddf55cbaa..9af096ef3af 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -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 { @@ -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(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 diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java index 94d7b674154..d976794a07d 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java @@ -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"); diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java index 9a7313aae9c..0766a041312 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java @@ -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"); diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.kt b/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.kt index e289ea94614..6186ee0b6c2 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.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 { diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.txt b/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.txt index 1db03cc8f11..8ee16ce23b3 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/anonymousDelegate.txt @@ -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; + } } diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/properties.kt b/plugins/kapt3/kapt3-compiler/testData/converter/properties.kt new file mode 100644 index 00000000000..feb0fb89595 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/properties.kt @@ -0,0 +1,8 @@ +class Test { + val simple: String = "123" + + val inferType = simple.length.toString() + "4891" + + val getter: String = "O" + get() = { field }() + "K" +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/properties.txt b/plugins/kapt3/kapt3-compiler/testData/converter/properties.txt new file mode 100644 index 00000000000..d4a82ef6abd --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/properties.txt @@ -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; + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt b/plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt index 323cb8c686d..6587e068041 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/propertyAnnotations.kt @@ -6,4 +6,4 @@ annotation class Anno2 class Test { @property:[Anno Anno2] val prop = "A" -} \ No newline at end of file +}