move inner classes of CodegenContext into CodegenContexts

This commit is contained in:
Stepan Koltsov
2012-05-28 17:34:45 +04:00
parent c2c45669f0
commit b2cea09fcc
8 changed files with 247 additions and 214 deletions
@@ -198,7 +198,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
final CodegenContext.ClosureContext closureContext = context.intoClosure(
final CodegenContexts.ClosureContext closureContext = context.intoClosure(
funDescriptor, function, name.getInternalName(), this, state.getInjector().getJetTypeMapper());
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
@@ -35,25 +35,6 @@ import java.util.LinkedHashMap;
* @author alex.tkachman
*/
public abstract class CodegenContext {
public static final CodegenContext STATIC = new CodegenContext(null, OwnerKind.NAMESPACE, null, null) {
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "ROOT";
}
};
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
private final DeclarationDescriptor contextType;
@@ -121,31 +102,31 @@ public abstract class CodegenContext {
}
public CodegenContext intoNamespace(NamespaceDescriptor descriptor) {
return new NamespaceContext(descriptor, this);
return new CodegenContexts.NamespaceContext(descriptor, this);
}
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new ClassContext(descriptor, kind, this, typeMapper);
return new CodegenContexts.ClassContext(descriptor, kind, this, typeMapper);
}
public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
return new CodegenContexts.AnonymousClassContext(descriptor, kind, this, closure, typeMapper);
}
public MethodContext intoFunction(FunctionDescriptor descriptor) {
return new MethodContext(descriptor, getContextKind(), this);
public CodegenContexts.MethodContext intoFunction(FunctionDescriptor descriptor) {
return new CodegenContexts.MethodContext(descriptor, getContextKind(), this);
}
public ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
public CodegenContexts.ConstructorContext intoConstructor(ConstructorDescriptor descriptor, JetTypeMapper typeMapper) {
if(descriptor == null) {
descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.<AnnotationDescriptor>emptyList(), true)
.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(), Visibilities.PUBLIC);
}
return new ConstructorContext(descriptor, getContextKind(), this, typeMapper);
return new CodegenContexts.ConstructorContext(descriptor, getContextKind(), this, typeMapper);
}
public ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, String internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) {
return new ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
public CodegenContexts.ClosureContext intoClosure(FunctionDescriptor funDescriptor, ClassDescriptor classDescriptor, String internalClassName, ClosureCodegen closureCodegen, JetTypeMapper typeMapper) {
return new CodegenContexts.ClosureContext(funDescriptor, classDescriptor, this, closureCodegen, internalClassName, typeMapper);
}
public FrameMap prepareFrame(JetTypeMapper mapper) {
@@ -190,7 +171,7 @@ public abstract class CodegenContext {
}
public int getTypeInfoConstantIndex(JetType type) {
if (parentContext != STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
if (parentContext != CodegenContexts.STATIC) { return parentContext.getTypeInfoConstantIndex(type); }
if(typeInfoConstants == null) {
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
@@ -280,174 +261,4 @@ public abstract class CodegenContext {
this.accessors.putAll(accessors);
}
}
public abstract static class ReceiverContext extends CodegenContext {
final CallableDescriptor receiverDescriptor;
public ReceiverContext(CallableDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
super(contextType, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
}
@Override
protected CallableDescriptor getReceiverDescriptor() {
return receiverDescriptor;
}
}
public static class MethodContext extends ReceiverContext {
public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return getParentContext().getThisDescriptor();
}
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
return getParentContext().lookupInContext(d, v, result);
}
public Type enclosingClassType(JetTypeMapper typeMapper) {
return getParentContext().enclosingClassType(typeMapper);
}
@Override
public boolean isStatic() {
return getParentContext().isStatic();
}
protected StackValue getOuterExpression(StackValue prefix) {
return getParentContext().getOuterExpression(prefix);
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();
}
}
public static class ConstructorContext extends MethodContext {
public ConstructorContext(ConstructorDescriptor contextType, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) {
super(contextType, kind, parent);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? local1
: null;
}
protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression;
}
@Override
public String toString() {
return "Constructor: " + getContextDescriptor().getName();
}
}
public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, null);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
}
public static class AnonymousClassContext extends CodegenContext {
public AnonymousClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL);
outerExpression = type != null
? StackValue.field(type, owner.getInternalName(), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Anonymous: " + getThisDescriptor();
}
}
public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName, JetTypeMapper typeMapper) {
super(contextType, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen);
this.classDescriptor = classDescriptor;
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, internalClassName, "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return classDescriptor;
}
@Override
public DeclarationDescriptor getContextDescriptor() {
return classDescriptor;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Closure: " + classDescriptor;
}
}
public static class NamespaceContext extends CodegenContext {
public NamespaceContext(NamespaceDescriptor contextType, CodegenContext parent) {
super(contextType, OwnerKind.NAMESPACE, parent, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "Namespace: " + getContextDescriptor().getName();
}
}
}
@@ -0,0 +1,223 @@
/*
* Copyright 2010-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.PropertyAccessorDescriptor;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
/**
* @author Stepan Koltsov
*/
public class CodegenContexts {
public static final CodegenContext STATIC = new CodegenContext(null, OwnerKind.NAMESPACE, null, null) {
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "ROOT";
}
};
protected static final StackValue local0 = StackValue.local(0, JetTypeMapper.TYPE_OBJECT);
protected static final StackValue local1 = StackValue.local(1, JetTypeMapper.TYPE_OBJECT);
public abstract static class ReceiverContext extends CodegenContext {
final CallableDescriptor receiverDescriptor;
public ReceiverContext(CallableDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
super(contextType, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
}
@Override
protected CallableDescriptor getReceiverDescriptor() {
return receiverDescriptor;
}
}
public static class MethodContext extends ReceiverContext {
public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return getParentContext().getThisDescriptor();
}
public StackValue lookupInContext(DeclarationDescriptor d, InstructionAdapter v, StackValue result) {
return getParentContext().lookupInContext(d, v, result);
}
public Type enclosingClassType(JetTypeMapper typeMapper) {
return getParentContext().enclosingClassType(typeMapper);
}
@Override
public boolean isStatic() {
return getParentContext().isStatic();
}
protected StackValue getOuterExpression(StackValue prefix) {
return getParentContext().getOuterExpression(prefix);
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();
}
}
public static class ConstructorContext extends MethodContext {
public ConstructorContext(ConstructorDescriptor contextType, OwnerKind kind, CodegenContext parent, JetTypeMapper typeMapper) {
super(contextType, kind, parent);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? local1
: null;
}
protected StackValue getOuterExpression(StackValue prefix) {
return outerExpression;
}
@Override
public String toString() {
return "Constructor: " + getContextDescriptor().getName();
}
}
public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, null);
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
}
public static class AnonymousClassContext extends CodegenContext {
public AnonymousClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closure, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL);
outerExpression = type != null
? StackValue.field(type, owner.getInternalName(), "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return (ClassDescriptor) getContextDescriptor();
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Anonymous: " + getThisDescriptor();
}
}
public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName, JetTypeMapper typeMapper) {
super(contextType, OwnerKind.IMPLEMENTATION, parentContext, closureCodegen);
this.classDescriptor = classDescriptor;
final Type type = enclosingClassType(typeMapper);
outerExpression = type != null
? StackValue.field(type, internalClassName, "this$0", false)
: null;
}
@Override
protected ClassDescriptor getThisDescriptor() {
return classDescriptor;
}
@Override
public DeclarationDescriptor getContextDescriptor() {
return classDescriptor;
}
@Override
public boolean isStatic() {
return false;
}
@Override
public String toString() {
return "Closure: " + classDescriptor;
}
}
public static class NamespaceContext extends CodegenContext {
public NamespaceContext(NamespaceDescriptor contextType, CodegenContext parent) {
super(contextType, OwnerKind.NAMESPACE, parent, null);
}
@Override
protected ClassDescriptor getThisDescriptor() {
return null;
}
@Override
public boolean isStatic() {
return true;
}
@Override
public String toString() {
return "Namespace: " + getContextDescriptor().getName();
}
}
}
@@ -1162,7 +1162,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
boolean isStatic = containingDeclaration instanceof NamespaceDescriptor;
propertyDescriptor = propertyDescriptor.getOriginal();
boolean isInsideClass = ((containingDeclaration == context.getThisDescriptor()) ||
(context.getParentContext() instanceof CodegenContext.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
(context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration)
&& contextKind() != OwnerKind.TRAIT_IMPL;
Method getter;
Method setter;
@@ -1438,8 +1438,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue generateReceiver(DeclarationDescriptor provided) {
assert context instanceof CodegenContext.ReceiverContext;
CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
assert context instanceof CodegenContexts.ReceiverContext;
CodegenContexts.ReceiverContext cur = (CodegenContexts.ReceiverContext) context;
if (cur.getReceiverDescriptor() == provided) {
StackValue result = cur.getReceiverExpression(typeMapper);
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, null);
@@ -1458,7 +1458,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
cur = context;
StackValue result = StackValue.local(0, TYPE_OBJECT);
while (cur != null) {
if(cur instanceof CodegenContext.MethodContext && !(cur instanceof CodegenContext.ConstructorContext))
if(cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext))
cur = cur.getParentContext();
if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
@@ -1474,7 +1474,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
result = cur.getOuterExpression(result);
if(cur instanceof CodegenContext.ConstructorContext) {
if(cur instanceof CodegenContexts.ConstructorContext) {
cur = cur.getParentContext();
}
cur = cur.getParentContext();
@@ -69,7 +69,7 @@ public class FunctionCodegen {
JvmMethodSignature jvmMethod, boolean needJetAnnotations,
@Nullable String propertyTypeSignature, FunctionDescriptor functionDescriptor) {
CodegenContext.MethodContext funContext = owner.intoFunction(functionDescriptor);
CodegenContexts.MethodContext funContext = owner.intoFunction(functionDescriptor);
final JetExpression bodyExpression = f.getBodyExpression();
generatedMethod(bodyExpression, jvmMethod, needJetAnnotations, propertyTypeSignature, funContext, functionDescriptor, f);
@@ -78,7 +78,7 @@ public class FunctionCodegen {
private void generatedMethod(JetExpression bodyExpressions,
JvmMethodSignature jvmSignature,
boolean needJetAnnotations, @Nullable String propertyTypeSignature,
CodegenContext.MethodContext context,
CodegenContexts.MethodContext context,
FunctionDescriptor functionDescriptor,
JetDeclarationWithBody fun
)
@@ -301,7 +301,7 @@ public class FunctionCodegen {
}
}
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
static void generateDefaultIfNeeded(CodegenContexts.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, @Nullable FunctionDescriptor functionDescriptor, OwnerKind kind) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if(kind != OwnerKind.TRAIT_IMPL) {
@@ -449,7 +449,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
CodegenContexts.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
JvmMethodSignature constructorMethod;
CallableMethod callableMethod;
@@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.objectweb.asm.MethodVisitor;
@@ -57,7 +56,7 @@ public class NamespaceCodegen {
public void generate(JetFile file) {
NamespaceDescriptor descriptor = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, file);
final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor);
final CodegenContext context = CodegenContexts.STATIC.intoNamespace(descriptor);
final FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state);
final PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, state);
@@ -100,7 +99,7 @@ public class NamespaceCodegen {
mv.visitCode();
FrameMap frameMap = new FrameMap();
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC, state);
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContexts.STATIC, state);
for (JetDeclaration declaration : namespace.getDeclarations()) {
if (declaration instanceof JetProperty) {
@@ -106,9 +106,9 @@ public class ObjectOrClosureCodegen {
FunctionDescriptor fd = (FunctionDescriptor) d;
// we generate method
assert context instanceof CodegenContext.ReceiverContext;
assert context instanceof CodegenContexts.ReceiverContext;
CodegenContext.ReceiverContext fcontext = (CodegenContext.ReceiverContext) context;
CodegenContexts.ReceiverContext fcontext = (CodegenContexts.ReceiverContext) context;
if(fcontext.getReceiverDescriptor() != fd)
return null;