Refactor CodegenContext and subclasses

Drop unused methods, inline parameters, fix warnings, etc.
This commit is contained in:
Alexander Udalov
2015-02-10 16:38:34 +03:00
parent 6ee4c70f2f
commit c84486f860
10 changed files with 70 additions and 79 deletions
@@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.context.ClassContext; import org.jetbrains.kotlin.codegen.context.ClosureContext;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
@@ -71,24 +71,21 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
public ClosureCodegen( public ClosureCodegen(
@NotNull GenerationState state, @NotNull GenerationState state,
@NotNull JetElement element, @NotNull JetElement element,
@NotNull FunctionDescriptor funDescriptor,
@Nullable SamType samType, @Nullable SamType samType,
@NotNull ClassContext context, @NotNull ClosureContext context,
@NotNull KotlinSyntheticClass.Kind syntheticClassKind, @NotNull KotlinSyntheticClass.Kind syntheticClassKind,
@NotNull FunctionGenerationStrategy strategy, @NotNull FunctionGenerationStrategy strategy,
@NotNull MemberCodegen<?> parentCodegen, @NotNull MemberCodegen<?> parentCodegen,
@NotNull ClassBuilder classBuilder, @NotNull ClassBuilder classBuilder
@NotNull Type asmType
) { ) {
super(state, parentCodegen, context, element, classBuilder); super(state, parentCodegen, context, element, classBuilder);
this.funDescriptor = funDescriptor; this.funDescriptor = context.getFunctionDescriptor();
this.classDescriptor = context.getContextDescriptor();
this.samType = samType; this.samType = samType;
this.syntheticClassKind = syntheticClassKind; this.syntheticClassKind = syntheticClassKind;
this.strategy = strategy; this.strategy = strategy;
this.classDescriptor = context.getContextDescriptor();
if (samType == null) { if (samType == null) {
this.superInterfaceTypes = new ArrayList<JetType>(); this.superInterfaceTypes = new ArrayList<JetType>();
@@ -115,7 +112,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
this.closure = bindingContext.get(CLOSURE, classDescriptor); this.closure = bindingContext.get(CLOSURE, classDescriptor);
assert closure != null : "Closure must be calculated for class: " + classDescriptor; assert closure != null : "Closure must be calculated for class: " + classDescriptor;
this.asmType = asmType; this.asmType = typeMapper.mapClass(classDescriptor);
visibilityFlag = AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor); visibilityFlag = AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor);
} }
@@ -1390,13 +1390,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
@Nullable SamType samType, @Nullable SamType samType,
@NotNull KotlinSyntheticClass.Kind kind @NotNull KotlinSyntheticClass.Kind kind
) { ) {
Type asmType = asmTypeForAnonymousClass(bindingContext, descriptor); ClassBuilder cv = state.getFactory().newVisitor(
ClassBuilder cv = state.getFactory().newVisitor(OtherOrigin(declaration, descriptor), asmType, declaration.getContainingFile()); OtherOrigin(declaration, descriptor),
ClassContext closureContext = context.intoClosure(descriptor, this, typeMapper); asmTypeForAnonymousClass(bindingContext, descriptor),
declaration.getContainingFile()
);
ClosureCodegen closureCodegen = new ClosureCodegen( ClosureCodegen closureCodegen = new ClosureCodegen(
state, declaration, descriptor, samType, closureContext, kind, state, declaration, samType, context.intoClosure(descriptor, this, typeMapper), kind, strategy, parentCodegen, cv
strategy, parentCodegen, cv, asmType
); );
closureCodegen.generate(); closureCodegen.generate();
@@ -1410,7 +1411,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
@Override @Override
public StackValue visitObjectLiteralExpression(@NotNull final JetObjectLiteralExpression expression, final StackValue receiver) { public StackValue visitObjectLiteralExpression(@NotNull JetObjectLiteralExpression expression, StackValue receiver) {
final ObjectLiteralResult objectLiteralResult = generateObjectLiteral(expression); final ObjectLiteralResult objectLiteralResult = generateObjectLiteral(expression);
final ClassDescriptor classDescriptor = objectLiteralResult.classDescriptor; final ClassDescriptor classDescriptor = objectLiteralResult.classDescriptor;
final Type type = typeMapper.mapType(classDescriptor); final Type type = typeMapper.mapType(classDescriptor);
@@ -2481,8 +2482,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
public StackValue generateThisOrOuter(@NotNull ClassDescriptor calleeContainingClass, boolean isSuper) { public StackValue generateThisOrOuter(@NotNull ClassDescriptor calleeContainingClass, boolean isSuper) {
boolean isSingleton = calleeContainingClass.getKind().isSingleton(); boolean isSingleton = calleeContainingClass.getKind().isSingleton();
if (isSingleton) { if (isSingleton) {
if (context.hasThisDescriptor() && if (calleeContainingClass.equals(context.getThisDescriptor()) &&
context.getThisDescriptor().equals(calleeContainingClass) &&
!AnnotationsPackage.isPlatformStaticInObjectOrClass(context.getContextDescriptor())) { !AnnotationsPackage.isPlatformStaticInObjectOrClass(context.getContextDescriptor())) {
return StackValue.local(0, typeMapper.mapType(calleeContainingClass)); return StackValue.local(0, typeMapper.mapType(calleeContainingClass));
} }
@@ -31,7 +31,6 @@ public class AnonymousClassContext extends ClassContext {
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable LocalLookup localLookup @Nullable LocalLookup localLookup
) { ) {
//noinspection SuspiciousMethodCalls
super(typeMapper, contextDescriptor, contextKind, parentContext, localLookup); super(typeMapper, contextDescriptor, contextKind, parentContext, localLookup);
} }
@@ -19,12 +19,16 @@ package org.jetbrains.kotlin.codegen.context;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.OwnerKind; import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.codegen.StackValue;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE; import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.canHaveOuter;
public class ClassContext extends FieldOwnerContext<ClassDescriptor> { public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
private final JetTypeMapper typeMapper;
public ClassContext( public ClassContext(
@NotNull JetTypeMapper typeMapper, @NotNull JetTypeMapper typeMapper,
@@ -33,12 +37,28 @@ public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable LocalLookup localLookup @Nullable LocalLookup localLookup
) { ) {
//noinspection SuspiciousMethodCalls
super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor), super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor),
contextDescriptor, localLookup); contextDescriptor, localLookup);
initOuterExpression(typeMapper, contextDescriptor);
this.typeMapper = typeMapper;
} }
@Override
@Nullable
protected StackValue.Field computeOuterExpression() {
ClassDescriptor enclosingClass = getEnclosingClass();
if (enclosingClass == null) return null;
if (!canHaveOuter(typeMapper.getBindingContext(), getContextDescriptor())) return null;
return StackValue.field(
typeMapper.mapType(enclosingClass),
typeMapper.mapType(getContextDescriptor()),
CAPTURED_THIS_FIELD,
/* isStatic = */ false,
StackValue.LOCAL_0
);
}
@Nullable @Nullable
public CodegenContext getClassObjectContext() { public CodegenContext getClassObjectContext() {
@@ -48,11 +68,6 @@ public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
return null; return null;
} }
@Override
public boolean isStatic() {
return false;
}
@Override @Override
public String toString() { public String toString() {
return "Class: " + getContextDescriptor(); return "Class: " + getContextDescriptor();
@@ -20,18 +20,28 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.OwnerKind; import org.jetbrains.kotlin.codegen.OwnerKind;
import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
class ClosureContext extends ClassContext { import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.anonymousClassForFunction;
public class ClosureContext extends ClassContext {
private final FunctionDescriptor functionDescriptor;
public ClosureContext( public ClosureContext(
@NotNull JetTypeMapper typeMapper, @NotNull JetTypeMapper typeMapper,
@NotNull ClassDescriptor classDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable LocalLookup localLookup @NotNull LocalLookup localLookup
) { ) {
//noinspection SuspiciousMethodCalls super(typeMapper, anonymousClassForFunction(typeMapper.getBindingContext(), functionDescriptor),
super(typeMapper, classDescriptor, OwnerKind.IMPLEMENTATION, parentContext, localLookup); OwnerKind.IMPLEMENTATION, parentContext, localLookup);
this.functionDescriptor = functionDescriptor;
}
@NotNull
public FunctionDescriptor getFunctionDescriptor() {
return functionDescriptor;
} }
@Override @Override
@@ -33,10 +33,7 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.util.*; import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag; import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.anonymousClassForFunction;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.canHaveOuter;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED; import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
@@ -49,10 +46,10 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private final ClassDescriptor thisDescriptor; private final ClassDescriptor thisDescriptor;
public final MutableClosure closure; public final MutableClosure closure;
private final LocalLookup enclosingLocalLookup; private final LocalLookup enclosingLocalLookup;
private final NullableLazyValue<StackValue.Field> outerExpression;
private Map<DeclarationDescriptor, DeclarationDescriptor> accessors; private Map<DeclarationDescriptor, DeclarationDescriptor> accessors;
private Map<DeclarationDescriptor, CodegenContext> childContexts; private Map<DeclarationDescriptor, CodegenContext> childContexts;
private NullableLazyValue<StackValue.Field> lazyOuterExpression;
public CodegenContext( public CodegenContext(
@NotNull T contextDescriptor, @NotNull T contextDescriptor,
@@ -60,14 +57,20 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@Nullable CodegenContext parentContext, @Nullable CodegenContext parentContext,
@Nullable MutableClosure closure, @Nullable MutableClosure closure,
@Nullable ClassDescriptor thisDescriptor, @Nullable ClassDescriptor thisDescriptor,
@Nullable LocalLookup expressionCodegen @Nullable LocalLookup localLookup
) { ) {
this.contextDescriptor = contextDescriptor; this.contextDescriptor = contextDescriptor;
this.contextKind = contextKind; this.contextKind = contextKind;
this.parentContext = parentContext; this.parentContext = parentContext;
this.closure = closure; this.closure = closure;
this.thisDescriptor = thisDescriptor; this.thisDescriptor = thisDescriptor;
this.enclosingLocalLookup = expressionCodegen; this.enclosingLocalLookup = localLookup;
this.outerExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue.Field>() {
@Override
public StackValue.Field invoke() {
return computeOuterExpression();
}
});
if (parentContext != null) { if (parentContext != null) {
parentContext.addChild(this); parentContext.addChild(this);
@@ -116,7 +119,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
private StackValue getOuterExpression(@Nullable StackValue prefix, boolean ignoreNoOuter, boolean captureThis) { private StackValue getOuterExpression(@Nullable StackValue prefix, boolean ignoreNoOuter, boolean captureThis) {
if (lazyOuterExpression == null || lazyOuterExpression.invoke() == null) { if (outerExpression.invoke() == null) {
if (!ignoreNoOuter) { if (!ignoreNoOuter) {
throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor()); throw new UnsupportedOperationException("Don't know how to generate outer expression for " + getContextDescriptor());
} }
@@ -128,7 +131,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
closure.setCaptureThis(); closure.setCaptureThis();
} }
return StackValue.changeReceiverForFieldAndSharedVar(lazyOuterExpression.invoke(), prefix); return StackValue.changeReceiverForFieldAndSharedVar(outerExpression.invoke(), prefix);
} }
@NotNull @NotNull
@@ -187,13 +190,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
@NotNull @NotNull
public ClassContext intoClosure( public ClosureContext intoClosure(
@NotNull FunctionDescriptor funDescriptor, @NotNull FunctionDescriptor funDescriptor,
@NotNull LocalLookup localLookup, @NotNull LocalLookup localLookup,
@NotNull JetTypeMapper typeMapper @NotNull JetTypeMapper typeMapper
) { ) {
ClassDescriptor classDescriptor = anonymousClassForFunction(typeMapper.getBindingContext(), funDescriptor); return new ClosureContext(typeMapper, funDescriptor, this, localLookup);
return new ClosureContext(typeMapper, classDescriptor, this, localLookup);
} }
@Nullable @Nullable
@@ -257,21 +259,9 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
return accessor; return accessor;
} }
public abstract boolean isStatic(); @Nullable
protected StackValue.Field computeOuterExpression() {
protected void initOuterExpression(@NotNull final JetTypeMapper typeMapper, @NotNull final ClassDescriptor classDescriptor) { return null;
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue.Field>() {
@Override
public StackValue.Field invoke() {
ClassDescriptor enclosingClass = getEnclosingClass();
if (enclosingClass == null) return null;
return canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor),
CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0)
: null;
}
});
} }
public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) { public StackValue lookupInContext(DeclarationDescriptor d, @Nullable StackValue result, GenerationState state, boolean ignoreNoOuter) {
@@ -78,11 +78,6 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
return lookupInContext(parameter, StackValue.LOCAL_0, state, ignoreNoOuter); return lookupInContext(parameter, StackValue.LOCAL_0, state, ignoreNoOuter);
} }
@Override
public boolean isStatic() {
return getParentContext().isStatic();
}
@Override @Override
public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) { public StackValue getOuterExpression(StackValue prefix, boolean ignoreNoOuter) {
return getParentContext().getOuterExpression(prefix, false); return getParentContext().getOuterExpression(prefix, false);
@@ -31,11 +31,6 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
this.packagePartType = packagePartType; this.packagePartType = packagePartType;
} }
@Override
public boolean isStatic() {
return true;
}
@Override @Override
public String toString() { public String toString() {
return "Package: " + getContextDescriptor().getName(); return "Package: " + getContextDescriptor().getName();
@@ -24,22 +24,17 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.TypeSubstitutor; import org.jetbrains.kotlin.types.TypeSubstitutor;
class RootContext extends CodegenContext { class RootContext extends CodegenContext<RootContext.FakeDescriptor> {
public RootContext() { public RootContext() {
super(new FakeDescriptor(), OwnerKind.PACKAGE, null, null, null, null); super(new FakeDescriptor(), OwnerKind.PACKAGE, null, null, null, null);
} }
@Override
public boolean isStatic() {
return true;
}
@Override @Override
public String toString() { public String toString() {
return "ROOT"; return "ROOT";
} }
private static class FakeDescriptor implements DeclarationDescriptor { static class FakeDescriptor implements DeclarationDescriptor {
@NotNull @NotNull
@Override @Override
public DeclarationDescriptor getOriginal() { public DeclarationDescriptor getOriginal() {
@@ -61,9 +61,4 @@ public class ScriptContext extends FieldOwnerContext<ClassDescriptor> {
} }
return "script$" + (index + 1); return "script$" + (index + 1);
} }
@Override
public boolean isStatic() {
return true;
}
} }