Correctly map declaration owner in JVM codegen
"context.contextKind()" was incorrect in ExpressionCodegen.intermediateValueForProperty(), because it represents the context of the call site, not the context of the property declaration #KT-4878 Fixed
This commit is contained in:
@@ -27,11 +27,6 @@ import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.jet.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.jet.codegen.binding.MutableClosure;
|
||||
@@ -63,10 +58,14 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.org.objectweb.asm.Label;
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.*;
|
||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||
import static org.jetbrains.jet.codegen.FunctionTypesUtil.functionTypeToImpl;
|
||||
@@ -78,6 +77,7 @@ import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedIn
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
|
||||
import static org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implements LocalLookup, ParentCodegenAware {
|
||||
private static final Set<DeclarationDescriptor> INTEGRAL_RANGES = KotlinBuiltIns.getInstance().getIntegralRanges();
|
||||
@@ -1803,8 +1803,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
@Nullable JetSuperExpression superExpression,
|
||||
@NotNull MethodKind methodKind
|
||||
) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
|
||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||
|
||||
boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||
@@ -1812,10 +1810,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
boolean isSuper = superExpression != null;
|
||||
boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context);
|
||||
|
||||
JetType delegateType = getPropertyDelegateType(propertyDescriptor, state.getBindingContext());
|
||||
JetType delegateType = getPropertyDelegateType(propertyDescriptor, bindingContext);
|
||||
boolean isDelegatedProperty = delegateType != null;
|
||||
|
||||
|
||||
CallableMethod callableGetter = null;
|
||||
CallableMethod callableSetter = null;
|
||||
|
||||
@@ -1841,7 +1838,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
}
|
||||
else {
|
||||
if (isSuper && !isInterface(containingDeclaration)) {
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(superExpression, state.getBindingContext(), context);
|
||||
ClassDescriptor owner = getSuperCallLabelTarget(superExpression, bindingContext, context);
|
||||
CodegenContext c = context.findParentContextWithDescriptor(owner);
|
||||
assert c != null : "Couldn't find a context for a super-call: " + propertyDescriptor;
|
||||
if (c != context.getParentContext()) {
|
||||
@@ -1875,8 +1872,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
|
||||
propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
|
||||
if (callableMethod == null) {
|
||||
owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
|
||||
context.getContextKind(), isCallInsideSameModuleAsDeclared(propertyDescriptor, context));
|
||||
owner = typeMapper.mapOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor,
|
||||
isCallInsideSameModuleAsDeclared(propertyDescriptor, context));
|
||||
}
|
||||
else {
|
||||
owner = callableMethod.getOwner();
|
||||
|
||||
@@ -555,16 +555,16 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
||||
|
||||
Type ownerType;
|
||||
if (contextClass instanceof PackageFragmentDescriptor) {
|
||||
ownerType = state.getTypeMapper().getOwner(functionDescriptor, kind, true);
|
||||
ownerType = typeMapper.mapOwner(functionDescriptor, true);
|
||||
}
|
||||
else if (contextClass instanceof ClassDescriptor) {
|
||||
ownerType = state.getTypeMapper().mapClass((ClassDescriptor) contextClass);
|
||||
ownerType = typeMapper.mapClass((ClassDescriptor) contextClass);
|
||||
}
|
||||
else if (isLocalNamedFun(functionDescriptor)) {
|
||||
ownerType = asmTypeForAnonymousClass(state.getBindingContext(), functionDescriptor);
|
||||
ownerType = asmTypeForAnonymousClass(bindingContext, functionDescriptor);
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Couldn't obtain owner name for " + functionDescriptor);
|
||||
throw new IllegalStateException("Couldn't obtain owner type for " + functionDescriptor);
|
||||
}
|
||||
|
||||
String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen.state;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
import org.jetbrains.jet.codegen.binding.BindingTraceAware;
|
||||
import org.jetbrains.jet.codegen.binding.CalculatedClosure;
|
||||
@@ -47,11 +46,11 @@ import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.boxType;
|
||||
import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
|
||||
import static org.jetbrains.jet.codegen.CodegenUtil.*;
|
||||
@@ -59,6 +58,7 @@ import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class JetTypeMapper extends BindingTraceAware {
|
||||
|
||||
@@ -90,20 +90,19 @@ public class JetTypeMapper extends BindingTraceAware {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type getOwner(@NotNull DeclarationDescriptor descriptor, @NotNull OwnerKind kind, boolean isInsideModule) {
|
||||
public Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isInsideModule) {
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
return asmTypeForPackage((PackageFragmentDescriptor) containingDeclaration, descriptor, isInsideModule);
|
||||
}
|
||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
return kind == OwnerKind.TRAIT_IMPL ? mapTraitImpl(classDescriptor) : mapClass(classDescriptor);
|
||||
return mapClass((ClassDescriptor) containingDeclaration);
|
||||
}
|
||||
else if (containingDeclaration instanceof ScriptDescriptor) {
|
||||
return asmTypeForScriptDescriptor(bindingContext, (ScriptDescriptor) containingDeclaration);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration);
|
||||
throw new UnsupportedOperationException("Don't know how to map owner for " + descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
class MyWrongClass : FieldAccess() {
|
||||
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val clazz = MyWrongClass()
|
||||
clazz.fieldO = "O"
|
||||
FieldAccess.fieldK = "K"
|
||||
return clazz.fieldO!! + FieldAccess.fieldK!!
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
public class fieldAccessFromExtensionInTraitImpl {
|
||||
public final String result = "OK";
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// KT-4878
|
||||
|
||||
import fieldAccessFromExtensionInTraitImpl as D
|
||||
|
||||
trait T {
|
||||
fun Int.foo(d: D) = d.result!!
|
||||
}
|
||||
|
||||
class A : T {
|
||||
fun bar() = 42.foo(D())
|
||||
}
|
||||
|
||||
fun box() = A().bar()
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
class FieldAccess {
|
||||
class fieldAccessViaSubclass {
|
||||
public String fieldO;
|
||||
|
||||
public static String fieldK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// KT-3492
|
||||
|
||||
class MyWrongClass : fieldAccessViaSubclass() {
|
||||
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val clazz = MyWrongClass()
|
||||
clazz.fieldO = "O"
|
||||
fieldAccessViaSubclass.fieldK = "K"
|
||||
return clazz.fieldO!! + fieldAccessViaSubclass.fieldK!!
|
||||
}
|
||||
+8
-3
@@ -214,9 +214,14 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxWithJava/property"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("FieldAccess.kt")
|
||||
public void testFieldAccess() throws Exception {
|
||||
doTestWithJava("compiler/testData/codegen/boxWithJava/property/FieldAccess.kt");
|
||||
@TestMetadata("fieldAccessFromExtensionInTraitImpl.kt")
|
||||
public void testFieldAccessFromExtensionInTraitImpl() throws Exception {
|
||||
doTestWithJava("compiler/testData/codegen/boxWithJava/property/fieldAccessFromExtensionInTraitImpl.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fieldAccessViaSubclass.kt")
|
||||
public void testFieldAccessViaSubclass() throws Exception {
|
||||
doTestWithJava("compiler/testData/codegen/boxWithJava/property/fieldAccessViaSubclass.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user