ClassContext refactoring, initial

This commit is contained in:
Maxim Shafirov
2011-07-04 13:27:15 +04:00
parent ef30fde1c2
commit 7d63d512b2
5 changed files with 68 additions and 30 deletions
@@ -0,0 +1,31 @@
/*
* @author max
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
public class ClassContext {
public static final ClassContext STATIC = new ClassContext(null, OwnerKind.NAMESPACE, null);
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
private final StackValue thisExpression;
public ClassContext(DeclarationDescriptor contextType, OwnerKind contextKind, StackValue thisExpression) {
this.contextType = contextType;
this.contextKind = contextKind;
this.thisExpression = thisExpression;
}
public DeclarationDescriptor getContextType() {
return contextType;
}
public OwnerKind getContextKind() {
return contextKind;
}
public StackValue getThisExpression() {
return thisExpression;
}
}
@@ -78,29 +78,23 @@ public class ExpressionCodegen extends JetVisitor {
private final JetTypeMapper typeMapper; private final JetTypeMapper typeMapper;
private final GenerationState state; private final GenerationState state;
private final Type returnType; private final Type returnType;
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
private final BindingContext bindingContext; private final BindingContext bindingContext;
private final StackValue thisExpression;
private final Map<ClassDescriptor, StackValue> outerThisExpressions = new HashMap<ClassDescriptor, StackValue>(); private final Map<ClassDescriptor, StackValue> outerThisExpressions = new HashMap<ClassDescriptor, StackValue>();
private final Map<TypeParameterDescriptor, StackValue> typeParameterExpressions = new HashMap<TypeParameterDescriptor, StackValue>(); private final Map<TypeParameterDescriptor, StackValue> typeParameterExpressions = new HashMap<TypeParameterDescriptor, StackValue>();
private final ClassContext context;
public ExpressionCodegen(MethodVisitor v, public ExpressionCodegen(MethodVisitor v,
FrameMap myMap, FrameMap myMap,
Type returnType, Type returnType,
DeclarationDescriptor contextType, ClassContext context,
OwnerKind contextKind,
@Nullable StackValue thisExpression,
GenerationState state) { GenerationState state) {
this.myMap = myMap; this.myMap = myMap;
this.typeMapper = state.getTypeMapper(); this.typeMapper = state.getTypeMapper();
this.returnType = returnType; this.returnType = returnType;
this.contextType = contextType;
this.contextKind = contextKind;
this.state = state; this.state = state;
this.v = new InstructionAdapter(v); this.v = new InstructionAdapter(v);
this.bindingContext = state.getBindingContext(); this.bindingContext = state.getBindingContext();
this.thisExpression = thisExpression; this.context = context;
} }
public void addOuterThis(ClassDescriptor outer, StackValue expression) { public void addOuterThis(ClassDescriptor outer, StackValue expression) {
@@ -320,6 +314,18 @@ public class ExpressionCodegen extends JetVisitor {
myContinueTargets.pop(); myContinueTargets.pop();
} }
private DeclarationDescriptor contextType() {
return context.getContextType();
}
private OwnerKind contextKind() {
return context.getContextKind();
}
private StackValue thisExpression() {
return context.getThisExpression();
}
private abstract class ForLoopGenerator { private abstract class ForLoopGenerator {
protected JetForExpression expression; protected JetForExpression expression;
protected Type loopRangeType; protected Type loopRangeType;
@@ -682,7 +688,7 @@ public class ExpressionCodegen extends JetVisitor {
boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl; boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl;
propertyDescriptor = propertyDescriptor.getOriginal(); propertyDescriptor = propertyDescriptor.getOriginal();
final JetType outType = propertyDescriptor.getOutType(); final JetType outType = propertyDescriptor.getOutType();
boolean isInsideClass = !forceInterface && containingDeclaration == contextType; boolean isInsideClass = !forceInterface && containingDeclaration == contextType();
Method getter; Method getter;
Method setter; Method setter;
if (forceField) { if (forceField) {
@@ -697,7 +703,7 @@ public class ExpressionCodegen extends JetVisitor {
String owner; String owner;
boolean isInterface; boolean isInterface;
if (isInsideClass || isStatic) { if (isInsideClass || isStatic) {
owner = typeMapper.getOwner(propertyDescriptor, contextKind); owner = typeMapper.getOwner(propertyDescriptor, contextKind());
isInterface = false; isInterface = false;
} }
else { else {
@@ -891,17 +897,17 @@ public class ExpressionCodegen extends JetVisitor {
} }
else { else {
// TODO hope it works; really need more checks here :) // TODO hope it works; really need more checks here :)
if (calleeContainingClass != null && contextType instanceof ClassDescriptor && if (calleeContainingClass != null && contextType() instanceof ClassDescriptor &&
calleeContainingClass == contextType.getContainingDeclaration()) { calleeContainingClass == contextType().getContainingDeclaration()) {
v.load(0, JetTypeMapper.TYPE_OBJECT); v.load(0, JetTypeMapper.TYPE_OBJECT);
return StackValue.field(typeMapper.jvmType(calleeContainingClass, OwnerKind.IMPLEMENTATION), return StackValue.field(typeMapper.jvmType(calleeContainingClass, OwnerKind.IMPLEMENTATION),
typeMapper.jvmName((ClassDescriptor) contextType, OwnerKind.IMPLEMENTATION), typeMapper.jvmName((ClassDescriptor) contextType(), OwnerKind.IMPLEMENTATION),
"this$0", "this$0",
false); false);
// TODO handle more levels of class nestng // TODO handle more levels of class nestng
} }
else { else {
return thisExpression != null ? thisExpression : StackValue.local(0, JetTypeMapper.TYPE_OBJECT); return thisExpression() != null ? thisExpression() : StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
} }
} }
} }
@@ -1499,18 +1505,18 @@ public class ExpressionCodegen extends JetVisitor {
} }
private void generateThis() { private void generateThis() {
if (thisExpression != null) { if (thisExpression() != null) {
myStack.push(thisExpression); myStack.push(thisExpression());
return; return;
} }
if (contextKind != OwnerKind.NAMESPACE) { if (contextKind() != OwnerKind.NAMESPACE) {
ClassDescriptor contextClass = (ClassDescriptor) contextType; ClassDescriptor contextClass = (ClassDescriptor) contextType();
final Type thisType = typeMapper.jvmType(contextClass, contextKind); final Type thisType = typeMapper.jvmType(contextClass, contextKind());
if (contextKind == OwnerKind.IMPLEMENTATION) { if (contextKind() == OwnerKind.IMPLEMENTATION) {
myStack.push(StackValue.local(0, thisType)); myStack.push(StackValue.local(0, thisType));
return; return;
} }
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) { else if (contextKind() == OwnerKind.DELEGATING_IMPLEMENTATION) {
v.load(0, thisType); v.load(0, thisType);
myStack.push(StackValue.field(JetTypeMapper.jetInterfaceType(contextClass), myStack.push(StackValue.field(JetTypeMapper.jetInterfaceType(contextClass),
thisType.getInternalName(), thisType.getInternalName(),
@@ -1701,8 +1707,8 @@ public class ExpressionCodegen extends JetVisitor {
return; return;
} }
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) { if (containingDeclaration == contextType() && contextType() instanceof ClassDescriptor) {
loadTypeInfo(typeMapper, (ClassDescriptor) contextType, v); loadTypeInfo(typeMapper, (ClassDescriptor) contextType(), v);
v.iconst(typeParameterDescriptor.getIndex()); v.iconst(typeParameterDescriptor.getIndex());
v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;"); v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;");
return; return;
@@ -92,7 +92,8 @@ public class FunctionCodegen {
} }
StackValue thisExpression = receiverType == null ? null : StackValue.local(thisIdx, state.getTypeMapper().mapType(receiverType)); StackValue thisExpression = receiverType == null ? null : StackValue.local(thisIdx, state.getTypeMapper().mapType(receiverType));
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), contextDesc, kind, thisExpression, state); ClassContext context = new ClassContext(contextDesc, kind, thisExpression);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), context, state);
int firstArg = thisIdx+1; int firstArg = thisIdx+1;
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = jvmSignature.getArgumentTypes();
@@ -112,8 +112,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind); ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind);
final InstructionAdapter iv = new InstructionAdapter(mv); final InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)));
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
String classname = state.getTypeMapper().jvmName(descriptor, kind); String classname = state.getTypeMapper().jvmName(descriptor, kind);
final Type classType = Type.getType("L" + classname + ";"); final Type classType = Type.getType("L" + classname + ";");
@@ -291,8 +291,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind); ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind);
final InstructionAdapter iv = new InstructionAdapter(mv); final InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)));
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
for (JetDelegationSpecifier initializer : constructor.getInitializers()) { for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
if (initializer instanceof JetDelegatorToThisCall) { if (initializer instanceof JetDelegatorToThisCall) {
@@ -70,7 +70,7 @@ public class NamespaceCodegen {
mv.visitCode(); mv.visitCode();
FrameMap frameMap = new FrameMap(); FrameMap frameMap = new FrameMap();
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, state); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, ClassContext.STATIC, state);
for (JetDeclaration declaration : namespace.getDeclarations()) { for (JetDeclaration declaration : namespace.getDeclarations()) {
if (declaration instanceof JetProperty) { if (declaration instanceof JetProperty) {