Fix for KT-3584: Wrong bytecode generated for local class with default parameters and captured local val
#KT-3584 Fixed
This commit is contained in:
@@ -25,6 +25,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.codegen.bridges.Bridge;
|
||||
import org.jetbrains.jet.codegen.bridges.BridgesPackage;
|
||||
@@ -36,6 +37,7 @@ import org.jetbrains.jet.codegen.state.GenerationState;
|
||||
import org.jetbrains.jet.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
@@ -514,9 +516,10 @@ public class FunctionCodegen extends ParentCodegenAware {
|
||||
@NotNull GenerationState state,
|
||||
@NotNull CallableMethod method,
|
||||
@NotNull ConstructorDescriptor constructorDescriptor,
|
||||
@NotNull ClassBuilder classBuilder
|
||||
@NotNull ClassBuilder classBuilder,
|
||||
@NotNull JetClassOrObject classOrObject
|
||||
) {
|
||||
if (!isDefaultConstructorNeeded(state.getBindingContext(), constructorDescriptor)) {
|
||||
if (!isEmptyConstructorNeeded(state.getBindingContext(), constructorDescriptor, classOrObject)) {
|
||||
return;
|
||||
}
|
||||
int flags = getVisibilityAccessFlag(constructorDescriptor);
|
||||
@@ -550,7 +553,7 @@ public class FunctionCodegen extends ParentCodegenAware {
|
||||
String desc = JetTypeMapper.getDefaultDescriptor(method.getAsmMethod(), false);
|
||||
v.invokespecial(methodOwner.getInternalName(), "<init>", desc, false);
|
||||
v.areturn(Type.VOID_TYPE);
|
||||
endVisit(mv, "default constructor for " + methodOwner.getInternalName(), null);
|
||||
endVisit(mv, "default constructor for " + methodOwner.getInternalName(), classOrObject);
|
||||
}
|
||||
|
||||
void generateDefaultIfNeeded(
|
||||
@@ -739,9 +742,15 @@ public class FunctionCodegen extends ParentCodegenAware {
|
||||
return needed;
|
||||
}
|
||||
|
||||
private static boolean isDefaultConstructorNeeded(@NotNull BindingContext context, @NotNull ConstructorDescriptor constructorDescriptor) {
|
||||
private static boolean isEmptyConstructorNeeded(
|
||||
@NotNull BindingContext context,
|
||||
@NotNull ConstructorDescriptor constructorDescriptor,
|
||||
@NotNull JetClassOrObject classOrObject
|
||||
) {
|
||||
ClassDescriptor classDescriptor = constructorDescriptor.getContainingDeclaration();
|
||||
|
||||
if (classOrObject.isLocal()) return false;
|
||||
|
||||
if (CodegenBinding.canHaveOuter(context, classDescriptor)) return false;
|
||||
|
||||
if (classDescriptor.getVisibility() == Visibilities.PRIVATE ||
|
||||
|
||||
@@ -1151,7 +1151,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
DefaultParameterValueLoader.DEFAULT, null);
|
||||
|
||||
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor);
|
||||
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
|
||||
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v, myClass);
|
||||
|
||||
if (isClassObject(descriptor)) {
|
||||
context.recordSyntheticAccessorIfNeeded(constructorDescriptor, bindingContext);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
fun box(): String {
|
||||
val s = "captured";
|
||||
|
||||
class A(val param: String = "OK") {
|
||||
val s2 = s + param
|
||||
}
|
||||
|
||||
if (A().s2 != "capturedOK") return "fail 1: ${A().s2}"
|
||||
|
||||
if (A("Test").s2 != "capturedTest") return "fail 1: ${A("Test").s2}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -4151,6 +4151,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt3584.kt")
|
||||
public void testKt3584() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/localClasses/kt3584.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localClass.kt")
|
||||
public void testLocalClass() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/localClasses/localClass.kt");
|
||||
|
||||
Reference in New Issue
Block a user