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.JetTypeMapperMode;
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.java.JvmAbi;
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) {
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);
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;
JvmClassName scriptClassName = classNameForScriptDescriptor(bindingContext, scriptDescriptor);
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);
script.put(script.type, v);
Type fieldType = typeMapper.mapType(valueParameterDescriptor);
@@ -65,7 +65,7 @@ public class ScriptCodegen extends MemberCodegen {
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, scriptDeclaration);
assert scriptDescriptor != null;
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_FUNCTION, scriptDescriptor);
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
assert classDescriptorForScript != null;
ScriptContext context =
@@ -183,8 +183,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
public void visitJetFile(JetFile file) {
if (file.isScript()) {
//noinspection ConstantConditions
ClassDescriptor classDescriptor =
bindingContext.get(CLASS_FOR_FUNCTION, bindingContext.get(SCRIPT, file.getScript()));
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript()));
classStack.push(classDescriptor);
//noinspection ConstantConditions
nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName());
@@ -45,7 +45,9 @@ import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDec
public class CodegenBinding {
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();
@@ -77,9 +79,9 @@ public class CodegenBinding {
@NotNull
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
return bindingContext.get(FQN, classDescriptor);
return fqn(bindingContext, classDescriptor);
}
@NotNull
@@ -96,7 +98,23 @@ public class CodegenBinding {
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) {
JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression;
expression = jetObjectLiteralExpression.getObjectDeclaration();
@@ -106,9 +124,16 @@ public class CodegenBinding {
if (descriptor == null) {
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
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(
@@ -135,7 +160,7 @@ public class CodegenBinding {
recordClosure(bindingTrace, null, classDescriptor, null, className, false);
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) {
@@ -179,8 +179,7 @@ public abstract class CodegenContext {
@NotNull LocalLookup localLookup,
@NotNull JetTypeMapper typeMapper
) {
ClassDescriptor classDescriptor = typeMapper.getBindingContext().get(CLASS_FOR_FUNCTION, funDescriptor);
assert classDescriptor != null : "Closure class for function should be present: " + funDescriptor;
ClassDescriptor classDescriptor = anonymousClassForFunction(typeMapper.getBindingContext(), funDescriptor);
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.state.GenerationState;
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.types.JetType;
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.isLocalNamedFun;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration;
public interface LocalLookup {
boolean lookupLocal(DeclarationDescriptor descriptor);
@@ -88,9 +86,7 @@ public interface LocalLookup {
boolean idx = localLookup != null && localLookup.lookupLocal(vd);
if (!idx) return null;
JetElement expression = (JetElement) callableDescriptorToDeclaration(state.getBindingContext(), vd);
JvmClassName cn = classNameForAnonymousClass(state.getBindingContext(), expression);
Type localType = cn.getAsmType();
Type localType = classNameForAnonymousClass(state.getBindingContext(), vd).getAsmType();
String fieldName = "$" + vd.getName();
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.lang.descriptors.*;
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.resolve.BindingContext;
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.CodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
public class JetTypeMapper extends BindingTraceAware {
@@ -825,10 +823,7 @@ public class JetTypeMapper extends BindingTraceAware {
signatureWriter.writeParameterTypeEnd();
}
else if (isLocalNamedFun(variableDescriptor)) {
Type type = classNameForAnonymousClass(
bindingContext,
(JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, variableDescriptor)
).getAsmType();
Type type = classNameForAnonymousClass(bindingContext, (FunctionDescriptor) variableDescriptor).getAsmType();
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
signatureWriter.writeAsmType(type, false);
@@ -883,7 +878,7 @@ public class JetTypeMapper extends BindingTraceAware {
for (ScriptDescriptor importedScript : importedScripts) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_FUNCTION, importedScript);
ClassDescriptor descriptor = bindingContext.get(CLASS_FOR_SCRIPT, importedScript);
assert descriptor != null;
mapType(descriptor.getDefaultType(), signatureWriter, JetTypeMapperMode.VALUE);
signatureWriter.writeParameterTypeEnd();
@@ -927,8 +922,7 @@ public class JetTypeMapper extends BindingTraceAware {
.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType()));
}
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
PsiElement psiElement = descriptorToDeclaration(bindingContext, descriptor);
return classNameForAnonymousClass(bindingContext, (JetElement) psiElement).getAsmType();
return classNameForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor).getAsmType();
}
else if (descriptor instanceof FunctionDescriptor) {
return StackValue