JVM_IR: read Klib
This commit is contained in:
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.konan.CompilerVersion
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.library.KotlinAbiVersion
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinLibraryProperResolverWithAttributes
|
||||
import org.jetbrains.kotlin.library.UnresolvedLibrary
|
||||
import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents
|
||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||
import org.jetbrains.kotlin.library.resolver.impl.libraryResolver
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
|
||||
val jvmLibrariesProvidedByDefault = setOf("stdlib", "kotlin")
|
||||
|
||||
class JvmLibraryResolver(
|
||||
repositories: List<String>,
|
||||
directLibs: List<String>,
|
||||
knownAbiVersions: List<KotlinAbiVersion>?,
|
||||
knownCompilerVersions: List<CompilerVersion>?,
|
||||
distributionKlib: String?,
|
||||
localKotlinDir: String?,
|
||||
skipCurrentDir: Boolean,
|
||||
logger: Logger
|
||||
) : KotlinLibraryProperResolverWithAttributes<KotlinLibrary>(
|
||||
repositories,
|
||||
directLibs,
|
||||
knownAbiVersions,
|
||||
knownCompilerVersions,
|
||||
distributionKlib,
|
||||
localKotlinDir,
|
||||
skipCurrentDir,
|
||||
logger,
|
||||
emptyList()
|
||||
) {
|
||||
// Stick with the default KotlinLibrary for now.
|
||||
override fun libraryComponentBuilder(file: File, isDefault: Boolean) = createKotlinLibraryComponents(file, isDefault)
|
||||
|
||||
// We do not need stdlib in klib form.
|
||||
override fun isProvidedByDefault(unresolved: UnresolvedLibrary): Boolean =
|
||||
unresolved.path in jvmLibrariesProvidedByDefault
|
||||
}
|
||||
|
||||
// TODO: This is a temporary set of library resolver policies for jvm compiler.
|
||||
fun jvmResolveLibraries(libraries: List<String>, logger: Logger): KotlinLibraryResolveResult {
|
||||
val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) }
|
||||
val libraryAbsolutePaths = libraries.map { File(it).absolutePath }
|
||||
// Configure the resolver to only work with absolute paths for now.
|
||||
val libraryResolver = JvmLibraryResolver(
|
||||
repositories = emptyList(),
|
||||
directLibs = libraryAbsolutePaths,
|
||||
knownAbiVersions = listOf(KotlinAbiVersion.CURRENT),
|
||||
knownCompilerVersions = emptyList<CompilerVersion>(),
|
||||
distributionKlib = null,
|
||||
localKotlinDir = null,
|
||||
skipCurrentDir = false,
|
||||
logger = logger
|
||||
).libraryResolver()
|
||||
val resolvedLibraries =
|
||||
libraryResolver.resolveWithDependencies(
|
||||
unresolvedLibraries = unresolvedLibraries,
|
||||
noStdLib = true,
|
||||
noDefaultLibs = true,
|
||||
noEndorsedLibs = true
|
||||
)
|
||||
return resolvedLibraries
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorReferenceDeserializer
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class JvmDescriptorReferenceDeserializer(currentModule: ModuleDescriptor, private val uniqIdAware: DescriptorUniqIdAware) :
|
||||
DescriptorReferenceDeserializer(currentModule, JvmMangler, builtIns = null, resolvedForwardDeclarations = mutableMapOf()),
|
||||
DescriptorUniqIdAware by uniqIdAware {
|
||||
|
||||
override fun resolveSpecialDescriptor(fqn: FqName): ClassDescriptor {
|
||||
error("Should never be called")
|
||||
}
|
||||
|
||||
override fun checkIfSpecialDescriptorId(id: Long) = false
|
||||
|
||||
override fun getDescriptorIdOrNull(descriptor: DeclarationDescriptor): Long? = null
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorUniqIdAware
|
||||
import org.jetbrains.kotlin.backend.common.serialization.tryGetExtension
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
|
||||
|
||||
class JvmDescriptorUniqIdAware(val symbolTable: SymbolTable, val stubGenerator: DeclarationStubGenerator) : DescriptorUniqIdAware {
|
||||
override fun DeclarationDescriptor.getUniqId(): Long? =
|
||||
when (this) {
|
||||
is DeserializedClassDescriptor -> this.classProto.tryGetExtension(KlibMetadataProtoBuf.classUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
is DeserializedSimpleFunctionDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.functionUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
is DeserializedPropertyDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.propertyUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
is DeserializedClassConstructorDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.constructorUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
is DeserializedTypeParameterDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeParamUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
is DeserializedTypeAliasDescriptor -> this.proto.tryGetExtension(KlibMetadataProtoBuf.typeAliasUniqId)?.index
|
||||
?: referenceAndHash(this)
|
||||
else -> referenceAndHash(this)
|
||||
}
|
||||
|
||||
private fun referenceAndHash(descriptor: DeclarationDescriptor): Long? =
|
||||
if (descriptor is CallableMemberDescriptor && descriptor.kind === CallableMemberDescriptor.Kind.FAKE_OVERRIDE)
|
||||
null
|
||||
else with(JvmMangler) {
|
||||
referenceWithParents(descriptor).hashedMangle
|
||||
}
|
||||
|
||||
|
||||
private fun referenceWithParents(descriptor: DeclarationDescriptor): IrDeclaration {
|
||||
val original = descriptor.original
|
||||
val result = referenceOrDeclare(original)
|
||||
var currentDescriptor = original
|
||||
var current = result
|
||||
// If current is a lazy declaration, the parent may already be set.
|
||||
while (current.parent == null) {
|
||||
val nextDescriptor = when {
|
||||
currentDescriptor is TypeParameterDescriptor && currentDescriptor.containingDeclaration is PropertyDescriptor -> {
|
||||
val property = currentDescriptor.containingDeclaration as PropertyDescriptor
|
||||
// No way to choose between getter and setter by descriptor alone :(
|
||||
property.getter ?: property.setter!!
|
||||
}
|
||||
else ->
|
||||
currentDescriptor.containingDeclaration!!
|
||||
}
|
||||
if (nextDescriptor is PackageFragmentDescriptor) {
|
||||
current.parent = symbolTable.findOrDeclareExternalPackageFragment(nextDescriptor)
|
||||
break
|
||||
} else {
|
||||
val next = referenceOrDeclare(nextDescriptor)
|
||||
current.parent = next as IrDeclarationParent
|
||||
currentDescriptor = nextDescriptor
|
||||
current = next
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun referenceOrDeclare(descriptor: DeclarationDescriptor): IrDeclaration =
|
||||
symbolTable.referenceMember(descriptor).also {
|
||||
if (!it.isBound) {
|
||||
stubGenerator.getDeclaration(it)
|
||||
}
|
||||
}.owner as IrDeclaration
|
||||
}
|
||||
|
||||
// May be needed in the future
|
||||
//
|
||||
//fun DeclarationDescriptor.willBeEliminatedInLowerings(): Boolean =
|
||||
// isAnnotationConstructor() ||
|
||||
// (this is PropertyAccessorDescriptor &&
|
||||
// correspondingProperty.hasJvmFieldAnnotation())
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.serialization.*
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.UniqId
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||
|
||||
class JvmIrLinker(
|
||||
currentModule: ModuleDescriptor,
|
||||
logger: LoggingContext,
|
||||
builtIns: IrBuiltIns,
|
||||
symbolTable: SymbolTable,
|
||||
stubGenerator: DeclarationStubGenerator
|
||||
) : KotlinIrLinker(logger, builtIns, symbolTable, emptyList(), null, JvmMangler,
|
||||
// TODO: Use protected shouldBeDeserialized() ?
|
||||
tolerateNonKlibDescriptors = true),
|
||||
DescriptorUniqIdAware {
|
||||
|
||||
override val descriptorReferenceDeserializer =
|
||||
JvmDescriptorReferenceDeserializer(currentModule, JvmDescriptorUniqIdAware(symbolTable, stubGenerator))
|
||||
override fun DeclarationDescriptor.getUniqId() = with(descriptorReferenceDeserializer) {
|
||||
getUniqId()
|
||||
}
|
||||
|
||||
override fun handleNoModuleDeserializerFound(key: UniqId): DeserializationState<*> {
|
||||
return globalDeserializationState // !!!!!! Wrong, as external references will all have UniqId.NONE
|
||||
}
|
||||
|
||||
override fun reader(moduleDescriptor: ModuleDescriptor, fileIndex: Int, uniqId: UniqId) =
|
||||
moduleDescriptor.kotlinLibrary.irDeclaration(uniqId.index, fileIndex)
|
||||
|
||||
override fun readSymbol(moduleDescriptor: ModuleDescriptor, fileIndex: Int, symbolIndex: Int) =
|
||||
moduleDescriptor.kotlinLibrary.symbol(symbolIndex, fileIndex)
|
||||
|
||||
override fun readType(moduleDescriptor: ModuleDescriptor, fileIndex: Int, typeIndex: Int) =
|
||||
moduleDescriptor.kotlinLibrary.type(typeIndex, fileIndex)
|
||||
|
||||
override fun readString(moduleDescriptor: ModuleDescriptor, fileIndex: Int, stringIndex: Int) =
|
||||
moduleDescriptor.kotlinLibrary.string(stringIndex, fileIndex)
|
||||
|
||||
override fun readBody(moduleDescriptor: ModuleDescriptor, fileIndex: Int, bodyIndex: Int) =
|
||||
moduleDescriptor.kotlinLibrary.body(bodyIndex, fileIndex)
|
||||
|
||||
override fun readFile(moduleDescriptor: ModuleDescriptor, fileIndex: Int) =
|
||||
moduleDescriptor.kotlinLibrary.file(fileIndex)
|
||||
|
||||
override fun readFileCount(moduleDescriptor: ModuleDescriptor) =
|
||||
moduleDescriptor.kotlinLibrary.fileCount()
|
||||
|
||||
override fun checkAccessibility(declarationDescriptor: DeclarationDescriptor): Boolean {
|
||||
require(declarationDescriptor is DeclarationDescriptorWithVisibility)
|
||||
return declarationDescriptor.isPublishedApi() ||
|
||||
declarationDescriptor.visibility.let {
|
||||
it.isPublicAPI || it == Visibilities.INTERNAL ||
|
||||
it == JavaVisibilities.PACKAGE_VISIBILITY || it == JavaVisibilities.PROTECTED_AND_PACKAGE
|
||||
}
|
||||
}
|
||||
|
||||
private val ModuleDescriptor.userName get() = kotlinLibrary.libraryFile.absolutePath
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.jvm.serialization
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
|
||||
object EmptyLoggingContext: LoggingContext {
|
||||
override var inVerbosePhase = false
|
||||
|
||||
override fun log(message: () -> String) {}
|
||||
}
|
||||
Reference in New Issue
Block a user