Refactor CodegenBinding & PsiCodegenPredictor

Use ASM Type to store names of classes, use strings in PsiCodegenPredictor.
Inline some methods, move closer to their usages
This commit is contained in:
Alexander Udalov
2013-10-02 19:16:31 +04:00
parent 035a7cccda
commit 8729c88aa2
12 changed files with 132 additions and 154 deletions
@@ -53,7 +53,6 @@ import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -1327,10 +1326,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
assert constructorDescriptor != null;
CallableMethod constructor = typeMapper.mapToCallableMethod(constructorDescriptor, closure);
JvmClassName name = bindingContext.get(FQN, constructorDescriptor.getContainingDeclaration());
assert name != null;
Type type = bindingContext.get(ASM_TYPE, constructorDescriptor.getContainingDeclaration());
assert type != null;
Type type = name.getAsmType();
v.anew(type);
v.dup();
Method cons = constructor.getSignature().getAsmMethod();
@@ -1352,7 +1350,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes));
}
v.invokespecial(name.getInternalName(), "<init>", cons.getDescriptor());
v.invokespecial(type.getInternalName(), "<init>", cons.getDescriptor());
return StackValue.onStack(type);
}
@@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.psi.JetScript;
import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Collection;
@@ -45,7 +44,7 @@ public class KotlinCodegenFacade {
String name = ScriptNameUtil.classNameForScript(file);
JetScript script = file.getScript();
assert script != null;
registerClassNameForScript(state.getBindingTrace(), script, JvmClassName.byInternalName(name));
registerClassNameForScript(state.getBindingTrace(), script, Type.getObjectType(name));
}
}
@@ -34,7 +34,6 @@ import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import javax.inject.Inject;
import java.util.Collections;
@@ -69,18 +68,16 @@ public class ScriptCodegen extends MemberCodegen {
ClassDescriptor classDescriptorForScript = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
assert classDescriptorForScript != null;
ScriptContext context =
(ScriptContext) CodegenContext.STATIC
.intoScript(scriptDescriptor, classDescriptorForScript);
ScriptContext context = (ScriptContext) CodegenContext.STATIC.intoScript(scriptDescriptor, classDescriptorForScript);
JvmClassName className = bindingContext.get(FQN, classDescriptorForScript);
assert className != null;
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript);
assert classType != null;
ClassBuilder classBuilder = classFileFactory.newVisitor(className.getAsmType(), scriptDeclaration.getContainingFile());
ClassBuilder classBuilder = classFileFactory.newVisitor(classType, scriptDeclaration.getContainingFile());
classBuilder.defineClass(scriptDeclaration,
V1_6,
ACC_PUBLIC,
className.getInternalName(),
classType.getInternalName(),
null,
"java/lang/Object",
new String[0]);
@@ -120,13 +117,13 @@ public class ScriptCodegen extends MemberCodegen {
InstructionAdapter instructionAdapter = new InstructionAdapter(mv);
JvmClassName className = bindingContext.get(FQN, classDescriptorForScript);
assert className != null;
Type classType = bindingContext.get(ASM_TYPE, classDescriptorForScript);
assert classType != null;
instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(0, classType);
instructionAdapter.invokespecial("java/lang/Object", "<init>", "()V");
instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(0, classType);
FrameMap frameMap = context.prepareFrame(typeMapper);
@@ -152,25 +149,25 @@ public class ScriptCodegen extends MemberCodegen {
for (ScriptDescriptor earlierScript : importedScripts) {
Type earlierClassType = asmTypeForScriptDescriptor(bindingContext, earlierScript);
instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(0, classType);
instructionAdapter.load(offset, earlierClassType);
offset += earlierClassType.getSize();
instructionAdapter.putfield(className.getInternalName(), getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
instructionAdapter.putfield(classType.getInternalName(), getScriptFieldName(earlierScript), earlierClassType.getDescriptor());
}
for (ValueParameterDescriptor parameter : scriptDescriptor.getValueParameters()) {
Type parameterType = typeMapper.mapType(parameter.getType());
instructionAdapter.load(0, className.getAsmType());
instructionAdapter.load(0, classType);
instructionAdapter.load(offset, parameterType);
offset += parameterType.getSize();
instructionAdapter.putfield(className.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor());
instructionAdapter.putfield(classType.getInternalName(), parameter.getName().getIdentifier(), parameterType.getDescriptor());
}
StackValue stackValue =
new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context, state).gen(scriptDeclaration.getBlockExpression());
if (stackValue.type != Type.VOID_TYPE) {
stackValue.put(stackValue.type, instructionAdapter);
instructionAdapter.putfield(className.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
instructionAdapter.putfield(classType.getInternalName(), ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME,
blockType.getDescriptor());
}
@@ -204,8 +201,7 @@ public class ScriptCodegen extends MemberCodegen {
ScriptDescriptor earlierDescriptor = t.first;
Type earlierClassName = t.second;
registerClassNameForScript(state.getBindingTrace(), earlierDescriptor,
JvmClassName.byInternalName(earlierClassName.getInternalName()));
registerClassNameForScript(state.getBindingTrace(), earlierDescriptor, earlierClassName);
}
List<ScriptDescriptor> earlierScriptDescriptors = Lists.newArrayList();
@@ -243,7 +239,7 @@ public class ScriptCodegen extends MemberCodegen {
@NotNull CompilationErrorHandler errorHandler
) {
registerEarlierScripts(earlierScripts);
registerClassNameForScript(state.getBindingTrace(), script, JvmClassName.byInternalName(classType.getInternalName()));
registerClassNameForScript(state.getBindingTrace(), script, classType);
state.beforeCompile();
KotlinCodegenFacade.generateNamespace(
@@ -22,6 +22,7 @@ import com.intellij.psi.tree.TokenSet;
import com.intellij.util.containers.Stack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.SamCodegenUtil;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
@@ -153,9 +154,9 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
super.visitEnumEntry(enumEntry);
}
else {
JvmClassName jvmClassName = bindingTrace.get(FQN, peekFromStack(classStack));
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, jvmClassName);
bindingTrace.record(FQN, descriptor, jvmClassName);
Type asmType = bindingTrace.get(ASM_TYPE, peekFromStack(classStack));
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, asmType);
bindingTrace.record(ASM_TYPE, descriptor, asmType);
}
}
@@ -231,7 +232,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
classStack.push(classDescriptor);
//noinspection ConstantConditions
nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName());
nameStack.push(bindingContext.get(ASM_TYPE, classDescriptor).getInternalName());
super.visitObjectLiteralExpression(expression);
nameStack.pop();
classStack.pop();
@@ -286,7 +287,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
boolean functionLiteral
) {
CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, peekFromStack(classStack),
JvmClassName.byInternalName(name), functionLiteral);
Type.getObjectType(name), functionLiteral);
}
@Override
@@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -52,7 +51,7 @@ public class CodegenBinding {
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, Type> ASM_TYPE = Slices.createSimpleSlice();
public static final WritableSlice<ClassDescriptor, Boolean> ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice();
@@ -82,7 +81,7 @@ public class CodegenBinding {
public static Type asmTypeForScriptDescriptor(BindingContext bindingContext, @NotNull ScriptDescriptor scriptDescriptor) {
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, scriptDescriptor);
//noinspection ConstantConditions
return fqn(bindingContext, classDescriptor);
return asmType(bindingContext, classDescriptor);
}
@NotNull
@@ -109,9 +108,9 @@ public class CodegenBinding {
}
@NotNull
private static Type fqn(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor descriptor) {
private static Type asmType(@NotNull BindingContext bindingContext, @NotNull ClassDescriptor descriptor) {
//noinspection ConstantConditions
return bindingContext.get(FQN, descriptor).getAsmType();
return bindingContext.get(ASM_TYPE, descriptor);
}
@NotNull
@@ -128,25 +127,25 @@ public class CodegenBinding {
return asmTypeForAnonymousClass(bindingContext, functionDescriptor);
}
return fqn(bindingContext, descriptor);
return asmType(bindingContext, descriptor);
}
@NotNull
public static Type asmTypeForAnonymousClass(@NotNull BindingContext bindingContext, @NotNull FunctionDescriptor descriptor) {
ClassDescriptor classDescriptor = anonymousClassForFunction(bindingContext, descriptor);
return fqn(bindingContext, classDescriptor);
return asmType(bindingContext, classDescriptor);
}
public static void registerClassNameForScript(
BindingTrace bindingTrace,
@NotNull ScriptDescriptor scriptDescriptor,
@NotNull JvmClassName className
@NotNull Type asmType
) {
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
scriptDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
Modality.FINAL,
Name.special("<script-" + className + ">"));
Name.special("<script-" + asmType.getInternalName() + ">"));
classDescriptor.initialize(
false,
Collections.<TypeParameterDescriptor>emptyList(),
@@ -156,7 +155,7 @@ public class CodegenBinding {
null,
false);
recordClosure(bindingTrace, null, classDescriptor, null, className, false);
recordClosure(bindingTrace, null, classDescriptor, null, asmType, false);
bindingTrace.record(CLASS_FOR_SCRIPT, scriptDescriptor, classDescriptor);
}
@@ -200,7 +199,7 @@ public class CodegenBinding {
@Nullable JetElement element,
ClassDescriptor classDescriptor,
@Nullable ClassDescriptor enclosing,
JvmClassName name,
Type asmType,
boolean functionLiteral
) {
JetDelegatorToSuperCall superCall = findSuperCall(bindingTrace.getBindingContext(), element);
@@ -219,8 +218,8 @@ public class CodegenBinding {
MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver);
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, name);
bindingTrace.record(FQN, classDescriptor, name);
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, classDescriptor, asmType);
bindingTrace.record(ASM_TYPE, classDescriptor, asmType);
bindingTrace.record(CLOSURE, classDescriptor, closure);
// TODO: this is temporary before we have proper inner classes
@@ -249,13 +248,13 @@ public class CodegenBinding {
public static void registerClassNameForScript(
BindingTrace bindingTrace,
@NotNull JetScript jetScript,
@NotNull JvmClassName className
@NotNull Type asmType
) {
ScriptDescriptor descriptor = bindingTrace.getBindingContext().get(SCRIPT, jetScript);
if (descriptor == null) {
throw new IllegalStateException("Descriptor is not found for PSI " + jetScript);
}
registerClassNameForScript(bindingTrace, descriptor, className);
registerClassNameForScript(bindingTrace, descriptor, asmType);
}
@NotNull
@@ -324,22 +323,22 @@ public class CodegenBinding {
}
@NotNull
public static JvmClassName getJvmInternalName(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
public static Type getAsmType(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
descriptor = descriptor.getOriginal();
JvmClassName alreadyComputedName = bindingTrace.getBindingContext().get(FQN, descriptor);
if (alreadyComputedName != null) {
return alreadyComputedName;
Type alreadyComputedType = bindingTrace.getBindingContext().get(ASM_TYPE, descriptor);
if (alreadyComputedType != null) {
return alreadyComputedType;
}
JvmClassName name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor));
Type asmType = Type.getObjectType(getAsmTypeImpl(bindingTrace, descriptor));
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name);
bindingTrace.record(FQN, descriptor, name);
return name;
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, asmType);
bindingTrace.record(ASM_TYPE, descriptor, asmType);
return asmType;
}
@NotNull
private static String getJvmInternalFQNameImpl(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
private static String getAsmTypeImpl(@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof FunctionDescriptor) {
throw new IllegalStateException("requested fq name for function: " + descriptor);
}
@@ -357,7 +356,7 @@ public class CodegenBinding {
return descriptor.getName().getIdentifier();
}
String containerInternalName = getJvmInternalName(bindingTrace, container).getInternalName();
String containerInternalName = getAsmType(bindingTrace, container).getInternalName();
if (descriptor instanceof ClassDescriptor && container instanceof ClassDescriptor) {
ClassDescriptor klass = (ClassDescriptor) descriptor;
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.NamespaceCodegen;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -30,7 +31,6 @@ import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.util.slicedmap.WritableSlice;
@@ -38,18 +38,19 @@ import org.jetbrains.jet.util.slicedmap.WritableSlice;
import java.util.Collection;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.java.PackageClassUtils.getPackageClassFqName;
public final class PsiCodegenPredictor {
private PsiCodegenPredictor() {
}
public static boolean checkPredictedNameFromPsi(
@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, JvmClassName nameFromDescriptors
@NotNull BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor, @Nullable Type nameFromDescriptors
) {
PsiElement element = descriptorToDeclaration(bindingTrace.getBindingContext(), descriptor);
if (element instanceof JetDeclaration) {
JvmClassName classNameFromPsi = getPredefinedJvmClassName((JetDeclaration) element);
assert classNameFromPsi == null || classNameFromPsi.equals(nameFromDescriptors) :
String classNameFromPsi = getPredefinedJvmInternalName((JetDeclaration) element);
assert classNameFromPsi == null || Type.getObjectType(classNameFromPsi).equals(nameFromDescriptors) :
String.format("Invalid algorithm for getting qualified name from psi! Predicted: %s, actual %s\n" +
"Element: %s", classNameFromPsi, nameFromDescriptors, element.getText());
}
@@ -57,97 +58,79 @@ public final class PsiCodegenPredictor {
return true;
}
@Nullable
public static JvmClassName getPredefinedJvmClassName(@NotNull JetFile jetFile, boolean withNamespace) {
String packageName = jetFile.getPackageName();
if (packageName == null) {
return null;
}
JvmClassName packageJvmName = JvmClassName.byFqNameWithoutInnerClasses(packageName);
return !withNamespace ? packageJvmName : addPackageClass(packageJvmName);
}
/**
* TODO: Finish this method for all cases. Now it's only used and tested in JetLightClass.
*
* @return null if no prediction can be done.
*/
@Nullable
public static JvmClassName getPredefinedJvmClassName(@NotNull JetDeclaration declaration) {
public static String getPredefinedJvmInternalName(@NotNull JetDeclaration declaration) {
// TODO: Method won't work for declarations inside class objects
// TODO: Method won't give correct class name for traits implementations
JetDeclaration parentDeclaration = PsiTreeUtil.getParentOfType(declaration, JetDeclaration.class);
if (parentDeclaration instanceof JetClassObject) {
assert declaration instanceof JetObjectDeclaration : "Only object declarations can be children of JetClassObject: " + declaration;
return getPredefinedJvmClassName(parentDeclaration);
return getPredefinedJvmInternalName(parentDeclaration);
}
JvmClassName parentClassName = parentDeclaration != null ?
getPredefinedJvmClassName(parentDeclaration) :
getPredefinedJvmClassName((JetFile) declaration.getContainingFile(), false);
if (parentClassName == null) {
return null;
String parentInternalName;
if (parentDeclaration != null) {
parentInternalName = getPredefinedJvmInternalName(parentDeclaration);
if (parentInternalName == null) {
return null;
}
}
else {
String packageName = ((JetFile) declaration.getContainingFile()).getPackageName();
if (packageName == null) {
return null;
}
parentInternalName = JvmClassName.byFqNameWithoutInnerClasses(packageName).getInternalName();
}
if (declaration instanceof JetClassObject) {
// Get parent and assign Class object prefix
return JvmClassName.byInternalName(parentClassName.getInternalName() + JvmAbi.CLASS_OBJECT_SUFFIX);
return parentInternalName + JvmAbi.CLASS_OBJECT_SUFFIX;
}
if (declaration instanceof JetNamedDeclaration) {
if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) ||
declaration instanceof JetEnumEntry) {
// Other subclasses are not valid for class name prediction.
// For example EnumEntry, JetFunctionLiteral
return null;
}
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) declaration;
Name name = namedDeclaration.getNameAsName();
if (name == null) {
return null;
}
FqName fqName = parentClassName.getFqName();
if (declaration instanceof JetNamedFunction) {
if (parentDeclaration == null) {
JvmClassName packageClass = addPackageClass(parentClassName);
return JvmClassName.byInternalName(packageClass.getInternalName() + "$" + name.asString());
}
if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) {
// Can't generate predefined name for internal functions
return null;
}
}
// NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not
// namespace$propertyName$ClassName
if (declaration instanceof JetProperty) {
return JvmClassName.byInternalName(parentClassName.getInternalName() + "$" + name.asString());
}
if (fqName.isRoot()) {
return JvmClassName.byInternalName(name.asString());
}
return JvmClassName.byInternalName(parentDeclaration == null ?
parentClassName.getInternalName() + "/" + name.asString() :
parentClassName.getInternalName() + "$" + name.asString());
if (!PsiTreeUtil.instanceOf(declaration, JetClass.class, JetObjectDeclaration.class, JetNamedFunction.class, JetProperty.class) ||
declaration instanceof JetEnumEntry) {
// Other subclasses are not valid for class name prediction.
// For example EnumEntry, JetFunctionLiteral
return null;
}
return null;
}
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) declaration;
Name name = namedDeclaration.getNameAsName();
if (name == null) {
return null;
}
private static JvmClassName addPackageClass(JvmClassName packageName) {
FqName name = packageName.getFqName();
String packageClassName = PackageClassUtils.getPackageClassName(name);
return name.isRoot() ?
JvmClassName.byFqNameWithoutInnerClasses(packageClassName) :
JvmClassName.byInternalName(packageName.getInternalName() + "/" + packageClassName);
if (declaration instanceof JetNamedFunction) {
if (parentDeclaration == null) {
FqName fqName = JvmClassName.byInternalName(parentInternalName).getFqName();
JvmClassName packageClass = JvmClassName.byFqNameWithoutInnerClasses(getPackageClassFqName(fqName));
return packageClass.getInternalName() + "$" + name.asString();
}
if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) {
// Can't generate predefined name for internal functions
return null;
}
}
// NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not
// namespace$propertyName$ClassName
if (declaration instanceof JetProperty) {
return parentInternalName + "$" + name.asString();
}
if (parentInternalName.isEmpty()) {
return name.asString();
}
return parentInternalName + (parentDeclaration == null ? "/" : "$") + name.asString();
}
@Nullable
@@ -166,7 +149,7 @@ public final class PsiCodegenPredictor {
public static JetFile getFileForCodegenNamedClass(
@NotNull BindingContext context,
@NotNull Collection<JetFile> allNamespaceFiles,
@NotNull final JvmClassName className
@NotNull final String classInternalName
) {
final Ref<DeclarationDescriptor> resultingDescriptor = Ref.create();
@@ -174,8 +157,8 @@ public final class PsiCodegenPredictor {
@Override
public <K, V> void record(WritableSlice<K, V> slice, K key, V value) {
super.record(slice, key, value);
if (slice == CodegenBinding.FQN && key instanceof DeclarationDescriptor) {
if (className.equals(value)) {
if (slice == CodegenBinding.ASM_TYPE && key instanceof DeclarationDescriptor && value instanceof Type) {
if (classInternalName.equals(((Type) value).getInternalName())) {
resultingDescriptor.set((DeclarationDescriptor) key);
}
}
@@ -29,7 +29,6 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import java.util.Collections;
import java.util.HashMap;
@@ -278,7 +277,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
ClassDescriptor enclosingClass = getEnclosingClass();
outerExpression = enclosingClass != null && canHaveOuter(typeMapper.getBindingContext(), classDescriptor)
? StackValue.field(typeMapper.mapType(enclosingClass),
CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor).getAsmType(),
CodegenBinding.getAsmType(typeMapper.getBindingTrace(), classDescriptor),
CAPTURED_THIS_FIELD,
false)
: null;
@@ -295,8 +294,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
for (LocalLookup.LocalLookupCase aCase : LocalLookup.LocalLookupCase.values()) {
if (aCase.isCase(d, state)) {
JvmClassName className = state.getBindingContext().get(FQN, getThisDescriptor());
Type classType = className == null ? null : className.getAsmType();
Type classType = state.getBindingContext().get(ASM_TYPE, getThisDescriptor());
StackValue innerValue = aCase.innerValue(d, enclosingLocalLookup, state, closure, classType);
if (innerValue == null) {
break;
@@ -334,13 +334,13 @@ public class JetTypeMapper extends BindingTraceAware {
}
if (descriptor instanceof ClassDescriptor) {
JvmClassName name = getJvmInternalName(bindingTrace, descriptor);
Type descriptorAsmType = getAsmType(bindingTrace, descriptor);
Type asmType;
if (kind == JetTypeMapperMode.TRAIT_IMPL) {
asmType = Type.getObjectType(name.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
asmType = Type.getObjectType(descriptorAsmType.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX);
}
else {
asmType = name.getAsmType();
asmType = descriptorAsmType;
}
writeGenericType(signatureVisitor, asmType, jetType, howThisTypeIsUsed);
@@ -43,8 +43,8 @@ import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetJavaMirrorMarker;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
@@ -66,10 +66,10 @@ public class KotlinLightClassForExplicitDeclaration extends AbstractLightClass i
return null;
}
JvmClassName jvmClassName = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject);
if (jvmClassName == null) return null;
String jvmInternalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject);
if (jvmInternalName == null) return null;
return new KotlinLightClassForExplicitDeclaration(manager, jvmClassName.getFqName(), classOrObject);
return new KotlinLightClassForExplicitDeclaration(manager, JvmClassName.byInternalName(jvmInternalName).getFqName(), classOrObject);
}
private final FqName classFqName; // FqName of (possibly inner) class
@@ -36,11 +36,10 @@ import com.intellij.util.PathUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.JetClsMethod;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.utils.ExceptionUtils;
@@ -235,12 +234,11 @@ public class LightClassUtil {
if (parent instanceof JetFile) {
// top-level declaration
JvmClassName jvmName = PsiCodegenPredictor.getPredefinedJvmClassName((JetFile) parent, true);
if (jvmName != null) {
FqName fqName = getPackageClassNameForFile((JetFile) parent);
if (fqName != null) {
Project project = declaration.getProject();
String fqName = jvmName.getFqName().asString();
return JavaElementFinder.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project));
return JavaElementFinder.getInstance(project).findClass(fqName.asString(), GlobalSearchScope.allScope(project));
}
}
else if (parent instanceof JetClassBody) {
@@ -251,6 +249,12 @@ public class LightClassUtil {
return null;
}
@Nullable
private static FqName getPackageClassNameForFile(@NotNull JetFile jetFile) {
String packageName = jetFile.getPackageName();
return packageName == null ? null : PackageClassUtils.getPackageClassFqName(new FqName(packageName));
}
private static PropertyAccessorsPsiMethods extractPropertyAccessors(
@NotNull JetDeclaration jetDeclaration,
@Nullable PsiMethod specialGetter, @Nullable PsiMethod specialSetter
@@ -375,11 +375,11 @@ public class JetSourceNavigationHelper {
@Nullable
public static PsiClass getOriginalClass(@NotNull JetClassOrObject classOrObject) {
// Copied from JavaPsiImplementationHelperImpl:getOriginalClass()
JvmClassName className = PsiCodegenPredictor.getPredefinedJvmClassName(classOrObject);
if (className == null) {
String internalName = PsiCodegenPredictor.getPredefinedJvmInternalName(classOrObject);
if (internalName == null) {
return null;
}
String fqName = className.getFqName().asString();
String fqName = JvmClassName.byInternalName(internalName).getFqName().asString();
JetFile file = (JetFile) classOrObject.getContainingFile();
@@ -74,7 +74,7 @@ public class DebuggerUtils {
// we may actually need to analyze the project in order to find a file which produces this class
AnalyzeExhaust analyzeExhaust = AnalyzerFacadeWithCache.analyzeFileWithCache(anyFile);
return PsiCodegenPredictor.getFileForCodegenNamedClass(analyzeExhaust.getBindingContext(), allNamespaceFiles, className);
return PsiCodegenPredictor.getFileForCodegenNamedClass(analyzeExhaust.getBindingContext(), allNamespaceFiles, className.getInternalName());
}
@NotNull