Refactor CodegenBinding#getAsmType()

- make it return the ASM_TYPE slice value and assert it is there
- move all the computation to the separate method "computeAsmType"
- only call getAsmType() in those places where the type must be recorded at
  slice ASM_TYPE, otherwise call JetTypeMapper#mapType(), which will check the
  slice and call computeAsmType
This commit is contained in:
Alexander Udalov
2014-09-02 18:58:07 +04:00
parent c1125402bd
commit d4a845da01
5 changed files with 37 additions and 29 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.jet.codegen;
import com.intellij.util.ArrayUtil;
import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.codegen.context.CodegenContext;
@@ -38,7 +39,8 @@ import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.method;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLASS_FOR_SCRIPT;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.asmTypeForScriptDescriptor;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.DiagnosticsPackage.OtherOrigin;
import static org.jetbrains.jet.lang.resolve.java.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
@@ -52,17 +54,17 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@NotNull GenerationState state,
@NotNull CodegenContext parentContext
) {
ScriptDescriptor scriptDescriptor = state.getBindingContext().get(BindingContext.SCRIPT, declaration);
BindingContext bindingContext = state.getBindingContext();
ScriptDescriptor scriptDescriptor = bindingContext.get(BindingContext.SCRIPT, declaration);
assert scriptDescriptor != null;
ClassDescriptor classDescriptorForScript = state.getBindingContext().get(CLASS_FOR_SCRIPT, scriptDescriptor);
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
assert classDescriptorForScript != null;
Type className = state.getBindingContext().get(ASM_TYPE, classDescriptorForScript);
assert className != null;
Type classType = asmTypeForScriptDescriptor(bindingContext, scriptDescriptor);
ClassBuilder builder = state.getFactory().newVisitor(OtherOrigin(declaration, classDescriptorForScript),
className, declaration.getContainingFile());
classType, declaration.getContainingFile());
List<ScriptDescriptor> earlierScripts = state.getEarlierScriptsForReplInterpreter();
ScriptContext scriptContext = parentContext.intoScript(
scriptDescriptor,
@@ -90,8 +92,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@Override
protected void generateDeclaration() {
Type classType = bindingContext.get(ASM_TYPE, context.getContextDescriptor());
assert classType != null;
Type classType = typeMapper.mapClass(context.getContextDescriptor());
v.defineClass(scriptDeclaration,
V1_6,
@@ -99,7 +100,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
classType.getInternalName(),
null,
"java/lang/Object",
new String[0]);
ArrayUtil.EMPTY_STRING_ARRAY);
generateReflectionObjectField(state, classType, v, method("kClassFromKotlin", K_CLASS_IMPL_TYPE, getType(Class.class)),
JvmAbi.KOTLIN_CLASS_FIELD_NAME, createOrGetClInitCodegen().v);
@@ -124,6 +125,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
@NotNull ClassBuilder classBuilder,
@NotNull final MethodContext methodContext
) {
//noinspection ConstantConditions
Type blockType = typeMapper.mapType(scriptDescriptor.getScriptCodeDescriptor().getReturnType());
PropertyDescriptor scriptResultProperty = scriptDescriptor.getScriptResultProperty();
@@ -142,8 +144,7 @@ public class ScriptCodegen extends MemberCodegen<JetScript> {
final InstructionAdapter iv = new InstructionAdapter(mv);
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript);
assert classType != null;
Type classType = typeMapper.mapType(classDescriptorForScript);
iv.load(0, classType);
iv.invokespecial("java/lang/Object", "<init>", "()V", false);
@@ -23,7 +23,10 @@ import com.intellij.util.containers.Stack;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.codegen.AsmUtil;
import org.jetbrains.jet.codegen.JvmRuntimeTypes;
import org.jetbrains.jet.codegen.SamCodegenUtil;
import org.jetbrains.jet.codegen.SamType;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.when.SwitchCodegenUtil;
import org.jetbrains.jet.codegen.when.WhenByEnumsMapping;
@@ -261,8 +264,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
recordClosure(expression.getObjectDeclaration(), classDescriptor, name);
pushClassDescriptor(classDescriptor);
//noinspection ConstantConditions
nameStack.push(bindingContext.get(ASM_TYPE, classDescriptor).getInternalName());
nameStack.push(CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName());
super.visitObjectLiteralExpression(expression);
nameStack.pop();
popClassDescriptor();
@@ -287,19 +287,25 @@ public class CodegenBinding {
@NotNull
public static Type getAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
klass = (ClassDescriptor) klass.getOriginal();
Type type = bindingContext.get(ASM_TYPE, klass);
assert type != null : "Type is not yet recorded for " + klass;
return type;
}
@NotNull
public static Type computeAsmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
Type alreadyComputedType = bindingContext.get(ASM_TYPE, klass);
if (alreadyComputedType != null) {
return alreadyComputedType;
}
Type asmType = Type.getObjectType(getAsmTypeImpl(bindingContext, klass));
Type asmType = Type.getObjectType(computeAsmTypeImpl(bindingContext, klass));
assert PsiCodegenPredictor.checkPredictedNameFromPsi(klass, asmType);
return asmType;
}
@NotNull
private static String getAsmTypeImpl(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
private static String computeAsmTypeImpl(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor klass) {
DeclarationDescriptor container = klass.getContainingDeclaration();
Name name = SpecialNames.safeIdentifier(klass.getName());
@@ -316,7 +322,7 @@ public class CodegenBinding {
assert container instanceof ClassDescriptor : "Unexpected container: " + container + " for " + klass;
String containerInternalName = getAsmType(bindingContext, (ClassDescriptor) container).getInternalName();
String containerInternalName = computeAsmTypeImpl(bindingContext, (ClassDescriptor) container);
switch (klass.getKind()) {
case ENUM_ENTRY:
return containerInternalName;
@@ -20,7 +20,6 @@ import kotlin.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.binding.MutableClosure;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
@@ -39,7 +38,8 @@ import java.util.Map;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.anonymousClassForFunction;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.canHaveOuter;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PROTECTED;
@@ -266,13 +266,12 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
lazyOuterExpression = LockBasedStorageManager.NO_LOCKS.createNullableLazyValue(new Function0<StackValue>() {
@Override
public StackValue invoke() {
BindingContext bindingContext = typeMapper.getBindingContext();
ClassDescriptor enclosingClass = getEnclosingClass();
return enclosingClass != null && canHaveOuter(bindingContext, classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass),
CodegenBinding.getAsmType(bindingContext, classDescriptor),
CAPTURED_THIS_FIELD,
false)
if (enclosingClass == null) return null;
return canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass), typeMapper.mapType(classDescriptor),
CAPTURED_THIS_FIELD, false)
: null;
}
});
@@ -289,7 +288,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) {
if (aCase.isCase(d)) {
Type classType = state.getBindingContext().get(ASM_TYPE, getThisDescriptor());
Type classType = state.getTypeMapper().mapType(getThisDescriptor());
StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType);
if (innerValue == null) {
break;
@@ -277,7 +277,7 @@ public class JetTypeMapper {
}
if (descriptor instanceof ClassDescriptor) {
Type asmType = getAsmType(bindingContext, (ClassDescriptor) descriptor);
Type asmType = computeAsmType(bindingContext, (ClassDescriptor) descriptor.getOriginal());
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed, projectionsAllowed);
return asmType;
}
@@ -296,7 +296,7 @@ public class JetTypeMapper {
@NotNull
public Type mapTraitImpl(@NotNull ClassDescriptor descriptor) {
return Type.getObjectType(getAsmType(bindingContext, descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
return Type.getObjectType(mapType(descriptor).getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
}
@NotNull