From 1a5bf331904083198e3b88e73b855a841ebd8dad Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Wed, 9 Mar 2016 14:06:25 +0300 Subject: [PATCH] Fix for KT-11034: Private set with @JvmStatic lateinit var doesn't compile #KT-11034 Fixed --- .../kotlin/codegen/FunctionCodegen.java | 2 +- .../kotlin/codegen/JvmStaticGenerator.kt | 49 ++++++++++--------- .../codegen/box/jvmStatic/privateSetter.kt | 24 +++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ 4 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 compiler/testData/codegen/box/jvmStatic/privateSetter.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 09a62b533a2..f43884ea36b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -188,7 +188,7 @@ public class FunctionCodegen { boolean staticInCompanionObject = AnnotationUtilKt.isPlatformStaticInCompanionObject(functionDescriptor); if (staticInCompanionObject) { ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen(); - parentBodyCodegen.addAdditionalTask(new JvmStaticGenerator(functionDescriptor, origin, state)); + parentBodyCodegen.addAdditionalTask(new JvmStaticGenerator(functionDescriptor, origin, state, parentBodyCodegen)); } if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES || isAbstractMethod(functionDescriptor, contextKind)) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt index ec0e4b97834..4dc2ab4347f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmStaticGenerator.kt @@ -17,26 +17,25 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.backend.common.CodegenUtil -import org.jetbrains.kotlin.codegen.context.MethodContext import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature -import org.jetbrains.org.objectweb.asm.MethodVisitor -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter class JvmStaticGenerator( val descriptor: FunctionDescriptor, val declarationOrigin: JvmDeclarationOrigin, - val state: GenerationState + val state: GenerationState, + parentBodyCodegen: ImplementationBodyCodegen ) : Function2 { private val typeMapper = state.typeMapper + init { + parentBodyCodegen.getContext().accessibleDescriptor(JvmCodegenUtil.getDirectMember(descriptor), null) + } + override fun invoke(codegen: ImplementationBodyCodegen, classBuilder: ClassBuilder) { val staticFunctionDescriptor = createStaticFunctionDescriptor(descriptor) @@ -44,15 +43,9 @@ class JvmStaticGenerator( codegen.functionCodegen.generateMethod( Synthetic(originElement, staticFunctionDescriptor), staticFunctionDescriptor, - object : FunctionGenerationStrategy() { - override fun generateBody( - mv: MethodVisitor, - frameMap: FrameMap, - signature: JvmMethodSignature, - context: MethodContext, - parentCodegen: MemberCodegen<*> - ) { - val iv = InstructionAdapter(mv) + object : FunctionGenerationStrategy.CodegenBased(state, descriptor) { + override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) { + val iv = codegen.v val classDescriptor = descriptor.containingDeclaration as ClassDescriptor val singletonValue = StackValue.singleton(classDescriptor, typeMapper) singletonValue.put(singletonValue.type, iv) @@ -62,12 +55,22 @@ class JvmStaticGenerator( iv.load(index, paramType) index += paramType.size } - - val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod( - codegen.getContext().accessibleDescriptor(descriptor, /* superCallTarget = */ null), - false - ) - syntheticOrOriginalMethod.genInvokeInstruction(iv) + if (descriptor is PropertyAccessorDescriptor) { + val propertyValue = codegen.intermediateValueForProperty(descriptor.correspondingProperty, false, null, StackValue.none()) + if (callableDescriptor is PropertyGetterDescriptor) { + propertyValue.put(signature.returnType, iv) + } + else { + propertyValue.store(StackValue.onStack(propertyValue.type), iv, true) + } + } + else { + val syntheticOrOriginalMethod = typeMapper.mapToCallableMethod( + codegen.context.accessibleDescriptor(descriptor, /* superCallTarget = */ null), + false + ) + syntheticOrOriginalMethod.genInvokeInstruction(iv) + } iv.areturn(asmMethod.returnType) } } diff --git a/compiler/testData/codegen/box/jvmStatic/privateSetter.kt b/compiler/testData/codegen/box/jvmStatic/privateSetter.kt new file mode 100644 index 00000000000..83259d510f0 --- /dev/null +++ b/compiler/testData/codegen/box/jvmStatic/privateSetter.kt @@ -0,0 +1,24 @@ +// WITH_RUNTIME +// FILE: JavaClass.java +class JavaClass { + + + public static String test() + { + return TestApp.getValue(); + } +} + +// FILE: Kotlin.kt +open class TestApp { + companion object { + @JvmStatic + var value: String = "OK" + private set + } +} + + +fun box(): String { + return JavaClass.test() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d80a2ba4dec..96dbcc15366 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -7510,6 +7510,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("privateSetter.kt") + public void testPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/privateSetter.kt"); + doTest(fileName); + } + @TestMetadata("propertyAccess.kt") public void testPropertyAccess() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/propertyAccess.kt");