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 GenerationState state;
private final Type returnType;
private final DeclarationDescriptor contextType;
private final OwnerKind contextKind;
private final BindingContext bindingContext;
private final StackValue thisExpression;
private final Map<ClassDescriptor, StackValue> outerThisExpressions = new HashMap<ClassDescriptor, StackValue>();
private final Map<TypeParameterDescriptor, StackValue> typeParameterExpressions = new HashMap<TypeParameterDescriptor, StackValue>();
private final ClassContext context;
public ExpressionCodegen(MethodVisitor v,
FrameMap myMap,
Type returnType,
DeclarationDescriptor contextType,
OwnerKind contextKind,
@Nullable StackValue thisExpression,
ClassContext context,
GenerationState state) {
this.myMap = myMap;
this.typeMapper = state.getTypeMapper();
this.returnType = returnType;
this.contextType = contextType;
this.contextKind = contextKind;
this.state = state;
this.v = new InstructionAdapter(v);
this.bindingContext = state.getBindingContext();
this.thisExpression = thisExpression;
this.context = context;
}
public void addOuterThis(ClassDescriptor outer, StackValue expression) {
@@ -320,6 +314,18 @@ public class ExpressionCodegen extends JetVisitor {
myContinueTargets.pop();
}
private DeclarationDescriptor contextType() {
return context.getContextType();
}
private OwnerKind contextKind() {
return context.getContextKind();
}
private StackValue thisExpression() {
return context.getThisExpression();
}
private abstract class ForLoopGenerator {
protected JetForExpression expression;
protected Type loopRangeType;
@@ -682,7 +688,7 @@ public class ExpressionCodegen extends JetVisitor {
boolean isStatic = containingDeclaration instanceof NamespaceDescriptorImpl;
propertyDescriptor = propertyDescriptor.getOriginal();
final JetType outType = propertyDescriptor.getOutType();
boolean isInsideClass = !forceInterface && containingDeclaration == contextType;
boolean isInsideClass = !forceInterface && containingDeclaration == contextType();
Method getter;
Method setter;
if (forceField) {
@@ -697,7 +703,7 @@ public class ExpressionCodegen extends JetVisitor {
String owner;
boolean isInterface;
if (isInsideClass || isStatic) {
owner = typeMapper.getOwner(propertyDescriptor, contextKind);
owner = typeMapper.getOwner(propertyDescriptor, contextKind());
isInterface = false;
}
else {
@@ -891,17 +897,17 @@ public class ExpressionCodegen extends JetVisitor {
}
else {
// TODO hope it works; really need more checks here :)
if (calleeContainingClass != null && contextType instanceof ClassDescriptor &&
calleeContainingClass == contextType.getContainingDeclaration()) {
if (calleeContainingClass != null && contextType() instanceof ClassDescriptor &&
calleeContainingClass == contextType().getContainingDeclaration()) {
v.load(0, JetTypeMapper.TYPE_OBJECT);
return StackValue.field(typeMapper.jvmType(calleeContainingClass, OwnerKind.IMPLEMENTATION),
typeMapper.jvmName((ClassDescriptor) contextType, OwnerKind.IMPLEMENTATION),
typeMapper.jvmName((ClassDescriptor) contextType(), OwnerKind.IMPLEMENTATION),
"this$0",
false);
// TODO handle more levels of class nestng
}
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() {
if (thisExpression != null) {
myStack.push(thisExpression);
if (thisExpression() != null) {
myStack.push(thisExpression());
return;
}
if (contextKind != OwnerKind.NAMESPACE) {
ClassDescriptor contextClass = (ClassDescriptor) contextType;
final Type thisType = typeMapper.jvmType(contextClass, contextKind);
if (contextKind == OwnerKind.IMPLEMENTATION) {
if (contextKind() != OwnerKind.NAMESPACE) {
ClassDescriptor contextClass = (ClassDescriptor) contextType();
final Type thisType = typeMapper.jvmType(contextClass, contextKind());
if (contextKind() == OwnerKind.IMPLEMENTATION) {
myStack.push(StackValue.local(0, thisType));
return;
}
else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) {
else if (contextKind() == OwnerKind.DELEGATING_IMPLEMENTATION) {
v.load(0, thisType);
myStack.push(StackValue.field(JetTypeMapper.jetInterfaceType(contextClass),
thisType.getInternalName(),
@@ -1701,8 +1707,8 @@ public class ExpressionCodegen extends JetVisitor {
return;
}
DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration();
if (containingDeclaration == contextType && contextType instanceof ClassDescriptor) {
loadTypeInfo(typeMapper, (ClassDescriptor) contextType, v);
if (containingDeclaration == contextType() && contextType() instanceof ClassDescriptor) {
loadTypeInfo(typeMapper, (ClassDescriptor) contextType(), v);
v.iconst(typeParameterDescriptor.getIndex());
v.invokevirtual("jet/typeinfo/TypeInfo", "getTypeParameter", "(I)Ljet/typeinfo/TypeInfo;");
return;
@@ -92,7 +92,8 @@ public class FunctionCodegen {
}
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;
Type[] argTypes = jvmSignature.getArgumentTypes();
@@ -112,8 +112,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, kind);
final InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE,
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state);
ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)));
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
String classname = state.getTypeMapper().jvmName(descriptor, kind);
final Type classType = Type.getType("L" + classname + ";");
@@ -291,8 +291,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, kind);
final InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE,
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state);
ClassContext context = new ClassContext(descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)));
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state);
for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
if (initializer instanceof JetDelegatorToThisCall) {
@@ -70,7 +70,7 @@ public class NamespaceCodegen {
mv.visitCode();
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()) {
if (declaration instanceof JetProperty) {