diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 5a967aa8167..b8b0160164b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -32,6 +32,7 @@ import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.binding.CalculatedClosure; +import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.context.*; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; @@ -63,7 +64,8 @@ import static org.jetbrains.jet.codegen.AsmTypeConstants.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; -import static org.jetbrains.jet.lang.resolve.BindingContextUtils.*; +import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; +import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull; /** * @author max @@ -1461,12 +1463,10 @@ public class ExpressionCodegen extends JetVisitor implem ClassDescriptor containing = (ClassDescriptor) variableDescriptor.getContainingDeclaration().getContainingDeclaration(); assert containing != null; Type type = typeMapper.mapType(containing.getDefaultType(), JetTypeMapperMode.VALUE); - StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().getName(), true).put(type, v); - return StackValue.onStack(type); + return StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().getName(), true); } else { - Type type = typeMapper.mapType(objectClassDescriptor.getDefaultType(), JetTypeMapperMode.VALUE); - return StackValue.field(type, JvmClassName.byType(type), "$instance", true); + return StackValue.singleton(objectClassDescriptor, typeMapper); } } @@ -1970,8 +1970,17 @@ public class ExpressionCodegen extends JetVisitor implem } public StackValue generateThisOrOuter(@NotNull final ClassDescriptor calleeContainingClass, boolean isSuper) { - PsiElement psiElement = classDescriptorToDeclaration(bindingContext, calleeContainingClass); - boolean isObject = psiElement instanceof JetClassOrObject && isNonLiteralObject((JetClassOrObject) psiElement); + boolean isSingleton = CodegenBinding.isSingleton(bindingContext, calleeContainingClass); + if (isSingleton) { + assert !isSuper; + + if (context.hasThisDescriptor() && context.getThisDescriptor().equals(calleeContainingClass)) { + return StackValue.local(0, typeMapper.mapType(calleeContainingClass.getDefaultType(), JetTypeMapperMode.VALUE)); + } + else { + return StackValue.singleton(calleeContainingClass, typeMapper); + } + } CodegenContext cur = context; Type type = asmType(calleeContainingClass.getDefaultType()); @@ -1985,12 +1994,7 @@ public class ExpressionCodegen extends JetVisitor implem final ClassDescriptor thisDescriptor = cur.getThisDescriptor(); if (!isSuper && thisDescriptor.equals(calleeContainingClass) || isSuper && DescriptorUtils.isSubclass(thisDescriptor, calleeContainingClass)) { - if (!isObject || (thisDescriptor.equals(calleeContainingClass))) { - return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass); - } - else { - v.getstatic(type.getInternalName(), "$instance", type.getDescriptor()); - } + return castToRequiredTypeOfInterfaceIfNeeded(result, thisDescriptor, calleeContainingClass); } result = cur.getOuterExpression(result, false); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 1c6affbf4f2..270dda1164c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -25,6 +25,7 @@ import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.state.GenerationState; +import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; @@ -354,6 +355,10 @@ public abstract class StackValue { return receiver; } + public static StackValue singleton(ClassDescriptor aClass, JetTypeMapper typeMapper) { + return new Singleton(aClass, typeMapper.mapType(aClass.getDefaultType(), JetTypeMapperMode.VALUE)); + } + private static class None extends StackValue { public static final None INSTANCE = new None(); @@ -1317,4 +1322,22 @@ public abstract class StackValue { } } } + + public static class Singleton extends StackValue { + private final ClassDescriptor classDescriptor; + + protected Singleton(ClassDescriptor classDescriptor, @NotNull Type type) { + super(type); + this.classDescriptor = classDescriptor; + } + + @Override + public void put(Type type, InstructionAdapter v) { + final ClassKind kind = classDescriptor.getKind(); + if (kind == ClassKind.CLASS_OBJECT || kind == ClassKind.OBJECT) { + v.getstatic(this.type.getInternalName(), "$instance", this.type.getDescriptor()); + coerce(type, v); + } + } + } } diff --git a/compiler/testData/codegen/regressions/kt2675.kt b/compiler/testData/codegen/regressions/kt2675.kt new file mode 100644 index 00000000000..3cd63cc3262 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt2675.kt @@ -0,0 +1,16 @@ +class A() { + + fun ok() = Foo.Bar.bar() + Foo.Bar.barv + + private object Foo { + fun foo() = "O" + val foov = "K" + + public object Bar { + fun bar() = foo() + val barv = foov + } + } +} + +fun box() = A().ok() diff --git a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java index 300971d753b..7afa4673f61 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java @@ -102,6 +102,9 @@ public class ObjectGenTest extends CodegenTestCase { public void testKt2398() { blackBoxFile("regressions/kt2398.kt", "OKKO"); - System.out.println(generateToText()); + } + + public void testKt2675() { + blackBoxFile("regressions/kt2675.kt"); } }