static final field for class object moved to class object class from containing class

This commit is contained in:
Alex Tkachman
2012-09-15 21:23:42 +03:00
parent 104f2a08d3
commit f8983d8516
3 changed files with 29 additions and 40 deletions
@@ -59,12 +59,12 @@ import org.jetbrains.jet.lexer.JetTokens;
import java.util.*; import java.util.*;
import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
/** /**
* @author max * @author max
@@ -1397,14 +1397,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
PsiElement declaration = descriptorToDeclaration(bindingContext, descriptor); PsiElement declaration = descriptorToDeclaration(bindingContext, descriptor);
if (declaration instanceof JetClass) { if (declaration instanceof JetClass) {
final ClassDescriptor descriptor1 = ((ClassDescriptor) descriptor).getClassObjectDescriptor(); final ClassDescriptor classObjectDescriptor = ((ClassDescriptor) descriptor).getClassObjectDescriptor();
assert descriptor1 != null; assert classObjectDescriptor != null;
final Type type = typeMapper.mapType(descriptor1); return StackValue.singleton(classObjectDescriptor, typeMapper);
return StackValue.field(type,
JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(),
JetTypeMapperMode.IMPL)),
"$classobj",
true);
} }
else { else {
// todo ? // todo ?
@@ -1875,9 +1870,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.load(0, OBJECT_TYPE); v.load(0, OBJECT_TYPE);
} }
else { else {
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); v.getstatic(exprType.getInternalName(), "$instance", exprType.getDescriptor());
Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), JetTypeMapperMode.IMPL);
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
} }
StackValue.onStack(exprType).put(type, v); StackValue.onStack(exprType).put(type, v);
} }
@@ -591,28 +591,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
private void generateFieldForClassObject() { private void generateFieldForClassObject() {
final JetClassObject classObject = getClassObject(); if (descriptor.getKind() != ClassKind.CLASS_OBJECT) return;
if (classObject != null) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
assert descriptor1 != null;
Type type = Type.getObjectType(typeMapper.mapType(descriptor1).getInternalName());
v.newField(classObject, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "$classobj", type.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() { v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL , "$instance", classAsmType.getDescriptor(), null, null);
@Override
public void generate(InstructionAdapter v) { staticInitializerChunks.add(new CodeChunk() {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); @Override
assert descriptor1 != null; public void generate(InstructionAdapter v) {
String name = typeMapper.mapType(descriptor1.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName(); v.anew(classAsmType);
final Type classObjectType = Type.getObjectType(name); v.dup();
v.anew(classObjectType); v.invokespecial(classAsmType.getInternalName(), "<init>", "()V");
v.dup(); v.putstatic(typeMapper.mapType(descriptor).getInternalName(), "$instance", classAsmType.getDescriptor());
v.invokespecial(name, "<init>", "()V"); }
v.putstatic(typeMapper.mapType(descriptor).getInternalName(), "$classobj", });
classObjectType.getDescriptor());
}
});
}
} }
protected void generatePrimaryConstructor() { protected void generatePrimaryConstructor() {
@@ -106,16 +106,21 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
assertNotNull(theClass); assertNotNull(theClass);
PsiField classobj = theClass.findFieldByName("$classobj", false); PsiField classobjField = theClass.findFieldByName("$classobj", false);
assertTrue(classobj != null && classobj.hasModifierProperty(PsiModifier.STATIC)); assertNull(classobjField);
PsiType type = classobj.getType(); final PsiClass classObjectClass = theClass.findInnerClassByName("ClassObject$", false);
assertTrue(type instanceof PsiClassType); assertNotNull(classObjectClass);
assertEquals("foo.TheClass.ClassObject$", classObjectClass.getQualifiedName());
assertTrue(classObjectClass.hasModifierProperty(PsiModifier.STATIC));
assertEquals("foo.TheClass.ClassObject$", type.getCanonicalText()); final PsiField instance = classObjectClass.findFieldByName("$instance", false);
assertNotNull(instance);
assertEquals("foo.TheClass.ClassObject$", instance.getType().getCanonicalText());
assertTrue(instance.hasModifierProperty(PsiModifier.PUBLIC));
assertTrue(instance.hasModifierProperty(PsiModifier.STATIC));
assertTrue(instance.hasModifierProperty(PsiModifier.FINAL));
PsiClass classObjectClass = ((PsiClassType) type).resolve();
assertTrue(classObjectClass != null && classObjectClass.hasModifierProperty(PsiModifier.STATIC));
PsiMethod[] methods = classObjectClass.findMethodsByName("getOut", false); PsiMethod[] methods = classObjectClass.findMethodsByName("getOut", false);
assertEquals("java.io.PrintStream", methods[0].getReturnType().getCanonicalText()); assertEquals("java.io.PrintStream", methods[0].getReturnType().getCanonicalText());