Add kdoc for new API of kotlinx-metadata-jvm

#KT-26602
This commit is contained in:
Alexander Udalov
2019-06-11 19:19:43 +02:00
parent 980b7ace40
commit 18a4247226
7 changed files with 571 additions and 10 deletions
@@ -1,5 +1,9 @@
# kotlinx-metadata-jvm
## 0.1.0
- [`KT-26602`](https://youtrack.jetbrains.com/issue/KT-26602) Provide a value-based API
## 0.0.6
- [`KT-31308`](https://youtrack.jetbrains.com/issue/KT-31308) Add module name extensions to kotlinx-metadata-jvm
@@ -4,6 +4,7 @@
*/
package kotlinx.metadata.jvm
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMemberSignature as JvmMemberSignatureImpl
/**
@@ -30,7 +31,9 @@ sealed class JvmMemberSignature {
}
/**
* A signature of a JVM method.
* A signature of a JVM method in the JVM-based format.
*
* Example: `JvmMethodSignature("equals", "(Ljava/lang/Object;)Z")`.
*
* @see JvmMemberSignature
*/
@@ -39,14 +42,16 @@ data class JvmMethodSignature(override val name: String, override val desc: Stri
}
/**
* A signature of a JVM field.
* A signature of a JVM field in the JVM-based format.
*
* Example: `JvmFieldSignature("value", "Ljava/lang/String;")`.
*
* @see JvmMemberSignature
*/
data class JvmFieldSignature(override val name: String, override val desc: String) : JvmMemberSignature() {
override fun asString() = name + ":" + desc
override fun asString() = "$name:$desc"
}
internal fun JvmMemberSignatureImpl.Method.wrapAsPublic() = JvmMethodSignature(name, desc)
internal fun JvmMemberSignatureImpl.Field.wrapAsPublic() = JvmFieldSignature(name, desc)
internal fun JvmMemberSignatureImpl.Field.wrapAsPublic() = JvmFieldSignature(name, desc)
@@ -157,8 +157,18 @@ abstract class KmModuleVisitor(private val delegate: KmModuleVisitor? = null) {
// TODO: JvmPackageName
}
/**
* Represents a Kotlin JVM module file.
*/
class KmModule : KmModuleVisitor() {
/**
* Table of all single- and multi-file facades declared in some package of this module, where keys are '.'-separated package names.
*/
val packageParts: MutableMap<String, KmPackageParts> = LinkedHashMap()
/**
* Annotations on the module.
*/
val annotations: MutableList<KmAnnotation> = ArrayList(0)
override fun visitPackageParts(fqName: String, fileFacades: List<String>, multiFileClassParts: Map<String, String>) {
@@ -169,6 +179,11 @@ class KmModule : KmModuleVisitor() {
annotations.add(annotation)
}
/**
* Populates the given visitor with data in this module.
*
* @param visitor the visitor which will visit data in this module.
*/
fun accept(visitor: KmModuleVisitor) {
for ((fqName, parts) in packageParts) {
visitor.visitPackageParts(fqName, parts.fileFacades, parts.multiFileClassParts)
@@ -177,6 +192,15 @@ class KmModule : KmModuleVisitor() {
}
}
/**
* Collection of all single- and multi-file facades in a package of some module.
*
* Packages are separated by '/' in the names of file facades.
*
* @property fileFacades the list of single-file facades in this package
* @property multiFileClassParts the map of multi-file classes where keys are names of multi-file class parts,
* and values are names of the corresponding multi-file facades
*/
class KmPackageParts(
val fileFacades: MutableList<String>,
val multiFileClassParts: MutableMap<String, String>
@@ -119,8 +119,7 @@ open class JvmFunctionExtensionVisitor @JvmOverloads constructor(
get() = TYPE
/**
* Visits the JVM signature of the function in the JVM-based format,
* or null if the JVM signature of this function is unknown.
* Visits the JVM signature of the function, or null if the JVM signature of this function is unknown.
*
* Example: `JvmMethodSignature("equals", "(Ljava/lang/Object;)Z")`
*
@@ -169,10 +168,10 @@ open class JvmPropertyExtensionVisitor @JvmOverloads constructor(
* Visits JVM signatures of field and accessors generated for the property.
*
* @param jvmFlags JVM-specific flags of the property, consisting of [JvmFlag.Property] flags
* @param fieldSignature the signature of the field, or `null` if this property has no field.
* @param fieldSignature the signature of the backing field of the property, or `null` if this property has no backing field.
* Example: `JvmFieldSignature("X", "Ljava/lang/Object;")`
* @param getterSignature the signature of the property getter, or `null` if this property has no getter or its signature is unknown.
* Example: `JvmMethodSignature("getX()", "Ljava/lang/Object;")`
* Example: `JvmMethodSignature("getX", "()Ljava/lang/Object;")`
* @param setterSignature the signature of the property setter, or `null` if this property has no setter or its signature is unknown.
* Example: `JvmMethodSignature("setX", "(Ljava/lang/Object;)V")`
*/
@@ -8,86 +8,160 @@ package kotlinx.metadata.jvm
import kotlinx.metadata.*
import kotlinx.metadata.jvm.impl.jvm
/**
* Metadata of local delegated properties used somewhere inside this class (but not in a nested class).
* Note that for classes produced by the Kotlin compiler, such properties will have default accessors.
*
* The order of local delegated properties in this list is important. The Kotlin compiler generates the corresponding property's index
* at the call site, so that reflection would be able to load the metadata of the property with that index at runtime.
* If an incorrect index is used, either the `KProperty<*>` object passed to delegate methods will point to the wrong property
* at runtime, or an exception will be thrown.
*/
val KmClass.localDelegatedProperties: MutableList<KmProperty>
get() = jvm.localDelegatedProperties
/**
* Name of the module where this class is declared.
*/
var KmClass.moduleName: String?
get() = jvm.moduleName
set(value) {
jvm.moduleName = value
}
/**
* JVM internal name of the original class this anonymous object is copied from. This value is set for anonymous objects
* copied from bodies of inline functions to the use site by the Kotlin compiler.
*/
var KmClass.anonymousObjectOriginName: String?
get() = jvm.anonymousObjectOriginName
set(value) {
jvm.anonymousObjectOriginName = value
}
/**
* Metadata of local delegated properties used somewhere inside this package fragment (but not in any class).
* Note that for classes produced by the Kotlin compiler, such properties will have default accessors.
*
* The order of local delegated properties in this list is important. The Kotlin compiler generates the corresponding property's index
* at the call site, so that reflection would be able to load the metadata of the property with that index at runtime.
* If an incorrect index is used, either the `KProperty<*>` object passed to delegate methods will point to the wrong property
* at runtime, or an exception will be thrown.
*/
val KmPackage.localDelegatedProperties: MutableList<KmProperty>
get() = jvm.localDelegatedProperties
/**
* Name of the module where this package fragment is declared.
*/
var KmPackage.moduleName: String?
get() = jvm.moduleName
set(value) {
jvm.moduleName = value
}
/**
* JVM signature of the function, or null if the JVM signature of this function is unknown.
*
* Example: `JvmMethodSignature("equals", "(Ljava/lang/Object;)Z")`.
*/
var KmFunction.signature: JvmMethodSignature?
get() = jvm.signature
set(value) {
jvm.signature = value
}
/**
* JVM internal name of the original class the lambda class for this function is copied from. This value is set for lambdas
* copied from bodies of inline functions to the use site by the Kotlin compiler.
*/
var KmFunction.lambdaClassOriginName: String?
get() = jvm.lambdaClassOriginName
set(value) {
jvm.lambdaClassOriginName = value
}
/**
* JVM-specific flags of the property, consisting of [JvmFlag.Property] flags.
*/
var KmProperty.jvmFlags: Flags
get() = jvm.jvmFlags
set(value) {
jvm.jvmFlags = value
}
/**
* JVM signature of the backing field of the property, or `null` if this property has no backing field.
*
* Example: `JvmFieldSignature("X", "Ljava/lang/Object;")`.
*/
var KmProperty.fieldSignature: JvmFieldSignature?
get() = jvm.fieldSignature
set(value) {
jvm.fieldSignature = value
}
/**
* JVM signature of the property getter, or `null` if this property has no getter or its signature is unknown.
*
* Example: `JvmMethodSignature("getX", "()Ljava/lang/Object;")`.
*/
var KmProperty.getterSignature: JvmMethodSignature?
get() = jvm.getterSignature
set(value) {
jvm.getterSignature = value
}
/**
* JVM signature of the property setter, or `null` if this property has no setter or its signature is unknown.
*
* Example: `JvmMethodSignature("setX", "(Ljava/lang/Object;)V")`.
*/
var KmProperty.setterSignature: JvmMethodSignature?
get() = jvm.setterSignature
set(value) {
jvm.setterSignature = value
}
/**
* JVM signature of a synthetic method which is generated to store annotations on a property in the bytecode.
*
* Example: `JvmMethodSignature("getX$annotations", "()V")`.
*/
var KmProperty.syntheticMethodForAnnotations: JvmMethodSignature?
get() = jvm.syntheticMethodForAnnotations
set(value) {
jvm.syntheticMethodForAnnotations = value
}
/**
* JVM signature of the constructor, or null if the JVM signature of this constructor is unknown.
*
* Example: `JvmMethodSignature("<init>", "(Ljava/lang/Object;)V")`.
*/
var KmConstructor.signature: JvmMethodSignature?
get() = jvm.signature
set(value) {
jvm.signature = value
}
/**
* Annotations on the type parameter.
*/
val KmTypeParameter.annotations: MutableList<KmAnnotation>
get() = jvm.annotations
/**
* `true` if the type is seen as a raw type in Java.
*/
var KmType.isRaw: Boolean
get() = jvm.isRaw
set(value) {
jvm.isRaw = value
}
/**
* Annotations on the type.
*/
val KmType.annotations: MutableList<KmAnnotation>
get() = jvm.annotations
@@ -9,25 +9,93 @@ package kotlinx.metadata
import kotlinx.metadata.impl.extensions.*
/**
* Represents a Kotlin declaration container, such as a class or a package fragment.
*/
interface KmDeclarationContainer {
/**
* Functions in the container.
*/
val functions: MutableList<KmFunction>
/**
* Properties in the container.
*/
val properties: MutableList<KmProperty>
/**
* Type aliases in the container.
*/
val typeAliases: MutableList<KmTypeAlias>
}
/**
* Represents a Kotlin class.
*/
class KmClass : KmClassVisitor(), KmDeclarationContainer {
/**
* Class flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag and [Flag.Class] flags.
*/
var flags: Flags = flagsOf()
/**
* Name of the class.
*/
lateinit var name: ClassName
/**
* Type parameters of the class.
*/
val typeParameters: MutableList<KmTypeParameter> = ArrayList(0)
/**
* Supertypes of the class.
*/
val supertypes: MutableList<KmType> = ArrayList(1)
/**
* Functions in the class.
*/
override val functions: MutableList<KmFunction> = ArrayList()
/**
* Properties in the class.
*/
override val properties: MutableList<KmProperty> = ArrayList()
/**
* Type aliases in the class.
*/
override val typeAliases: MutableList<KmTypeAlias> = ArrayList(0)
/**
* Constructors of the class.
*/
val constructors: MutableList<KmConstructor> = ArrayList(1)
/**
* Name of the companion object of this class, if it has one.
*/
var companionObject: String? = null
/**
* Names of nested classes of this class.
*/
val nestedClasses: MutableList<String> = ArrayList(0)
/**
* Names of enum entries, if this class is an enum class.
*/
val enumEntries: MutableList<String> = ArrayList(0)
/**
* Names of direct subclasses of this class, if this class is `sealed`.
*/
val sealedSubclasses: MutableList<ClassName> = ArrayList(0)
/**
* Version requirements on this class.
*/
val versionRequirements: MutableList<KmVersionRequirement> = ArrayList(0)
private val extensions: List<KmClassExtension> =
@@ -78,6 +146,11 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
override fun visitExtensions(type: KmExtensionType): KmClassExtensionVisitor =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this class.
*
* @param visitor the visitor which will visit data in this class
*/
fun accept(visitor: KmClassVisitor) {
visitor.visit(flags, name)
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
@@ -96,9 +169,23 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
}
}
/**
* Represents a Kotlin package fragment, including single file facades and multi-file class parts.
*/
class KmPackage : KmPackageVisitor(), KmDeclarationContainer {
/**
* Functions in the package fragment.
*/
override val functions: MutableList<KmFunction> = ArrayList()
/**
* Properties in the package fragment.
*/
override val properties: MutableList<KmProperty> = ArrayList()
/**
* Type aliases in the package fragment.
*/
override val typeAliases: MutableList<KmTypeAlias> = ArrayList(0)
private val extensions: List<KmPackageExtension> =
@@ -116,6 +203,11 @@ class KmPackage : KmPackageVisitor(), KmDeclarationContainer {
override fun visitExtensions(type: KmExtensionType): KmPackageExtensionVisitor =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this package fragment.
*
* @param visitor the visitor which will visit data in this package fragment
*/
fun accept(visitor: KmPackageVisitor) {
functions.forEach { visitor.visitFunction(it.flags, it.name)?.let(it::accept) }
properties.forEach { visitor.visitProperty(it.flags, it.name, it.getterFlags, it.setterFlags)?.let(it::accept) }
@@ -125,20 +217,43 @@ class KmPackage : KmPackageVisitor(), KmDeclarationContainer {
}
}
/**
* Represents a synthetic class generated for a Kotlin lambda.
*/
class KmLambda : KmLambdaVisitor() {
/**
* Signature of the synthetic anonymous function, representing the lambda.
*/
lateinit var function: KmFunction
override fun visitFunction(flags: Flags, name: String): KmFunctionVisitor =
KmFunction(flags, name).also { function = it }
/**
* Populates the given visitor with data in this lambda.
*
* @param visitor the visitor which will visit data in this lambda
*/
fun accept(visitor: KmLambdaVisitor) {
visitor.visitFunction(function.flags, function.name)?.let(function::accept)
visitor.visitEnd()
}
}
/**
* Represents a constructor of a Kotlin class.
*
* @property flags constructor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag and [Flag.Constructor] flags
*/
class KmConstructor(var flags: Flags) : KmConstructorVisitor() {
/**
* Value parameters of the constructor.
*/
val valueParameters: MutableList<KmValueParameter> = ArrayList()
/**
* Version requirements on the constructor.
*/
val versionRequirements: MutableList<KmVersionRequirement> = ArrayList(0)
private val extensions: List<KmConstructorExtension> =
@@ -153,6 +268,11 @@ class KmConstructor(var flags: Flags) : KmConstructorVisitor() {
override fun visitExtensions(type: KmExtensionType): KmConstructorExtensionVisitor =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this constructor.
*
* @param visitor the visitor which will visit data in this class
*/
fun accept(visitor: KmConstructorVisitor) {
valueParameters.forEach { visitor.visitValueParameter(it.flags, it.name)?.let(it::accept) }
versionRequirements.forEach { visitor.visitVersionRequirement()?.let(it::accept) }
@@ -161,15 +281,44 @@ class KmConstructor(var flags: Flags) : KmConstructorVisitor() {
}
}
/**
* Represents a Kotlin function declaration.
*
* @property flags function flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag and [Flag.Function] flags
* @property name the name of the function
*/
class KmFunction(
var flags: Flags,
var name: String
) : KmFunctionVisitor() {
/**
* Type parameters of the function.
*/
val typeParameters: MutableList<KmTypeParameter> = ArrayList(0)
/**
* Type of the receiver of the function, if this is an extension function.
*/
var receiverParameterType: KmType? = null
/**
* Value parameters of the function.
*/
val valueParameters: MutableList<KmValueParameter> = ArrayList()
/**
* Return type of the function.
*/
lateinit var returnType: KmType
/**
* Version requirements on the function.
*/
val versionRequirements: MutableList<KmVersionRequirement> = ArrayList(0)
/**
* Contract of the function.
*/
var contract: KmContract? = null
private val extensions: List<KmFunctionExtension> =
@@ -196,6 +345,11 @@ class KmFunction(
override fun visitExtensions(type: KmExtensionType): KmFunctionExtensionVisitor =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this function.
*
* @param visitor the visitor which will visit data in this function
*/
fun accept(visitor: KmFunctionVisitor) {
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
@@ -208,16 +362,45 @@ class KmFunction(
}
}
/**
* Represents a Kotlin property declaration.
*
* @property flags property flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag and [Flag.Property] flags
* @property name the name of the property
* @property getterFlags property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag
* and [Flag.PropertyAccessor] flags
* @property setterFlags property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag
* and [Flag.PropertyAccessor] flags
*/
class KmProperty(
var flags: Flags,
var name: String,
var getterFlags: Flags,
var setterFlags: Flags
) : KmPropertyVisitor() {
/**
* Type parameters of the property.
*/
val typeParameters: MutableList<KmTypeParameter> = ArrayList(0)
/**
* Type of the receiver of the property, if this is an extension property.
*/
var receiverParameterType: KmType? = null
/**
* Value parameter of the setter of this property, if this is a `var` property.
*/
var setterParameter: KmValueParameter? = null
/**
* Type of the property.
*/
lateinit var returnType: KmType
/**
* Version requirements on the property.
*/
val versionRequirements: MutableList<KmVersionRequirement> = ArrayList(0)
private val extensions: List<KmPropertyExtension> =
@@ -241,6 +424,11 @@ class KmProperty(
override fun visitExtensions(type: KmExtensionType): KmPropertyExtensionVisitor =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this property.
*
* @param visitor the visitor which will visit data in this property
*/
fun accept(visitor: KmPropertyVisitor) {
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
receiverParameterType?.let { visitor.visitReceiverParameterType(it.flags)?.let(it::accept) }
@@ -252,14 +440,40 @@ class KmProperty(
}
}
/**
* Represents a Kotlin type alias declaration.
*
* @property flags type alias flags, consisting of [Flag.HAS_ANNOTATIONS] and visibility flag
* @property name the name of the type alias
*/
class KmTypeAlias(
var flags: Flags,
var name: String
) : KmTypeAliasVisitor() {
/**
* Type parameters of the type alias.
*/
val typeParameters: MutableList<KmTypeParameter> = ArrayList(0)
/**
* Underlying type of the type alias, i.e. the type in the right-hand side of the type alias declaration.
*/
lateinit var underlyingType: KmType
/**
* 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 no type aliases are used in the underlying type, expanded type is equal to the underlying type.
*/
lateinit var expandedType: KmType
/**
* Annotations on the type alias.
*/
val annotations: MutableList<KmAnnotation> = ArrayList(0)
/**
* Version requirements on the type alias.
*/
val versionRequirements: MutableList<KmVersionRequirement> = ArrayList(0)
override fun visitTypeParameter(flags: Flags, name: String, id: Int, variance: KmVariance): KmTypeParameterVisitor =
@@ -278,6 +492,11 @@ class KmTypeAlias(
override fun visitVersionRequirement(): KmVersionRequirementVisitor =
KmVersionRequirement().addTo(versionRequirements)
/**
* Populates the given visitor with data in this type alias.
*
* @param visitor the visitor which will visit data in this type alias
*/
fun accept(visitor: KmTypeAliasVisitor) {
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
visitor.visitUnderlyingType(underlyingType.flags)?.let(underlyingType::accept)
@@ -288,11 +507,24 @@ class KmTypeAlias(
}
}
/**
* Represents a value parameter of a Kotlin constructor, function or property setter.
*
* @property flags value parameter flags, consisting of [Flag.ValueParameter] flags
* @property name the name of the value parameter
*/
class KmValueParameter(
var flags: Flags,
var name: String
) : KmValueParameterVisitor() {
/**
* Type of the value parameter, if this is **not** a `vararg` parameter.
*/
var type: KmType? = null
/**
* Type of the value parameter, if this is a `vararg` parameter.
*/
var varargElementType: KmType? = null
override fun visitType(flags: Flags): KmTypeVisitor =
@@ -301,6 +533,11 @@ class KmValueParameter(
override fun visitVarargElementType(flags: Flags): KmTypeVisitor =
KmType(flags).also { varargElementType = it }
/**
* Populates the given visitor with data in this value parameter.
*
* @param visitor the visitor which will visit data in this value parameter
*/
fun accept(visitor: KmValueParameterVisitor) {
type?.let { visitor.visitType(it.flags)?.let(it::accept) }
varargElementType?.let { visitor.visitVarargElementType(it.flags)?.let(it::accept) }
@@ -308,12 +545,24 @@ class KmValueParameter(
}
}
/**
* Represents a type parameter of a Kotlin class, function, property or type alias.
*
* @property flags type parameter flags, consisting of [Flag.TypeParameter] flags
* @property name the name of the type parameter
* @property 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) }`)
* @property variance the declaration-site variance of the type parameter
*/
class KmTypeParameter(
var flags: Flags,
var name: String,
var id: Int,
var variance: KmVariance
) : KmTypeParameterVisitor() {
/**
* Upper bounds of the type parameter.
*/
val upperBounds: MutableList<KmType> = ArrayList(1)
private val extensions: List<KmTypeParameterExtension> =
@@ -325,6 +574,11 @@ class KmTypeParameter(
override fun visitExtensions(type: KmExtensionType): KmTypeParameterExtensionVisitor? =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this type parameter.
*
* @param visitor the visitor which will visit data in this type parameter
*/
fun accept(visitor: KmTypeParameterVisitor) {
upperBounds.forEach { visitor.visitUpperBound(it.flags)?.let(it::accept) }
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
@@ -332,11 +586,50 @@ class KmTypeParameter(
}
}
/**
* Represents a type.
*
* @property flags type flags, consisting of [Flag.Type] flags
*/
class KmType(var flags: Flags) : KmTypeVisitor() {
/**
* Classifier of the type.
*/
lateinit var classifier: KmClassifier
/**
* Arguments of the type, if the type's classifier is a class or a type alias.
*/
val arguments: MutableList<KmTypeProjection> = ArrayList(0)
/**
* 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>`.
*/
var abbreviatedType: KmType? = null
/**
* Outer type of this 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).
*/
var outerType: KmType? = null
/**
* Upper bound of this type, if this type is flexible. In that case, all other data refers to the lower bound of the type.
*
* Flexible types in Kotlin include platform types in Kotlin/JVM and `dynamic` type in Kotlin/JS.
*/
var flexibleTypeUpperBound: KmFlexibleTypeUpperBound? = null
private val extensions: List<KmTypeExtension> =
@@ -373,6 +666,11 @@ class KmType(var flags: Flags) : KmTypeVisitor() {
override fun visitExtensions(type: KmExtensionType): KmTypeExtension =
extensions.singleOfType(type)
/**
* Populates the given visitor with data in this type.
*
* @param visitor the visitor which will visit data in this type
*/
fun accept(visitor: KmTypeVisitor) {
when (val classifier = classifier) {
is KmClassifier.Class -> visitor.visitClass(classifier.name)
@@ -396,11 +694,36 @@ class KmType(var flags: Flags) : KmTypeVisitor() {
}
}
/**
* Represents 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.
*/
class KmVersionRequirement : KmVersionRequirementVisitor() {
/**
* Kind of the version that this declaration requires.
*/
lateinit var kind: KmVersionRequirementVersionKind
/**
* Level of the diagnostic that must be reported on the usages of the declaration in case the version requirement is not satisfied.
*/
lateinit var level: KmVersionRequirementLevel
/**
* Optional error code to be displayed in the diagnostic.
*/
var errorCode: Int? = null
/**
* Optional message to be displayed in the diagnostic.
*/
var message: String? = null
/**
* Version required by this requirement.
*/
lateinit var version: KmVersion
override fun visit(kind: KmVersionRequirementVersionKind, level: KmVersionRequirementLevel, errorCode: Int?, message: String?) {
@@ -414,6 +737,11 @@ class KmVersionRequirement : KmVersionRequirementVisitor() {
this.version = KmVersion(major, minor, patch)
}
/**
* Populates the given visitor with data in this version requirement.
*
* @param visitor the visitor which will visit data in this version requirement
*/
fun accept(visitor: KmVersionRequirementVisitor) {
visitor.visit(kind, level, errorCode, message)
visitor.visitVersion(version.major, version.minor, version.patch)
@@ -421,23 +749,55 @@ class KmVersionRequirement : KmVersionRequirementVisitor() {
}
}
/**
* Represents a 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.
*/
class KmContract : KmContractVisitor() {
/**
* Effects of this contract.
*/
val effects: MutableList<KmEffect> = ArrayList(1)
override fun visitEffect(type: KmEffectType, invocationKind: KmEffectInvocationKind?): KmEffectVisitor =
KmEffect(type, invocationKind).addTo(effects)
/**
* Populates the given visitor with data in this contract.
*
* @param visitor the visitor which will visit data in this contract
*/
fun accept(visitor: KmContractVisitor) {
effects.forEach { visitor.visitEffect(it.type, it.invocationKind)?.let(it::accept) }
visitor.visitEnd()
}
}
/**
* Represents 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.
*
* @property type type of the effect
* @property invocationKind optional number of invocations of the lambda parameter of this function,
* specified further in the effect expression
*/
class KmEffect(
var type: KmEffectType,
var invocationKind: KmEffectInvocationKind?
) : KmEffectVisitor() {
/**
* Arguments of the effect constructor, i.e. the constant value for the [KmEffectType.RETURNS_CONSTANT] effect,
* or the parameter reference for the [KmEffectType.CALLS] effect.
*/
val constructorArguments: MutableList<KmEffectExpression> = ArrayList(1)
/**
* Conclusion of the effect. If this value is set, the effect represents an implication with this value as the right-hand side.
*/
var conclusion: KmEffectExpression? = null
override fun visitConstructorArgument(): KmEffectExpressionVisitor =
@@ -446,6 +806,11 @@ class KmEffect(
override fun visitConclusionOfConditionalEffect(): KmEffectExpressionVisitor =
KmEffectExpression().also { conclusion = it }
/**
* Populates the given visitor with data in this effect.
*
* @param visitor the visitor which will visit data in this effect
*/
fun accept(visitor: KmEffectVisitor) {
constructorArguments.forEach { visitor.visitConstructorArgument()?.let(it::accept) }
conclusion?.let { visitor.visitConclusionOfConditionalEffect()?.let(it::accept) }
@@ -453,12 +818,44 @@ class KmEffect(
}
}
/**
* Represents an 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.
*/
class KmEffectExpression : KmEffectExpressionVisitor() {
/**
* Effect expression flags, consisting of [Flag.EffectExpression] flags.
*/
var flags: Flags = flagsOf()
/**
* 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.
*/
var parameterIndex: Int? = null
/**
* Constant value used in the effect expression.
*/
var constantValue: KmConstantValue? = null
/**
* Type used as the target of an `is`-expression in the effect expression.
*/
var isInstanceType: KmType? = null
/**
* Arguments of an `&&`-expression. If this list is non-empty, the resulting effect expression is a conjunction of this expression
* and elements of the list.
*/
val andArguments: MutableList<KmEffectExpression> = ArrayList(0)
/**
* Arguments of an `||`-expression. If this list is non-empty, the resulting effect expression is a disjunction of this expression
* and elements of the list.
*/
val orArguments: MutableList<KmEffectExpression> = ArrayList(0)
override fun visit(flags: Flags, parameterIndex: Int?) {
@@ -479,6 +876,11 @@ class KmEffectExpression : KmEffectExpressionVisitor() {
override fun visitOrArgument(): KmEffectExpressionVisitor =
KmEffectExpression().addTo(orArguments)
/**
* Populates the given visitor with data in this effect expression.
*
* @param visitor the visitor which will visit data in this effect expression
*/
fun accept(visitor: KmEffectExpressionVisitor) {
visitor.visit(flags, parameterIndex)
constantValue?.let { visitor.visitConstantValue(it.value) }
@@ -489,27 +891,80 @@ class KmEffectExpression : KmEffectExpressionVisitor() {
}
}
/**
* Represents a classifier of a Kotlin type. A classifier is a class, type parameter or type alias.
* For example, in `MutableMap<in String?, *>`, `MutableMap` is the classifier.
*/
sealed class KmClassifier {
/**
* Represents a class used as a classifier in a type.
*
* @property name the name of the class
*/
data class Class(val name: ClassName) : KmClassifier()
/**
* Represents a type parameter used as a classifier in a type.
*
* @property id id of the type parameter
*/
data class TypeParameter(val id: Int) : KmClassifier()
/**
* Represents a type alias used as a classifier in a type. Note that all types are expanded for metadata produced
* by the Kotlin compiler, so the type with a type alias classifier may only appear in [KmType.abbreviatedType].
*
* @property name the name of the type alias
*/
data class TypeAlias(val name: ClassName) : KmClassifier()
}
/**
* Represents 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.
*
* @property variance the variance of the type projection, or `null` if this is a star projection
* @property type the projected type, or `null` if this is a star projection
*/
data class KmTypeProjection(var variance: KmVariance?, var type: KmType?) {
companion object {
/**
* Star projection (`*`).
* For example, in `MutableMap<in String?, *>`, `*` is the star projection which is the second type argument of the type.
*/
@JvmField
val STAR = KmTypeProjection(null, null)
}
}
/**
* Represents an upper bound of a flexible Kotlin type.
*
* @property type upper bound of the flexible type
* @property 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
*/
data class KmFlexibleTypeUpperBound(var type: KmType, var typeFlexibilityId: String?)
/**
* Represents a version used in a version requirement.
*
* @property major the major component of the version (e.g. "1" in "1.2.3")
* @property minor the minor component of the version (e.g. "2" in "1.2.3")
* @property patch the patch component of the version (e.g. "3" in "1.2.3")
*/
data class KmVersion(val major: Int, val minor: Int, val patch: Int) {
override fun toString(): String = "$major.$minor.$patch"
}
/**
* Represents a constant value used in an effect expression.
*
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
* may change in a subsequent release.
*
* @property value the constant value. May be `true`, `false` or `null`
*/
data class KmConstantValue(val value: Any?)
internal fun <T> T.addTo(collection: MutableCollection<T>): T {
@@ -406,7 +406,7 @@ abstract class KmTypeAliasVisitor @JvmOverloads constructor(private val delegate
/**
* 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.
* with their expanded types. If no type aliases are used in the underlying type, expanded type is equal to the underlying type.
*
* @param flags type flags, consisting of [Flag.Type] flags
*/
@@ -468,7 +468,7 @@ abstract class KmValueParameterVisitor @JvmOverloads constructor(private val del
}
/**
* A visitor to visit a type parameter of a Kotlin class, function or property.
* A visitor to visit a type parameter of a Kotlin class, function, property or type alias.
*
* When using this class, zero or more [visitUpperBound] calls must be done first, followed by [visitEnd].
*/