Minor refactoring in CodegenBinding

- CLASS_FOR_FUNCTION slice was used for two purposes: to record closure classes
  for functions and for scripts. Separate this slice into two slices:
  CLASS_FOR_FUNCTION and CLASS_FOR_SCRIPT
- add classNameForAnonymousClass() overloaded method to CodegenBinding, taking
  a function descriptor (not a PSI element)
This commit is contained in:
Alexander Udalov
2013-04-08 20:11:14 +04:00
parent f907d008e7
commit 121cb13883
8 changed files with 43 additions and 28 deletions
@@ -35,6 +35,7 @@ import org.jetbrains.jet.codegen.state.GenerationStateAware;
import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDeclarationWithBody;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
@@ -1249,7 +1249,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
private StackValue genClosure(JetDeclarationWithBody declaration, @Nullable ClassDescriptor samInterfaceClass) { private StackValue genClosure(JetDeclarationWithBody declaration, @Nullable ClassDescriptor samInterfaceClass) {
FunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, declaration); FunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_FUNCTION, descriptor); assert descriptor != null : "Function is not resolved to descriptor: " + declaration.getText();
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, descriptor);
CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor); CalculatedClosure 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;
@@ -1624,7 +1625,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert scriptDescriptor != null; assert scriptDescriptor != null;
JvmClassName scriptClassName = classNameForScriptDescriptor(bindingContext, scriptDescriptor); JvmClassName scriptClassName = classNameForScriptDescriptor(bindingContext, scriptDescriptor);
ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor; ValueParameterDescriptor valueParameterDescriptor = (ValueParameterDescriptor) descriptor;
ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_FUNCTION, scriptDescriptor); ClassDescriptor scriptClass = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
StackValue script = StackValue.thisOrOuter(this, scriptClass, false); StackValue script = StackValue.thisOrOuter(this, scriptClass, false);
script.put(script.type, v); script.put(script.type, v);
Type fieldType = typeMapper.mapType(valueParameterDescriptor); Type fieldType = typeMapper.mapType(valueParameterDescriptor);
@@ -65,7 +65,7 @@ public class ScriptCodegen extends MemberCodegen {
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration); ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
assert scriptDescriptor != null; assert scriptDescriptor != null;
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_FUNCTION, scriptDescriptor); ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
assert classDescriptorForScript != null; assert classDescriptorForScript != null;
ScriptContext context = ScriptContext context =
@@ -183,8 +183,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
public void visitJetFile(JetFile file) { public void visitJetFile(JetFile file) {
if (file.isScript()) { if (file.isScript()) {
//noinspection ConstantConditions //noinspection ConstantConditions
ClassDescriptor classDescriptor = ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript()));
bindingContext.get(CLASS_FOR_FUNCTION, bindingContext.get(SCRIPT, file.getScript()));
classStack.push(classDescriptor); classStack.push(classDescriptor);
//noinspection ConstantConditions //noinspection ConstantConditions
nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName()); nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName());
@@ -45,7 +45,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDec
public class CodegenBinding { public class CodegenBinding {
public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice(); public static final WritableSlice<ClassDescriptor, MutableClosure> CLOSURE = Slices.createSimpleSlice();
public static final WritableSlice<DeclarationDescriptor, ClassDescriptor> CLASS_FOR_FUNCTION = Slices.createSimpleSlice(); public static final WritableSlice<FunctionDescriptor, ClassDescriptor> CLASS_FOR_FUNCTION = Slices.createSimpleSlice();
public static final WritableSlice<ScriptDescriptor, ClassDescriptor> CLASS_FOR_SCRIPT = Slices.createSimpleSlice();
public static final WritableSlice<DeclarationDescriptor, JvmClassName> FQN = Slices.createSimpleSlice(); public static final WritableSlice<DeclarationDescriptor, JvmClassName> FQN = Slices.createSimpleSlice();
@@ -77,9 +79,9 @@ public class CodegenBinding {
@NotNull @NotNull
public static JvmClassName classNameForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) { public static JvmClassName classNameForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) {
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_FUNCTION, scriptDescriptor); ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
//noinspection ConstantConditions //noinspection ConstantConditions
return bindingContext.get(FQN, classDescriptor); return fqn(bindingContext, classDescriptor);
} }
@NotNull @NotNull
@@ -96,7 +98,23 @@ public class CodegenBinding {
return closure == null ? null : closure.getEnclosingClass(); return closure == null ? null : closure.getEnclosingClass();
} }
public static JvmClassName classNameForAnonymousClass(BindingContext bindingContext, JetElement expression) { @NotNull
public static ClassDescriptor anonymousClassForFunction(
@NotNull BindingContext bindingContext,
@NotNull FunctionDescriptor descriptor
) {
//noinspection ConstantConditions
return bindingContext.get(CLASS_FOR_FUNCTION, descriptor);
}
@NotNull
private static JvmClassName fqn(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor descriptor) {
//noinspection ConstantConditions
return bindingContext.get(FQN, descriptor);
}
@NotNull
public static JvmClassName classNameForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull JetElement expression) {
if (expression instanceof JetObjectLiteralExpression) { if (expression instanceof JetObjectLiteralExpression) {
JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression; JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression;
expression = jetObjectLiteralExpression.getObjectDeclaration(); expression = jetObjectLiteralExpression.getObjectDeclaration();
@@ -106,9 +124,16 @@ public class CodegenBinding {
if (descriptor == null) { if (descriptor == null) {
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
assert functionDescriptor != null; assert functionDescriptor != null;
descriptor = bindingContext.get(CLASS_FOR_FUNCTION, functionDescriptor); return classNameForAnonymousClass(bindingContext, functionDescriptor);
} }
return bindingContext.get(FQN, descriptor);
return fqn(bindingContext, descriptor);
}
@NotNull
public static JvmClassName classNameForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull FunctionDescriptor descriptor) {
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, descriptor);
return fqn(bindingContext, classDescriptor);
} }
public static void registerClassNameForScript( public static void registerClassNameForScript(
@@ -135,7 +160,7 @@ public class CodegenBinding {
recordClosure(bindingTrace, null, classDescriptor, null, className, false); recordClosure(bindingTrace, null, classDescriptor, null, className, false);
assert PsiCodegenPredictor.checkPredictedClassNameForFun(bindingTrace.getBindingContext(), scriptDescriptor, classDescriptor); assert PsiCodegenPredictor.checkPredictedClassNameForFun(bindingTrace.getBindingContext(), scriptDescriptor, classDescriptor);
bindingTrace.record(CLASS_FOR_FUNCTION, scriptDescriptor, classDescriptor); bindingTrace.record(CLASS_FOR_SCRIPT, scriptDescriptor, classDescriptor);
} }
public static boolean canHaveOuter(BindingContext bindingContext, @NotNull ClassDescriptor classDescriptor) { public static boolean canHaveOuter(BindingContext bindingContext, @NotNull ClassDescriptor classDescriptor) {
@@ -179,8 +179,7 @@ public abstract class CodegenContext {
@NotNull LocalLookup localLookup, @NotNull LocalLookup localLookup,
@NotNull JetTypeMapper typeMapper @NotNull JetTypeMapper typeMapper
) { ) {
ClassDescriptor classDescriptor = typeMapper.getBindingContext().get(CLASS_FOR_FUNCTION, funDescriptor); ClassDescriptor classDescriptor = anonymousClassForFunction(typeMapper.getBindingContext(), funDescriptor);
assert classDescriptor != null : "Closure class for function should be present: " + funDescriptor;
return new ClosureContext(typeMapper, funDescriptor, classDescriptor, this, localLookup); return new ClosureContext(typeMapper, funDescriptor, classDescriptor, this, localLookup);
} }
@@ -22,14 +22,12 @@ import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_RECEIVER_FIELD; import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_RECEIVER_FIELD;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.classNameForAnonymousClass; import static org.jetbrains.jet.codegen.binding.CodegenBinding.classNameForAnonymousClass;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
public interface LocalLookup { public interface LocalLookup {
boolean lookupLocal(DeclarationDescriptor descriptor); boolean lookupLocal(DeclarationDescriptor descriptor);
@@ -88,9 +86,7 @@ public interface LocalLookup {
boolean idx = localLookup != null && localLookup.lookupLocal(vd); boolean idx = localLookup != null && localLookup.lookupLocal(vd);
if (!idx) return null; if (!idx) return null;
JetElement expression = (JetElement) callableDescriptorToDeclaration(state.getBindingContext(), vd); Type localType = classNameForAnonymousClass(state.getBindingContext(), vd).getAsmType();
JvmClassName cn = classNameForAnonymousClass(state.getBindingContext(), expression);
Type localType = cn.getAsmType();
String fieldName = "$" + vd.getName(); String fieldName = "$" + vd.getName();
StackValue innerValue = StackValue.field(localType, className, fieldName, false); StackValue innerValue = StackValue.field(localType, className, fieldName, false);
@@ -28,7 +28,6 @@ import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.codegen.signature.*;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
@@ -49,7 +48,6 @@ import static org.jetbrains.jet.codegen.AsmUtil.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType; import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
public class JetTypeMapper extends BindingTraceAware { public class JetTypeMapper extends BindingTraceAware {
@@ -825,10 +823,7 @@ public class JetTypeMapper extends BindingTraceAware {
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
else if (isLocalNamedFun(variableDescriptor)) { else if (isLocalNamedFun(variableDescriptor)) {
Type type = classNameForAnonymousClass( Type type = classNameForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor).getAsmType();
bindingContext,
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, variableDescriptor)
).getAsmType();
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
signatureWriter.writeAsmType(type, false); signatureWriter.writeAsmType(type, false);
@@ -883,7 +878,7 @@ public class JetTypeMapper extends BindingTraceAware {
for (ScriptDescriptor importedScript : importedScripts) { for (ScriptDescriptor importedScript : importedScripts) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_FUNCTION, importedScript); ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_SCRIPT, importedScript);
assert descriptor != null; assert descriptor != null;
mapType(descriptor.getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE); mapType(descriptor.getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
@@ -927,8 +922,7 @@ public class JetTypeMapper extends BindingTraceAware {
.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType())); .sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType()));
} }
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
PsiElement psiElement = descriptorToDeclaration(bindingContext, descriptor); return classNameForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor).getAsmType();
return classNameForAnonymousClass(bindingContext, (JetElement) psiElement).getAsmType();
} }
else if (descriptor instanceof FunctionDescriptor) { else if (descriptor instanceof FunctionDescriptor) {
return StackValue return StackValue