Keep package part name in pakage context

This commit is contained in:
Mikhael Bogdanov
2014-02-12 11:05:07 +04:00
parent 353d1c488b
commit dbf5187054
7 changed files with 62 additions and 29 deletions
@@ -3928,7 +3928,7 @@ The "returned" value of try expression with no finally is either the last expres
public NameGenerator getInlineNameGenerator() { public NameGenerator getInlineNameGenerator() {
if (inlineNameGenerator == null) { if (inlineNameGenerator == null) {
CodegenContext context = getContext(); CodegenContext context = getContext();
String prefix = InlineCodegenUtil.getInlineName(context.getContextDescriptor(), typeMapper); String prefix = InlineCodegenUtil.getInlineName(context, typeMapper);
inlineNameGenerator = new NameGenerator(prefix + "$$inline"); inlineNameGenerator = new NameGenerator(prefix + "$$inline");
} }
@@ -30,6 +30,7 @@ import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.Type; import org.jetbrains.asm4.Type;
import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.context.FieldOwnerContext;
import org.jetbrains.jet.codegen.context.PackageContext;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.codegen.state.GenerationStateAware;
import org.jetbrains.jet.descriptors.serialization.BitEncoding; import org.jetbrains.jet.descriptors.serialization.BitEncoding;
@@ -169,7 +170,8 @@ public class PackageCodegen extends GenerationStateAware {
@Nullable @Nullable
private ClassBuilder generate(@NotNull JetFile file) { private ClassBuilder generate(@NotNull JetFile file) {
boolean generateSrcClass = false; boolean generateSrcClass = false;
FieldOwnerContext packagePartContext = CodegenContext.STATIC.intoPackagePart(getPackageFragment(file)); Type packagePartType = getPackagePartType(getPackageClassFqName(name), file.getVirtualFile());
PackageContext packagePartContext = CodegenContext.STATIC.intoPackagePart(getPackageFragment(file), packagePartType);
for (JetDeclaration declaration : file.getDeclarations()) { for (JetDeclaration declaration : file.getDeclarations()) {
if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) {
@@ -188,7 +190,6 @@ public class PackageCodegen extends GenerationStateAware {
if (!generateSrcClass) return null; if (!generateSrcClass) return null;
Type packagePartType = getPackagePartType(getPackageClassFqName(name), file.getVirtualFile());
ClassBuilder builder = state.getFactory().forPackagePart(packagePartType, file); ClassBuilder builder = state.getFactory().forPackagePart(packagePartType, file);
new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate(); new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate();
@@ -212,7 +213,9 @@ public class PackageCodegen extends GenerationStateAware {
} }
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) { public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
CodegenContext context = CodegenContext.STATIC.intoPackagePart(getPackageFragment((JetFile) classOrObject.getContainingFile())); JetFile file = (JetFile) classOrObject.getContainingFile();
Type packagePartType = getPackagePartType(getPackageClassFqName(name), file.getVirtualFile());
CodegenContext context = CodegenContext.STATIC.intoPackagePart(getPackageFragment(file), packagePartType);
MemberCodegen.genClassOrObject(context, classOrObject, state, null); MemberCodegen.genClassOrObject(context, classOrObject, state, null);
} }
@@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.psi.*;
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;
import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.InlineUtil; import org.jetbrains.jet.lang.types.lang.InlineUtil;
import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -140,7 +139,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) { if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state); VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state);
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(), node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(),
callableMethod.getAsmMethod().getDescriptor()); callableMethod.getAsmMethod().getDescriptor());
if (node == null) { if (node == null) {
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor)); throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
@@ -189,7 +188,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
InliningInfo info = InliningInfo info =
new InliningInfo(expressionMap, null, null, null, state, new InliningInfo(expressionMap, null, null, null, state,
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()), codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
codegen.getContext().getContextDescriptor()); codegen.getContext(), call);
MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper()); //with captured MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper()); //with captured
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, new VarRemapper.ShiftRemapper(initialFrameSize, null)); VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, new VarRemapper.ShiftRemapper(initialFrameSize, null));
@@ -387,7 +386,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) { public static CodegenContext getContext(DeclarationDescriptor descriptor, GenerationState state) {
if (descriptor instanceof PackageFragmentDescriptor) { if (descriptor instanceof PackageFragmentDescriptor) {
return new PackageContext((PackageFragmentDescriptor) descriptor, null); return new PackageContext((PackageFragmentDescriptor) descriptor, null, null);
} }
CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state); CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state);
@@ -20,12 +20,15 @@ import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.asm4.*; import org.jetbrains.asm4.*;
import org.jetbrains.asm4.tree.MethodNode; import org.jetbrains.asm4.tree.MethodNode;
import org.jetbrains.jet.codegen.PackageCodegen; import org.jetbrains.jet.codegen.PackageCodegen;
import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.CodegenBinding;
import org.jetbrains.jet.codegen.context.CodegenContext;
import org.jetbrains.jet.codegen.context.PackageContext;
import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf;
@@ -127,23 +130,31 @@ public class InlineCodegenUtil {
return null; return null;
} }
public static String getInlineName(@NotNull DeclarationDescriptor referencedDescriptor, @NotNull JetTypeMapper typeMapper) { public static String getInlineName(@NotNull CodegenContext codegenContext, @NotNull JetTypeMapper typeMapper) {
return getInlineName(referencedDescriptor, referencedDescriptor, typeMapper); return getInlineName(codegenContext, codegenContext.getContextDescriptor(), typeMapper);
} }
private static String getInlineName(@NotNull DeclarationDescriptor referencedDescriptor, @NotNull DeclarationDescriptor currentDescriptor, @NotNull JetTypeMapper typeMapper) { private static String getInlineName(@NotNull CodegenContext codegenContext, @NotNull DeclarationDescriptor currentDescriptor, @NotNull JetTypeMapper typeMapper) {
PsiFile file;
if (currentDescriptor instanceof PackageFragmentDescriptor) { if (currentDescriptor instanceof PackageFragmentDescriptor) {
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), referencedDescriptor); file = getContainingFile(codegenContext, typeMapper);
if (psiElement == null) {
psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), referencedDescriptor.getContainingDeclaration()); Type packageFragmentType = null;
if (psiElement == null) { if (file == null) {
throw new RuntimeException("Couldn't find declaration for " + referencedDescriptor.getContainingDeclaration().getName() + "." + referencedDescriptor.getName() ); //in case package fragment clinit
if (codegenContext.getParentContext() instanceof PackageContext) {
packageFragmentType = ((PackageContext) codegenContext.getParentContext()).getPackagePartType();
} }
} else {
packageFragmentType =
PackageCodegen.getPackagePartType(PackageClassUtils.getPackageClassFqName(getFqName(currentDescriptor).toSafe()),
file.getVirtualFile());
} }
Type packageFragmentType = if (packageFragmentType == null) {
PackageCodegen.getPackagePartType(PackageClassUtils.getPackageClassFqName(getFqName(currentDescriptor).toSafe()), DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
psiElement.getContainingFile().getVirtualFile()); throw new RuntimeException("Couldn't find declaration for " + contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() );
}
return packageFragmentType.getInternalName().replace('.', '/'); return packageFragmentType.getInternalName().replace('.', '/');
} }
@@ -163,7 +174,7 @@ public class InlineCodegenUtil {
String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString(); String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString();
return getInlineName(referencedDescriptor, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix; return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix;
} }
@Nullable @Nullable
@@ -215,4 +226,19 @@ public class InlineCodegenUtil {
public static boolean isInitCallOfFunction(String owner, String name) { public static boolean isInitCallOfFunction(String owner, String name) {
return "<init>".equals(name); return "<init>".equals(name);
} }
@Nullable
public static PsiFile getContainingFile(CodegenContext codegenContext, JetTypeMapper typeMapper) {
DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), contextDescriptor);
if (psiElement == null) {
//in case of synthetic
psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), contextDescriptor);
}
if (psiElement != null) {
return psiElement.getContainingFile();
}
return null;
}
} }
@@ -159,8 +159,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
} }
@NotNull @NotNull
public FieldOwnerContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor) { public PackageContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor, Type packagePartType) {
return new PackageContext(descriptor, this); return new PackageContext(descriptor, this, packagePartType);
} }
@NotNull @NotNull
@@ -20,11 +20,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.OwnerKind;
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.asm4.Type;
public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> { public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor> {
public PackageContext(@NotNull PackageFragmentDescriptor contextDescriptor, @Nullable CodegenContext parent) { private final Type packagePartType;
public PackageContext(@NotNull PackageFragmentDescriptor contextDescriptor, @Nullable CodegenContext parent, Type packagePartType) {
super(contextDescriptor, OwnerKind.PACKAGE, parent, null, null, null); super(contextDescriptor, OwnerKind.PACKAGE, parent, null, null, null);
this.packagePartType = packagePartType;
} }
@Override @Override
@@ -36,4 +40,8 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
public String toString() { public String toString() {
return "Package: " + getContextDescriptor().getName(); return "Package: " + getContextDescriptor().getName();
} }
public Type getPackagePartType() {
return packagePartType;
}
} }
@@ -23,19 +23,16 @@ import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
public class PackageFacadeContext extends PackageContext { public class PackageFacadeContext extends PackageContext {
private final Type delegateTo;
public PackageFacadeContext( public PackageFacadeContext(
@NotNull PackageFragmentDescriptor contextDescriptor, @NotNull PackageFragmentDescriptor contextDescriptor,
@Nullable CodegenContext parent, @Nullable CodegenContext parent,
@NotNull Type delegateTo @NotNull Type delegateTo
) { ) {
super(contextDescriptor, parent); super(contextDescriptor, parent, delegateTo);
this.delegateTo = delegateTo;
} }
@NotNull @NotNull
public Type getDelegateToClassType() { public Type getDelegateToClassType() {
return delegateTo; return getPackagePartType();
} }
} }