Make stdlib work with -Xmultifile-package-facades.
Fixed wrong owner mapping in presence of -Xmultifile-package-facades. Fixed backing field mapping issue. Added more tests.
This commit is contained in:
@@ -19,14 +19,16 @@ package org.jetbrains.kotlin.codegen
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import java.util.*
|
||||
|
||||
public class CodegenFileClassesProvider() : JvmFileClassesProvider {
|
||||
private val fileParts = hashMapOf<JetFile, JvmFileClassInfo>()
|
||||
|
||||
override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo =
|
||||
fileParts.getOrPut(file) { JvmFileClassUtil.getFileClassInfoNoResolve(file) }
|
||||
public class CodegenFileClassesProvider(private val packageFacadesAsMultifileClasses: Boolean) : JvmFileClassesProvider {
|
||||
override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo {
|
||||
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||
if (packageFacadesAsMultifileClasses && !fileClassInfo.isMultifileClass) {
|
||||
return JvmFileClassUtil.getMultifilePackageFacadePartInfo(file)
|
||||
}
|
||||
else {
|
||||
return fileClassInfo
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -295,7 +296,7 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
return implementationOwnerType;
|
||||
}
|
||||
else {
|
||||
return fileClassesProvider.getFileClassType(element.getContainingJetFile());
|
||||
return FileClassesPackage.getFileClassType(fileClassesProvider, element.getContainingJetFile());
|
||||
}
|
||||
}
|
||||
/*disabled cause of KT-7775
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.fileClasses.getFileClassType
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageParts
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider
|
||||
|
||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||
@@ -313,7 +314,7 @@ public class PackageCodegen {
|
||||
@Nullable
|
||||
private ClassBuilder generate(@NotNull JetFile file, @NotNull Map<CallableMemberDescriptor, Runnable> generateCallableMemberTasks) {
|
||||
boolean generatePackagePart = false;
|
||||
Type packagePartType = state.getFileClassesProvider().getFileClassType(file);
|
||||
Type packagePartType = FileClassesPackage.getFileClassType(state.getFileClassesProvider(), file);
|
||||
PackageContext packagePartContext = state.getRootContext().intoPackagePart(packageFragment, packagePartType);
|
||||
|
||||
for (JetDeclaration declaration : file.getDeclarations()) {
|
||||
@@ -414,7 +415,7 @@ public class PackageCodegen {
|
||||
|
||||
public void generateClassOrObject(@NotNull JetClassOrObject classOrObject) {
|
||||
JetFile file = classOrObject.getContainingJetFile();
|
||||
Type packagePartType = state.getFileClassesProvider().getFileClassType(file);
|
||||
Type packagePartType = FileClassesPackage.getFileClassType(state.getFileClassesProvider(), file);
|
||||
CodegenContext context = state.getRootContext().intoPackagePart(packageFragment, packagePartType);
|
||||
MemberCodegen.genClassOrObject(context, classOrObject, state, null);
|
||||
}
|
||||
|
||||
+3
-2
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
|
||||
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
@@ -394,7 +395,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
else if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
JetFile containingFile = DescriptorToSourceUtils.getContainingFile(descriptor);
|
||||
assert containingFile != null : "File not found for " + descriptor;
|
||||
return fileClassesProvider.getFileClassInternalName(containingFile) + '$' + name;
|
||||
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + '$' + name;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -575,7 +576,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
}
|
||||
|
||||
return fileClassesProvider.getFileClassInternalName(file);
|
||||
return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
|
||||
}
|
||||
|
||||
private static <T> T peekFromStack(@NotNull Stack<T> stack) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -55,7 +56,7 @@ public final class PsiCodegenPredictor {
|
||||
@Nullable
|
||||
public static String getPredefinedJvmInternalName(
|
||||
@NotNull JetDeclaration declaration,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider
|
||||
) {
|
||||
// TODO: Method won't work for declarations inside companion objects
|
||||
// TODO: Method won't give correct class name for traits implementations
|
||||
@@ -64,7 +65,7 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
String parentInternalName;
|
||||
if (parentDeclaration != null) {
|
||||
parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesManager);
|
||||
parentInternalName = getPredefinedJvmInternalName(parentDeclaration, fileClassesProvider);
|
||||
if (parentInternalName == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -74,7 +75,7 @@ public final class PsiCodegenPredictor {
|
||||
|
||||
if (declaration instanceof JetNamedFunction) {
|
||||
Name name = ((JetNamedFunction) declaration).getNameAsName();
|
||||
return name == null ? null : fileClassesManager.getFileClassInternalName(containingFile) + "$" + name.asString();
|
||||
return name == null ? null : FileClassesPackage.getFileClassInternalName(fileClassesProvider, containingFile) + "$" + name.asString();
|
||||
}
|
||||
|
||||
parentInternalName = AsmUtil.internalNameByFqNameWithoutInnerClasses(containingFile.getPackageFqName());
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.codegen.context.*;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmVirtualFileFinder;
|
||||
@@ -214,7 +215,7 @@ public class InlineCodegenUtil {
|
||||
@NotNull CodegenContext codegenContext,
|
||||
@NotNull DeclarationDescriptor currentDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
@NotNull JvmFileClassesProvider fileClassesManager
|
||||
@NotNull JvmFileClassesProvider fileClassesProvider
|
||||
) {
|
||||
if (currentDescriptor instanceof PackageFragmentDescriptor) {
|
||||
PsiFile file = getContainingFile(codegenContext);
|
||||
@@ -223,7 +224,7 @@ public class InlineCodegenUtil {
|
||||
if (file == null) {
|
||||
implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(codegenContext);
|
||||
} else {
|
||||
implementationOwnerType = fileClassesManager.getFileClassType((JetFile) file);
|
||||
implementationOwnerType = FileClassesPackage.getFileClassType(fileClassesProvider, (JetFile) file);
|
||||
}
|
||||
|
||||
if (implementationOwnerType == null) {
|
||||
@@ -252,7 +253,7 @@ public class InlineCodegenUtil {
|
||||
String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString();
|
||||
|
||||
//noinspection ConstantConditions
|
||||
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesManager) + "$" + suffix;
|
||||
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesProvider) + "$" + suffix;
|
||||
}
|
||||
|
||||
public static boolean isInvokeOnLambda(@NotNull String owner, @NotNull String name) {
|
||||
|
||||
@@ -82,7 +82,7 @@ public class GenerationState jvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider()
|
||||
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider(packageFacadesAsMultifileClasses)
|
||||
|
||||
public val classBuilderMode: ClassBuilderMode = builderFactory.getClassBuilderMode()
|
||||
public val bindingTrace: BindingTrace = DelegatingBindingTrace(bindingContext, "trace in GenerationState")
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||
@@ -30,12 +31,14 @@ import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.fileClasses.FileClassesPackage;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||
import org.jetbrains.kotlin.name.*;
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap;
|
||||
import org.jetbrains.kotlin.psi.JetExpression;
|
||||
@@ -56,8 +59,8 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||
import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializedType;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
@@ -160,46 +163,78 @@ public class JetTypeMapper {
|
||||
JetFile file = DescriptorToSourceUtils.getContainingFile(descriptor);
|
||||
if (file != null) {
|
||||
Visibility visibility = descriptor.getVisibility();
|
||||
if (Visibilities.isPrivate(visibility)) {
|
||||
return fileClassesProvider.getFileClassInternalName(file);
|
||||
if (descriptor instanceof PropertyDescriptor || Visibilities.isPrivate(visibility)) {
|
||||
return FileClassesPackage.getFileClassInternalName(fileClassesProvider, file);
|
||||
}
|
||||
else {
|
||||
return fileClassesProvider.getFacadeClassInternalName(file);
|
||||
return FileClassesPackage.getFacadeClassInternalName(fileClassesProvider, file);
|
||||
}
|
||||
}
|
||||
|
||||
CallableMemberDescriptor directMember = getDirectMember(descriptor);
|
||||
|
||||
if (directMember instanceof DeserializedCallableMemberDescriptor) {
|
||||
Name implClassName = JvmFileClassUtil.getImplClassName((DeserializedCallableMemberDescriptor) directMember);
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
||||
JetScope scope = packageFragmentDescriptor.getMemberScope();
|
||||
if (scope instanceof AbstractScopeAdapter) {
|
||||
scope = ((AbstractScopeAdapter) scope).getActualScope();
|
||||
}
|
||||
if (scope instanceof LazyJavaPackageScope) {
|
||||
String facadeShortName = ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
|
||||
if (facadeShortName != null) {
|
||||
FqName facadeFqName = packageFragmentDescriptor.getFqName().child(Name.identifier(facadeShortName));
|
||||
return internalNameByFqNameWithoutInnerClasses(facadeFqName);
|
||||
}
|
||||
}
|
||||
else if (scope instanceof DeserializedPackageMemberScope) {
|
||||
FqName implClassFqName = packageFragmentDescriptor.getFqName().child(implClassName);
|
||||
return internalNameByFqNameWithoutInnerClasses(implClassFqName);
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unexpected member scope for deserialized callable: " + scope);
|
||||
}
|
||||
}
|
||||
String facadeFqName = getPackageMemberOwnerInternalName((DeserializedCallableMemberDescriptor) directMember);
|
||||
if (facadeFqName != null) return facadeFqName;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unreachable state");
|
||||
//return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
|
||||
// XXX This method (and getPackageMemberOwnerShortName) is a dirty hack
|
||||
// introduced to make stdlib work with package facades built as multifile facades for M13.
|
||||
// We need some safe, concise way to identify multifile facade and multifile part
|
||||
// from a deserialized package member descriptor.
|
||||
// Possible approaches:
|
||||
// - create a special instance of DeserializedPackageFragmentDescriptor for each facade class (multifile or single-file),
|
||||
// keep related mapping information there;
|
||||
// - provide a proper SourceElement for such descriptors (similar to KotlinJvmBinarySourceElement).
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
assert containingDeclaration instanceof PackageFragmentDescriptor : "Not a top-level member: " + descriptor;
|
||||
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
||||
|
||||
String facadeShortName = getPackageMemberOwnerShortName(descriptor);
|
||||
if (facadeShortName == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
FqName facadeFqName = packageFragmentDescriptor.getFqName().child(Name.identifier(facadeShortName));
|
||||
return internalNameByFqNameWithoutInnerClasses(facadeFqName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getPackageMemberOwnerShortName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
|
||||
// XXX Dirty hack; see getPAckageMemberOwnerInternalName above for more details.
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof PackageFragmentDescriptor) {
|
||||
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
|
||||
JetScope scope = packageFragmentDescriptor.getMemberScope();
|
||||
if (scope instanceof AbstractScopeAdapter) {
|
||||
scope = ((AbstractScopeAdapter) scope).getActualScope();
|
||||
}
|
||||
if (scope instanceof LazyJavaPackageScope) {
|
||||
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
|
||||
return ((LazyJavaPackageScope) scope).getFacadeSimpleNameForPartSimpleName(implClassName.asString());
|
||||
}
|
||||
else if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
|
||||
return PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName()).shortName().asString();
|
||||
}
|
||||
else if (scope instanceof DeserializedPackageMemberScope) {
|
||||
// XXX IncrementalPackageScope
|
||||
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
|
||||
return implClassName.asString();
|
||||
}
|
||||
else {
|
||||
throw new AssertionError("Unexpected member scope for deserialized callable: " + scope +
|
||||
"; descriptor: " + descriptor);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Type mapReturnType(@NotNull CallableDescriptor descriptor) {
|
||||
return mapReturnType(descriptor, null);
|
||||
|
||||
Reference in New Issue
Block a user