Fix for KT-4206: NoSuchFieldError with class objects
#KT-4206 Fixed
This commit is contained in:
@@ -1956,7 +1956,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
boolean isStatic = DescriptorUtils.isStaticDeclaration(propertyDescriptor);
|
||||
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) || isBackingFieldInAnotherClass;
|
||||
boolean isSuper = superExpression != null;
|
||||
boolean isExtensionProperty = propertyDescriptor.getExtensionReceiverParameter() != null;
|
||||
|
||||
@@ -1969,16 +1969,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
boolean skipPropertyAccessors = forceField && !isBackingFieldInAnotherClass;
|
||||
|
||||
CodegenContext backingFieldContext = context.getParentContext();
|
||||
boolean changeOwnerOnTypeMap = isBackingFieldInAnotherClass;
|
||||
|
||||
if (isBackingFieldInAnotherClass && forceField) {
|
||||
//delegate call to classObject owner : OWNER
|
||||
//delegate call to classObject backingFieldOwner : OWNER
|
||||
backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration());
|
||||
int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty);
|
||||
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER;
|
||||
if (!skipPropertyAccessors) {
|
||||
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor, true, delegateType);
|
||||
changeOwnerOnTypeMap = changeOwnerOnTypeMap && !(propertyDescriptor instanceof AccessorForPropertyBackingFieldInOuterClass);
|
||||
}
|
||||
isStatic = true;
|
||||
}
|
||||
|
||||
if (!skipPropertyAccessors) {
|
||||
@@ -2016,17 +2017,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
}
|
||||
|
||||
Type owner;
|
||||
CallableMethod callableMethod = callableGetter != null ? callableGetter : callableSetter;
|
||||
|
||||
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
if (callableMethod == null) {
|
||||
owner = typeMapper.mapOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
|
||||
isCallInsideSameModuleAsDeclared(propertyDescriptor, context, state.getOutDirectory()));
|
||||
}
|
||||
else {
|
||||
owner = callableMethod.getOwner();
|
||||
}
|
||||
Type backingFieldOwner = typeMapper.mapOwner(changeOwnerOnTypeMap ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
|
||||
isCallInsideSameModuleAsDeclared(propertyDescriptor, context, state.getOutDirectory()));
|
||||
|
||||
String fieldName;
|
||||
if (isExtensionProperty && !isDelegatedProperty) {
|
||||
@@ -2041,9 +2034,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
fieldName = JvmAbi.getDefaultFieldNameForProperty(propertyDescriptor.getName(), isDelegatedProperty);
|
||||
}
|
||||
|
||||
return StackValue.property(propertyDescriptor, owner,
|
||||
return StackValue.property(propertyDescriptor, backingFieldOwner,
|
||||
typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
||||
isStatic, fieldName, callableGetter, callableSetter, state, receiver);
|
||||
isStaticBackingField, fieldName, callableGetter, callableSetter, state, receiver);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.jet.codegen;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import kotlin.Function1;
|
||||
import kotlin.Function2;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -199,16 +198,16 @@ public abstract class StackValue implements StackValueI {
|
||||
@NotNull
|
||||
public static Property property(
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@NotNull Type methodOwner,
|
||||
@NotNull Type backingFieldOwner,
|
||||
@NotNull Type type,
|
||||
boolean isStatic,
|
||||
boolean isStaticBackingField,
|
||||
@Nullable String fieldName,
|
||||
@Nullable CallableMethod getter,
|
||||
@Nullable CallableMethod setter,
|
||||
GenerationState state,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
return new Property(descriptor, methodOwner, getter, setter, isStatic, fieldName, type, state, receiver);
|
||||
return new Property(descriptor, backingFieldOwner, getter, setter, isStaticBackingField, fieldName, type, state, receiver);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1028,7 +1027,7 @@ public abstract class StackValue implements StackValueI {
|
||||
static class Property extends StackValueWithSimpleReceiver {
|
||||
private final CallableMethod getter;
|
||||
private final CallableMethod setter;
|
||||
private final Type methodOwner;
|
||||
private final Type backingFieldOwner;
|
||||
|
||||
private final PropertyDescriptor descriptor;
|
||||
private final GenerationState state;
|
||||
@@ -1036,13 +1035,13 @@ public abstract class StackValue implements StackValueI {
|
||||
private final String fieldName;
|
||||
|
||||
public Property(
|
||||
@NotNull PropertyDescriptor descriptor, @NotNull Type methodOwner,
|
||||
@NotNull PropertyDescriptor descriptor, @NotNull Type backingFieldOwner,
|
||||
@Nullable CallableMethod getter, @Nullable CallableMethod setter, boolean isStaticBackingField,
|
||||
@Nullable String fieldName, @NotNull Type type, @NotNull GenerationState state,
|
||||
@NotNull StackValue receiver
|
||||
) {
|
||||
super(type, isStatic(isStaticBackingField, getter), isStatic(isStaticBackingField, setter), receiver);
|
||||
this.methodOwner = methodOwner;
|
||||
this.backingFieldOwner = backingFieldOwner;
|
||||
this.getter = getter;
|
||||
this.setter = setter;
|
||||
this.descriptor = descriptor;
|
||||
@@ -1054,7 +1053,7 @@ public abstract class StackValue implements StackValueI {
|
||||
public void putNoReceiver(@NotNull Type type, @NotNull InstructionAdapter v) {
|
||||
if (getter == null) {
|
||||
assert fieldName != null : "Property should have either a getter or a field name: " + descriptor;
|
||||
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, methodOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
v.visitFieldInsn(isStaticPut ? GETSTATIC : GETFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
genNotNullAssertionForField(v, state, descriptor);
|
||||
coerceTo(type, v);
|
||||
}
|
||||
@@ -1069,7 +1068,7 @@ public abstract class StackValue implements StackValueI {
|
||||
coerceFrom(topOfStackType, v);
|
||||
if (setter == null) {
|
||||
assert fieldName != null : "Property should have either a setter or a field name: " + descriptor;
|
||||
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, methodOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
v.visitFieldInsn(isStaticStore ? PUTSTATIC : PUTFIELD, backingFieldOwner.getInternalName(), fieldName, this.type.getDescriptor());
|
||||
}
|
||||
else {
|
||||
setter.invokeWithoutAssertions(v);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class Foo {
|
||||
class object {
|
||||
val bar: String
|
||||
|
||||
{
|
||||
bar = "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
return Foo.bar
|
||||
}
|
||||
@@ -6173,6 +6173,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/staticFields"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectAnonymousInitializer.kt")
|
||||
public void testClassObjectAnonymousInitializer() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/staticFields/classObjectAnonymousInitializer.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("classObjectInc.kt")
|
||||
public void testClassObjectInc() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/staticFields/classObjectInc.kt");
|
||||
|
||||
Reference in New Issue
Block a user