Preliminary implementation of parts & facade in FIR-based compiler
This commit is contained in:
@@ -39,7 +39,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral
|
||||
import org.jetbrains.kotlin.types.expressions.LabelResolver
|
||||
@@ -554,7 +554,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
val owner = state.typeMapper.mapImplementationOwner(functionDescriptor)
|
||||
val methodId = MethodId(owner.internalName, asmMethod)
|
||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DeserializedCallableMemberDescriptor) {
|
||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) {
|
||||
return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
||||
}
|
||||
|
||||
@@ -608,16 +608,16 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
||||
return SMAPAndMethodNode(body, SMAP(listOf(FileMapping.SKIP)))
|
||||
}
|
||||
|
||||
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
|
||||
assert(callableDescriptor is DescriptorWithContainerSource) { "Not a deserialized function or proper: $callableDescriptor" }
|
||||
|
||||
val containingClasses =
|
||||
KotlinTypeMapper.getContainingClassesForDeserializedCallable(callableDescriptor as DeserializedCallableMemberDescriptor)
|
||||
KotlinTypeMapper.getContainingClassesForDeserializedCallable(callableDescriptor as DescriptorWithContainerSource)
|
||||
|
||||
val containerId = containingClasses.implClassId
|
||||
|
||||
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
|
||||
findVirtualFile(state, containerId)?.contentsToByteArray()
|
||||
?: throw IllegalStateException("Couldn't find declaration file for " + containerId)
|
||||
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
|
||||
}
|
||||
|
||||
val methodNode =
|
||||
|
||||
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
|
||||
@@ -1291,7 +1292,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
|
||||
val directMember = DescriptorUtils.getDirectMember(descriptor)
|
||||
|
||||
if (directMember is DeserializedCallableMemberDescriptor) {
|
||||
if (directMember is DescriptorWithContainerSource) {
|
||||
val facadeFqName = getPackageMemberOwnerInternalName(directMember, publicFacade)
|
||||
if (facadeFqName != null) return facadeFqName
|
||||
}
|
||||
@@ -1319,7 +1320,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
descriptor is PropertyDescriptor && !descriptor.isConst
|
||||
|
||||
fun getContainingClassesForDeserializedCallable(
|
||||
deserializedDescriptor: DeserializedCallableMemberDescriptor
|
||||
deserializedDescriptor: DescriptorWithContainerSource
|
||||
): ContainingClassesInfo {
|
||||
val parentDeclaration = deserializedDescriptor.containingDeclaration
|
||||
|
||||
@@ -1351,7 +1352,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
return classId
|
||||
}
|
||||
|
||||
private fun getPackageMemberOwnerInternalName(descriptor: DeserializedCallableMemberDescriptor, publicFacade: Boolean): String? {
|
||||
private fun getPackageMemberOwnerInternalName(descriptor: DescriptorWithContainerSource, publicFacade: Boolean): String? {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
assert(containingDeclaration is PackageFragmentDescriptor) { "Not a top-level member: $descriptor" }
|
||||
|
||||
@@ -1366,7 +1367,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
|
||||
private val FAKE_CLASS_ID_FOR_BUILTINS = ClassId.topLevel(FqName("kotlin.KotlinPackage"))
|
||||
|
||||
private fun getPackageMemberContainingClassesInfo(descriptor: DeserializedCallableMemberDescriptor): ContainingClassesInfo? {
|
||||
private fun getPackageMemberContainingClassesInfo(descriptor: DescriptorWithContainerSource): ContainingClassesInfo? {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
if (containingDeclaration is BuiltInsPackageFragment) {
|
||||
return ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS)
|
||||
@@ -1377,6 +1378,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
val facadeName = when (containingDeclaration) {
|
||||
is LazyJavaPackageFragment -> containingDeclaration.getFacadeNameForPartName(implClassName) ?: return null
|
||||
is IncrementalMultifileClassPackageFragment -> containingDeclaration.facadeName
|
||||
// TODO: for multi-file class part, they can be different
|
||||
is PackageFragmentDescriptor -> implClassName
|
||||
else -> throw AssertionError(
|
||||
"Unexpected package fragment for $descriptor: $containingDeclaration (${containingDeclaration.javaClass.simpleName})"
|
||||
)
|
||||
|
||||
+4
-2
@@ -260,7 +260,8 @@ class Fir2IrDeclarationStorage(
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED
|
||||
): IrSimpleFunction {
|
||||
fun create(): IrSimpleFunction {
|
||||
val descriptor = WrappedSimpleFunctionDescriptor()
|
||||
val containerSource = function.containerSource
|
||||
val descriptor = containerSource?.let { WrappedFunctionDescriptorWithContainerSource(it) } ?: WrappedSimpleFunctionDescriptor()
|
||||
return function.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareSimpleFunction(startOffset, endOffset, origin, descriptor) { symbol ->
|
||||
IrFunctionImpl(
|
||||
@@ -338,7 +339,8 @@ class Fir2IrDeclarationStorage(
|
||||
|
||||
fun getIrProperty(property: FirProperty): IrProperty {
|
||||
return propertyCache.getOrPut(property) {
|
||||
val descriptor = WrappedPropertyDescriptor()
|
||||
val containerSource = property.containerSource
|
||||
val descriptor = containerSource?.let { WrappedPropertyDescriptorWithContainerSource(it) } ?: WrappedPropertyDescriptor()
|
||||
val origin = IrDeclarationOrigin.DEFINED
|
||||
property.convertWithOffsets { startOffset, endOffset ->
|
||||
irSymbolTable.declareProperty(
|
||||
|
||||
+47
-6
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||
import org.jetbrains.kotlin.fir.declarations.FirNamedDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirEnumEntryImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberFunctionImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirMemberPropertyImpl
|
||||
import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext
|
||||
import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
@@ -42,6 +44,7 @@ import org.jetbrains.kotlin.load.kotlin.*
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -49,6 +52,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
@@ -64,7 +68,11 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
private val typeAliasCache = mutableMapOf<ClassId, FirTypeAliasSymbol?>()
|
||||
private val packagePartsCache = mutableMapOf<FqName, Collection<PackagePartsCacheData>>()
|
||||
|
||||
private class PackagePartsCacheData(val proto: ProtoBuf.Package, val context: FirDeserializationContext) {
|
||||
private class PackagePartsCacheData(
|
||||
val proto: ProtoBuf.Package,
|
||||
val context: FirDeserializationContext,
|
||||
val source: JvmPackagePartSource
|
||||
) {
|
||||
val topLevelFunctionNameIndex by lazy {
|
||||
proto.functionList.withIndex()
|
||||
.groupBy({ context.nameResolver.getName(it.value.name) }) { (index) -> index }
|
||||
@@ -95,20 +103,42 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
if (!hasTopLevelClassOf(classId)) return@mapNotNull null
|
||||
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(classId) ?: return@mapNotNull null
|
||||
|
||||
val data = kotlinJvmBinaryClass.classHeader.data ?: return@mapNotNull null
|
||||
val strings = kotlinJvmBinaryClass.classHeader.strings ?: return@mapNotNull null
|
||||
val header = kotlinJvmBinaryClass.classHeader
|
||||
val data = header.data ?: header.incompatibleData ?: return@mapNotNull null
|
||||
val strings = header.strings ?: return@mapNotNull null
|
||||
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(data, strings)
|
||||
|
||||
val source = JvmPackagePartSource(
|
||||
kotlinJvmBinaryClass, packageProto, nameResolver,
|
||||
kotlinJvmBinaryClass.incompatibility, kotlinJvmBinaryClass.isPreReleaseInvisible
|
||||
)
|
||||
|
||||
PackagePartsCacheData(
|
||||
packageProto,
|
||||
FirDeserializationContext.createForPackage(
|
||||
packageFqName, packageProto, nameResolver, session,
|
||||
JvmBinaryAnnotationDeserializer(session)
|
||||
)
|
||||
),
|
||||
source
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
|
||||
val header = kotlinClass.classHeader
|
||||
return (header.data ?: header.incompatibleData)?.takeIf { header.kind in expectedKinds }
|
||||
}
|
||||
|
||||
private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>?
|
||||
get() {
|
||||
// TODO: skipMetadataVersionCheck
|
||||
if (classHeader.metadataVersion.isCompatible()) return null
|
||||
return IncompatibleVersionErrorData(classHeader.metadataVersion, JvmMetadataVersion.INSTANCE, location, classId)
|
||||
}
|
||||
|
||||
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
|
||||
get() = classHeader.isPreRelease
|
||||
|
||||
override fun getClassUseSiteMemberScope(
|
||||
classId: ClassId,
|
||||
useSiteSession: FirSession,
|
||||
@@ -339,7 +369,9 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
val functionIds = part.topLevelFunctionNameIndex[name] ?: return emptyList()
|
||||
return functionIds.map { part.proto.getFunction(it) }
|
||||
.map {
|
||||
part.context.memberDeserializer.loadFunction(it).symbol
|
||||
val firNamedFunction = part.context.memberDeserializer.loadFunction(it) as FirMemberFunctionImpl
|
||||
firNamedFunction.containerSource = part.source
|
||||
firNamedFunction.symbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +379,9 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
val propertyIds = part.topLevelPropertyNameIndex[name] ?: return emptyList()
|
||||
return propertyIds.map { part.proto.getProperty(it) }
|
||||
.map {
|
||||
part.context.memberDeserializer.loadProperty(it).symbol
|
||||
val firProperty = part.context.memberDeserializer.loadProperty(it) as FirMemberPropertyImpl
|
||||
firProperty.containerSource = part.source
|
||||
firProperty.symbol
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,4 +430,11 @@ class KotlinDeserializedJvmSymbolsProvider(
|
||||
}
|
||||
|
||||
override fun getPackage(fqName: FqName): FqName? = null
|
||||
|
||||
companion object {
|
||||
private val KOTLIN_CLASS = setOf(KotlinClassHeader.Kind.CLASS)
|
||||
|
||||
private val KOTLIN_FILE_FACADE_OR_MULTIFILE_CLASS_PART =
|
||||
setOf(KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART)
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.fir.VisitedSupertype
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
interface FirCallableMemberDeclaration : @VisitedSupertype FirDeclaration, FirMemberDeclaration, FirCallableDeclaration {
|
||||
|
||||
@@ -14,6 +15,8 @@ interface FirCallableMemberDeclaration : @VisitedSupertype FirDeclaration, FirMe
|
||||
|
||||
val isStatic: Boolean get() = status.isStatic
|
||||
|
||||
val containerSource: DeserializedContainerSource? get() = null
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitCallableMemberDeclaration(this, data)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
|
||||
+3
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.transformSingle
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
abstract class FirAbstractCallableMember : FirAbstractMemberDeclaration, FirCallableMemberDeclaration {
|
||||
|
||||
@@ -22,6 +23,8 @@ abstract class FirAbstractCallableMember : FirAbstractMemberDeclaration, FirCall
|
||||
final override var receiverTypeRef: FirTypeRef?
|
||||
final override var returnTypeRef: FirTypeRef
|
||||
|
||||
override var containerSource: DeserializedContainerSource? = null
|
||||
|
||||
override fun <D> transformReturnTypeRef(transformer: FirTransformer<D>, data: D) {
|
||||
returnTypeRef = returnTypeRef.transformSingle(transformer, data)
|
||||
}
|
||||
|
||||
+10
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.TypeIntersectionScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -432,6 +434,10 @@ open class WrappedSimpleFunctionDescriptor(
|
||||
}
|
||||
}
|
||||
|
||||
class WrappedFunctionDescriptorWithContainerSource(
|
||||
override val containerSource: DeserializedContainerSource
|
||||
) : WrappedSimpleFunctionDescriptor(), DescriptorWithContainerSource
|
||||
|
||||
open class WrappedClassConstructorDescriptor(
|
||||
annotations: Annotations = Annotations.EMPTY,
|
||||
sourceElement: SourceElement = SourceElement.NO_SOURCE
|
||||
@@ -833,6 +839,10 @@ open class WrappedPropertyDescriptor(
|
||||
override fun <V : Any?> getUserData(key: CallableDescriptor.UserDataKey<V>?): V? = null
|
||||
}
|
||||
|
||||
class WrappedPropertyDescriptorWithContainerSource(
|
||||
override var containerSource: DeserializedContainerSource
|
||||
) : WrappedPropertyDescriptor(), DescriptorWithContainerSource
|
||||
|
||||
open class WrappedFieldDescriptor(
|
||||
annotations: Annotations = Annotations.EMPTY,
|
||||
private val sourceElement: SourceElement = SourceElement.NO_SOURCE
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ class E(s: String) : Exception(s) {
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
if (box() == "OK") {
|
||||
System.out.println("Hello")
|
||||
println("Hello")
|
||||
throw E("Hello")
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -67,10 +67,10 @@ fun ClassDescriptor.getParentJavaStaticClassScope(): LazyJavaStaticClassScope? {
|
||||
return superClassDescriptor.staticScope as? LazyJavaStaticClassScope ?: superClassDescriptor.getParentJavaStaticClassScope()
|
||||
}
|
||||
|
||||
fun DeserializedMemberDescriptor.getImplClassNameForDeserialized(): JvmClassName? =
|
||||
fun DescriptorWithContainerSource.getImplClassNameForDeserialized(): JvmClassName? =
|
||||
(containerSource as? JvmPackagePartSource)?.className
|
||||
|
||||
fun DeserializedMemberDescriptor.isFromJvmPackagePart(): Boolean =
|
||||
fun DescriptorWithContainerSource.isFromJvmPackagePart(): Boolean =
|
||||
containerSource is JvmPackagePartSource
|
||||
|
||||
fun ValueParameterDescriptor.getParameterNameAnnotation(): AnnotationDescriptor? {
|
||||
|
||||
+6
-2
@@ -16,7 +16,11 @@ import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErr
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.*
|
||||
|
||||
interface DeserializedMemberDescriptor : MemberDescriptor {
|
||||
interface DescriptorWithContainerSource : MemberDescriptor {
|
||||
val containerSource: DeserializedContainerSource?
|
||||
}
|
||||
|
||||
interface DeserializedMemberDescriptor : MemberDescriptor, DescriptorWithContainerSource {
|
||||
val proto: MessageLite
|
||||
|
||||
val nameResolver: NameResolver
|
||||
@@ -30,7 +34,7 @@ interface DeserializedMemberDescriptor : MemberDescriptor {
|
||||
|
||||
// Information about the origin of this callable's container (class or package part on JVM) or null if there's no such information.
|
||||
// TODO: merge with sourceElement of containingDeclaration
|
||||
val containerSource: DeserializedContainerSource?
|
||||
override val containerSource: DeserializedContainerSource?
|
||||
|
||||
val coroutinesExperimentalCompatibilityMode: CoroutinesCompatibilityMode
|
||||
|
||||
|
||||
Reference in New Issue
Block a user