Drop package facades:

- getting rid of package facades in InlineCodegen & related stuff.
Provide binary source element to top-level package members.
This commit is contained in:
Dmitry Petrov
2015-10-16 21:52:11 +03:00
parent 989f761166
commit 70c91b2e75
10 changed files with 127 additions and 71 deletions
@@ -769,9 +769,9 @@ public class InlineCodegen extends CallGenerator {
if (incrementalCompilationComponents == null || targetId == null) return; if (incrementalCompilationComponents == null || targetId == null) return;
IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId); IncrementalCache incrementalCache = incrementalCompilationComponents.getIncrementalCache(targetId);
String sourceFile = InlineCodegenUtilsKt.getClassFilePath(sourceDescriptor, incrementalCache); String classFilePath = InlineCodegenUtilsKt.getClassFilePath(sourceDescriptor, typeMapper, incrementalCache);
String targetFile = InlineCodegenUtilsKt.getSourceFilePath(targetDescriptor); String sourceFilePath = InlineCodegenUtilsKt.getSourceFilePath(targetDescriptor);
incrementalCache.registerInline(sourceFile, jvmSignature.toString(), targetFile); incrementalCache.registerInline(classFilePath, jvmSignature.toString(), sourceFilePath);
} }
@Override @Override
@@ -164,26 +164,6 @@ public class InlineCodegenUtil {
return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars))); return fileFinder.findVirtualFileWithHeader(new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
} }
//TODO: navigate to inner classes
@Nullable
public static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) {
ClassOrPackageFragmentDescriptor
containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false);
if (containerDescriptor instanceof PackageFragmentDescriptor) {
return PackageClassUtils.getPackageClassId(getFqName(containerDescriptor).toSafe());
}
if (containerDescriptor instanceof ClassDescriptor) {
ClassId classId = DescriptorUtilsKt.getClassId((ClassDescriptor) containerDescriptor);
if (isInterface(containerDescriptor)) {
FqName relativeClassName = classId.getRelativeClassName();
//TODO test nested trait fun inlining
classId = new ClassId(classId.getPackageFqName(), Name.identifier(relativeClassName.shortName().asString() + JvmAbi.DEFAULT_IMPLS_SUFFIX));
}
return classId;
}
return null;
}
public static String getInlineName( public static String getInlineName(
@NotNull CodegenContext codegenContext, @NotNull CodegenContext codegenContext,
@NotNull JetTypeMapper typeMapper, @NotNull JetTypeMapper typeMapper,
@@ -16,13 +16,15 @@
package org.jetbrains.kotlin.codegen.inline package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.state.JetTypeMapper
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass import org.jetbrains.kotlin.load.kotlin.VirtualFileKotlinClass
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
public val FunctionDescriptor.sourceFilePath: String public val FunctionDescriptor.sourceFilePath: String
@@ -32,19 +34,30 @@ public val FunctionDescriptor.sourceFilePath: String
return containingFile?.virtualFile?.canonicalPath!! return containingFile?.virtualFile?.canonicalPath!!
} }
public fun FunctionDescriptor.getClassFilePath(cache: IncrementalCache): String { public fun FunctionDescriptor.getClassFilePath(typeMapper: JetTypeMapper, cache: IncrementalCache): String {
val container = containingDeclaration as? DeclarationDescriptorWithSource val container = containingDeclaration as? DeclarationDescriptorWithSource
val source = container?.source val source = container?.source
return when (source) { return when (source) {
is KotlinJvmBinaryPackageSourceElement -> {
if (this !is DeserializedCallableMemberDescriptor) {
throw AssertionError("Expected DeserializedCallableMemberDescriptor, got: $this")
}
val kotlinClass = source.getContainingBinaryClass(this) ?:
throw AssertionError("Descriptor $this is not found, in: $source")
if (kotlinClass !is VirtualFileKotlinClass) {
throw AssertionError("Expected VirtualFileKotlinClass, got $kotlinClass")
}
kotlinClass.file.canonicalPath!!
}
is KotlinJvmBinarySourceElement -> { is KotlinJvmBinarySourceElement -> {
assert(this is DeserializedSimpleFunctionDescriptor) { "Expected DeserializedSimpleFunctionDescriptor, got: $this" } assert(this is DeserializedSimpleFunctionDescriptor) { "Expected DeserializedSimpleFunctionDescriptor, got: $this" }
val kotlinClass = source.binaryClass as VirtualFileKotlinClass val kotlinClass = source.binaryClass as VirtualFileKotlinClass
kotlinClass.file.canonicalPath!! kotlinClass.file.canonicalPath!!
} }
else -> { else -> {
val classId = InlineCodegenUtil.getContainerClassId(this)!! val implementationOwnerType = typeMapper.mapOwner(this)
val className = JvmClassName.byClassId(classId).internalName val className = implementationOwnerType.internalName
cache.getClassFilePath(className) cache.getClassFilePath(className)
} }
} }
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.codegen.*;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding; import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.binding.MutableClosure; import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor; import org.jetbrains.kotlin.codegen.binding.PsiCodegenPredictor;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.FileClasses; import org.jetbrains.kotlin.fileClasses.FileClasses;
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
import org.jetbrains.kotlin.name.*; import org.jetbrains.kotlin.name.*;
@@ -241,8 +241,8 @@ public class JetTypeMapper {
if (parentDeclaration instanceof PackageFragmentDescriptor) { if (parentDeclaration instanceof PackageFragmentDescriptor) {
containingClassesInfo = getPackageMemberContainingClassesInfo(deserializedDescriptor); containingClassesInfo = getPackageMemberContainingClassesInfo(deserializedDescriptor);
} else { } else {
containingClassesInfo = ContainingClassesInfo.forClassMemberOrNull( ClassId classId = getContainerClassIdForClassDescriptor((ClassDescriptor) parentDeclaration);
InlineCodegenUtil.getContainerClassId(deserializedDescriptor)); containingClassesInfo = ContainingClassesInfo.forClassMemberOrNull(classId);
} }
if (containingClassesInfo == null) { if (containingClassesInfo == null) {
throw new IllegalStateException("Couldn't find container for " + deserializedDescriptor.getName()); throw new IllegalStateException("Couldn't find container for " + deserializedDescriptor.getName());
@@ -250,6 +250,16 @@ public class JetTypeMapper {
return containingClassesInfo; return containingClassesInfo;
} }
private static ClassId getContainerClassIdForClassDescriptor(ClassDescriptor classDescriptor) {
ClassId classId = DescriptorUtilsKt.getClassId(classDescriptor);
if (isInterface(classDescriptor)) {
FqName relativeClassName = classId.getRelativeClassName();
//TODO test nested trait fun inlining
classId = new ClassId(classId.getPackageFqName(), Name.identifier(relativeClassName.shortName().asString() + JvmAbi.DEFAULT_IMPLS_SUFFIX));
}
return classId;
}
@Nullable @Nullable
private String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) { private String getPackageMemberOwnerInternalName(@NotNull DeserializedCallableMemberDescriptor descriptor) {
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
@@ -20,6 +20,7 @@ import com.google.protobuf.MessageLite
import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.CachedValuesManager
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.java.descriptors.getImplClassName
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -70,24 +71,11 @@ public object JvmFileClassUtil {
@JvmStatic @JvmStatic
public fun getImplClassName(callable: DeserializedCallableMemberDescriptor): Name? = public fun getImplClassName(callable: DeserializedCallableMemberDescriptor): Name? =
getImplClassName(callable.proto, callable.nameResolver) callable.getImplClassName()
@JvmStatic @JvmStatic
public fun getImplClassName(proto: MessageLite, nameResolver: NameResolver): Name? = public fun getImplClassName(proto: MessageLite, nameResolver: NameResolver): Name? =
when (proto) { getImplClassName(proto, nameResolver)
is ProtoBuf.Constructor ->
null
is ProtoBuf.Function ->
if (proto.hasExtension(JvmProtoBuf.methodImplClassName))
proto.getExtension(JvmProtoBuf.methodImplClassName)
else null
is ProtoBuf.Property ->
if (proto.hasExtension(JvmProtoBuf.propertyImplClassName))
proto.getExtension(JvmProtoBuf.propertyImplClassName)
else null
else ->
error("Unknown message: $proto")
}?.let { nameResolver.getName(it) }
@JvmStatic @JvmStatic
public fun getHiddenPartFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName = public fun getHiddenPartFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName =
@@ -46,14 +46,21 @@ public fun isContainedByCompiledPartOfOurModule(descriptor: DeclarationDescripto
if (outDirectory == null || packageFragment !is LazyJavaPackageFragment) return false if (outDirectory == null || packageFragment !is LazyJavaPackageFragment) return false
val source = getSourceElement(descriptor) val source = getSourceElement(descriptor)
if (source is KotlinJvmBinarySourceElement) {
val binaryClass = source.binaryClass val binaryClass = when (source) {
if (binaryClass is VirtualFileKotlinClass) { is KotlinJvmBinarySourceElement ->
val file = binaryClass.file source.binaryClass
if (file.fileSystem.protocol == StandardFileSystems.FILE_PROTOCOL) { is KotlinJvmBinaryPackageSourceElement ->
val ioFile = VfsUtilCore.virtualToIoFile(file) source.getRepresentativeBinaryClass()
return ioFile.absolutePath.startsWith(outDirectory.absolutePath + File.separator); else ->
} null
}
if (binaryClass is VirtualFileKotlinClass) {
val file = binaryClass.file
if (file.fileSystem.protocol == StandardFileSystems.FILE_PROTOCOL) {
val ioFile = VfsUtilCore.virtualToIoFile(file)
return ioFile.absolutePath.startsWith(outDirectory.absolutePath + File.separator);
} }
} }
@@ -16,13 +16,19 @@
package org.jetbrains.kotlin.load.java.descriptors package org.jetbrains.kotlin.load.java.descriptors
import com.google.protobuf.MessageLite
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaStaticClassScope import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaStaticClassScope
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.serialization.ProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
import org.jetbrains.kotlin.types.JetType import org.jetbrains.kotlin.types.JetType
fun copyValueParameters( fun copyValueParameters(
@@ -60,3 +66,22 @@ fun ClassDescriptor.getParentJavaStaticClassScope(): LazyJavaStaticClassScope? {
return staticScope return staticScope
} }
fun DeserializedCallableMemberDescriptor.getImplClassName(): Name? =
getImplClassName(this.proto, this.nameResolver)
fun getImplClassName(proto: MessageLite, nameResolver: NameResolver): Name? =
when (proto) {
is ProtoBuf.Constructor ->
null
is ProtoBuf.Function ->
if (proto.hasExtension(JvmProtoBuf.methodImplClassName))
proto.getExtension(JvmProtoBuf.methodImplClassName)
else null
is ProtoBuf.Property ->
if (proto.hasExtension(JvmProtoBuf.propertyImplClassName))
proto.getExtension(JvmProtoBuf.propertyImplClassName)
else null
else ->
error("Unknown message: $proto")
}?.let { nameResolver.getName(it) }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaPackage import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
@@ -57,8 +58,6 @@ class LazyJavaPackageFragment(
override fun toString() = "lazy java package fragment: $fqName" override fun toString() = "lazy java package fragment: $fqName"
override fun getSource(): SourceElement { override fun getSource(): SourceElement {
// TODO source element for a bunch of Kotlin binary classes containing members of the same package return KotlinJvmBinaryPackageSourceElement(jPackage, kotlinBinaryClasses)
val representativeClass = kotlinBinaryClasses.firstOrNull() ?: return SourceElement.NO_SOURCE
return KotlinJvmBinarySourceElement(representativeClass)
} }
} }
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.load.java.descriptors.getImplClassName
import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
class KotlinJvmBinaryPackageSourceElement(
private val jPackage: JavaPackage,
kotlinBinaryClasses: List<KotlinJvmBinaryClass>
) : SourceElement {
private val implClassNameToBinaryClass = run {
val result = hashMapOf<String, KotlinJvmBinaryClass>()
for (kotlinBinaryClass in kotlinBinaryClasses) {
result[kotlinBinaryClass.classId.shortClassName.asString()] = kotlinBinaryClass
}
result
}
override fun toString(): String = "Binary package ${jPackage.getFqName()}: ${implClassNameToBinaryClass.keys}"
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
public fun getRepresentativeBinaryClass(): KotlinJvmBinaryClass {
return implClassNameToBinaryClass.values.first()
}
public fun getContainingBinaryClass(descriptor: DeserializedCallableMemberDescriptor): KotlinJvmBinaryClass? {
val name = descriptor.getImplClassName() ?: return null
return implClassNameToBinaryClass[name.asString()]
}
}
@@ -520,21 +520,6 @@ public class IncrementalCacheImpl(
value.dumpMap { java.lang.Long.toHexString(it) } value.dumpMap { java.lang.Long.toHexString(it) }
} }
private inner class PackagePartMap(storageFile: File) : BasicStringMap<Boolean>(storageFile, BooleanDataDescriptor.INSTANCE) {
public fun addPackagePart(className: JvmClassName) {
storage[className.internalName] = true
}
public fun remove(className: JvmClassName) {
storage.remove(className.internalName)
}
public fun isPackagePart(className: JvmClassName): Boolean =
className.internalName in storage
override fun dumpValue(value: Boolean) = ""
}
private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) { private inner class MultifileClassFacadeMap(storageFile: File) : BasicStringMap<List<String>>(storageFile, StringListExternalizer) {
public fun add(facadeName: JvmClassName, partNames: List<String>) { public fun add(facadeName: JvmClassName, partNames: List<String>) {
storage[facadeName.internalName] = partNames storage[facadeName.internalName] = partNames