diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8614e9cc8d6..c278f0af984 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3928,7 +3928,7 @@ The "returned" value of try expression with no finally is either the last expres public NameGenerator getInlineNameGenerator() { if (inlineNameGenerator == null) { CodegenContext context = getContext(); - String prefix = InlineCodegenUtil.getInlineName(context.getContextDescriptor(), typeMapper); + String prefix = InlineCodegenUtil.getInlineName(context, typeMapper); inlineNameGenerator = new NameGenerator(prefix + "$$inline"); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java index 142d0a4e55a..859042f0316 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PackageCodegen.java @@ -30,6 +30,7 @@ import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.context.CodegenContext; 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.GenerationStateAware; import org.jetbrains.jet.descriptors.serialization.BitEncoding; @@ -169,7 +170,8 @@ public class PackageCodegen extends GenerationStateAware { @Nullable private ClassBuilder generate(@NotNull JetFile file) { 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()) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { @@ -188,7 +190,6 @@ public class PackageCodegen extends GenerationStateAware { if (!generateSrcClass) return null; - Type packagePartType = getPackagePartType(getPackageClassFqName(name), file.getVirtualFile()); ClassBuilder builder = state.getFactory().forPackagePart(packagePartType, file); new PackagePartCodegen(builder, file, packagePartType, packagePartContext, state).generate(); @@ -212,7 +213,9 @@ public class PackageCodegen extends GenerationStateAware { } 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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java index d5a719fbb33..ef029d79c91 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java @@ -42,7 +42,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; 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.renderer.DescriptorRenderer; @@ -140,7 +139,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner { if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) { VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state); node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(), - callableMethod.getAsmMethod().getDescriptor()); + callableMethod.getAsmMethod().getDescriptor()); if (node == null) { throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor)); @@ -189,7 +188,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner { InliningInfo info = new InliningInfo(expressionMap, null, null, null, state, codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()), - codegen.getContext().getContextDescriptor()); + codegen.getContext(), call); MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper()); //with captured 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) { if (descriptor instanceof PackageFragmentDescriptor) { - return new PackageContext((PackageFragmentDescriptor) descriptor, null); + return new PackageContext((PackageFragmentDescriptor) descriptor, null, null); } CodegenContext parent = getContext(descriptor.getContainingDeclaration(), state); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegenUtil.java index b9a0a96a98a..409f8f1fd00 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegenUtil.java @@ -20,12 +20,15 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.*; import org.jetbrains.asm4.tree.MethodNode; import org.jetbrains.jet.codegen.PackageCodegen; 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.JetTypeMapper; import org.jetbrains.jet.descriptors.serialization.JavaProtoBuf; @@ -127,23 +130,31 @@ public class InlineCodegenUtil { return null; } - public static String getInlineName(@NotNull DeclarationDescriptor referencedDescriptor, @NotNull JetTypeMapper typeMapper) { - return getInlineName(referencedDescriptor, referencedDescriptor, typeMapper); + public static String getInlineName(@NotNull CodegenContext codegenContext, @NotNull JetTypeMapper 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) { - PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), referencedDescriptor); - if (psiElement == null) { - psiElement = BindingContextUtils.descriptorToDeclaration(typeMapper.getBindingContext(), referencedDescriptor.getContainingDeclaration()); - if (psiElement == null) { - throw new RuntimeException("Couldn't find declaration for " + referencedDescriptor.getContainingDeclaration().getName() + "." + referencedDescriptor.getName() ); + file = getContainingFile(codegenContext, typeMapper); + + Type packageFragmentType = null; + if (file == null) { + //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 = - PackageCodegen.getPackagePartType(PackageClassUtils.getPackageClassFqName(getFqName(currentDescriptor).toSafe()), - psiElement.getContainingFile().getVirtualFile()); + if (packageFragmentType == null) { + DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor(); + throw new RuntimeException("Couldn't find declaration for " + contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() ); + } return packageFragmentType.getInternalName().replace('.', '/'); } @@ -163,7 +174,7 @@ public class InlineCodegenUtil { String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString(); - return getInlineName(referencedDescriptor, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix; + return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix; } @Nullable @@ -215,4 +226,19 @@ public class InlineCodegenUtil { public static boolean isInitCallOfFunction(String owner, String name) { return "".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; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index 426d448fd51..571a77709cf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -159,8 +159,8 @@ public abstract class CodegenContext { } @NotNull - public FieldOwnerContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor) { - return new PackageContext(descriptor, this); + public PackageContext intoPackagePart(@NotNull PackageFragmentDescriptor descriptor, Type packagePartType) { + return new PackageContext(descriptor, this, packagePartType); } @NotNull diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageContext.java index 5d3afc409f2..5ef390b3665 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageContext.java @@ -20,11 +20,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; +import org.jetbrains.asm4.Type; public class PackageContext extends FieldOwnerContext { - - 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); + this.packagePartType = packagePartType; } @Override @@ -36,4 +40,8 @@ public class PackageContext extends FieldOwnerContext public String toString() { return "Package: " + getContextDescriptor().getName(); } + + public Type getPackagePartType() { + return packagePartType; + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageFacadeContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageFacadeContext.java index 5bcb5d9e308..f71f9667299 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageFacadeContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/PackageFacadeContext.java @@ -23,19 +23,16 @@ import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; public class PackageFacadeContext extends PackageContext { - private final Type delegateTo; - public PackageFacadeContext( @NotNull PackageFragmentDescriptor contextDescriptor, @Nullable CodegenContext parent, @NotNull Type delegateTo ) { - super(contextDescriptor, parent); - this.delegateTo = delegateTo; + super(contextDescriptor, parent, delegateTo); } @NotNull public Type getDelegateToClassType() { - return delegateTo; + return getPackagePartType(); } }