Preliminary implementation of parts & facade in FIR-based compiler

This commit is contained in:
Mikhail Glukhikh
2019-05-16 12:58:38 +03:00
parent 2bf80ff64e
commit f3960c9482
10 changed files with 89 additions and 23 deletions
@@ -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})"
)
@@ -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(
@@ -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)
}
}
@@ -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) {
@@ -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)
}
@@ -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
View File
@@ -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? {
@@ -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