Add kotlinx-metadata library for handling Kotlin metadata
#KT-23198
This commit is contained in:
@@ -238,8 +238,8 @@ public class Flags {
|
||||
return new BooleanFlagField(offset);
|
||||
}
|
||||
|
||||
protected final int offset;
|
||||
protected final int bitWidth;
|
||||
public final int offset;
|
||||
public final int bitWidth;
|
||||
|
||||
private FlagField(int offset, int bitWidth) {
|
||||
this.offset = offset;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
description = "Kotlin metadata manipulation library"
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":kotlin-stdlib"))
|
||||
compileOnly(project(":core:metadata"))
|
||||
compileOnly(protobufLite())
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
description = "Kotlin JVM metadata manipulation library"
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
val shadows by configurations.creating {
|
||||
isTransitive = false
|
||||
}
|
||||
configurations.getByName("compileOnly").extendsFrom(shadows)
|
||||
configurations.getByName("testCompile").extendsFrom(shadows)
|
||||
|
||||
dependencies {
|
||||
compile(project(":kotlin-stdlib"))
|
||||
shadows(project(":kotlinx-metadata"))
|
||||
shadows(project(":core:metadata"))
|
||||
shadows(project(":core:metadata.jvm"))
|
||||
shadows(protobufLite())
|
||||
testCompile(commonDep("junit:junit"))
|
||||
}
|
||||
|
||||
noDefaultJar()
|
||||
|
||||
val shadowJar = task<ShadowJar>("shadowJar") {
|
||||
callGroovy("manifestAttributes", manifest, project)
|
||||
manifest.attributes["Implementation-Version"] = version
|
||||
|
||||
from(the<JavaPluginConvention>().sourceSets["main"].output)
|
||||
exclude("**/*.proto")
|
||||
configurations = listOf(shadows)
|
||||
|
||||
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()
|
||||
|
||||
// Change this version before publishing
|
||||
version = "0.1-SNAPSHOT"
|
||||
// publish()
|
||||
|
||||
projectTest {
|
||||
workingDir = rootDir
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
kotlinx.metadata.jvm.impl.JvmMetadataExtensions
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
/**
|
||||
* A mirror to the [Metadata] annotation on a JVM class file, containing the metadata of Kotlin declarations declared in the class file.
|
||||
* Properties of this class correspond to the properties of [Metadata], but the names are not shortened because there's no restriction
|
||||
* on the bytecode size here.
|
||||
*
|
||||
* Note that [Metadata] is not yet public (see https://youtrack.jetbrains.com/issue/KT-23602). In order to create an instance of
|
||||
* [KotlinClassHeader] from the [Metadata] annotation instance obtained reflectively, one could use Java code to workaround
|
||||
* the internal visibility error.
|
||||
*
|
||||
* @param kind see [kind]
|
||||
* @param metadataVersion see [metadataVersion]
|
||||
* @param bytecodeVersion see [bytecodeVersion]
|
||||
* @param data1 see [data1]
|
||||
* @param data2 see [data2]
|
||||
* @param extraString see [extraString]
|
||||
* @param packageName see [packageName]
|
||||
* @param extraInt see [extraInt]
|
||||
*/
|
||||
class KotlinClassHeader(
|
||||
kind: Int?,
|
||||
metadataVersion: IntArray?,
|
||||
bytecodeVersion: IntArray?,
|
||||
data1: Array<String>?,
|
||||
data2: Array<String>?,
|
||||
extraString: String?,
|
||||
packageName: String?,
|
||||
extraInt: Int?
|
||||
) {
|
||||
/**
|
||||
* A kind of the metadata this header encodes.
|
||||
*
|
||||
* @see Metadata.k
|
||||
* @see CLASS_KIND
|
||||
* @see FILE_FACADE_KIND
|
||||
* @see SYNTHETIC_CLASS_KIND
|
||||
* @see MULTI_FILE_CLASS_FACADE_KIND
|
||||
* @see MULTI_FILE_CLASS_PART_KIND
|
||||
*/
|
||||
val kind: Int = kind ?: 1
|
||||
|
||||
/**
|
||||
* The version of the metadata provided in other properties of this header.
|
||||
*
|
||||
* @see Metadata.mv
|
||||
* @see COMPATIBLE_METADATA_VERSION
|
||||
*/
|
||||
val metadataVersion: IntArray = metadataVersion ?: intArrayOf()
|
||||
|
||||
/**
|
||||
* The version of the bytecode interface (naming conventions, signatures) of the corresponding class file.
|
||||
*
|
||||
* @see Metadata.bv
|
||||
* @see COMPATIBLE_BYTECODE_VERSION
|
||||
*/
|
||||
val bytecodeVersion: IntArray = bytecodeVersion ?: intArrayOf()
|
||||
|
||||
/**
|
||||
* The first array of strings used to encode the metadata.
|
||||
*
|
||||
* @see Metadata.d1
|
||||
*/
|
||||
val data1: Array<String> = data1 ?: emptyArray()
|
||||
|
||||
/**
|
||||
* The second array of strings used to encode the metadata.
|
||||
*
|
||||
* @see Metadata.d2
|
||||
*/
|
||||
val data2: Array<String> = data2 ?: emptyArray()
|
||||
|
||||
/**
|
||||
* An extra string field for the metadata.
|
||||
*
|
||||
* @see Metadata.xs
|
||||
*/
|
||||
val extraString: String = extraString ?: ""
|
||||
|
||||
/**
|
||||
* Fully qualified name of the Kotlin package of the corresponding class, in case [JvmPackageName] was used.
|
||||
*
|
||||
* @see Metadata.pn
|
||||
*/
|
||||
val packageName: String = packageName ?: ""
|
||||
|
||||
/**
|
||||
* An extra int field for the metadata.
|
||||
*
|
||||
* @see Metadata.xi
|
||||
*/
|
||||
val extraInt: Int = extraInt ?: 0
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* A class file kind signifying that the corresponding class file contains a declaration of a Kotlin class.
|
||||
*
|
||||
* @see kind
|
||||
*/
|
||||
const val CLASS_KIND = 1
|
||||
|
||||
/**
|
||||
* A class file kind signifying that the corresponding class file is a compiled Kotlin file facade.
|
||||
*
|
||||
* @see kind
|
||||
*/
|
||||
const val FILE_FACADE_KIND = 2
|
||||
|
||||
/**
|
||||
* A class file kind signifying that the corresponding class file is synthetic, e.g. it's a class for lambda, `$DefaultImpls` class
|
||||
* for interface method implementations, `$WhenMappings` class for optimized `when` over enums, etc.
|
||||
*
|
||||
* @see kind
|
||||
*/
|
||||
const val SYNTHETIC_CLASS_KIND = 3
|
||||
|
||||
/**
|
||||
* A class file kind signifying that the corresponding class file is a compiled multi-file class facade.
|
||||
*
|
||||
* @see kind
|
||||
* @see JvmMultifileClass
|
||||
*/
|
||||
const val MULTI_FILE_CLASS_FACADE_KIND = 4
|
||||
|
||||
/**
|
||||
* A class file kind signifying that the corresponding class file is a compiled multi-file class part, i.e. an internal class
|
||||
* with method bodies and their metadata, accessed only from the corresponding facade.
|
||||
*
|
||||
* @see kind
|
||||
* @see JvmMultifileClass
|
||||
*/
|
||||
const val MULTI_FILE_CLASS_PART_KIND = 5
|
||||
|
||||
/**
|
||||
* The latest metadata version supported by this version of the library.
|
||||
*
|
||||
* @see metadataVersion
|
||||
*/
|
||||
@JvmField
|
||||
val COMPATIBLE_METADATA_VERSION = intArrayOf(1, 1, 10)
|
||||
|
||||
/**
|
||||
* The latest bytecode version supported by this version of the library.
|
||||
*
|
||||
* @see bytecodeVersion
|
||||
*/
|
||||
@JvmField
|
||||
val COMPATIBLE_BYTECODE_VERSION = intArrayOf(1, 0, 2)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
import kotlinx.metadata.InconsistentKotlinMetadataException
|
||||
import kotlinx.metadata.KmClassVisitor
|
||||
import kotlinx.metadata.KmLambdaVisitor
|
||||
import kotlinx.metadata.KmPackageVisitor
|
||||
import kotlinx.metadata.impl.accept
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import kotlin.LazyThreadSafetyMode.PUBLICATION
|
||||
|
||||
/**
|
||||
* Represents the parsed metadata of a Kotlin JVM class file.
|
||||
*
|
||||
* To create an instance of [KotlinClassMetadata], first obtain a [KotlinClassHeader] instance by loading the contents
|
||||
* of the [Metadata] annotation on a class file, and then call [KotlinClassMetadata.read].
|
||||
*/
|
||||
sealed class KotlinClassMetadata(val header: KotlinClassHeader) {
|
||||
/**
|
||||
* Represents metadata of a class file containing a declaration of a Kotlin class.
|
||||
*/
|
||||
class Class internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header) {
|
||||
private val classData by lazy(PUBLICATION) {
|
||||
val data1 = (header.data1.takeIf(Array<*>::isNotEmpty)
|
||||
?: throw InconsistentKotlinMetadataException("data1 must not be empty"))
|
||||
JvmProtoBufUtil.readClassDataFrom(data1, header.data2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given visitor visit metadata of this class.
|
||||
*
|
||||
* @param v the visitor that must visit this class
|
||||
*/
|
||||
fun accept(v: KmClassVisitor) {
|
||||
val (strings, proto) = classData
|
||||
proto.accept(v, strings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents metadata of a class file containing a compiled Kotlin file facade.
|
||||
*/
|
||||
class FileFacade internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header) {
|
||||
private val packageData by lazy(PUBLICATION) {
|
||||
val data1 = (header.data1.takeIf(Array<*>::isNotEmpty)
|
||||
?: throw InconsistentKotlinMetadataException("data1 must not be empty"))
|
||||
JvmProtoBufUtil.readPackageDataFrom(data1, header.data2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the given visitor visit metadata of this file facade.
|
||||
*
|
||||
* @param v the visitor that must visit this file facade
|
||||
*/
|
||||
fun accept(v: KmPackageVisitor) {
|
||||
val (strings, proto) = packageData
|
||||
proto.accept(v, strings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents metadata of a class file containing a synthetic class, e.g. a class for lambda, `$DefaultImpls` class for interface
|
||||
* method implementations, `$WhenMappings` class for optimized `when` over enums, etc.
|
||||
*/
|
||||
class SyntheticClass internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header) {
|
||||
private val functionData by lazy(PUBLICATION) {
|
||||
header.data1.takeIf(Array<*>::isNotEmpty)?.let { data1 ->
|
||||
JvmProtoBufUtil.readFunctionDataFrom(data1, header.data2)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if this synthetic class is a class file compiled for a Kotlin lambda.
|
||||
*/
|
||||
val isLambda: Boolean
|
||||
get() = header.data1.isNotEmpty()
|
||||
|
||||
/**
|
||||
* Makes the given visitor visit metadata of this file facade, if this synthetic class represents a Kotlin lambda
|
||||
* (`isLambda` == true).
|
||||
*
|
||||
* Throws [IllegalStateException] if this synthetic class does not represent a Kotlin lambda.
|
||||
*
|
||||
* @param v the visitor that must visit this lambda
|
||||
*/
|
||||
fun accept(v: KmLambdaVisitor) {
|
||||
if (!isLambda) throw IllegalStateException(
|
||||
"accept(KmLambdaVisitor) is only possible for synthetic classes which are lambdas (isLambda = true)"
|
||||
)
|
||||
|
||||
val (strings, proto) = functionData!!
|
||||
proto.accept(v, strings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents metadata of a class file containing a compiled multi-file class facade.
|
||||
*
|
||||
* @see JvmMultifileClass
|
||||
*/
|
||||
class MultiFileClassFacade internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header) {
|
||||
/**
|
||||
* JVM internal names of the part classes which this multi-file class combines.
|
||||
*/
|
||||
val partClassNames: List<String> = header.data1.asList()
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents metadata of a class file containing a compiled multi-file class part, i.e. an internal class with method bodies
|
||||
* and their metadata, accessed only from the corresponding facade.
|
||||
*
|
||||
* @see JvmMultifileClass
|
||||
*/
|
||||
class MultiFileClassPart internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header) {
|
||||
private val packageData by lazy(PUBLICATION) {
|
||||
val data1 = (header.data1.takeIf(Array<*>::isNotEmpty)
|
||||
?: throw InconsistentKotlinMetadataException("data1 must not be empty"))
|
||||
JvmProtoBufUtil.readPackageDataFrom(data1, header.data2)
|
||||
}
|
||||
|
||||
/**
|
||||
* JVM internal name of the corresponding multi-file class facade.
|
||||
*/
|
||||
val facadeClassName: String
|
||||
get() = header.extraString
|
||||
|
||||
/**
|
||||
* Makes the given visitor visit metadata of this multi-file class part.
|
||||
*
|
||||
* @param v the visitor that must visit this multi-file class part
|
||||
*/
|
||||
fun accept(v: KmPackageVisitor) {
|
||||
val (strings, proto) = packageData
|
||||
proto.accept(v, strings)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents metadata of an unknown class file. This class is used if an old version of this library is used against a new kind
|
||||
* of class files generated by the Kotlin compiler, unsupported by this library.
|
||||
*/
|
||||
class Unknown internal constructor(header: KotlinClassHeader) : KotlinClassMetadata(header)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Reads and parses the given header of a Kotlin JVM class file and returns the correct type of [KotlinClassMetadata] encoded by
|
||||
* this header, or `null` if this header encodes an unsupported kind of Kotlin classes or has an unsupported metadata version.
|
||||
*
|
||||
* Throws [InconsistentKotlinMetadataException] if the metadata has inconsistencies which signal that it may have been
|
||||
* modified by a separate tool.
|
||||
*
|
||||
* @param header the header of a Kotlin JVM class file to be parsed
|
||||
*/
|
||||
@JvmStatic
|
||||
fun read(header: KotlinClassHeader): KotlinClassMetadata? {
|
||||
// We only support metadata of version 1.1.* (this is Kotlin from 1.0 until today)
|
||||
val version = header.metadataVersion
|
||||
if (version.getOrNull(0) != 1 || version.getOrNull(1) != 1) return null
|
||||
|
||||
return try {
|
||||
when (header.kind) {
|
||||
KotlinClassHeader.CLASS_KIND -> KotlinClassMetadata.Class(header)
|
||||
KotlinClassHeader.FILE_FACADE_KIND -> KotlinClassMetadata.FileFacade(header)
|
||||
KotlinClassHeader.SYNTHETIC_CLASS_KIND -> KotlinClassMetadata.SyntheticClass(header)
|
||||
KotlinClassHeader.MULTI_FILE_CLASS_FACADE_KIND -> KotlinClassMetadata.MultiFileClassFacade(header)
|
||||
KotlinClassHeader.MULTI_FILE_CLASS_PART_KIND -> KotlinClassMetadata.MultiFileClassPart(header)
|
||||
else -> KotlinClassMetadata.Unknown(header)
|
||||
}
|
||||
} catch (e: InconsistentKotlinMetadataException) {
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
throw InconsistentKotlinMetadataException("Exception occurred when reading Kotlin metadata", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm.impl
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.impl.extensions.MetadataExtensions
|
||||
import kotlinx.metadata.impl.readAnnotation
|
||||
import kotlinx.metadata.jvm.*
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
|
||||
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
|
||||
internal class JvmMetadataExtensions : MetadataExtensions {
|
||||
override fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable) {
|
||||
val ext = v.visitExtensions(JvmFunctionExtensionVisitor.TYPE) as? JvmFunctionExtensionVisitor ?: return
|
||||
ext.visit(JvmProtoBufUtil.getJvmMethodSignature(proto, strings, types))
|
||||
}
|
||||
|
||||
override fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable) {
|
||||
val ext = v.visitExtensions(JvmPropertyExtensionVisitor.TYPE) as? JvmPropertyExtensionVisitor ?: return
|
||||
val fieldSignature = JvmProtoBufUtil.getJvmFieldSignature(proto, strings, types)
|
||||
val propertySignature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature)
|
||||
val getterSignature =
|
||||
if (propertySignature != null && propertySignature.hasGetter()) propertySignature.getter else null
|
||||
val setterSignature =
|
||||
if (propertySignature != null && propertySignature.hasSetter()) propertySignature.setter else null
|
||||
ext.visit(
|
||||
fieldSignature?.name,
|
||||
fieldSignature?.desc,
|
||||
getterSignature?.run { strings.getString(name) + strings.getString(desc) },
|
||||
setterSignature?.run { strings.getString(name) + strings.getString(desc) }
|
||||
)
|
||||
|
||||
val syntheticMethod =
|
||||
if (propertySignature != null && propertySignature.hasSyntheticMethod()) propertySignature.syntheticMethod else null
|
||||
ext.visitSyntheticMethodForAnnotations(syntheticMethod?.run { strings.getString(name) + strings.getString(desc) })
|
||||
|
||||
ext.visitEnd()
|
||||
}
|
||||
|
||||
override fun readConstructorExtensions(v: KmConstructorVisitor, proto: ProtoBuf.Constructor, strings: NameResolver, types: TypeTable) {
|
||||
val ext = v.visitExtensions(JvmConstructorExtensionVisitor.TYPE) as? JvmConstructorExtensionVisitor ?: return
|
||||
ext.visit(JvmProtoBufUtil.getJvmConstructorSignature(proto, strings, types))
|
||||
}
|
||||
|
||||
override fun readTypeParameterExtensions(v: KmTypeParameterVisitor, proto: ProtoBuf.TypeParameter, strings: NameResolver) {
|
||||
val ext = v.visitExtensions(JvmTypeParameterExtensionVisitor.TYPE) as? JvmTypeParameterExtensionVisitor ?: return
|
||||
for (annotation in proto.getExtension(JvmProtoBuf.typeParameterAnnotation)) {
|
||||
ext.visitAnnotation(annotation.readAnnotation(strings))
|
||||
}
|
||||
ext.visitEnd()
|
||||
}
|
||||
|
||||
override fun readTypeExtensions(v: KmTypeVisitor, proto: ProtoBuf.Type, strings: NameResolver) {
|
||||
val ext = v.visitExtensions(JvmTypeExtensionVisitor.TYPE) as? JvmTypeExtensionVisitor ?: return
|
||||
ext.visit(proto.getExtension(JvmProtoBuf.isRaw))
|
||||
for (annotation in proto.getExtension(JvmProtoBuf.typeAnnotation)) {
|
||||
ext.visitAnnotation(annotation.readAnnotation(strings))
|
||||
}
|
||||
ext.visitEnd()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
|
||||
/**
|
||||
* A visitor to visit JVM extensions for a function.
|
||||
*/
|
||||
open class JvmFunctionExtensionVisitor @JvmOverloads constructor(
|
||||
private val delegate: JvmFunctionExtensionVisitor? = null
|
||||
) : KmFunctionExtensionVisitor {
|
||||
/**
|
||||
* Visits the JVM signature of the function, in the JVM-based format: `"equals(Ljava/lang/Object;)Z"`,
|
||||
* or null if the JVM signature of this function is unknown.
|
||||
*
|
||||
* @param desc the signature of the function
|
||||
*/
|
||||
open fun visit(desc: String?) {
|
||||
delegate?.visit(desc)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The type of this extension visitor.
|
||||
*
|
||||
* @see KmExtensionType
|
||||
*/
|
||||
@JvmField
|
||||
val TYPE: KmExtensionType = KmExtensionType(JvmFunctionExtensionVisitor::class)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit JVM extensions for a property.
|
||||
*/
|
||||
open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
|
||||
private val delegate: JvmPropertyExtensionVisitor? = null
|
||||
) : KmPropertyExtensionVisitor {
|
||||
/**
|
||||
* Visits JVM signatures of field and accessors generated for the property.
|
||||
*
|
||||
* @param fieldName the name of the field, or `null` if this property has no field
|
||||
* @param fieldTypeDesc the type of the field in the JVM-based format (`"Ljava/lang/Object;"`), or `null` if this property has no field
|
||||
* @param getterDesc the signature of the property getter in the JVM-based format: `"getX()Ljava/lang/Object;"`,
|
||||
* or `null` if this property has no getter or its signature is unknown
|
||||
* @param setterDesc the signature of the property setter in the JVM-based format: `"setX(Ljava/lang/Object;)V"`,
|
||||
* or `null` if this property has no setter or its signature is unknown
|
||||
*/
|
||||
open fun visit(fieldName: String?, fieldTypeDesc: String?, getterDesc: String?, setterDesc: String?) {
|
||||
delegate?.visit(fieldName, fieldTypeDesc, getterDesc, setterDesc)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the JVM signature of a synthetic method which is generated to store annotations on a property in the bytecode,
|
||||
* in the JVM-based format: `"getX$annotations()V"`
|
||||
*
|
||||
* @param desc the signature of the synthetic method
|
||||
*/
|
||||
open fun visitSyntheticMethodForAnnotations(desc: String?) {
|
||||
delegate?.visitSyntheticMethodForAnnotations(desc)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the end of JVM extensions for the property.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The type of this extension visitor.
|
||||
*
|
||||
* @see KmExtensionType
|
||||
*/
|
||||
@JvmField
|
||||
val TYPE: KmExtensionType = KmExtensionType(JvmPropertyExtensionVisitor::class)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit JVM extensions for a constructor.
|
||||
*/
|
||||
open class JvmConstructorExtensionVisitor @JvmOverloads constructor(
|
||||
private val delegate: JvmConstructorExtensionVisitor? = null
|
||||
) : KmConstructorExtensionVisitor {
|
||||
/**
|
||||
* Visits the JVM signature of the constructor, in the JVM-based format: `"<init>(Ljava/lang/Object;)V"`,
|
||||
* or null if the JVM signature of this constructor is unknown.
|
||||
*
|
||||
* @param desc the signature of the constructor
|
||||
*/
|
||||
open fun visit(desc: String?) {
|
||||
delegate?.visit(desc)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The type of this extension visitor.
|
||||
*
|
||||
* @see KmExtensionType
|
||||
*/
|
||||
@JvmField
|
||||
val TYPE: KmExtensionType = KmExtensionType(JvmConstructorExtensionVisitor::class)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit JVM extensions for a type parameter.
|
||||
*/
|
||||
open class JvmTypeParameterExtensionVisitor @JvmOverloads constructor(
|
||||
private val delegate: JvmTypeParameterExtensionVisitor? = null
|
||||
) : KmTypeParameterExtensionVisitor {
|
||||
/**
|
||||
* Visits an annotation on the type parameter.
|
||||
*
|
||||
* @param annotation the annotation on the type parameter
|
||||
*/
|
||||
open fun visitAnnotation(annotation: KmAnnotation) {
|
||||
delegate?.visitAnnotation(annotation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the end of JVM extensions for the type parameter.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The type of this extension visitor.
|
||||
*
|
||||
* @see KmExtensionType
|
||||
*/
|
||||
@JvmField
|
||||
val TYPE: KmExtensionType = KmExtensionType(JvmTypeParameterExtensionVisitor::class)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit JVM extensions for a type.
|
||||
*/
|
||||
open class JvmTypeExtensionVisitor @JvmOverloads constructor(
|
||||
private val delegate: JvmTypeExtensionVisitor? = null
|
||||
) : KmTypeExtensionVisitor {
|
||||
/**
|
||||
* Visits the JVM-specific flags of a type.
|
||||
*
|
||||
* @param isRaw whether the type is seen as a raw type in Java
|
||||
*/
|
||||
open fun visit(isRaw: Boolean) {
|
||||
delegate?.visit(isRaw)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits an annotation on the type.
|
||||
*
|
||||
* @param annotation the annotation on the type
|
||||
*/
|
||||
open fun visitAnnotation(annotation: KmAnnotation) {
|
||||
delegate?.visitAnnotation(annotation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the end of JVM extensions for the type parameter.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The type of this extension visitor.
|
||||
*
|
||||
* @see KmExtensionType
|
||||
*/
|
||||
@JvmField
|
||||
val TYPE: KmExtensionType = KmExtensionType(JvmTypeExtensionVisitor::class)
|
||||
|
||||
/**
|
||||
* The type flexibility id, signifying that the visited type is a JVM platform type.
|
||||
*
|
||||
* @see KmTypeVisitor.visitFlexibleTypeUpperBound
|
||||
*/
|
||||
const val PLATFORM_TYPE_ID = JvmProtoBufUtil.PLATFORM_TYPE_ID
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.jvm
|
||||
|
||||
import kotlinx.metadata.ClassName
|
||||
import kotlinx.metadata.isLocal
|
||||
|
||||
/**
|
||||
* JVM internal name of the class, where package names are separated by '/', and class names are separated by '$',
|
||||
* for example: `"org/foo/bar/Baz$Nested"`
|
||||
*/
|
||||
val ClassName.jvmInternalName: String
|
||||
get() =
|
||||
if (this.isLocal) substring(1)
|
||||
else replace('/', '$')
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. 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.test
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.jvm.JvmFunctionExtensionVisitor
|
||||
import kotlinx.metadata.jvm.KotlinClassHeader
|
||||
import kotlinx.metadata.jvm.KotlinClassMetadata
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class MetadataSmokeTest {
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
private fun Class<*>.readMetadata(): KotlinClassHeader {
|
||||
return getAnnotation(Metadata::class.java).run {
|
||||
KotlinClassHeader(k, mv, bv, d1, d2, xs, pn, xi)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun listInlineFunctions() {
|
||||
@Suppress("unused")
|
||||
class L {
|
||||
val x: Int inline get() = 42
|
||||
inline fun foo(f: () -> String) = f()
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
val inlineFunctions = mutableListOf<String>()
|
||||
|
||||
val klass = KotlinClassMetadata.read(L::class.java.readMetadata()) as KotlinClassMetadata.Class
|
||||
klass.accept(object : KmClassVisitor() {
|
||||
override fun visitFunction(flags: Int, name: String): KmFunctionVisitor? {
|
||||
return object : KmFunctionVisitor() {
|
||||
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? {
|
||||
if (type != JvmFunctionExtensionVisitor.TYPE) return null
|
||||
|
||||
return object : JvmFunctionExtensionVisitor() {
|
||||
override fun visit(desc: String?) {
|
||||
if (Flags.Function.IS_INLINE(flags) && desc != null) {
|
||||
inlineFunctions += desc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
assertEquals(
|
||||
listOf("foo(Lkotlin/jvm/functions/Function0;)Ljava/lang/String;"),
|
||||
inlineFunctions
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
/**
|
||||
* A fully qualified name of a classifier from the Kotlin's point of view. May differ from the JVM name of the class
|
||||
* which is the runtime representation of this Kotlin classifier (for example, Kotlin class "kotlin/Int" -> JVM class "java/lang/Integer")
|
||||
*
|
||||
* Package names in this name are separated by '/', and class names are separated by '.', for example: `"org/foo/bar/Baz.Nested"`.
|
||||
*
|
||||
* If this name starts with '.', it represents a local class or an anonymous object. This is used by the Kotlin compiler
|
||||
* to prevent lookup of this name in the resolution.
|
||||
*/
|
||||
// TODO: use inline class in 1.3
|
||||
typealias ClassName = String
|
||||
|
||||
val ClassName.isLocal: Boolean
|
||||
get() = this.startsWith(".")
|
||||
@@ -0,0 +1,481 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. 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
|
||||
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf.*
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags as F
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf.Class.Kind as ClassKind
|
||||
|
||||
/**
|
||||
* A container of all flags applicable to all Kotlin declarations. A "flag" is a boolean trait that is either present or not
|
||||
* in a declaration. To check whether the flag is present in the bitmask, call [MetadataFlag.invoke] on the flag, passing the bitmask
|
||||
* as the argument:
|
||||
*
|
||||
* override fun visitFunction(flags: Int, name: String): KmFunctionVisitor? {
|
||||
* if (Flags.Function.IS_INLINE(flags)) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* To construct a bitmask out of several flags, call [Flags.invoke] on the needed flags:
|
||||
*
|
||||
* v.visitFunction(Flags(Flags.Function.IS_DECLARATION, Flags.Function.IS_INLINE), "foo")
|
||||
*
|
||||
* Flags common to multiple kinds of Kotlin declarations ("common flags") are declared directly in the [Flags] object.
|
||||
* Flags applicable to specific kinds of declarations ("declaration-specific flags") are declared in nested objects of the [Flags] object.
|
||||
*
|
||||
* Some flags are mutually exclusive, i.e. there are "flag groups" such that no more than one flag from each group can be present
|
||||
* in the same bitmask. Among common flags, there are the following flag groups:
|
||||
* * visibility flags: [IS_INTERNAL], [IS_PRIVATE], [IS_PROTECTED], [IS_PUBLIC], [IS_PRIVATE_TO_THIS], [IS_LOCAL]
|
||||
* * modality flags: [IS_FINAL], [IS_OPEN], [IS_ABSTRACT], [IS_SEALED]
|
||||
*
|
||||
* Some declaration-specific flags form other flag groups, see the documentation of the corresponding containers for more information.
|
||||
*/
|
||||
object Flags {
|
||||
/**
|
||||
* Combines several flags into an integer bitmask. Note that in case several mutually exclusive flags are passed (for example,
|
||||
* several visibility flags), the resulting bitmask will hold the value of the latest flag.
|
||||
*
|
||||
* For example, `Flags(Flags.IS_PRIVATE, Flags.IS_PUBLIC, Flags.IS_INTERNAL)` is the same as `Flags(Flags.IS_INTERNAL)`
|
||||
*/
|
||||
operator fun invoke(vararg flags: MetadataFlag): Int =
|
||||
flags.fold(0) { acc, flag -> flag + acc }
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding declaration has at least one annotation.
|
||||
*
|
||||
* This flag is useful for reading Kotlin metadata on JVM efficiently. On JVM, most of the annotations are written not to the Kotlin
|
||||
* metadata, but directly on the corresponding declarations in the class file. This flag can be used as an optimization to avoid
|
||||
* reading annotations from the class file (which can be slow) in case when a declaration has no annotations.
|
||||
*/
|
||||
@JvmField
|
||||
val HAS_ANNOTATIONS = MetadataFlag(F.HAS_ANNOTATIONS)
|
||||
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is `internal`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INTERNAL = MetadataFlag(F.VISIBILITY, Visibility.INTERNAL_VALUE)
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is `private`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_PRIVATE = MetadataFlag(F.VISIBILITY, Visibility.PRIVATE_VALUE)
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is `protected`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_PROTECTED = MetadataFlag(F.VISIBILITY, Visibility.PROTECTED_VALUE)
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is `public`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_PUBLIC = MetadataFlag(F.VISIBILITY, Visibility.PUBLIC_VALUE)
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is "private-to-this", which is a non-denotable visibility of
|
||||
* private members in Kotlin which are callable only on the same instance of the declaring class.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_PRIVATE_TO_THIS = MetadataFlag(F.VISIBILITY, Visibility.PRIVATE_TO_THIS_VALUE)
|
||||
|
||||
/**
|
||||
* A visibility flag, signifying that the corresponding declaration is local, i.e. declared inside a code block
|
||||
* and not visible from the outside.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_LOCAL = MetadataFlag(F.VISIBILITY, Visibility.LOCAL_VALUE)
|
||||
|
||||
|
||||
/**
|
||||
* A modality flag, signifying that the corresponding declaration is `final`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_FINAL = MetadataFlag(F.MODALITY, Modality.FINAL_VALUE)
|
||||
|
||||
/**
|
||||
* A modality flag, signifying that the corresponding declaration is `open`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_OPEN = MetadataFlag(F.MODALITY, Modality.OPEN_VALUE)
|
||||
|
||||
/**
|
||||
* A modality flag, signifying that the corresponding declaration is `abstract`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_ABSTRACT = MetadataFlag(F.MODALITY, Modality.ABSTRACT_VALUE)
|
||||
|
||||
/**
|
||||
* A modality flag, signifying that the corresponding declaration is `sealed`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_SEALED = MetadataFlag(F.MODALITY, Modality.SEALED_VALUE)
|
||||
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin classes, including interfaces, objects, enum classes and annotation classes.
|
||||
*
|
||||
* In addition to the common flag groups, the following flag groups exist for class flags:
|
||||
* * class kind flags: [IS_CLASS], [IS_INTERFACE], [IS_ENUM_CLASS], [IS_ENUM_ENTRY], [IS_ANNOTATION_CLASS], [IS_OBJECT],
|
||||
* [IS_COMPANION_OBJECT]
|
||||
*/
|
||||
object Class {
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is a usual `class`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_CLASS = MetadataFlag(F.CLASS_KIND, ClassKind.CLASS_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is an `interface`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INTERFACE = MetadataFlag(F.CLASS_KIND, ClassKind.INTERFACE_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is an `enum class`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_ENUM_CLASS = MetadataFlag(F.CLASS_KIND, ClassKind.ENUM_CLASS_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is an enum entry.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_ENUM_ENTRY = MetadataFlag(F.CLASS_KIND, ClassKind.ENUM_ENTRY_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is an `annotation class`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_ANNOTATION_CLASS = MetadataFlag(F.CLASS_KIND, ClassKind.ANNOTATION_CLASS_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is a non-companion `object`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_OBJECT = MetadataFlag(F.CLASS_KIND, ClassKind.OBJECT_VALUE)
|
||||
|
||||
/**
|
||||
* A class kind flag, signifying that the corresponding class is a `companion object`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_COMPANION_OBJECT = MetadataFlag(F.CLASS_KIND, ClassKind.COMPANION_OBJECT_VALUE)
|
||||
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding class is `inner`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INNER = MetadataFlag(F.IS_INNER)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding class is `data`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DATA = MetadataFlag(F.IS_DATA)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding class is `external`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXTERNAL = MetadataFlag(F.IS_EXTERNAL_CLASS)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding class is `expect`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXPECT = MetadataFlag(F.IS_EXPECT_CLASS)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding class is `inline`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INLINE = MetadataFlag(F.IS_INLINE_CLASS)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin constructors.
|
||||
*/
|
||||
object Constructor {
|
||||
/**
|
||||
* Signifies that the corresponding constructor is primary, i.e. declared in the class header, not in the class body.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_PRIMARY = MetadataFlag(F.IS_SECONDARY, 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin functions.
|
||||
*
|
||||
* In addition to the common flag groups, the following flag groups exist for function flags:
|
||||
* * member kind flags: [IS_DECLARATION], [IS_FAKE_OVERRIDE], [IS_DELEGATION], [IS_SYNTHESIZED]
|
||||
*/
|
||||
object Function {
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding function is explicitly declared in the containing class.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DECLARATION = MetadataFlag(F.MEMBER_KIND, MemberKind.DECLARATION_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding function exists in the containing class because a function with a suitable
|
||||
* signature exists in a supertype. This flag is not written by the Kotlin compiler and its effects are unspecified.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_FAKE_OVERRIDE = MetadataFlag(F.MEMBER_KIND, MemberKind.FAKE_OVERRIDE_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding function exists in the containing class because it has been produced
|
||||
* by interface delegation (delegation "by").
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DELEGATION = MetadataFlag(F.MEMBER_KIND, MemberKind.DELEGATION_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding function exists in the containing class because it has been synthesized
|
||||
* by the compiler and has no declaration in the source code.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_SYNTHESIZED = MetadataFlag(F.MEMBER_KIND, MemberKind.SYNTHESIZED_VALUE)
|
||||
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `operator`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_OPERATOR = MetadataFlag(F.IS_OPERATOR)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `infix`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INFIX = MetadataFlag(F.IS_INFIX)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `inline`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INLINE = MetadataFlag(F.IS_INLINE)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `tailrec`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_TAILREC = MetadataFlag(F.IS_TAILREC)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `external`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXTERNAL = MetadataFlag(F.IS_EXTERNAL_FUNCTION)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `suspend`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_SUSPEND = MetadataFlag(F.IS_SUSPEND)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding function is `expect`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXPECT = MetadataFlag(F.IS_EXPECT_FUNCTION)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin properties.
|
||||
*
|
||||
* In addition to the common flag groups, the following flag groups exist for property flags:
|
||||
* * member kind flags: [IS_DECLARATION], [IS_FAKE_OVERRIDE], [IS_DELEGATION], [IS_SYNTHESIZED]
|
||||
*/
|
||||
object Property {
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding property is explicitly declared in the containing class.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DECLARATION = MetadataFlag(F.MEMBER_KIND, MemberKind.DECLARATION_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding property exists in the containing class because a property with a suitable
|
||||
* signature exists in a supertype. This flag is not written by the Kotlin compiler and its effects are unspecified.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_FAKE_OVERRIDE = MetadataFlag(F.MEMBER_KIND, MemberKind.FAKE_OVERRIDE_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding property exists in the containing class because it has been produced
|
||||
* by interface delegation (delegation "by").
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DELEGATION = MetadataFlag(F.MEMBER_KIND, MemberKind.DELEGATION_VALUE)
|
||||
|
||||
/**
|
||||
* A member kind flag, signifying that the corresponding property exists in the containing class because it has been synthesized
|
||||
* by the compiler and has no declaration in the source code.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_SYNTHESIZED = MetadataFlag(F.MEMBER_KIND, MemberKind.SYNTHESIZED_VALUE)
|
||||
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is `var`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_VAR = MetadataFlag(F.IS_VAR)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property has a getter.
|
||||
*/
|
||||
@JvmField
|
||||
val HAS_GETTER = MetadataFlag(F.HAS_GETTER)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property has a setter.
|
||||
*/
|
||||
@JvmField
|
||||
val HAS_SETTER = MetadataFlag(F.HAS_SETTER)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is `const`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_CONST = MetadataFlag(F.IS_CONST)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is `lateinit`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_LATEINIT = MetadataFlag(F.IS_LATEINIT)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property has a constant value. On JVM, this flag allows an optimization similarly to
|
||||
* [F.HAS_ANNOTATIONS]: constant values of properties are written to the bytecode directly, and this flag can be used to avoid
|
||||
* reading the value from the bytecode in case there isn't one.
|
||||
*/
|
||||
@JvmField
|
||||
val HAS_CONSTANT = MetadataFlag(F.HAS_CONSTANT)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is `external`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXTERNAL = MetadataFlag(F.IS_EXTERNAL_PROPERTY)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is a delegated property.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_DELEGATED = MetadataFlag(F.IS_DELEGATED)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property is `expect`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXPECT = MetadataFlag(F.IS_EXPECT_PROPERTY)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin property getters and setters.
|
||||
*/
|
||||
object PropertyAccessor {
|
||||
/**
|
||||
* Signifies that the corresponding property accessor is not default, i.e. it has a body and/or annotations in the source code.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_NOT_DEFAULT = MetadataFlag(F.IS_NOT_DEFAULT)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property accessor is `external`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_EXTERNAL = MetadataFlag(F.IS_EXTERNAL_ACCESSOR)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding property accessor is `inline`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_INLINE = MetadataFlag(F.IS_INLINE_ACCESSOR)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin types.
|
||||
*/
|
||||
object Type {
|
||||
/**
|
||||
* Signifies that the corresponding type is marked as nullable, i.e. has a question mark at the end of its notation.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_NULLABLE = MetadataFlag(0, 1, 1)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding type is `suspend`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_SUSPEND = MetadataFlag(F.SUSPEND_TYPE.offset + 1, F.SUSPEND_TYPE.bitWidth, 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin type parameters.
|
||||
*/
|
||||
object TypeParameter {
|
||||
/**
|
||||
* Signifies that the corresponding type parameter is `reified`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_REIFIED = MetadataFlag(0, 1, 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin value parameters.
|
||||
*/
|
||||
object ValueParameter {
|
||||
/**
|
||||
* Signifies that the corresponding value parameter declares a default value. Note that the default value itself can be a complex
|
||||
* expression and is not available via metadata. Also note that in case of an override of a parameter with default value, the
|
||||
* parameter in the derived method does _not_ declare the default value ([DECLARES_DEFAULT_VALUE] == false), but the parameter is
|
||||
* still optional at the call site because the default value from the base method is used.
|
||||
*/
|
||||
@JvmField
|
||||
val DECLARES_DEFAULT_VALUE = MetadataFlag(F.DECLARES_DEFAULT_VALUE)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding value parameter is `crossinline`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_CROSSINLINE = MetadataFlag(F.IS_CROSSINLINE)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding value parameter is `noinline`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_NOINLINE = MetadataFlag(F.IS_NOINLINE)
|
||||
}
|
||||
|
||||
/**
|
||||
* A container of flags applicable to Kotlin effect expressions.
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*/
|
||||
object EffectExpression {
|
||||
/**
|
||||
* Signifies that the corresponding effect expression should be negated to compute the proposition or the conclusion of an effect.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_NEGATED = MetadataFlag(F.IS_NEGATED)
|
||||
|
||||
/**
|
||||
* Signifies that the corresponding effect expression checks whether a value of some variable is `null`.
|
||||
*/
|
||||
@JvmField
|
||||
val IS_NULL_CHECK_PREDICATE = MetadataFlag(F.IS_NULL_CHECK_PREDICATE)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
class InconsistentKotlinMetadataException(message: String, cause: Throwable? = null) : RuntimeException(message, cause)
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. 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
|
||||
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags.BooleanFlagField
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags.FlagField
|
||||
|
||||
/**
|
||||
* Represents a boolean flag that is either present or not in a Kotlin declaration.
|
||||
*
|
||||
* @see Flags
|
||||
*/
|
||||
class MetadataFlag internal constructor(
|
||||
private val offset: Int,
|
||||
private val bitWidth: Int,
|
||||
private val value: Int
|
||||
) {
|
||||
internal constructor(field: FlagField<*>, value: Int) : this(field.offset, field.bitWidth, value)
|
||||
|
||||
internal constructor(field: BooleanFlagField) : this(field, 1)
|
||||
|
||||
internal operator fun plus(flags: Int): Int =
|
||||
(flags and (((1 shl bitWidth) - 1) shl offset).inv()) + (value shl offset)
|
||||
|
||||
/**
|
||||
* Checks whether the flag is present in the given bitmask.
|
||||
*/
|
||||
operator fun invoke(flags: Int): Boolean =
|
||||
(flags ushr offset) and ((1 shl bitWidth) - 1) == value
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
/**
|
||||
* Represents an annotation, written to the Kotlin metadata. Note that not all annotations are written to metadata on all platforms.
|
||||
* For example, on JVM most of the annotations are written directly on the corresponding declarations in the class file,
|
||||
* and entries in the metadata only have a flag ([Flags.HAS_ANNOTATIONS]) to signal if they do have annotations in the bytecode.
|
||||
* On JVM, only annotations on type parameters and types are serialized to the Kotlin metadata.
|
||||
*
|
||||
* @param className the fully qualified name of the annotation class
|
||||
* @param arguments explicitly specified arguments to the annotation; does not include default values for annotation parameters
|
||||
* (specified in the annotation class declaration)
|
||||
*/
|
||||
data class KmAnnotation(val className: ClassName, val arguments: Map<String, KmAnnotationArgument<*>>)
|
||||
|
||||
/**
|
||||
* Represents an argument to the annotation.
|
||||
*
|
||||
* @param T the type of the value of this argument
|
||||
*/
|
||||
sealed class KmAnnotationArgument<out T : Any> {
|
||||
/**
|
||||
* The value of this argument.
|
||||
*/
|
||||
abstract val value: T
|
||||
|
||||
data class ByteValue(override val value: Byte) : KmAnnotationArgument<Byte>()
|
||||
data class CharValue(override val value: Char) : KmAnnotationArgument<Char>()
|
||||
data class ShortValue(override val value: Short) : KmAnnotationArgument<Short>()
|
||||
data class IntValue(override val value: Int) : KmAnnotationArgument<Int>()
|
||||
data class LongValue(override val value: Long) : KmAnnotationArgument<Long>()
|
||||
data class FloatValue(override val value: Float) : KmAnnotationArgument<Float>()
|
||||
data class DoubleValue(override val value: Double) : KmAnnotationArgument<Double>()
|
||||
data class BooleanValue(override val value: Boolean) : KmAnnotationArgument<Boolean>()
|
||||
|
||||
data class StringValue(override val value: String) : KmAnnotationArgument<String>()
|
||||
data class KClassValue(override val value: ClassName) : KmAnnotationArgument<ClassName>()
|
||||
data class EnumValue(val enumClassName: ClassName, val enumEntryName: String) : KmAnnotationArgument<String>() {
|
||||
override val value: String = "$enumClassName.$enumEntryName"
|
||||
}
|
||||
|
||||
data class AnnotationValue(override val value: KmAnnotation) : KmAnnotationArgument<KmAnnotation>()
|
||||
data class ArrayValue(override val value: List<KmAnnotationArgument<*>>) : KmAnnotationArgument<List<KmAnnotationArgument<*>>>()
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* A type of the extension visitor expected by the code that uses the visitor API.
|
||||
*
|
||||
* Each declaration which can have platform-specific extensions in the metadata has a method `visitExtensions` in its visitor, e.g.:
|
||||
*
|
||||
* open fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor?
|
||||
*
|
||||
* The client code is supposed to return the extension visitor corresponding to the given type, or to return `null` if the type is
|
||||
* of no interest to that code. Each platform-specific extension visitor has a [KmExtensionType] instance declared in the `TYPE` property
|
||||
* its companion object. For example, to load JVM extensions on a function, one could do:
|
||||
*
|
||||
* override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? {
|
||||
* if (type != JvmFunctionExtensionVisitor.TYPE) return null
|
||||
*
|
||||
* return object : JvmFunctionExtensionVisitor() {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* In case an extension visitor of an unrelated type is returned, the code using the visitor API must ignore that visitor.
|
||||
*/
|
||||
data class KmExtensionType(val klass: KClass<out KmExtensionVisitor>)
|
||||
|
||||
/**
|
||||
* A base interface for all extension visitors.
|
||||
*/
|
||||
interface KmExtensionVisitor
|
||||
|
||||
/**
|
||||
* A visitor to visit platform-specific extensions for a function.
|
||||
*/
|
||||
interface KmFunctionExtensionVisitor : KmExtensionVisitor
|
||||
|
||||
/**
|
||||
* A visitor to visit platform-specific extensions for a property.
|
||||
*/
|
||||
interface KmPropertyExtensionVisitor : KmExtensionVisitor
|
||||
|
||||
/**
|
||||
* A visitor to visit platform-specific extensions for a constructor.
|
||||
*/
|
||||
interface KmConstructorExtensionVisitor : KmExtensionVisitor
|
||||
|
||||
/**
|
||||
* A visitor to visit platform-specific extensions for a type parameter.
|
||||
*/
|
||||
interface KmTypeParameterExtensionVisitor : KmExtensionVisitor
|
||||
|
||||
/**
|
||||
* A visitor to visit platform-specific extensions for a type.
|
||||
*/
|
||||
interface KmTypeExtensionVisitor : KmExtensionVisitor
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.impl.extensions
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
|
||||
import java.util.*
|
||||
|
||||
interface MetadataExtensions {
|
||||
fun readFunctionExtensions(v: KmFunctionVisitor, proto: ProtoBuf.Function, strings: NameResolver, types: TypeTable)
|
||||
|
||||
fun readPropertyExtensions(v: KmPropertyVisitor, proto: ProtoBuf.Property, strings: NameResolver, types: TypeTable)
|
||||
|
||||
fun readConstructorExtensions(v: KmConstructorVisitor, proto: ProtoBuf.Constructor, strings: NameResolver, types: TypeTable)
|
||||
|
||||
fun readTypeParameterExtensions(v: KmTypeParameterVisitor, proto: ProtoBuf.TypeParameter, strings: NameResolver)
|
||||
|
||||
fun readTypeExtensions(v: KmTypeVisitor, proto: ProtoBuf.Type, strings: NameResolver)
|
||||
|
||||
companion object {
|
||||
val INSTANCE: MetadataExtensions by lazy {
|
||||
ServiceLoader.load(MetadataExtensions::class.java).toList().firstOrNull()
|
||||
?: error(
|
||||
"No MetadataExtensions instances found in the classpath. Please ensure that the META-INF/services/ " +
|
||||
"is not stripped from your application and that the Java virtual machine is not running " +
|
||||
"under a security manager"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.impl
|
||||
|
||||
import kotlinx.metadata.ClassName
|
||||
import kotlinx.metadata.KmAnnotation
|
||||
import kotlinx.metadata.KmAnnotationArgument
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf.Annotation.Argument.Value.Type.*
|
||||
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
|
||||
|
||||
fun ProtoBuf.Annotation.readAnnotation(strings: NameResolver): KmAnnotation =
|
||||
KmAnnotation(
|
||||
strings.getClassName(id),
|
||||
argumentList.mapNotNull { argument ->
|
||||
argument.value.readAnnotationArgument(strings)?.let { value ->
|
||||
strings.getString(argument.nameId) to value
|
||||
}
|
||||
}.toMap()
|
||||
)
|
||||
|
||||
private fun ProtoBuf.Annotation.Argument.Value.readAnnotationArgument(strings: NameResolver): KmAnnotationArgument<*>? =
|
||||
when (type) {
|
||||
BYTE -> KmAnnotationArgument.ByteValue(intValue.toByte())
|
||||
CHAR -> KmAnnotationArgument.CharValue(intValue.toChar())
|
||||
SHORT -> KmAnnotationArgument.ShortValue(intValue.toShort())
|
||||
INT -> KmAnnotationArgument.IntValue(intValue.toInt())
|
||||
LONG -> KmAnnotationArgument.LongValue(intValue)
|
||||
FLOAT -> KmAnnotationArgument.FloatValue(floatValue)
|
||||
DOUBLE -> KmAnnotationArgument.DoubleValue(doubleValue)
|
||||
BOOLEAN -> KmAnnotationArgument.BooleanValue(intValue != 0L)
|
||||
STRING -> KmAnnotationArgument.StringValue(strings.getString(stringValue))
|
||||
CLASS -> KmAnnotationArgument.KClassValue(strings.getClassName(classId))
|
||||
ENUM -> KmAnnotationArgument.EnumValue(strings.getClassName(classId), strings.getString(enumValueId))
|
||||
ANNOTATION -> KmAnnotationArgument.AnnotationValue(annotation.readAnnotation(strings))
|
||||
ARRAY -> KmAnnotationArgument.ArrayValue(arrayElementList.mapNotNull { it.readAnnotationArgument(strings) })
|
||||
null -> null
|
||||
}
|
||||
|
||||
internal fun NameResolver.getClassName(index: Int): ClassName {
|
||||
val name = getQualifiedClassName(index)
|
||||
return if (isLocalClassName(index)) ".$name" else name
|
||||
}
|
||||
@@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. 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.impl
|
||||
|
||||
import kotlinx.metadata.*
|
||||
import kotlinx.metadata.impl.extensions.MetadataExtensions
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.*
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
|
||||
class ReadContext(
|
||||
internal val strings: NameResolver,
|
||||
internal val types: TypeTable,
|
||||
internal val versionRequirements: VersionRequirementTable,
|
||||
private val parent: ReadContext? = null
|
||||
) {
|
||||
internal val extensions = MetadataExtensions.INSTANCE
|
||||
private val typeParameterNameToId = mutableMapOf<Int, Int>()
|
||||
|
||||
operator fun get(index: Int): String =
|
||||
strings.getString(index)
|
||||
|
||||
fun className(index: Int): ClassName =
|
||||
strings.getClassName(index)
|
||||
|
||||
fun getTypeParameterId(name: Int): Int? =
|
||||
typeParameterNameToId[name] ?: parent?.getTypeParameterId(name)
|
||||
|
||||
fun withTypeParameters(typeParameters: List<ProtoBuf.TypeParameter>): ReadContext =
|
||||
ReadContext(strings, types, versionRequirements, this).apply {
|
||||
for (typeParameter in typeParameters) {
|
||||
typeParameterNameToId[typeParameter.name] = typeParameter.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun ProtoBuf.Class.accept(v: KmClassVisitor, strings: NameResolver) {
|
||||
val c = ReadContext(strings, TypeTable(typeTable), VersionRequirementTable.create(versionRequirementTable))
|
||||
.withTypeParameters(typeParameterList)
|
||||
|
||||
v.visit(flags, c.className(fqName))
|
||||
|
||||
for (typeParameter in typeParameterList) {
|
||||
typeParameter.accept(v::visitTypeParameter, c)
|
||||
}
|
||||
|
||||
for (supertype in supertypes(c.types)) {
|
||||
v.visitSupertype(supertype.typeFlags)?.let { supertype.accept(it, c) }
|
||||
}
|
||||
|
||||
for (constructor in constructorList) {
|
||||
v.visitConstructor(constructor.flags)?.let { constructor.accept(it, c) }
|
||||
}
|
||||
|
||||
v.visitDeclarations(functionList, propertyList, typeAliasList, c)
|
||||
|
||||
if (hasCompanionObjectName()) {
|
||||
v.visitCompanionObject(c[companionObjectName])
|
||||
}
|
||||
|
||||
for (nestedClassName in nestedClassNameList) {
|
||||
v.visitNestedClass(c[nestedClassName])
|
||||
}
|
||||
|
||||
for (enumEntry in enumEntryList) {
|
||||
if (!enumEntry.hasName()) {
|
||||
throw InconsistentKotlinMetadataException("No name for EnumEntry")
|
||||
}
|
||||
v.visitEnumEntry(c[enumEntry.name])
|
||||
}
|
||||
|
||||
for (sealedSubclassFqName in sealedSubclassFqNameList) {
|
||||
v.visitSealedSubclass(c.className(sealedSubclassFqName))
|
||||
}
|
||||
|
||||
if (hasVersionRequirement()) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
fun ProtoBuf.Package.accept(v: KmPackageVisitor, strings: NameResolver) {
|
||||
val c = ReadContext(strings, TypeTable(typeTable), VersionRequirementTable.create(versionRequirementTable))
|
||||
|
||||
v.visitDeclarations(functionList, propertyList, typeAliasList, c)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun KmDeclarationContainerVisitor.visitDeclarations(
|
||||
functions: List<ProtoBuf.Function>,
|
||||
properties: List<ProtoBuf.Property>,
|
||||
typeAliases: List<ProtoBuf.TypeAlias>,
|
||||
c: ReadContext
|
||||
) {
|
||||
for (function in functions) {
|
||||
visitFunction(function.flags, c[function.name])?.let { function.accept(it, c) }
|
||||
}
|
||||
|
||||
for (property in properties) {
|
||||
val flags = property.flags
|
||||
val defaultAccessorFlags = Flags.getAccessorFlags(
|
||||
Flags.HAS_ANNOTATIONS.get(flags), Flags.VISIBILITY.get(flags), Flags.MODALITY.get(flags), false, false, false
|
||||
)
|
||||
visitProperty(
|
||||
flags,
|
||||
c[property.name],
|
||||
if (property.hasGetterFlags()) property.getterFlags else defaultAccessorFlags,
|
||||
if (property.hasSetterFlags()) property.setterFlags else defaultAccessorFlags
|
||||
)?.let { property.accept(it, c) }
|
||||
}
|
||||
|
||||
for (typeAlias in typeAliases) {
|
||||
visitTypeAlias(typeAlias.flags, c[typeAlias.name])?.let { typeAlias.accept(it, c) }
|
||||
}
|
||||
}
|
||||
|
||||
fun ProtoBuf.Function.accept(v: KmLambdaVisitor, strings: NameResolver) {
|
||||
val c = ReadContext(strings, TypeTable(typeTable), VersionRequirementTable.EMPTY)
|
||||
|
||||
v.visitFunction(flags, c[name])?.let { accept(it, c) }
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Constructor.accept(v: KmConstructorVisitor, c: ReadContext) {
|
||||
for (parameter in valueParameterList) {
|
||||
v.visitValueParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasVersionRequirement()) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
|
||||
}
|
||||
|
||||
c.extensions.readConstructorExtensions(v, this, c.strings, c.types)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Function.accept(v: KmFunctionVisitor, outer: ReadContext) {
|
||||
val c = outer.withTypeParameters(typeParameterList)
|
||||
|
||||
for (typeParameter in typeParameterList) {
|
||||
typeParameter.accept(v::visitTypeParameter, c)
|
||||
}
|
||||
|
||||
receiverType(c.types)?.let { receiverType ->
|
||||
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
||||
}
|
||||
|
||||
for (parameter in valueParameterList) {
|
||||
v.visitValueParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
||||
}
|
||||
|
||||
returnType(c.types).let { returnType ->
|
||||
v.visitReturnType(returnType.typeFlags)?.let { returnType.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasContract()) {
|
||||
v.visitContract()?.let { contract.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasVersionRequirement()) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
|
||||
}
|
||||
|
||||
c.extensions.readFunctionExtensions(v, this, c.strings, c.types)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Property.accept(v: KmPropertyVisitor, outer: ReadContext) {
|
||||
val c = outer.withTypeParameters(typeParameterList)
|
||||
|
||||
for (typeParameter in typeParameterList) {
|
||||
typeParameter.accept(v::visitTypeParameter, c)
|
||||
}
|
||||
|
||||
receiverType(c.types)?.let { receiverType ->
|
||||
v.visitReceiverParameterType(receiverType.typeFlags)?.let { receiverType.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasSetterValueParameter()) {
|
||||
val parameter = setterValueParameter
|
||||
v.visitSetterParameter(parameter.flags, c[parameter.name])?.let { parameter.accept(it, c) }
|
||||
}
|
||||
|
||||
returnType(c.types).let { returnType ->
|
||||
v.visitReturnType(returnType.typeFlags)?.let { returnType.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasVersionRequirement()) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
|
||||
}
|
||||
|
||||
c.extensions.readPropertyExtensions(v, this, c.strings, c.types)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.TypeAlias.accept(v: KmTypeAliasVisitor, outer: ReadContext) {
|
||||
val c = outer.withTypeParameters(typeParameterList)
|
||||
|
||||
for (typeParameter in typeParameterList) {
|
||||
typeParameter.accept(v::visitTypeParameter, c)
|
||||
}
|
||||
|
||||
underlyingType(c.types).let { underlyingType ->
|
||||
v.visitUnderlyingType(underlyingType.typeFlags)?.let { underlyingType.accept(it, c) }
|
||||
}
|
||||
|
||||
expandedType(c.types).let { expandedType ->
|
||||
v.visitExpandedType(expandedType.typeFlags)?.let { expandedType.accept(it, c) }
|
||||
}
|
||||
|
||||
for (annotation in annotationList) {
|
||||
v.visitAnnotation(annotation.readAnnotation(c.strings))
|
||||
}
|
||||
|
||||
if (hasVersionRequirement()) {
|
||||
v.visitVersionRequirement()?.let { acceptVersionRequirementVisitor(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.ValueParameter.accept(v: KmValueParameterVisitor, c: ReadContext) {
|
||||
type(c.types).let { type ->
|
||||
v.visitType(type.typeFlags)?.let { type.accept(it, c) }
|
||||
}
|
||||
|
||||
varargElementType(c.types)?.let { varargElementType ->
|
||||
v.visitVarargElementType(varargElementType.typeFlags)?.let { varargElementType.accept(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private inline fun ProtoBuf.TypeParameter.accept(
|
||||
visit: (flags: Int, name: String, id: Int, variance: KmVariance) -> KmTypeParameterVisitor?,
|
||||
c: ReadContext
|
||||
) {
|
||||
val variance = when (variance!!) {
|
||||
ProtoBuf.TypeParameter.Variance.IN -> KmVariance.IN
|
||||
ProtoBuf.TypeParameter.Variance.OUT -> KmVariance.OUT
|
||||
ProtoBuf.TypeParameter.Variance.INV -> KmVariance.INVARIANT
|
||||
}
|
||||
|
||||
visit(typeParameterFlags, c[name], id, variance)?.let { accept(it, c) }
|
||||
}
|
||||
|
||||
private fun ProtoBuf.TypeParameter.accept(v: KmTypeParameterVisitor, c: ReadContext) {
|
||||
for (upperBound in upperBounds(c.types)) {
|
||||
v.visitUpperBound(upperBound.typeFlags)?.let { upperBound.accept(it, c) }
|
||||
}
|
||||
|
||||
c.extensions.readTypeParameterExtensions(v, this, c.strings)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Type.accept(v: KmTypeVisitor, c: ReadContext) {
|
||||
when {
|
||||
hasClassName() -> v.visitClass(c.className(className))
|
||||
hasTypeAliasName() -> v.visitTypeAlias(c.className(typeAliasName))
|
||||
hasTypeParameter() -> v.visitTypeParameter(typeParameter)
|
||||
hasTypeParameterName() -> {
|
||||
val id = c.getTypeParameterId(typeParameterName)
|
||||
?: throw InconsistentKotlinMetadataException("No type parameter id for ${c[typeParameterName]}")
|
||||
v.visitTypeParameter(id)
|
||||
}
|
||||
else -> {
|
||||
throw InconsistentKotlinMetadataException("No classifier (class, type alias or type parameter) recorded for Type")
|
||||
}
|
||||
}
|
||||
|
||||
for (argument in argumentList) {
|
||||
val variance = when (argument.projection!!) {
|
||||
ProtoBuf.Type.Argument.Projection.IN -> KmVariance.IN
|
||||
ProtoBuf.Type.Argument.Projection.OUT -> KmVariance.OUT
|
||||
ProtoBuf.Type.Argument.Projection.INV -> KmVariance.INVARIANT
|
||||
ProtoBuf.Type.Argument.Projection.STAR -> null
|
||||
}
|
||||
|
||||
if (variance != null) {
|
||||
val argumentType = argument.type(c.types)
|
||||
?: throw InconsistentKotlinMetadataException("No type argument for non-STAR projection in Type")
|
||||
v.visitArgument(argumentType.typeFlags, variance)?.let { argumentType.accept(it, c) }
|
||||
} else {
|
||||
v.visitStarProjection()
|
||||
}
|
||||
}
|
||||
|
||||
abbreviatedType(c.types)?.let { abbreviatedType ->
|
||||
v.visitAbbreviatedType(abbreviatedType.typeFlags)?.let { abbreviatedType.accept(it, c) }
|
||||
}
|
||||
|
||||
outerType(c.types)?.let { outerType ->
|
||||
v.visitOuterType(outerType.typeFlags)?.let { outerType.accept(it, c) }
|
||||
}
|
||||
|
||||
flexibleUpperBound(c.types)?.let { upperBound ->
|
||||
v.visitFlexibleTypeUpperBound(
|
||||
upperBound.typeFlags,
|
||||
if (hasFlexibleTypeCapabilitiesId()) c[flexibleTypeCapabilitiesId] else null
|
||||
)?.let { upperBound.accept(it, c) }
|
||||
}
|
||||
|
||||
c.extensions.readTypeExtensions(v, this, c.strings)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun MessageLite.acceptVersionRequirementVisitor(v: KmVersionRequirementVisitor, c: ReadContext) {
|
||||
val message = VersionRequirement.create(this, c.strings, c.versionRequirements)
|
||||
?: throw InconsistentKotlinMetadataException("No VersionRequirement with the given id in the table")
|
||||
|
||||
val kind = when (message.kind) {
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION -> KmVersionRequirementVersionKind.LANGUAGE_VERSION
|
||||
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION -> KmVersionRequirementVersionKind.COMPILER_VERSION
|
||||
ProtoBuf.VersionRequirement.VersionKind.API_VERSION -> KmVersionRequirementVersionKind.API_VERSION
|
||||
}
|
||||
|
||||
val level = when (message.level) {
|
||||
DeprecationLevel.WARNING -> KmVersionRequirementLevel.WARNING
|
||||
DeprecationLevel.ERROR -> KmVersionRequirementLevel.ERROR
|
||||
DeprecationLevel.HIDDEN -> KmVersionRequirementLevel.HIDDEN
|
||||
}
|
||||
|
||||
v.visit(kind, level, message.errorCode, message.message)
|
||||
|
||||
val (major, minor, patch) = message.version
|
||||
v.visitVersion(major, minor, patch)
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Contract.accept(v: KmContractVisitor, c: ReadContext) {
|
||||
for (effect in effectList) {
|
||||
if (!effect.hasEffectType()) continue
|
||||
|
||||
val effectType = when (effect.effectType!!) {
|
||||
ProtoBuf.Effect.EffectType.RETURNS_CONSTANT -> KmEffectType.RETURNS_CONSTANT
|
||||
ProtoBuf.Effect.EffectType.CALLS -> KmEffectType.CALLS
|
||||
ProtoBuf.Effect.EffectType.RETURNS_NOT_NULL -> KmEffectType.RETURNS_NOT_NULL
|
||||
}
|
||||
|
||||
val effectKind = if (!effect.hasKind()) null else when (effect.kind!!) {
|
||||
ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE -> KmEffectInvocationKind.AT_MOST_ONCE
|
||||
ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE -> KmEffectInvocationKind.EXACTLY_ONCE
|
||||
ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE -> KmEffectInvocationKind.AT_LEAST_ONCE
|
||||
}
|
||||
|
||||
v.visitEffect(effectType, effectKind)?.let { effect.accept(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Effect.accept(v: KmEffectVisitor, c: ReadContext) {
|
||||
for (constructorArgument in effectConstructorArgumentList) {
|
||||
v.visitConstructorArgument()?.let { constructorArgument.accept(it, c) }
|
||||
}
|
||||
|
||||
if (hasConclusionOfConditionalEffect()) {
|
||||
v.visitConclusionOfConditionalEffect()?.let { conclusionOfConditionalEffect.accept(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private fun ProtoBuf.Expression.accept(v: KmEffectExpressionVisitor, c: ReadContext) {
|
||||
v.visit(
|
||||
flags,
|
||||
if (hasValueParameterReference()) valueParameterReference else null
|
||||
)
|
||||
|
||||
if (hasConstantValue()) {
|
||||
v.visitConstantValue(
|
||||
when (constantValue!!) {
|
||||
ProtoBuf.Expression.ConstantValue.TRUE -> true
|
||||
ProtoBuf.Expression.ConstantValue.FALSE -> false
|
||||
ProtoBuf.Expression.ConstantValue.NULL -> null
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
isInstanceType(c.types)?.let { type ->
|
||||
v.visitIsInstanceType(type.typeFlags)?.let { type.accept(it, c) }
|
||||
}
|
||||
|
||||
for (andArgument in andArgumentList) {
|
||||
v.visitAndArgument()?.let { andArgument.accept(it, c) }
|
||||
}
|
||||
|
||||
for (orArgument in orArgumentList) {
|
||||
v.visitOrArgument()?.let { orArgument.accept(it, c) }
|
||||
}
|
||||
|
||||
v.visitEnd()
|
||||
}
|
||||
|
||||
private val ProtoBuf.Type.typeFlags: Int
|
||||
get() = (if (nullable) 1 shl 0 else 0) +
|
||||
(flags shl 1)
|
||||
|
||||
private val ProtoBuf.TypeParameter.typeParameterFlags: Int
|
||||
get() = if (reified) 1 else 0
|
||||
@@ -0,0 +1,811 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. 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
|
||||
|
||||
/**
|
||||
* A visitor to visit Kotlin declarations, which are containers of other declarations: functions, properties and type aliases.
|
||||
*/
|
||||
abstract class KmDeclarationContainerVisitor @JvmOverloads constructor(protected open val delegate: KmDeclarationContainerVisitor? = null) {
|
||||
/**
|
||||
* Visits a function in the container.
|
||||
*
|
||||
* @param flags function flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag and [Flags.Function] flags
|
||||
* @param name the name of the function
|
||||
*/
|
||||
open fun visitFunction(flags: Int, name: String): KmFunctionVisitor? =
|
||||
delegate?.visitFunction(flags, name)
|
||||
|
||||
/**
|
||||
* Visits a property in the container.
|
||||
*
|
||||
* @param flags property flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag and [Flags.Property] flags
|
||||
* @param name the name of the property
|
||||
* @param getterFlags property accessor flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag
|
||||
* and [Flags.PropertyAccessor] flags
|
||||
* @param setterFlags property accessor flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag
|
||||
* and [Flags.PropertyAccessor] flags
|
||||
*/
|
||||
open fun visitProperty(flags: Int, name: String, getterFlags: Int, setterFlags: Int): KmPropertyVisitor? =
|
||||
delegate?.visitProperty(flags, name, getterFlags, setterFlags)
|
||||
|
||||
/**
|
||||
* Visits a type alias in the container.
|
||||
*
|
||||
* @param flags type alias flags, consisting of [Flags.HAS_ANNOTATIONS] and visibility flag
|
||||
* @param name the name of the type alias
|
||||
*/
|
||||
open fun visitTypeAlias(flags: Int, name: String): KmTypeAliasVisitor? =
|
||||
delegate?.visitTypeAlias(flags, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit Kotlin classes, including interfaces, objects, enum classes and annotation classes.
|
||||
*
|
||||
* When using this class, [visit] must be called first, followed by zero or more [visitTypeParameter] calls, followed by zero or more calls
|
||||
* to other visit* methods, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmClassVisitor @JvmOverloads constructor(delegate: KmClassVisitor? = null) : KmDeclarationContainerVisitor(delegate) {
|
||||
override val delegate: KmClassVisitor?
|
||||
get() = super.delegate as KmClassVisitor?
|
||||
|
||||
/**
|
||||
* Visits the basic information about the class.
|
||||
*
|
||||
* @param flags class flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag and [Flags.Class] flags
|
||||
* @param name the name of the class
|
||||
*/
|
||||
open fun visit(flags: Int, name: ClassName) {
|
||||
delegate?.visit(flags, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a type parameter of the class.
|
||||
*
|
||||
* @param flags type parameter flags, consisting of [Flags.TypeParameter] flags
|
||||
* @param name the name of the type parameter
|
||||
* @param id the id of the type parameter, useful to be able to uniquely identify the type parameter in different contexts where
|
||||
* the name isn't enough (e.g. `class A<T> { fun <T> foo(t: T) }`)
|
||||
* @param variance the declaration-site variance of the type parameter
|
||||
*/
|
||||
open fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||
delegate?.visitTypeParameter(flags, name, id, variance)
|
||||
|
||||
/**
|
||||
* Visits a supertype of the class.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitSupertype(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitSupertype(flags)
|
||||
|
||||
/**
|
||||
* Visits a constructor of the class.
|
||||
*
|
||||
* @param flags constructor flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag and [Flags.Constructor] flags
|
||||
*/
|
||||
open fun visitConstructor(flags: Int): KmConstructorVisitor? =
|
||||
delegate?.visitConstructor(flags)
|
||||
|
||||
/**
|
||||
* Visits the name of the companion object of this class, if it has one.
|
||||
*
|
||||
* @param name the name of the companion object
|
||||
*/
|
||||
open fun visitCompanionObject(name: String) {
|
||||
delegate?.visitCompanionObject(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the name of a nested class of this class.
|
||||
*
|
||||
* @param name the name of a nested class
|
||||
*/
|
||||
open fun visitNestedClass(name: String) {
|
||||
delegate?.visitNestedClass(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the name of an enum entry, if this class is an enum class.
|
||||
*
|
||||
* @param name the name of an enum entry
|
||||
*/
|
||||
open fun visitEnumEntry(name: String) {
|
||||
delegate?.visitEnumEntry(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the name of a direct subclass of this class, if this class is `sealed`.
|
||||
*
|
||||
* @param name the name of a direct subclass
|
||||
*/
|
||||
open fun visitSealedSubclass(name: ClassName) {
|
||||
delegate?.visitSealedSubclass(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this class.
|
||||
*/
|
||||
open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
delegate?.visitVersionRequirement()
|
||||
|
||||
/**
|
||||
* Visits the end of the class.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit Kotlin package fragments, including single file facades and multi-file class parts.
|
||||
*
|
||||
* When using this class, [visitEnd] must be called exactly once and after calls to all other visit* methods.
|
||||
*/
|
||||
abstract class KmPackageVisitor @JvmOverloads constructor(delegate: KmPackageVisitor? = null) : KmDeclarationContainerVisitor(delegate) {
|
||||
override val delegate: KmPackageVisitor?
|
||||
get() = super.delegate as KmPackageVisitor?
|
||||
|
||||
/**
|
||||
* Visits the end of the package fragment.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit the metadata of a synthetic class generated for a Kotlin lambda.
|
||||
*
|
||||
* When using this class, [visitFunction] must be called first, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmLambdaVisitor @JvmOverloads constructor(private val delegate: KmLambdaVisitor? = null) {
|
||||
/**
|
||||
* Visits the signature of a synthetic anonymous function, representing the lambda.
|
||||
*
|
||||
* @param flags function flags, consisting of [Flags.HAS_ANNOTATIONS], visibility flag, modality flag and [Flags.Function] flags
|
||||
* @param name the name of the function (usually `"<anonymous>"` or `"<no name provided>"` for lambdas emitted by the Kotlin compiler)
|
||||
*/
|
||||
open fun visitFunction(flags: Int, name: String): KmFunctionVisitor? =
|
||||
delegate?.visitFunction(flags, name)
|
||||
|
||||
/**
|
||||
* Visits the end of the lambda.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a constructor of a Kotlin class.
|
||||
*
|
||||
* When using this class, [visitEnd] must be called exactly once and after calls to all other visit* methods.
|
||||
*/
|
||||
abstract class KmConstructorVisitor @JvmOverloads constructor(private val delegate: KmConstructorVisitor? = null) {
|
||||
/**
|
||||
* Visits a value parameter of the constructor.
|
||||
*
|
||||
* @param flags value parameter flags, consisting of [Flags.ValueParameter] flags
|
||||
* @param name the name of the value parameter
|
||||
*/
|
||||
open fun visitValueParameter(flags: Int, name: String): KmValueParameterVisitor? =
|
||||
delegate?.visitValueParameter(flags, name)
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this constructor.
|
||||
*/
|
||||
open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
delegate?.visitVersionRequirement()
|
||||
|
||||
/**
|
||||
* Visits the extensions of the given type on the constructor.
|
||||
*
|
||||
* @param type the type of extension visitor to be returned
|
||||
*/
|
||||
open fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor? =
|
||||
delegate?.visitExtensions(type)
|
||||
|
||||
/**
|
||||
* Visits the end of the constructor.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a Kotlin function declaration.
|
||||
*
|
||||
* When using this class, zero or more calls to [visitTypeParameter] must be done first, followed by zero or more calls
|
||||
* to other visit* methods, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmFunctionVisitor @JvmOverloads constructor(private val delegate: KmFunctionVisitor? = null) {
|
||||
/**
|
||||
* Visits a type parameter of the function.
|
||||
*
|
||||
* @param flags type parameter flags, consisting of [Flags.TypeParameter] flags
|
||||
* @param name the name of the type parameter
|
||||
* @param id the id of the type parameter, useful to be able to uniquely identify the type parameter in different contexts where
|
||||
* the name isn't enough (e.g. `class A<T> { fun <T> foo(t: T) }`)
|
||||
* @param variance the declaration-site variance of the type parameter
|
||||
*/
|
||||
open fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||
delegate?.visitTypeParameter(flags, name, id, variance)
|
||||
|
||||
/**
|
||||
* Visits the type of the receiver of the function, if this is an extension function.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitReceiverParameterType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitReceiverParameterType(flags)
|
||||
|
||||
/**
|
||||
* Visits a value parameter of the function.
|
||||
*
|
||||
* @param flags value parameter flags, consisting of [Flags.ValueParameter] flags
|
||||
* @param name the name of the value parameter
|
||||
*/
|
||||
open fun visitValueParameter(flags: Int, name: String): KmValueParameterVisitor? =
|
||||
delegate?.visitValueParameter(flags, name)
|
||||
|
||||
/**
|
||||
* Visits the return type of the function.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitReturnType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitReturnType(flags)
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this function.
|
||||
*/
|
||||
open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
delegate?.visitVersionRequirement()
|
||||
|
||||
/**
|
||||
* Visits the contract of the function.
|
||||
*/
|
||||
open fun visitContract(): KmContractVisitor? =
|
||||
delegate?.visitContract()
|
||||
|
||||
/**
|
||||
* Visits the extensions of the given type on the function.
|
||||
*
|
||||
* @param type the type of extension visitor to be returned
|
||||
*/
|
||||
open fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor? =
|
||||
delegate?.visitExtensions(type)
|
||||
|
||||
/**
|
||||
* Visits the end of the function.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a Kotlin property declaration.
|
||||
*
|
||||
* When using this class, zero or more calls to [visitTypeParameter] must be done first, followed by zero or more calls
|
||||
* to other visit* methods, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmPropertyVisitor @JvmOverloads constructor(private val delegate: KmPropertyVisitor? = null) {
|
||||
/**
|
||||
* Visits a type parameter of the property.
|
||||
*
|
||||
* @param flags type parameter flags, consisting of [Flags.TypeParameter] flags
|
||||
* @param name the name of the type parameter
|
||||
* @param id the id of the type parameter, useful to be able to uniquely identify the type parameter in different contexts where
|
||||
* the name isn't enough (e.g. `class A<T> { fun <T> foo(t: T) }`)
|
||||
* @param variance the declaration-site variance of the type parameter
|
||||
*/
|
||||
open fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||
delegate?.visitTypeParameter(flags, name, id, variance)
|
||||
|
||||
/**
|
||||
* Visits the type of the receiver of the property, if this is an extension property.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitReceiverParameterType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitReceiverParameterType(flags)
|
||||
|
||||
/**
|
||||
* Visits a value parameter of the setter of this property, if this is a `var` property.
|
||||
*
|
||||
* @param flags value parameter flags, consisting of [Flags.ValueParameter] flags
|
||||
* @param name the name of the value parameter (`"<set-?>"` for properties emitted by the Kotlin compiler)
|
||||
*/
|
||||
open fun visitSetterParameter(flags: Int, name: String): KmValueParameterVisitor? =
|
||||
delegate?.visitSetterParameter(flags, name)
|
||||
|
||||
/**
|
||||
* Visits the type of the property.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitReturnType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitReturnType(flags)
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this property.
|
||||
*/
|
||||
open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
delegate?.visitVersionRequirement()
|
||||
|
||||
/**
|
||||
* Visits the extensions of the given type on the property.
|
||||
*
|
||||
* @param type the type of extension visitor to be returned
|
||||
*/
|
||||
open fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor? =
|
||||
delegate?.visitExtensions(type)
|
||||
|
||||
/**
|
||||
* Visits the end of the property.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a Kotlin type alias declaration.
|
||||
*
|
||||
* When using this class, zero or more calls to [visitTypeParameter] must be done first, followed by zero or more calls
|
||||
* to other visit* methods, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmTypeAliasVisitor @JvmOverloads constructor(private val delegate: KmTypeAliasVisitor? = null) {
|
||||
/**
|
||||
* Visits a type parameter of the type alias.
|
||||
*
|
||||
* @param flags type parameter flags, consisting of [Flags.TypeParameter] flags
|
||||
* @param name the name of the type parameter
|
||||
* @param id the id of the type parameter, useful to be able to uniquely identify the type parameter in different contexts where
|
||||
* the name isn't enough (e.g. `class A<T> { fun <T> foo(t: T) }`)
|
||||
* @param variance the declaration-site variance of the type parameter
|
||||
*/
|
||||
open fun visitTypeParameter(flags: Int, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor? =
|
||||
delegate?.visitTypeParameter(flags, name, id, variance)
|
||||
|
||||
/**
|
||||
* Visits the underlying type of the type alias, i.e. the type in the right-hand side of the type alias declaration.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitUnderlyingType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitUnderlyingType(flags)
|
||||
|
||||
/**
|
||||
* Visits the expanded type of the type alias, i.e. the full expansion of the underlying type, where all type aliases are substituted
|
||||
* with their expanded types. If not type aliases are used in the underlying type, expanded type is equal to the underlying type.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitExpandedType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitExpandedType(flags)
|
||||
|
||||
/**
|
||||
* Visits the annotation on the type alias.
|
||||
*
|
||||
* @param annotation annotation on the type alias
|
||||
*/
|
||||
open fun visitAnnotation(annotation: KmAnnotation) {
|
||||
delegate?.visitAnnotation(annotation)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the version requirement on this type alias.
|
||||
*/
|
||||
open fun visitVersionRequirement(): KmVersionRequirementVisitor? =
|
||||
delegate?.visitVersionRequirement()
|
||||
|
||||
/**
|
||||
* Visits the end of the type alias.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a value parameter of a Kotlin constructor, function or property setter.
|
||||
*
|
||||
* When using this class, either [visitType] or [visitVarargElementType] must be called first (depending on whether the value parameter
|
||||
* is `vararg` or not), followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmValueParameterVisitor @JvmOverloads constructor(private val delegate: KmValueParameterVisitor? = null) {
|
||||
/**
|
||||
* Visits the type of the value parameter, if this is **not** a `vararg` parameter.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitType(flags)
|
||||
|
||||
/**
|
||||
* Visits the type of the value parameter, if this is a `vararg` parameter.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitVarargElementType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitVarargElementType(flags)
|
||||
|
||||
/**
|
||||
* Visits the end of the value parameter.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a type parameter of a Kotlin class, function or property.
|
||||
*
|
||||
* When using this class, zero or more [visitUpperBound] calls must be done first, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmTypeParameterVisitor @JvmOverloads constructor(private val delegate: KmTypeParameterVisitor? = null) {
|
||||
/**
|
||||
* Visits the upper bound of the type parameter.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitUpperBound(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitUpperBound(flags)
|
||||
|
||||
/**
|
||||
* Visits the extensions of the given type on the type parameter.
|
||||
*
|
||||
* @param type the type of extension visitor to be returned
|
||||
*/
|
||||
open fun visitExtensions(type: KmExtensionType): KmTypeParameterExtensionVisitor? =
|
||||
delegate?.visitExtensions(type)
|
||||
|
||||
/**
|
||||
* Visits the end of the type parameter.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit a type. The type must have a classifier which is one of: a class [visitClass], type parameter [visitTypeParameter]
|
||||
* or type alias [visitTypeAlias]. If the type's classifier is a class or a type alias, it can have type arguments ([visitArgument] and
|
||||
* [visitStarProjection]). If the type's classifier is an inner class, it can have the outer type ([visitOuterType]), which captures
|
||||
* the generic type arguments of the outer class. Also, each type can have an abbreviation ([visitAbbreviatedType]) in case a type alias
|
||||
* was used originally at this site in the declaration (all types are expanded by default for metadata produced by the Kotlin compiler).
|
||||
* If [visitFlexibleTypeUpperBound] is called, this type is regarded as a flexible type, and its contents represent the lower bound,
|
||||
* and the result of the call represents the upper bound.
|
||||
*
|
||||
* When using this class, [visitEnd] must be called exactly once and after calls to all other visit* methods.
|
||||
*/
|
||||
abstract class KmTypeVisitor @JvmOverloads constructor(private val delegate: KmTypeVisitor? = null) {
|
||||
/**
|
||||
* Visits the name of the class, if this type's classifier is a class.
|
||||
*
|
||||
* @param name the name of the class
|
||||
*/
|
||||
open fun visitClass(name: ClassName) {
|
||||
delegate?.visitClass(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the name of the type alias, if this type's classifier is a type alias. Note that all types are expanded for metadata produced
|
||||
* by the Kotlin compiler, so the the type with a type alias classifier may only appear in a call to [visitAbbreviatedType].
|
||||
*
|
||||
* @param name the name of the type alias
|
||||
*/
|
||||
open fun visitTypeAlias(name: ClassName) {
|
||||
delegate?.visitTypeAlias(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the id of the type parameter, if this type's classifier is a type parameter.
|
||||
*
|
||||
* @param id id of the type parameter
|
||||
*/
|
||||
open fun visitTypeParameter(id: Int) {
|
||||
delegate?.visitTypeParameter(id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the type projection used in a type argument of the type based on a class or on a type alias.
|
||||
* For example, in `MutableMap<in String?, *>`, `in String?` is the type projection which is the first type argument of the type.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
* @param variance the variance of the type projection
|
||||
*/
|
||||
open fun visitArgument(flags: Int, variance: KmVariance): KmTypeVisitor? =
|
||||
delegate?.visitArgument(flags, variance)
|
||||
|
||||
/**
|
||||
* Visits the star (`*`) projection used in a type argument of the type based on a class or on a type alias.
|
||||
* For example, in `MutableMap<in String?, *>`, `*` is the star projection which is the second type argument of the type.
|
||||
*/
|
||||
open fun visitStarProjection() {
|
||||
delegate?.visitStarProjection()
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the abbreviation of this type. Note that all types are expanded for metadata produced by the Kotlin compiler. For example:
|
||||
*
|
||||
* typealias A<T> = MutableList<T>
|
||||
*
|
||||
* fun foo(a: A<Any>) {}
|
||||
*
|
||||
* The type of the `foo`'s parameter in the metadata is actually `MutableList<Any>`, and its abbreviation is `A<Any>`.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitAbbreviatedType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitAbbreviatedType(flags)
|
||||
|
||||
/**
|
||||
* Visits the outer type, if this type's classifier is an inner class. For example:
|
||||
*
|
||||
* class A<T> { inner class B<U> }
|
||||
*
|
||||
* fun foo(a: A<*>.B<Byte?>) {}
|
||||
*
|
||||
* The type of the `foo`'s parameter in the metadata is `B<Byte>` (a type whose classifier is class `B`, and it has one type argument,
|
||||
* type `Byte?`), and its outer type is `A<*>` (a type whose classifier is class `A`, and it has one type argument, star projection).
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitOuterType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitOuterType(flags)
|
||||
|
||||
/**
|
||||
* Visits the upper bound of the type, marking it as flexible and its contents as the lower bound. Flexible types in Kotlin include
|
||||
* platform types in Kotlin/JVM and `dynamic` type in Kotlin/JS.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
* @param typeFlexibilityId id of the kind of flexibility this type has. For example, "kotlin.jvm.PlatformType" for JVM platform types,
|
||||
* or "kotlin.DynamicType" for JS dynamic type
|
||||
*/
|
||||
open fun visitFlexibleTypeUpperBound(flags: Int, typeFlexibilityId: String?): KmTypeVisitor? =
|
||||
delegate?.visitFlexibleTypeUpperBound(flags, typeFlexibilityId)
|
||||
|
||||
/**
|
||||
* Visits the extensions of the given type on the type.
|
||||
*
|
||||
* @param type the type of extension visitor to be returned
|
||||
*/
|
||||
open fun visitExtensions(type: KmExtensionType): KmTypeExtensionVisitor? =
|
||||
delegate?.visitExtensions(type)
|
||||
|
||||
/**
|
||||
* Visits the end of the type.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit the contents of a version requirement on a Kotlin declaration.
|
||||
*
|
||||
* Version requirement is an internal feature of the Kotlin compiler and the standard Kotlin library,
|
||||
* enabled for example with the internal [kotlin.internal.RequireKotlin] annotation.
|
||||
*
|
||||
* When using this class, [visit] must be called first, followed by [visitVersion], followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmVersionRequirementVisitor @JvmOverloads constructor(private val delegate: KmVersionRequirementVisitor? = null) {
|
||||
/**
|
||||
* Visits the description of this version requirement.
|
||||
*
|
||||
* @param kind the kind of the version that this declaration requires: compiler, language or API version
|
||||
* @param level the level of the diagnostic that must be reported on the usages of the declaration in case
|
||||
* the version requirement is not satisfied
|
||||
* @param errorCode optional error code to be displayed in the diagnostic
|
||||
* @param message optional message to be displayed in the diagnostic
|
||||
*/
|
||||
open fun visit(kind: KmVersionRequirementVersionKind, level: KmVersionRequirementLevel, errorCode: Int?, message: String?) {
|
||||
delegate?.visit(kind, level, errorCode, message)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the version required by this requirement.
|
||||
*
|
||||
* @param major the major component of the version (e.g. "1" in "1.2.3")
|
||||
* @param minor the minor component of the version (e.g. "2" in "1.2.3")
|
||||
* @param patch the patch component of the version (e.g. "3" in "1.2.3")
|
||||
*/
|
||||
open fun visitVersion(major: Int, minor: Int, patch: Int) {
|
||||
delegate?.visitVersion(major, minor, patch)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the end of the version requirement.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit the contents of the contract of a Kotlin function.
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*
|
||||
* When using this class, zero or more calls to [visitEffect] must be done first, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmContractVisitor @JvmOverloads constructor(private val delegate: KmContractVisitor? = null) {
|
||||
/**
|
||||
* Visits an effect of this contract.
|
||||
*
|
||||
* @param type type of the effect
|
||||
* @param invocationKind optional number of invocations of the lambda parameter of this function,
|
||||
* specified further in the effect expression
|
||||
*/
|
||||
open fun visitEffect(type: KmEffectType, invocationKind: KmEffectInvocationKind?): KmEffectVisitor? =
|
||||
delegate?.visitEffect(type, invocationKind)
|
||||
|
||||
/**
|
||||
* Visits the end of the contract.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit an effect (a part of the contract of a Kotlin function).
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*
|
||||
* When using this class, zero or more calls to [visitConstructorArgument] or [visitConclusionOfConditionalEffect] must be done first,
|
||||
* followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmEffectVisitor @JvmOverloads constructor(private val delegate: KmEffectVisitor? = null) {
|
||||
/**
|
||||
* Visits the optional argument of the effect constructor, i.e. the constant value for the [KmEffectType.RETURNS_CONSTANT] effect,
|
||||
* or the parameter reference for the [KmEffectType.CALLS] effect.
|
||||
*/
|
||||
open fun visitConstructorArgument(): KmEffectExpressionVisitor? =
|
||||
delegate?.visitConstructorArgument()
|
||||
|
||||
/**
|
||||
* Visits the optional conclusion of the effect. If this method is called, the effect represents an implication with the
|
||||
* right-hand side handled by the returned visitor.
|
||||
*/
|
||||
open fun visitConclusionOfConditionalEffect(): KmEffectExpressionVisitor? =
|
||||
delegate?.visitConclusionOfConditionalEffect()
|
||||
|
||||
/**
|
||||
* Visits the end of the effect.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A visitor to visit the effect expression, the contents of an effect (a part of the contract of a Kotlin function).
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*
|
||||
* When using this class, [visit] must be called first, followed by zero or more calls to other visit* methods, followed by [visitEnd].
|
||||
*/
|
||||
abstract class KmEffectExpressionVisitor @JvmOverloads constructor(private val delegate: KmEffectExpressionVisitor? = null) {
|
||||
/**
|
||||
* Visits the basic information of the effect expression.
|
||||
*
|
||||
* @param flags effect expression flags, consisting of [Flags.EffectExpression] flags
|
||||
* @param parameterIndex optional 1-based index of the value parameter of the function, for effects which assert something about
|
||||
* the function parameters. The index 0 means the extension receiver parameter
|
||||
*/
|
||||
open fun visit(flags: Int, parameterIndex: Int?) {
|
||||
delegate?.visit(flags, parameterIndex)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the constant value used in the effect expression. May be `true`, `false` or `null`.
|
||||
*
|
||||
* @param value the constant value
|
||||
*/
|
||||
open fun visitConstantValue(value: Any?) {
|
||||
delegate?.visitConstantValue(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits the type used as the target of an `is`-expression in the effect expression.
|
||||
*
|
||||
* @param flags type flags, consisting of [Flags.Type] flags
|
||||
*/
|
||||
open fun visitIsInstanceType(flags: Int): KmTypeVisitor? =
|
||||
delegate?.visitIsInstanceType(flags)
|
||||
|
||||
/**
|
||||
* Visits the argument of an `&&`-expression. If this method is called, the expression represents the left-hand side and
|
||||
* the returned visitor handles the right-hand side.
|
||||
*/
|
||||
open fun visitAndArgument(): KmEffectExpressionVisitor? =
|
||||
delegate?.visitAndArgument()
|
||||
|
||||
/**
|
||||
* Visits the argument of an `||`-expression. If this method is called, the expression represents the left-hand side and
|
||||
* the returned visitor handles the right-hand side.
|
||||
*/
|
||||
open fun visitOrArgument(): KmEffectExpressionVisitor? =
|
||||
delegate?.visitOrArgument()
|
||||
|
||||
/**
|
||||
* Visits the end of the effect expression.
|
||||
*/
|
||||
open fun visitEnd() {
|
||||
delegate?.visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Variance applied to a type parameter on the declaration site (*declaration-site variance*),
|
||||
* or to a type in a projection (*use-site variance*).
|
||||
*/
|
||||
enum class KmVariance {
|
||||
/**
|
||||
* The affected type parameter or type is *invariant*, which means it has no variance applied to it.
|
||||
*/
|
||||
INVARIANT,
|
||||
|
||||
/**
|
||||
* The affected type parameter or type is *contravariant*. Denoted by the `in` modifier in the source code.
|
||||
*/
|
||||
IN,
|
||||
|
||||
/**
|
||||
* The affected type parameter or type is *covariant*. Denoted by the `out` modifier in the source code.
|
||||
*/
|
||||
OUT,
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of an effect (a part of the contract of a Kotlin function).
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*/
|
||||
enum class KmEffectType {
|
||||
RETURNS_CONSTANT,
|
||||
CALLS,
|
||||
RETURNS_NOT_NULL,
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of invocations of a lambda parameter specified by an effect (a part of the contract of a Kotlin function).
|
||||
*
|
||||
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
|
||||
* may change in a subsequent release.
|
||||
*/
|
||||
enum class KmEffectInvocationKind {
|
||||
AT_MOST_ONCE,
|
||||
EXACTLY_ONCE,
|
||||
AT_LEAST_ONCE,
|
||||
}
|
||||
|
||||
/**
|
||||
* Severity of the diagnostic reported by the compiler when a version requirement is not satisfied.
|
||||
*/
|
||||
enum class KmVersionRequirementLevel {
|
||||
WARNING,
|
||||
ERROR,
|
||||
HIDDEN,
|
||||
}
|
||||
|
||||
/**
|
||||
* The kind of the version that is required by a version requirement.
|
||||
*/
|
||||
enum class KmVersionRequirementVersionKind {
|
||||
LANGUAGE_VERSION,
|
||||
COMPILER_VERSION,
|
||||
API_VERSION,
|
||||
}
|
||||
@@ -113,6 +113,8 @@ include ":kotlin-build-common",
|
||||
":kotlin-stdlib-jdk8",
|
||||
":kotlin-stdlib:samples",
|
||||
":kotlin-stdlib:jvm-minimal-for-test",
|
||||
":kotlinx-metadata",
|
||||
":kotlinx-metadata-jvm",
|
||||
":prepare:build.version",
|
||||
":kotlin-build-common",
|
||||
":prepare:formatter",
|
||||
@@ -204,6 +206,8 @@ project(':kotlin-stdlib:samples').projectDir = "$rootDir/libraries/stdlib/sample
|
||||
project(":kotlin-stdlib:jvm-minimal-for-test").projectDir = "$rootDir/libraries/stdlib/jvm-minimal-for-test" as File
|
||||
project(':kotlin-reflect').projectDir = "$rootDir/libraries/reflect" 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-jvm').projectDir = "$rootDir/libraries/kotlinx-metadata/jvm" 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-client-embeddable').projectDir = "$rootDir/prepare/compiler-client-embeddable" as File
|
||||
|
||||
Reference in New Issue
Block a user