Collected klib scheme to a single interface.

This commit is contained in:
Alexander Gorshenev
2017-05-18 20:21:56 +03:00
committed by alexander-gorshenev
parent bca34894d3
commit 53473fc0dd
2 changed files with 39 additions and 29 deletions
@@ -65,13 +65,36 @@ abstract class FileBasedLibraryReader(
} }
} }
// This scheme describes the Konan Library (klib) layout.
interface SplitScheme {
val libDir: File
val target: String?
// This is a default implementation. Can't make it an assignment.
get() = null
val klibFile
get() = File("${libDir.path}.klib")
val moduleFile
get() = File(libDir, "module")
val linkdataDir
get() = File(libDir, "linkdata")
val resourcesDir
get() = File(libDir, "resources")
val targetDir
get() = File(libDir, target!!)
val kotlinDir
get() = File(targetDir, "kotlin")
val nativeDir
get() = File(targetDir, "native")
}
// TODO: Get rid of the configuration here. // TODO: Get rid of the configuration here.
class SplitLibraryReader(val libDir: File, configuration: CompilerConfiguration) class SplitLibraryReader(override val libDir: File, configuration: CompilerConfiguration)
: FileBasedLibraryReader(libDir, configuration, SplitMetadataReader(libDir)) { : FileBasedLibraryReader(libDir, configuration, SplitMetadataReader(libDir)),
SplitScheme {
public constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration) public constructor(path: String, configuration: CompilerConfiguration) : this(File(path), configuration)
val klibFile = File("${libDir.path}.klib") override val target: String? = TargetManager(configuration).currentName
init { init {
unpackIfNeeded() unpackIfNeeded()
@@ -98,16 +121,9 @@ class SplitLibraryReader(val libDir: File, configuration: CompilerConfiguration)
private val File.dirAbsolutePaths: List<String> private val File.dirAbsolutePaths: List<String>
get() = this.listFiles!!.toList()!!.map{it->it.absolutePath} get() = this.listFiles!!.toList()!!.map{it->it.absolutePath}
private val targetDir: File
get() {
val target = TargetManager(configuration).currentName
val dir = File(libDir, target)
return dir
}
override val bitcodePaths: List<String> override val bitcodePaths: List<String>
get() = File(targetDir, "kotlin").dirAbsolutePaths + get() = kotlinDir.dirAbsolutePaths +
File(targetDir, "native").dirAbsolutePaths nativeDir.dirAbsolutePaths
} }
/* ------------ writer part ----------------*/ /* ------------ writer part ----------------*/
@@ -133,15 +149,11 @@ abstract class FileBasedLibraryWriter (
val file: File): KonanLibraryWriter { val file: File): KonanLibraryWriter {
} }
class SplitLibraryWriter(val libDir: File, target: String, val nopack: Boolean = false): FileBasedLibraryWriter(libDir) { class SplitLibraryWriter(override val libDir: File, override val target: String?, val nopack: Boolean = false):
FileBasedLibraryWriter(libDir), SplitScheme {
public constructor(path: String, target: String, nopack: Boolean): this(File(path), target, nopack) public constructor(path: String, target: String, nopack: Boolean): this(File(path), target, nopack)
val klibFile = File("${libDir.path}.klib")
val linkdataDir = File(libDir, "linkdata")
val resourcesDir = File(libDir, "resources")
val targetDir = File(libDir, target)
val kotlinDir = File(targetDir, "kotlin")
val nativeDir = File(targetDir, "native")
// TODO: Experiment with separate bitcode files. // TODO: Experiment with separate bitcode files.
// Per package or per class. // Per package or per class.
val mainBitcodeFile = File(kotlinDir, "program.kt.bc") val mainBitcodeFile = File(kotlinDir, "program.kt.bc")
@@ -167,7 +179,7 @@ class SplitLibraryWriter(val libDir: File, target: String, val nopack: Boolean =
} }
override fun addLinkData(linkData: LinkData) { override fun addLinkData(linkData: LinkData) {
SplitMetadataGenerator(linkdataDir).addLinkData(linkData) SplitMetadataGenerator(libDir).addLinkData(linkData)
} }
override fun addNativeBitcode(library: String) { override fun addNativeBitcode(library: String) {
@@ -26,14 +26,11 @@ interface MetadataReader {
fun loadSerializedPackageFragment(fqName: String): String fun loadSerializedPackageFragment(fqName: String): String
} }
class SplitMetadataReader(file: File) : MetadataReader { class SplitMetadataReader(override val libDir: File) : MetadataReader, SplitScheme {
val linkDataDir = File(file, "linkdata")
override fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData { override fun loadSerializedModule(currentAbiVersion: Int): NamedModuleData {
val header = Properties() val header = Properties()
val file = File(linkDataDir, "module") moduleFile.bufferedReader().use { reader ->
file.bufferedReader().use { reader ->
header.load(reader) header.load(reader)
} }
val headerAbiVersion = header.getProperty("abi_version")!! val headerAbiVersion = header.getProperty("abi_version")!!
@@ -49,27 +46,28 @@ class SplitMetadataReader(file: File) : MetadataReader {
override fun loadSerializedPackageFragment(fqName: String): String { override fun loadSerializedPackageFragment(fqName: String): String {
val realName = if (fqName == "") "<root>" else fqName val realName = if (fqName == "") "<root>" else fqName
return File(linkDataDir, realName).readText() return File(linkdataDir, realName).readText()
} }
} }
internal class SplitMetadataGenerator(val file: File) { internal class SplitMetadataGenerator(override val libDir: File): SplitScheme {
fun addLinkData(linkData: LinkData) { fun addLinkData(linkData: LinkData) {
val linkdataDir = File(libDir, "linkdata")
val header = Properties() val header = Properties()
header.putAll(hashMapOf( header.putAll(hashMapOf(
"abi_version" to "${linkData.abiVersion}", "abi_version" to "${linkData.abiVersion}",
"module_name" to "${linkData.moduleName}", "module_name" to "${linkData.moduleName}",
"module_data" to "${linkData.module}" "module_data" to "${linkData.module}"
)) ))
header.store(File(file, "module").outputStream(), null) header.store(moduleFile.outputStream(), null)
linkData.fragments.forEachIndexed { index, it -> linkData.fragments.forEachIndexed { index, it ->
val name = linkData.fragmentNames[index] val name = linkData.fragmentNames[index]
val realName = if (name == "") "<root>" else name val realName = if (name == "") "<root>" else name
File(file, realName).writeText(it) File(linkdataDir, realName).writeText(it)
} }
} }
} }