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 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.binding.CodegenBinding.*;
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.getNotNull;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
/**
* @author max
@@ -1397,14 +1397,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
if (descriptor instanceof ClassDescriptor) {
PsiElement declaration = descriptorToDeclaration(bindingContext, descriptor);
if (declaration instanceof JetClass) {
final ClassDescriptor descriptor1 = ((ClassDescriptor) descriptor).getClassObjectDescriptor();
assert descriptor1 != null;
final Type type = typeMapper.mapType(descriptor1);
return StackValue.field(type,
JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(),
JetTypeMapperMode.IMPL)),
"$classobj",
true);
final ClassDescriptor classObjectDescriptor = ((ClassDescriptor) descriptor).getClassObjectDescriptor();
assert classObjectDescriptor != null;
return StackValue.singleton(classObjectDescriptor, typeMapper);
}
else {
// todo ?
@@ -1875,9 +1870,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
v.load(0, OBJECT_TYPE);
}
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration();
Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), JetTypeMapperMode.IMPL);
v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
v.getstatic(exprType.getInternalName(), "$instance", exprType.getDescriptor());
}
StackValue.onStack(exprType).put(type, v);
}
@@ -591,28 +591,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateFieldForClassObject() {
final JetClassObject classObject = getClassObject();
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);
if (descriptor.getKind() != ClassKind.CLASS_OBJECT) return;
staticInitializerChunks.add(new CodeChunk() {
@Override
public void generate(InstructionAdapter v) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
assert descriptor1 != null;
String name = typeMapper.mapType(descriptor1.getDefaultType(), JetTypeMapperMode.IMPL).getInternalName();
final Type classObjectType = Type.getObjectType(name);
v.anew(classObjectType);
v.dup();
v.invokespecial(name, "<init>", "()V");
v.putstatic(typeMapper.mapType(descriptor).getInternalName(), "$classobj",
classObjectType.getDescriptor());
}
});
}
v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL , "$instance", classAsmType.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() {
@Override
public void generate(InstructionAdapter v) {
v.anew(classAsmType);
v.dup();
v.invokespecial(classAsmType.getInternalName(), "<init>", "()V");
v.putstatic(typeMapper.mapType(descriptor).getInternalName(), "$instance", classAsmType.getDescriptor());
}
});
}
protected void generatePrimaryConstructor() {
@@ -106,16 +106,21 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase {
assertNotNull(theClass);
PsiField classobj = theClass.findFieldByName("$classobj", false);
assertTrue(classobj != null && classobj.hasModifierProperty(PsiModifier.STATIC));
PsiField classobjField = theClass.findFieldByName("$classobj", false);
assertNull(classobjField);
PsiType type = classobj.getType();
assertTrue(type instanceof PsiClassType);
final PsiClass classObjectClass = theClass.findInnerClassByName("ClassObject$", false);
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);
assertEquals("java.io.PrintStream", methods[0].getReturnType().getCanonicalText());