Introduce kotlinx-metadata-klib.
`kotlinx-metadata-klib` is an extension of `kotlinx-metadata` that can be used to read and write metadata that is stored inside KLIBs. Note: current version is in its early days and in active development. Almost nothing is stable or properly tested.
This commit is contained in:
@@ -48,6 +48,9 @@ internal class JvmMetadataExtensions : MetadataExtensions {
|
|||||||
ext.visitEnd()
|
ext.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModuleFragment is not used by JVM backend.
|
||||||
|
override fun readModuleFragmentExtensions(v: KmModuleFragmentVisitor, proto: ProtoBuf.PackageFragment, c: ReadContext) {}
|
||||||
|
|
||||||
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext) {
|
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext) {
|
||||||
val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return
|
val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return
|
||||||
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, c.strings, c.types)?.wrapAsPublic())
|
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, c.strings, c.types)?.wrapAsPublic())
|
||||||
@@ -144,6 +147,13 @@ internal class JvmMetadataExtensions : MetadataExtensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PackageFragment is not used by JVM backend.
|
||||||
|
override fun writeModuleFragmentExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.PackageFragment.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmModuleFragmentExtensionVisitor? = null
|
||||||
|
|
||||||
override fun writeFunctionExtensions(
|
override fun writeFunctionExtensions(
|
||||||
type: KmExtensionType, proto: ProtoBuf.Function.Builder, c: WriteContext
|
type: KmExtensionType, proto: ProtoBuf.Function.Builder, c: WriteContext
|
||||||
): KmFunctionExtensionVisitor? {
|
): KmFunctionExtensionVisitor? {
|
||||||
@@ -262,6 +272,9 @@ internal class JvmMetadataExtensions : MetadataExtensions {
|
|||||||
|
|
||||||
override fun createPackageExtension(): KmPackageExtension = JvmPackageExtension()
|
override fun createPackageExtension(): KmPackageExtension = JvmPackageExtension()
|
||||||
|
|
||||||
|
override fun createModuleFragmentExtensions(): KmModuleFragmentExtension =
|
||||||
|
error("metadata-jvm doesn't have any extensions for module fragment!")
|
||||||
|
|
||||||
override fun createFunctionExtension(): KmFunctionExtension = JvmFunctionExtension()
|
override fun createFunctionExtension(): KmFunctionExtension = JvmFunctionExtension()
|
||||||
|
|
||||||
override fun createPropertyExtension(): KmPropertyExtension = JvmPropertyExtension()
|
override fun createPropertyExtension(): KmPropertyExtension = JvmPropertyExtension()
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
|
|
||||||
|
description = "Kotlin Library (KLIB) metadata manipulation library"
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("jps-compatible")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "org.jetbrains.kotlinx"
|
||||||
|
|
||||||
|
val deployVersion = findProperty("kotlinxMetadataKlibDeployVersion") as String?
|
||||||
|
version = deployVersion ?: "0.0.1-SNAPSHOT"
|
||||||
|
|
||||||
|
jvmTarget = "1.6"
|
||||||
|
javaHome = rootProject.extra["JDK_16"] as String
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
"main" { projectDefault() }
|
||||||
|
}
|
||||||
|
|
||||||
|
val shadows by configurations.creating {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
configurations.getByName("compileOnly").extendsFrom(shadows)
|
||||||
|
configurations.getByName("testCompile").extendsFrom(shadows)
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile(kotlinStdlib())
|
||||||
|
shadows(project(":kotlinx-metadata"))
|
||||||
|
shadows(project(":core:metadata"))
|
||||||
|
shadows(project(":compiler:serialization"))
|
||||||
|
shadows(project(":kotlin-util-klib-metadata"))
|
||||||
|
shadows(project(":kotlin-util-klib"))
|
||||||
|
shadows(protobufLite())
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deployVersion != null) {
|
||||||
|
publish()
|
||||||
|
}
|
||||||
|
|
||||||
|
noDefaultJar()
|
||||||
|
|
||||||
|
tasks.register<ShadowJar>("shadowJar") {
|
||||||
|
callGroovy("manifestAttributes", manifest, project)
|
||||||
|
manifest.attributes["Implementation-Version"] = version
|
||||||
|
|
||||||
|
from(mainSourceSet.output)
|
||||||
|
exclude("**/*.proto")
|
||||||
|
configurations = listOf(shadows)
|
||||||
|
relocate("org.jetbrains.kotlin", "kotlinx.metadata.internal")
|
||||||
|
|
||||||
|
val artifactRef = outputs.files.singleFile
|
||||||
|
runtimeJarArtifactBy(this, artifactRef)
|
||||||
|
addArtifact("runtime", this, artifactRef)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourcesJar {
|
||||||
|
for (dependency in shadows.dependencies) {
|
||||||
|
if (dependency is ProjectDependency) {
|
||||||
|
val javaPlugin = dependency.dependencyProject.convention.findPlugin(JavaPluginConvention::class.java)
|
||||||
|
if (javaPlugin != null) {
|
||||||
|
from(javaPlugin.sourceSets["main"].allSource)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
javadocJar()
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlinx.metadata.klib.impl.KlibMetadataExtensions
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.KmAnnotation
|
||||||
|
|
||||||
|
class KlibHeader(
|
||||||
|
val moduleName: String,
|
||||||
|
val file: List<KlibSourceFile>,
|
||||||
|
val packageFragmentName: List<String>,
|
||||||
|
val emptyPackage: List<String>,
|
||||||
|
val annotation: List<KmAnnotation>
|
||||||
|
)
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.KmAnnotation
|
||||||
|
import kotlinx.metadata.KmModuleFragment
|
||||||
|
import kotlinx.metadata.impl.WriteContext
|
||||||
|
import kotlinx.metadata.impl.accept
|
||||||
|
import kotlinx.metadata.klib.impl.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataStringTable
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parseModuleHeader
|
||||||
|
import org.jetbrains.kotlin.library.metadata.parsePackageFragment
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to modify the way fragments of the single package are read by [KlibModuleMetadata.read].
|
||||||
|
* For example, it may be convenient to join fragments into a single one.
|
||||||
|
*/
|
||||||
|
interface KlibModuleFragmentReadStrategy {
|
||||||
|
fun processModuleParts(parts: List<KmModuleFragment>): List<KmModuleFragment>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val DEFAULT = object : KlibModuleFragmentReadStrategy {
|
||||||
|
override fun processModuleParts(parts: List<KmModuleFragment>) =
|
||||||
|
parts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to modify the way module fragments are written by [KlibModuleMetadata.write].
|
||||||
|
* For example, splitting big fragments into several small one allows to improve IDE performance.
|
||||||
|
*/
|
||||||
|
interface KlibModuleFragmentWriteStrategy {
|
||||||
|
fun processPackageParts(parts: List<KmModuleFragment>): List<KmModuleFragment>
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val DEFAULT = object : KlibModuleFragmentWriteStrategy {
|
||||||
|
override fun processPackageParts(parts: List<KmModuleFragment>): List<KmModuleFragment> =
|
||||||
|
parts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the parsed metadata of KLIB.
|
||||||
|
*/
|
||||||
|
class KlibModuleMetadata(
|
||||||
|
val name: String,
|
||||||
|
val fragments: List<KmModuleFragment>,
|
||||||
|
val annotations: List<KmAnnotation>
|
||||||
|
) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialized representation of module metadata.
|
||||||
|
*/
|
||||||
|
class SerializedKlibMetadata(
|
||||||
|
val header: ByteArray,
|
||||||
|
val fragments: List<List<ByteArray>>,
|
||||||
|
val fragmentNames: List<String>
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies access to library's metadata.
|
||||||
|
*/
|
||||||
|
interface MetadataLibraryProvider {
|
||||||
|
val moduleHeaderData: ByteArray
|
||||||
|
fun packageMetadataParts(fqName: String): Set<String>
|
||||||
|
fun packageMetadata(fqName: String, partName: String): ByteArray
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Deserializes metadata from the given [library].
|
||||||
|
* @param readStrategy specifies the way module fragments of a single package are modified (e.g. merged) after deserialization.
|
||||||
|
*/
|
||||||
|
fun read(
|
||||||
|
library: MetadataLibraryProvider,
|
||||||
|
readStrategy: KlibModuleFragmentReadStrategy = KlibModuleFragmentReadStrategy.DEFAULT
|
||||||
|
): KlibModuleMetadata {
|
||||||
|
val moduleHeaderProto = parseModuleHeader(library.moduleHeaderData)
|
||||||
|
val nameResolver = NameResolverImpl(moduleHeaderProto.strings, moduleHeaderProto.qualifiedNames)
|
||||||
|
val moduleHeader = moduleHeaderProto.readHeader(nameResolver)
|
||||||
|
val fileIndex = SourceFileIndexReadExtension(moduleHeader.file)
|
||||||
|
val moduleFragments = moduleHeader.packageFragmentName.flatMap { packageFqName ->
|
||||||
|
library.packageMetadataParts(packageFqName).map { part ->
|
||||||
|
val packageFragment = parsePackageFragment(library.packageMetadata(packageFqName, part))
|
||||||
|
KmModuleFragment().apply { packageFragment.accept(this, nameResolver, listOf(fileIndex)) }
|
||||||
|
}.let(readStrategy::processModuleParts)
|
||||||
|
}
|
||||||
|
return KlibModuleMetadata(moduleHeader.moduleName, moduleFragments, moduleHeader.annotation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes metadata back to serialized representation.
|
||||||
|
* @param writeStrategy specifies the way module fragments are modified (e.g. split) before serialization.
|
||||||
|
*/
|
||||||
|
fun write(
|
||||||
|
writeStrategy: KlibModuleFragmentWriteStrategy = KlibModuleFragmentWriteStrategy.DEFAULT
|
||||||
|
): SerializedKlibMetadata {
|
||||||
|
val reverseIndex = ReverseSourceFileIndexWriteExtension()
|
||||||
|
val c = WriteContext(KlibMetadataStringTable(), listOf(reverseIndex))
|
||||||
|
|
||||||
|
val groupedFragments = fragments
|
||||||
|
.groupBy(KmModuleFragment::fqNameOrFail)
|
||||||
|
.mapValues { writeStrategy.processPackageParts(it.value) }
|
||||||
|
|
||||||
|
val header = KlibHeader(
|
||||||
|
name,
|
||||||
|
reverseIndex.fileIndex,
|
||||||
|
groupedFragments.map { it.key },
|
||||||
|
groupedFragments.filter { it.value.all(KmModuleFragment::isEmpty) }.map { it.key },
|
||||||
|
annotations
|
||||||
|
)
|
||||||
|
val groupedProtos = groupedFragments.mapValues { (_, fragments) ->
|
||||||
|
fragments.map {
|
||||||
|
KlibModuleFragmentWriter(c.strings as KlibMetadataStringTable, c.contextExtensions).also(it::accept).write()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SerializedKlibMetadata(
|
||||||
|
header.writeHeader(c).build().toByteArray(),
|
||||||
|
groupedProtos.map { it.value.map(ProtoBuf.PackageFragment::toByteArray) },
|
||||||
|
header.packageFragmentName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KmModuleFragment.fqNameOrFail(): String =
|
||||||
|
fqName ?: error("Module fragment must have a fully-qualified name.")
|
||||||
|
|
||||||
|
private fun KmModuleFragment.isEmpty(): Boolean =
|
||||||
|
classes.isEmpty() && (pkg?.let { it.functions.isEmpty() && it.properties.isEmpty() && it.typeAliases.isEmpty() } ?: true)
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
class KlibSourceFile(
|
||||||
|
val name: String
|
||||||
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
class UniqId(val index: Long)
|
||||||
@@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.impl.extensions.*
|
||||||
|
import kotlinx.metadata.klib.*
|
||||||
|
|
||||||
|
internal val KmFunction.klibExtensions: KlibFunctionExtension
|
||||||
|
get() = visitExtensions(KlibFunctionExtensionVisitor.TYPE) as KlibFunctionExtension
|
||||||
|
|
||||||
|
internal val KmClass.klibExtensions: KlibClassExtension
|
||||||
|
get() = visitExtensions(KlibClassExtensionVisitor.TYPE) as KlibClassExtension
|
||||||
|
|
||||||
|
internal val KmType.klibExtensions: KlibTypeExtension
|
||||||
|
get() = visitExtensions(KlibTypeExtensionVisitor.TYPE) as KlibTypeExtension
|
||||||
|
|
||||||
|
internal val KmProperty.klibExtensions: KlibPropertyExtension
|
||||||
|
get() = visitExtensions(KlibPropertyExtensionVisitor.TYPE) as KlibPropertyExtension
|
||||||
|
|
||||||
|
internal val KmConstructor.klibExtensions: KlibConstructorExtension
|
||||||
|
get() = visitExtensions(KlibConstructorExtensionVisitor.TYPE) as KlibConstructorExtension
|
||||||
|
|
||||||
|
internal val KmTypeParameter.klibExtensions: KlibTypeParameterExtension
|
||||||
|
get() = visitExtensions(KlibTypeParameterExtensionVisitor.TYPE) as KlibTypeParameterExtension
|
||||||
|
|
||||||
|
internal val KmPackage.klibExtensions: KlibPackageExtension
|
||||||
|
get() = visitExtensions(KlibPackageExtensionVisitor.TYPE) as KlibPackageExtension
|
||||||
|
|
||||||
|
internal val KmModuleFragment.klibExtensions: KlibModuleFragmentExtension
|
||||||
|
get() = visitExtensions(KlibModuleFragmentExtensionVisitor.TYPE) as KlibModuleFragmentExtension
|
||||||
|
|
||||||
|
internal class KlibFunctionExtension : KlibFunctionExtensionVisitor(), KmFunctionExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
var uniqId: UniqId? = null
|
||||||
|
var file: KlibSourceFile? = null
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
this.uniqId = uniqId
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmFunctionExtensionVisitor) {
|
||||||
|
require(visitor is KlibFunctionExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
uniqId?.let(visitor::visitUniqId)
|
||||||
|
file?.let(visitor::visitFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibClassExtension : KlibClassExtensionVisitor(), KmClassExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
var uniqId: UniqId? = null
|
||||||
|
var file: KlibSourceFile? = null
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
this.uniqId = uniqId
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmClassExtensionVisitor) {
|
||||||
|
require(visitor is KlibClassExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
uniqId?.let(visitor::visitUniqId)
|
||||||
|
file?.let(visitor::visitFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibTypeExtension : KlibTypeExtensionVisitor(), KmTypeExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmTypeExtensionVisitor) {
|
||||||
|
require(visitor is KlibTypeExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibPropertyExtension : KlibPropertyExtensionVisitor(), KmPropertyExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
val getterAnnotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
val setterAnnotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
var uniqId: UniqId? = null
|
||||||
|
var file: Int? = null
|
||||||
|
var compileTimeValue: KmAnnotationArgument<*>? = null
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetterAnnotation(annotation: KmAnnotation) {
|
||||||
|
getterAnnotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSetterAnnotation(annotation: KmAnnotation) {
|
||||||
|
setterAnnotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: Int) {
|
||||||
|
this.file = file
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
this.uniqId = uniqId
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCompileTimeValue(value: KmAnnotationArgument<*>) {
|
||||||
|
this.compileTimeValue = value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmPropertyExtensionVisitor) {
|
||||||
|
require(visitor is KlibPropertyExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
getterAnnotations.forEach(visitor::visitGetterAnnotation)
|
||||||
|
setterAnnotations.forEach(visitor::visitSetterAnnotation)
|
||||||
|
file?.let(visitor::visitFile)
|
||||||
|
uniqId?.let(visitor::visitUniqId)
|
||||||
|
compileTimeValue?.let(visitor::visitCompileTimeValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibConstructorExtension : KlibConstructorExtensionVisitor(), KmConstructorExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
var uniqId: UniqId? = null
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
this.uniqId = uniqId
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmConstructorExtensionVisitor) {
|
||||||
|
require(visitor is KlibConstructorExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
uniqId?.let(visitor::visitUniqId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibTypeParameterExtension : KlibTypeParameterExtensionVisitor(), KmTypeParameterExtension {
|
||||||
|
|
||||||
|
val annotations: MutableList<KmAnnotation> = mutableListOf()
|
||||||
|
var uniqId: UniqId? = null
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
annotations += annotation
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
this.uniqId = uniqId
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmTypeParameterExtensionVisitor) {
|
||||||
|
require(visitor is KlibTypeParameterExtensionVisitor)
|
||||||
|
annotations.forEach(visitor::visitAnnotation)
|
||||||
|
uniqId?.let(visitor::visitUniqId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibPackageExtension : KlibPackageExtensionVisitor(), KmPackageExtension {
|
||||||
|
|
||||||
|
var fqName: String? = null
|
||||||
|
|
||||||
|
override fun visitFqName(name: String) {
|
||||||
|
fqName = name
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmPackageExtensionVisitor) {
|
||||||
|
require(visitor is KlibPackageExtensionVisitor)
|
||||||
|
fqName?.let(visitor::visitFqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KlibModuleFragmentExtension : KlibModuleFragmentExtensionVisitor(), KmModuleFragmentExtension {
|
||||||
|
|
||||||
|
val moduleFragmentFiles: MutableList<KlibSourceFile> = ArrayList()
|
||||||
|
var fqName: String? = null
|
||||||
|
val className: MutableList<ClassName> = ArrayList()
|
||||||
|
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
moduleFragmentFiles += file
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFqName(fqName: String) {
|
||||||
|
this.fqName = fqName
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClassName(className: ClassName) {
|
||||||
|
this.className += className
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun accept(visitor: KmModuleFragmentExtensionVisitor) {
|
||||||
|
require(visitor is KlibModuleFragmentExtensionVisitor)
|
||||||
|
moduleFragmentFiles.forEach(visitor::visitFile)
|
||||||
|
fqName?.let(visitor::visitFqName)
|
||||||
|
className.forEach(visitor::visitClassName)
|
||||||
|
}
|
||||||
|
}
|
||||||
+350
@@ -0,0 +1,350 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.impl.*
|
||||||
|
import kotlinx.metadata.impl.extensions.*
|
||||||
|
import kotlinx.metadata.klib.*
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
|
|
||||||
|
internal class KlibMetadataExtensions : MetadataExtensions {
|
||||||
|
|
||||||
|
private fun ReadContext.getSourceFile(index: Int) =
|
||||||
|
contextExtensions.filterIsInstance<SourceFileIndexReadExtension>().first().getSourceFile(index)
|
||||||
|
|
||||||
|
private fun WriteContext.getIndexOf(file: KlibSourceFile) =
|
||||||
|
contextExtensions.filterIsInstance<ReverseSourceFileIndexWriteExtension>().first().getIndexOf(file)
|
||||||
|
|
||||||
|
override fun readClassExtensions(v: KmClassVisitor, proto: ProtoBuf.Class, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibClassExtensionVisitor.TYPE) as? KlibClassExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.classAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.classUniqId)?.let { descriptorUniqId ->
|
||||||
|
extension.visitUniqId(descriptorUniqId.readUniqId())
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.classFile)?.let {
|
||||||
|
extension.visitFile(c.getSourceFile(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readPackageExtensions(v: KmPackageVisitor, proto: ProtoBuf.Package, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibPackageExtensionVisitor.TYPE) as? KlibPackageExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.packageFqName)?.let {
|
||||||
|
val fqName = (c.strings as NameResolverImpl).getPackageFqName(it)
|
||||||
|
extension.visitFqName(fqName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readModuleFragmentExtensions(v: KmModuleFragmentVisitor, proto: ProtoBuf.PackageFragment, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibModuleFragmentExtensionVisitor.TYPE) as? KlibModuleFragmentExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.packageFragmentFiles)
|
||||||
|
.map { c.getSourceFile(it) }
|
||||||
|
.forEach(extension::visitFile)
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.fqName)?.let(extension::visitFqName)
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.className)
|
||||||
|
.map(c.strings::getQualifiedClassName)
|
||||||
|
.forEach(extension::visitClassName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibFunctionExtensionVisitor.TYPE) as? KlibFunctionExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.functionAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.functionUniqId)?.let { descriptorUniqId ->
|
||||||
|
extension.visitUniqId(descriptorUniqId.readUniqId())
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.functionFile)?.let {
|
||||||
|
val file = c.getSourceFile(it)
|
||||||
|
extension.visitFile(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibPropertyExtensionVisitor.TYPE) as? KlibPropertyExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.propertyAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.propertyGetterAnnotation).forEach { annotation ->
|
||||||
|
extension.visitGetterAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.propertySetterAnnotation).forEach { annotation ->
|
||||||
|
extension.visitSetterAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.propertyUniqId)?.let { descriptorUniqId ->
|
||||||
|
extension.visitUniqId(descriptorUniqId.readUniqId())
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.propertyFile)?.let(extension::visitFile)
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.compileTimeValue)?.let { value ->
|
||||||
|
value.readAnnotationArgument(c.strings)?.let { extension.visitCompileTimeValue(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readConstructorExtensions(v: KmConstructorVisitor, proto: ProtoBuf.Constructor, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibConstructorExtensionVisitor.TYPE) as? KlibConstructorExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.constructorAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.constructorUniqId)?.let { descriptorUniqId ->
|
||||||
|
extension.visitUniqId(descriptorUniqId.readUniqId())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readTypeParameterExtensions(v: KmTypeParameterVisitor, proto: ProtoBuf.TypeParameter, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibTypeParameterExtensionVisitor.TYPE) as? KlibTypeParameterExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.typeParameterAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
proto.getExtensionOrNull(KlibMetadataProtoBuf.typeParamUniqId)?.let { descriptorUniqId ->
|
||||||
|
extension.visitUniqId(descriptorUniqId.readUniqId())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun readTypeExtensions(v: KmTypeVisitor, proto: ProtoBuf.Type, c: ReadContext) {
|
||||||
|
val extension = v.visitExtensions(KlibTypeExtensionVisitor.TYPE) as? KlibTypeExtensionVisitor ?: return
|
||||||
|
|
||||||
|
proto.getExtension(KlibMetadataProtoBuf.typeAnnotation).forEach { annotation ->
|
||||||
|
extension.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeClassExtensions(type: KmExtensionType, proto: ProtoBuf.Class.Builder, c: WriteContext): KmClassExtensionVisitor? {
|
||||||
|
if (type != KlibClassExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibClassExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.classAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.classUniqId,
|
||||||
|
uniqId.writeUniqId().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
val fileIdx = c.getIndexOf(file)
|
||||||
|
proto.setExtension(KlibMetadataProtoBuf.classFile, fileIdx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writePackageExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.Package.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmPackageExtensionVisitor? {
|
||||||
|
if (type != KlibPackageExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibPackageExtensionVisitor() {
|
||||||
|
override fun visitFqName(name: String) {
|
||||||
|
val nameIdx = (c.strings as StringTableImpl).getPackageFqNameIndex(FqName(name))
|
||||||
|
proto.setExtension(KlibMetadataProtoBuf.packageFqName, nameIdx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeModuleFragmentExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.PackageFragment.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmModuleFragmentExtensionVisitor? {
|
||||||
|
if (type != KlibModuleFragmentExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibModuleFragmentExtensionVisitor() {
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
val fileIdx = c.getIndexOf(file)
|
||||||
|
proto.addExtension(KlibMetadataProtoBuf.packageFragmentFiles, fileIdx)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFqName(fqName: String) {
|
||||||
|
proto.setExtension(KlibMetadataProtoBuf.fqName, fqName)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClassName(className: ClassName) {
|
||||||
|
val classNameIdx = (c.strings as StringTableImpl).getQualifiedClassNameIndex(ClassId.fromString(className))
|
||||||
|
proto.addExtension(KlibMetadataProtoBuf.className, classNameIdx)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeFunctionExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.Function.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmFunctionExtensionVisitor? {
|
||||||
|
if (type != KlibFunctionExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibFunctionExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.functionAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.functionUniqId,
|
||||||
|
uniqId.writeUniqId().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: KlibSourceFile) {
|
||||||
|
val index = c.getIndexOf(file)
|
||||||
|
proto.setExtension(KlibMetadataProtoBuf.functionFile, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writePropertyExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.Property.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmPropertyExtensionVisitor? {
|
||||||
|
if (type != KlibPropertyExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibPropertyExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.propertyAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitGetterAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.propertyGetterAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSetterAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.propertySetterAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.propertyUniqId,
|
||||||
|
uniqId.writeUniqId().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFile(file: Int) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.propertyFile,
|
||||||
|
file
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCompileTimeValue(value: KmAnnotationArgument<*>) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.compileTimeValue,
|
||||||
|
value.writeAnnotationArgument(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeConstructorExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.Constructor.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmConstructorExtensionVisitor? {
|
||||||
|
if (type != KlibConstructorExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibConstructorExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.constructorAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.constructorUniqId,
|
||||||
|
uniqId.writeUniqId().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeTypeParameterExtensions(
|
||||||
|
type: KmExtensionType,
|
||||||
|
proto: ProtoBuf.TypeParameter.Builder,
|
||||||
|
c: WriteContext
|
||||||
|
): KmTypeParameterExtensionVisitor? {
|
||||||
|
if (type != KlibTypeParameterExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibTypeParameterExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.typeParameterAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitUniqId(uniqId: UniqId) {
|
||||||
|
proto.setExtension(
|
||||||
|
KlibMetadataProtoBuf.typeParamUniqId,
|
||||||
|
uniqId.writeUniqId().build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun writeTypeExtensions(type: KmExtensionType, proto: ProtoBuf.Type.Builder, c: WriteContext): KmTypeExtensionVisitor? {
|
||||||
|
if (type != KlibTypeExtensionVisitor.TYPE) return null
|
||||||
|
return object : KlibTypeExtensionVisitor() {
|
||||||
|
override fun visitAnnotation(annotation: KmAnnotation) {
|
||||||
|
proto.addExtension(
|
||||||
|
KlibMetadataProtoBuf.typeAnnotation,
|
||||||
|
annotation.writeAnnotation(c.strings).build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createClassExtension(): KmClassExtension =
|
||||||
|
KlibClassExtension()
|
||||||
|
|
||||||
|
override fun createPackageExtension(): KmPackageExtension =
|
||||||
|
KlibPackageExtension()
|
||||||
|
|
||||||
|
override fun createModuleFragmentExtensions(): KmModuleFragmentExtension =
|
||||||
|
KlibModuleFragmentExtension()
|
||||||
|
|
||||||
|
override fun createFunctionExtension(): KmFunctionExtension =
|
||||||
|
KlibFunctionExtension()
|
||||||
|
|
||||||
|
override fun createPropertyExtension(): KmPropertyExtension =
|
||||||
|
KlibPropertyExtension()
|
||||||
|
|
||||||
|
override fun createConstructorExtension(): KmConstructorExtension =
|
||||||
|
KlibConstructorExtension()
|
||||||
|
|
||||||
|
override fun createTypeParameterExtension(): KmTypeParameterExtension =
|
||||||
|
KlibTypeParameterExtension()
|
||||||
|
|
||||||
|
override fun createTypeExtension(): KmTypeExtension =
|
||||||
|
KlibTypeExtension()
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.impl.readAnnotation
|
||||||
|
import kotlinx.metadata.klib.KlibHeader
|
||||||
|
import kotlinx.metadata.klib.KlibSourceFile
|
||||||
|
import kotlinx.metadata.klib.UniqId
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||||
|
|
||||||
|
internal fun KlibMetadataProtoBuf.DescriptorUniqId.readUniqId(): UniqId =
|
||||||
|
UniqId(index)
|
||||||
|
|
||||||
|
internal fun KlibMetadataProtoBuf.Header.readHeader(strings: NameResolver): KlibHeader =
|
||||||
|
KlibHeader(
|
||||||
|
moduleName,
|
||||||
|
fileList.map(KlibMetadataProtoBuf.File::readFile),
|
||||||
|
packageFragmentNameList,
|
||||||
|
emptyPackageList,
|
||||||
|
annotationList.map { it.readAnnotation(strings) }
|
||||||
|
)
|
||||||
|
|
||||||
|
internal fun KlibMetadataProtoBuf.File.readFile(): KlibSourceFile =
|
||||||
|
KlibSourceFile(name)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.impl.ReadContextExtension
|
||||||
|
import kotlinx.metadata.klib.KlibSourceFile
|
||||||
|
|
||||||
|
class SourceFileIndexReadExtension(
|
||||||
|
private val files: List<KlibSourceFile>
|
||||||
|
) : ReadContextExtension {
|
||||||
|
fun getSourceFile(index: Int): KlibSourceFile = files[index]
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.impl.WriteContext
|
||||||
|
import kotlinx.metadata.impl.writeAnnotation
|
||||||
|
import kotlinx.metadata.klib.KlibHeader
|
||||||
|
import kotlinx.metadata.klib.KlibSourceFile
|
||||||
|
import kotlinx.metadata.klib.UniqId
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.serialization.StringTableImpl
|
||||||
|
|
||||||
|
internal fun UniqId.writeUniqId(): KlibMetadataProtoBuf.DescriptorUniqId.Builder =
|
||||||
|
KlibMetadataProtoBuf.DescriptorUniqId.newBuilder().apply {
|
||||||
|
index = this@writeUniqId.index
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KlibHeader.writeHeader(context: WriteContext): KlibMetadataProtoBuf.Header.Builder =
|
||||||
|
KlibMetadataProtoBuf.Header.newBuilder().also { proto ->
|
||||||
|
val (strings, qualifiedNames) = (context.strings as StringTableImpl).buildProto()
|
||||||
|
proto.moduleName = moduleName
|
||||||
|
proto.qualifiedNames = qualifiedNames
|
||||||
|
proto.strings = strings
|
||||||
|
proto.addAllPackageFragmentName(packageFragmentName)
|
||||||
|
proto.addAllFile(file.map { it.writeFile().build() })
|
||||||
|
proto.addAllAnnotation(annotation.map { it.writeAnnotation(context.strings).build() })
|
||||||
|
proto.addAllEmptyPackage(emptyPackage)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun KlibSourceFile.writeFile(): KlibMetadataProtoBuf.File.Builder =
|
||||||
|
KlibMetadataProtoBuf.File.newBuilder().also { proto ->
|
||||||
|
proto.name = name
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib.impl
|
||||||
|
|
||||||
|
import kotlinx.metadata.impl.*
|
||||||
|
import kotlinx.metadata.klib.KlibSourceFile
|
||||||
|
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataStringTable
|
||||||
|
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||||
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
|
|
||||||
|
class ReverseSourceFileIndexWriteExtension : WriteContextExtension {
|
||||||
|
private val filesReverseIndex = mutableMapOf<KlibSourceFile, Int>()
|
||||||
|
|
||||||
|
val fileIndex: List<KlibSourceFile>
|
||||||
|
get() = filesReverseIndex
|
||||||
|
.map { (file, index) -> index to file }
|
||||||
|
.sortedBy { it.first }
|
||||||
|
.map { it.second }
|
||||||
|
|
||||||
|
fun getIndexOf(file: KlibSourceFile): Int = filesReverseIndex.getOrPut(file) {
|
||||||
|
filesReverseIndex.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class KlibModuleFragmentWriter(
|
||||||
|
stringTable: KlibMetadataStringTable,
|
||||||
|
contextExtensions: List<WriteContextExtension> = emptyList()
|
||||||
|
) : ModuleFragmentWriter(stringTable, contextExtensions) {
|
||||||
|
|
||||||
|
fun write(): ProtoBuf.PackageFragment =
|
||||||
|
t.build()
|
||||||
|
|
||||||
|
override fun visitEnd() {
|
||||||
|
val isPackageEmpty = if (t.`package` == null) {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
t.`package`.let { it.functionCount == 0 && it.propertyCount == 0 && it.typeAliasCount == 0 }
|
||||||
|
}
|
||||||
|
val isEmpty = t.class_Count == 0 && isPackageEmpty
|
||||||
|
t.setExtension(KlibMetadataProtoBuf.isEmpty, isEmpty)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.klib.impl.klibExtensions
|
||||||
|
|
||||||
|
val KmFunction.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
var KmFunction.uniqId: UniqId?
|
||||||
|
get() = klibExtensions.uniqId
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.uniqId = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmFunction.file: KlibSourceFile?
|
||||||
|
get() = klibExtensions.file
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.file = value
|
||||||
|
}
|
||||||
|
|
||||||
|
val KmClass.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
var KmClass.uniqId: UniqId?
|
||||||
|
get() = klibExtensions.uniqId
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.uniqId = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmClass.file: KlibSourceFile?
|
||||||
|
get() = klibExtensions.file
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.file = value
|
||||||
|
}
|
||||||
|
|
||||||
|
val KmProperty.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
val KmProperty.setterAnnotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.setterAnnotations
|
||||||
|
|
||||||
|
val KmProperty.getterAnnotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.getterAnnotations
|
||||||
|
|
||||||
|
var KmProperty.uniqId: UniqId?
|
||||||
|
get() = klibExtensions.uniqId
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.uniqId = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmProperty.file: Int?
|
||||||
|
get() = klibExtensions.file
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.file = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmProperty.compileTimeValue: KmAnnotationArgument<*>?
|
||||||
|
get() = klibExtensions.compileTimeValue
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.compileTimeValue = value
|
||||||
|
}
|
||||||
|
|
||||||
|
val KmType.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
val KmConstructor.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
var KmConstructor.uniqId: UniqId?
|
||||||
|
get() = klibExtensions.uniqId
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.uniqId = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmPackage.fqName: String?
|
||||||
|
get() = klibExtensions.fqName
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.fqName = value
|
||||||
|
}
|
||||||
|
|
||||||
|
var KmModuleFragment.fqName: String?
|
||||||
|
get() = klibExtensions.fqName
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.fqName = value
|
||||||
|
}
|
||||||
|
|
||||||
|
val KmModuleFragment.className: MutableList<ClassName>?
|
||||||
|
get() = klibExtensions.className
|
||||||
|
|
||||||
|
val KmModuleFragment.moduleFragmentFiles: MutableList<KlibSourceFile>?
|
||||||
|
get() = klibExtensions.moduleFragmentFiles
|
||||||
|
|
||||||
|
val KmTypeParameter.annotations: MutableList<KmAnnotation>
|
||||||
|
get() = klibExtensions.annotations
|
||||||
|
|
||||||
|
var KmTypeParameter.uniqId: UniqId?
|
||||||
|
get() = klibExtensions.uniqId
|
||||||
|
set(value) {
|
||||||
|
klibExtensions.uniqId = value
|
||||||
|
}
|
||||||
+130
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* 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 kotlinx.metadata.klib
|
||||||
|
|
||||||
|
import kotlinx.metadata.*
|
||||||
|
|
||||||
|
abstract class KlibFunctionExtensionVisitor : KmFunctionExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitUniqId(uniqId: UniqId)
|
||||||
|
|
||||||
|
abstract fun visitFile(file: KlibSourceFile)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibFunctionExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibClassExtensionVisitor : KmClassExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitUniqId(uniqId: UniqId)
|
||||||
|
|
||||||
|
abstract fun visitFile(file: KlibSourceFile)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibClassExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibTypeExtensionVisitor : KmTypeExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibTypeExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibPropertyExtensionVisitor : KmPropertyExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitGetterAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitSetterAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitFile(file: Int)
|
||||||
|
|
||||||
|
abstract fun visitUniqId(uniqId: UniqId)
|
||||||
|
|
||||||
|
abstract fun visitCompileTimeValue(value: KmAnnotationArgument<*>)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibPropertyExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibConstructorExtensionVisitor : KmConstructorExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitUniqId(uniqId: UniqId)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibConstructorExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibTypeParameterExtensionVisitor : KmTypeParameterExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitAnnotation(annotation: KmAnnotation)
|
||||||
|
|
||||||
|
abstract fun visitUniqId(uniqId: UniqId)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibTypeParameterExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibPackageExtensionVisitor : KmPackageExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitFqName(name: String)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibPackageExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class KlibModuleFragmentExtensionVisitor : KmModuleFragmentExtensionVisitor {
|
||||||
|
|
||||||
|
abstract fun visitFile(file: KlibSourceFile)
|
||||||
|
|
||||||
|
abstract fun visitFqName(fqName: String)
|
||||||
|
|
||||||
|
abstract fun visitClassName(className: ClassName)
|
||||||
|
|
||||||
|
override val type: KmExtensionType
|
||||||
|
get() = TYPE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TYPE = KmExtensionType(KlibModuleFragmentExtensionVisitor::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,6 +64,11 @@ interface KmClassExtensionVisitor : KmDeclarationContainerExtensionVisitor
|
|||||||
*/
|
*/
|
||||||
interface KmPackageExtensionVisitor : KmDeclarationContainerExtensionVisitor
|
interface KmPackageExtensionVisitor : KmDeclarationContainerExtensionVisitor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A visitor to visit platform-specific extensions for a module fragment.
|
||||||
|
*/
|
||||||
|
interface KmModuleFragmentExtensionVisitor : KmExtensionVisitor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to visit platform-specific extensions for a function.
|
* A visitor to visit platform-specific extensions for a function.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ interface MetadataExtensions {
|
|||||||
|
|
||||||
fun readPackageExtensions(v: KmPackageVisitor, proto: ProtoBuf.Package, c: ReadContext)
|
fun readPackageExtensions(v: KmPackageVisitor, proto: ProtoBuf.Package, c: ReadContext)
|
||||||
|
|
||||||
|
fun readModuleFragmentExtensions(v: KmModuleFragmentVisitor, proto: ProtoBuf.PackageFragment, c: ReadContext)
|
||||||
|
|
||||||
fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext)
|
fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, c: ReadContext)
|
||||||
|
|
||||||
fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, c: ReadContext)
|
fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, c: ReadContext)
|
||||||
@@ -30,6 +32,10 @@ interface MetadataExtensions {
|
|||||||
|
|
||||||
fun writePackageExtensions(type: KmExtensionType, proto: ProtoBuf.Package.Builder, c: WriteContext): KmPackageExtensionVisitor?
|
fun writePackageExtensions(type: KmExtensionType, proto: ProtoBuf.Package.Builder, c: WriteContext): KmPackageExtensionVisitor?
|
||||||
|
|
||||||
|
fun writeModuleFragmentExtensions(
|
||||||
|
type: KmExtensionType, proto: ProtoBuf.PackageFragment.Builder, c: WriteContext
|
||||||
|
): KmModuleFragmentExtensionVisitor?
|
||||||
|
|
||||||
fun writeFunctionExtensions(type: KmExtensionType, proto: ProtoBuf.Function.Builder, c: WriteContext): KmFunctionExtensionVisitor?
|
fun writeFunctionExtensions(type: KmExtensionType, proto: ProtoBuf.Function.Builder, c: WriteContext): KmFunctionExtensionVisitor?
|
||||||
|
|
||||||
fun writePropertyExtensions(type: KmExtensionType, proto: ProtoBuf.Property.Builder, c: WriteContext): KmPropertyExtensionVisitor?
|
fun writePropertyExtensions(type: KmExtensionType, proto: ProtoBuf.Property.Builder, c: WriteContext): KmPropertyExtensionVisitor?
|
||||||
@@ -48,6 +54,8 @@ interface MetadataExtensions {
|
|||||||
|
|
||||||
fun createPackageExtension(): KmPackageExtension
|
fun createPackageExtension(): KmPackageExtension
|
||||||
|
|
||||||
|
fun createModuleFragmentExtensions(): KmModuleFragmentExtension
|
||||||
|
|
||||||
fun createFunctionExtension(): KmFunctionExtension
|
fun createFunctionExtension(): KmFunctionExtension
|
||||||
|
|
||||||
fun createPropertyExtension(): KmPropertyExtension
|
fun createPropertyExtension(): KmPropertyExtension
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ interface KmClassExtension : KmClassExtensionVisitor, KmExtension<KmClassExtensi
|
|||||||
|
|
||||||
interface KmPackageExtension : KmPackageExtensionVisitor, KmExtension<KmPackageExtensionVisitor>
|
interface KmPackageExtension : KmPackageExtensionVisitor, KmExtension<KmPackageExtensionVisitor>
|
||||||
|
|
||||||
|
interface KmModuleFragmentExtension : KmModuleFragmentExtensionVisitor, KmExtension<KmModuleFragmentExtensionVisitor>
|
||||||
|
|
||||||
interface KmFunctionExtension : KmFunctionExtensionVisitor, KmExtension<KmFunctionExtensionVisitor>
|
interface KmFunctionExtension : KmFunctionExtensionVisitor, KmExtension<KmFunctionExtensionVisitor>
|
||||||
|
|
||||||
interface KmPropertyExtension : KmPropertyExtensionVisitor, KmExtension<KmPropertyExtensionVisitor>
|
interface KmPropertyExtension : KmPropertyExtensionVisitor, KmExtension<KmPropertyExtensionVisitor>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ fun ProtoBuf.Annotation.readAnnotation(strings: NameResolver): KmAnnotation =
|
|||||||
}.toMap()
|
}.toMap()
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun ProtoBuf.Annotation.Argument.Value.readAnnotationArgument(strings: NameResolver): KmAnnotationArgument<*>? {
|
fun ProtoBuf.Annotation.Argument.Value.readAnnotationArgument(strings: NameResolver): KmAnnotationArgument<*>? {
|
||||||
if (Flags.IS_UNSIGNED[flags]) {
|
if (Flags.IS_UNSIGNED[flags]) {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
BYTE -> KmAnnotationArgument.UByteValue(intValue.toByte())
|
BYTE -> KmAnnotationArgument.UByteValue(intValue.toByte())
|
||||||
|
|||||||
@@ -11,15 +11,23 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
|
|||||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.Flags as F
|
import org.jetbrains.kotlin.metadata.deserialization.Flags as F
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to populate [BasicReadContext] with additional data
|
||||||
|
* that can be used when reading metadata in [MetadataExtensions].
|
||||||
|
*/
|
||||||
|
interface ReadContextExtension
|
||||||
|
|
||||||
class ReadContext(
|
class ReadContext(
|
||||||
val strings: NameResolver,
|
val strings: NameResolver,
|
||||||
val types: TypeTable,
|
val types: TypeTable,
|
||||||
internal val versionRequirements: VersionRequirementTable,
|
internal val versionRequirements: VersionRequirementTable,
|
||||||
private val parent: ReadContext? = null
|
private val parent: ReadContext? = null,
|
||||||
|
val contextExtensions: List<ReadContextExtension> = emptyList()
|
||||||
) {
|
) {
|
||||||
internal val extensions = MetadataExtensions.INSTANCES
|
|
||||||
private val typeParameterNameToId = mutableMapOf<Int, Int>()
|
private val typeParameterNameToId = mutableMapOf<Int, Int>()
|
||||||
|
|
||||||
|
internal val extensions = MetadataExtensions.INSTANCES
|
||||||
|
|
||||||
operator fun get(index: Int): String =
|
operator fun get(index: Int): String =
|
||||||
strings.getString(index)
|
strings.getString(index)
|
||||||
|
|
||||||
@@ -30,16 +38,24 @@ class ReadContext(
|
|||||||
typeParameterNameToId[name] ?: parent?.getTypeParameterId(name)
|
typeParameterNameToId[name] ?: parent?.getTypeParameterId(name)
|
||||||
|
|
||||||
fun withTypeParameters(typeParameters: List<ProtoBuf.TypeParameter>): ReadContext =
|
fun withTypeParameters(typeParameters: List<ProtoBuf.TypeParameter>): ReadContext =
|
||||||
ReadContext(strings, types, versionRequirements, this).apply {
|
ReadContext(strings, types, versionRequirements, this, contextExtensions).apply {
|
||||||
for (typeParameter in typeParameters) {
|
for (typeParameter in typeParameters) {
|
||||||
typeParameterNameToId[typeParameter.name] = typeParameter.id
|
typeParameterNameToId[typeParameter.name] = typeParameter.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ProtoBuf.Class.accept(v: KmClassVisitor, strings: NameResolver) {
|
fun ProtoBuf.Class.accept(
|
||||||
val c = ReadContext(strings, TypeTable(typeTable), VersionRequirementTable.create(versionRequirementTable))
|
v: KmClassVisitor,
|
||||||
.withTypeParameters(typeParameterList)
|
strings: NameResolver,
|
||||||
|
contextExtensions: List<ReadContextExtension> = emptyList()
|
||||||
|
) {
|
||||||
|
val c = ReadContext(
|
||||||
|
strings,
|
||||||
|
TypeTable(typeTable),
|
||||||
|
VersionRequirementTable.create(versionRequirementTable),
|
||||||
|
contextExtensions = contextExtensions
|
||||||
|
).withTypeParameters(typeParameterList)
|
||||||
|
|
||||||
v.visit(flags, c.className(fqName))
|
v.visit(flags, c.className(fqName))
|
||||||
|
|
||||||
@@ -87,8 +103,17 @@ fun ProtoBuf.Class.accept(v: KmClassVisitor, strings: NameResolver) {
|
|||||||
v.visitEnd()
|
v.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ProtoBuf.Package.accept(v: KmPackageVisitor, strings: NameResolver) {
|
fun ProtoBuf.Package.accept(
|
||||||
val c = ReadContext(strings, TypeTable(typeTable), VersionRequirementTable.create(versionRequirementTable))
|
v: KmPackageVisitor,
|
||||||
|
strings: NameResolver,
|
||||||
|
contextExtensions: List<ReadContextExtension> = emptyList()
|
||||||
|
) {
|
||||||
|
val c = ReadContext(
|
||||||
|
strings,
|
||||||
|
TypeTable(typeTable),
|
||||||
|
VersionRequirementTable.create(versionRequirementTable),
|
||||||
|
contextExtensions = contextExtensions
|
||||||
|
)
|
||||||
|
|
||||||
v.visitDeclarations(functionList, propertyList, typeAliasList, c)
|
v.visitDeclarations(functionList, propertyList, typeAliasList, c)
|
||||||
|
|
||||||
@@ -99,6 +124,31 @@ fun ProtoBuf.Package.accept(v: KmPackageVisitor, strings: NameResolver) {
|
|||||||
v.visitEnd()
|
v.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ProtoBuf.PackageFragment.accept(
|
||||||
|
v: KmModuleFragmentVisitor,
|
||||||
|
strings: NameResolver,
|
||||||
|
contextExtensions: List<ReadContextExtension> = emptyList()
|
||||||
|
) {
|
||||||
|
val c = ReadContext(
|
||||||
|
strings,
|
||||||
|
TypeTable(ProtoBuf.TypeTable.newBuilder().build()),
|
||||||
|
VersionRequirementTable.EMPTY,
|
||||||
|
contextExtensions = contextExtensions
|
||||||
|
)
|
||||||
|
|
||||||
|
v.visitPackage()?.let { `package`.accept(it, strings, contextExtensions) }
|
||||||
|
|
||||||
|
class_List.forEach { clazz ->
|
||||||
|
v.visitClass()?.let { clazz.accept(it, strings, contextExtensions) }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (extension in c.extensions) {
|
||||||
|
extension.readModuleFragmentExtensions(v, this, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
v.visitEnd()
|
||||||
|
}
|
||||||
|
|
||||||
private fun KmDeclarationContainerVisitor.visitDeclarations(
|
private fun KmDeclarationContainerVisitor.visitDeclarations(
|
||||||
functions: List<ProtoBuf.Function>,
|
functions: List<ProtoBuf.Function>,
|
||||||
properties: List<ProtoBuf.Property>,
|
properties: List<ProtoBuf.Property>,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ fun KmAnnotation.writeAnnotation(strings: StringTable): ProtoBuf.Annotation.Buil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KmAnnotationArgument<*>.writeAnnotationArgument(strings: StringTable): ProtoBuf.Annotation.Argument.Value.Builder =
|
fun KmAnnotationArgument<*>.writeAnnotationArgument(strings: StringTable): ProtoBuf.Annotation.Argument.Value.Builder =
|
||||||
ProtoBuf.Annotation.Argument.Value.newBuilder().apply {
|
ProtoBuf.Annotation.Argument.Value.newBuilder().apply {
|
||||||
when (this@writeAnnotationArgument) {
|
when (this@writeAnnotationArgument) {
|
||||||
is KmAnnotationArgument.ByteValue -> {
|
is KmAnnotationArgument.ByteValue -> {
|
||||||
|
|||||||
@@ -6,13 +6,20 @@
|
|||||||
package kotlinx.metadata.impl
|
package kotlinx.metadata.impl
|
||||||
|
|
||||||
import kotlinx.metadata.*
|
import kotlinx.metadata.*
|
||||||
|
import kotlinx.metadata.impl.extensions.MetadataExtensions
|
||||||
import kotlinx.metadata.impl.extensions.applySingleExtension
|
import kotlinx.metadata.impl.extensions.applySingleExtension
|
||||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
||||||
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
|
||||||
import org.jetbrains.kotlin.metadata.serialization.StringTable
|
import org.jetbrains.kotlin.metadata.serialization.StringTable
|
||||||
|
|
||||||
class WriteContext(val strings: StringTable) {
|
/**
|
||||||
|
* Allows to populate [WriteContext] with additional data
|
||||||
|
* that can be used when writing metadata in [MetadataExtensions].
|
||||||
|
*/
|
||||||
|
interface WriteContextExtension
|
||||||
|
|
||||||
|
open class WriteContext(val strings: StringTable, val contextExtensions: List<WriteContextExtension> = emptyList()) {
|
||||||
val versionRequirements: MutableVersionRequirementTable = MutableVersionRequirementTable()
|
val versionRequirements: MutableVersionRequirementTable = MutableVersionRequirementTable()
|
||||||
|
|
||||||
operator fun get(string: String): Int =
|
operator fun get(string: String): Int =
|
||||||
@@ -393,9 +400,9 @@ private fun writeEffectExpression(c: WriteContext, output: (ProtoBuf.Expression.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class ClassWriter(stringTable: StringTable) : KmClassVisitor() {
|
open class ClassWriter(stringTable: StringTable, contextExtensions: List<WriteContextExtension> = emptyList()) : KmClassVisitor() {
|
||||||
protected val t = ProtoBuf.Class.newBuilder()!!
|
protected val t = ProtoBuf.Class.newBuilder()!!
|
||||||
protected val c = WriteContext(stringTable)
|
protected val c: WriteContext = WriteContext(stringTable, contextExtensions)
|
||||||
|
|
||||||
override fun visit(flags: Flags, name: ClassName) {
|
override fun visit(flags: Flags, name: ClassName) {
|
||||||
if (flags != ProtoBuf.Class.getDefaultInstance().flags) {
|
if (flags != ProtoBuf.Class.getDefaultInstance().flags) {
|
||||||
@@ -455,9 +462,9 @@ open class ClassWriter(stringTable: StringTable) : KmClassVisitor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class PackageWriter(stringTable: StringTable) : KmPackageVisitor() {
|
open class PackageWriter(stringTable: StringTable, contextExtensions: List<WriteContextExtension> = emptyList()) : KmPackageVisitor() {
|
||||||
protected val t = ProtoBuf.Package.newBuilder()!!
|
protected val t = ProtoBuf.Package.newBuilder()!!
|
||||||
protected val c = WriteContext(stringTable)
|
protected val c: WriteContext = WriteContext(stringTable, contextExtensions)
|
||||||
|
|
||||||
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? =
|
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor? =
|
||||||
writeFunction(c, flags, name) { t.addFunction(it) }
|
writeFunction(c, flags, name) { t.addFunction(it) }
|
||||||
@@ -480,6 +487,31 @@ open class PackageWriter(stringTable: StringTable) : KmPackageVisitor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class ModuleFragmentWriter(stringTable: StringTable, contextExtensions: List<WriteContextExtension> = emptyList()) :
|
||||||
|
KmModuleFragmentVisitor() {
|
||||||
|
protected val t = ProtoBuf.PackageFragment.newBuilder()
|
||||||
|
protected val c: WriteContext = WriteContext(stringTable, contextExtensions)
|
||||||
|
|
||||||
|
override fun visitPackage(): KmPackageVisitor? = object : PackageWriter(c.strings, c.contextExtensions) {
|
||||||
|
override fun visitEnd() {
|
||||||
|
super.visitEnd()
|
||||||
|
this@ModuleFragmentWriter.t.setPackage(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitClass(): KmClassVisitor? = object : ClassWriter(c.strings, c.contextExtensions) {
|
||||||
|
override fun visitEnd() {
|
||||||
|
super.visitEnd()
|
||||||
|
this@ModuleFragmentWriter.t.addClass_(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmModuleFragmentExtensionVisitor? =
|
||||||
|
applySingleExtension(type) {
|
||||||
|
writeModuleFragmentExtensions(type, t, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open class LambdaWriter(stringTable: StringTable) : KmLambdaVisitor() {
|
open class LambdaWriter(stringTable: StringTable) : KmLambdaVisitor() {
|
||||||
protected var t: ProtoBuf.Function.Builder? = null
|
protected var t: ProtoBuf.Function.Builder? = null
|
||||||
protected val c = WriteContext(stringTable)
|
protected val c = WriteContext(stringTable)
|
||||||
|
|||||||
@@ -217,6 +217,46 @@ class KmPackage : KmPackageVisitor(), KmDeclarationContainer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a Kotlin module fragment. This is used to represent metadata of a part of a module on platforms other than JVM.
|
||||||
|
*/
|
||||||
|
class KmModuleFragment : KmModuleFragmentVisitor() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Top-level functions, type aliases and properties in the module fragment.
|
||||||
|
*/
|
||||||
|
var pkg: KmPackage? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Classes in the module fragment.
|
||||||
|
*/
|
||||||
|
val classes: MutableList<KmClass> = ArrayList()
|
||||||
|
|
||||||
|
private val extensions: List<KmModuleFragmentExtension> =
|
||||||
|
MetadataExtensions.INSTANCES.map(MetadataExtensions::createModuleFragmentExtensions)
|
||||||
|
|
||||||
|
override fun visitPackage(): KmPackageVisitor? =
|
||||||
|
KmPackage().also { pkg = it }
|
||||||
|
|
||||||
|
override fun visitExtensions(type: KmExtensionType): KmModuleFragmentExtensionVisitor? =
|
||||||
|
extensions.singleOfType(type)
|
||||||
|
|
||||||
|
override fun visitClass(): KmClassVisitor? =
|
||||||
|
KmClass().addTo(classes)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populates the given visitor with data in this module fragment.
|
||||||
|
*
|
||||||
|
* @param visitor the visitor which will visit data in the module fragment.
|
||||||
|
*/
|
||||||
|
fun accept(visitor: KmModuleFragmentVisitor) {
|
||||||
|
pkg?.let { visitor.visitPackage()?.let(it::accept) }
|
||||||
|
classes.forEach { visitor.visitClass()?.let(it::accept) }
|
||||||
|
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
|
||||||
|
visitor.visitEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a synthetic class generated for a Kotlin lambda.
|
* Represents a synthetic class generated for a Kotlin lambda.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -179,6 +179,42 @@ abstract class KmPackageVisitor @JvmOverloads constructor(delegate: KmPackageVis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A visitor to visit module fragments. The module fragment can have no more than one package, and any number of classes,
|
||||||
|
* and must have at least one declaration.
|
||||||
|
*
|
||||||
|
* When using this class, [visitEnd] must be called exactly once and after calls to all other visit* methods.
|
||||||
|
*/
|
||||||
|
abstract class KmModuleFragmentVisitor @JvmOverloads constructor(private val delegate: KmModuleFragmentVisitor? = null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a package within the module fragment.
|
||||||
|
*/
|
||||||
|
open fun visitPackage(): KmPackageVisitor? =
|
||||||
|
delegate?.visitPackage()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits a class within the module fragment.
|
||||||
|
*/
|
||||||
|
open fun visitClass(): KmClassVisitor? =
|
||||||
|
delegate?.visitClass()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the extensions of the given type on the module fragment.
|
||||||
|
*
|
||||||
|
* @param type the type of extension visitor to be returned.
|
||||||
|
*/
|
||||||
|
open fun visitExtensions(type: KmExtensionType): KmModuleFragmentExtensionVisitor? =
|
||||||
|
delegate?.visitExtensions(type)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visits the end of the module fragment.
|
||||||
|
*/
|
||||||
|
open fun visitEnd() {
|
||||||
|
delegate?.visitEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A visitor to visit the metadata of a synthetic class generated for a Kotlin lambda.
|
* A visitor to visit the metadata of a synthetic class generated for a Kotlin lambda.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ include ":kotlin-build-common",
|
|||||||
":kotlin-source-map-loader",
|
":kotlin-source-map-loader",
|
||||||
":kotlinx-metadata",
|
":kotlinx-metadata",
|
||||||
":kotlinx-metadata-jvm",
|
":kotlinx-metadata-jvm",
|
||||||
|
":kotlinx-metadata-klib",
|
||||||
":prepare:build.version",
|
":prepare:build.version",
|
||||||
":kotlin-build-common",
|
":kotlin-build-common",
|
||||||
":prepare:formatter",
|
":prepare:formatter",
|
||||||
@@ -324,6 +325,7 @@ project(':kotlin-reflect').projectDir = "$rootDir/libraries/reflect" as File
|
|||||||
project(':kotlin-reflect-api').projectDir = "$rootDir/libraries/reflect/api" as File
|
project(':kotlin-reflect-api').projectDir = "$rootDir/libraries/reflect/api" as File
|
||||||
project(':kotlinx-metadata').projectDir = "$rootDir/libraries/kotlinx-metadata" as File
|
project(':kotlinx-metadata').projectDir = "$rootDir/libraries/kotlinx-metadata" as File
|
||||||
project(':kotlinx-metadata-jvm').projectDir = "$rootDir/libraries/kotlinx-metadata/jvm" as File
|
project(':kotlinx-metadata-jvm').projectDir = "$rootDir/libraries/kotlinx-metadata/jvm" as File
|
||||||
|
project(':kotlinx-metadata-klib').projectDir = "$rootDir/libraries/kotlinx-metadata/klib" as File
|
||||||
project(':kotlin-compiler').projectDir = "$rootDir/prepare/compiler" as File
|
project(':kotlin-compiler').projectDir = "$rootDir/prepare/compiler" as File
|
||||||
project(':kotlin-compiler-embeddable').projectDir = "$rootDir/prepare/compiler-embeddable" as File
|
project(':kotlin-compiler-embeddable').projectDir = "$rootDir/prepare/compiler-embeddable" as File
|
||||||
project(':kotlin-compiler-client-embeddable').projectDir = "$rootDir/prepare/compiler-client-embeddable" as File
|
project(':kotlin-compiler-client-embeddable').projectDir = "$rootDir/prepare/compiler-client-embeddable" as File
|
||||||
|
|||||||
Reference in New Issue
Block a user