Rework flags in kotlinx.metadata:

Introduce extensions for KmNodes to work with various modifiers instead of old Flags.SOMETHING.invoke(flags).
Provide Visibility, Modality, and Kind enums.
Introduce KmPropertyAccessorAttributes to replace KmProperty.getterFlags and KmProperty.setterFlags.
Deprecate nodes constructors which take flags but not flags itself (yet).
Adapt KotlinP to changes.

#KT-59440 Fixed
This commit is contained in:
Leonid Startsev
2023-03-24 20:50:57 +01:00
committed by Space Team
parent ecc1f9fb0b
commit 1a1cbcb321
17 changed files with 1344 additions and 207 deletions
@@ -140,7 +140,8 @@ internal class ModuleMetadataEmitter(
override fun visitTypealias(element: TypealiasStub, data: VisitingContext): KmTypeAlias =
data.withMappingExtensions {
KmTypeAlias(element.flags, element.alias.topLevelName).also { km ->
KmTypeAlias(element.alias.topLevelName).also { km ->
km.flags = element.flags
km.underlyingType = element.aliasee.map(shouldExpandTypeAliases = false)
km.expandedType = element.aliasee.map()
}
@@ -156,7 +157,8 @@ internal class ModuleMetadataEmitter(
annotations = listOf(AnnotationStub.Deprecated.unableToImport)
)
}
KmFunction(function.flags, function.name).also { km ->
KmFunction(function.name).also { km ->
km.flags = function.flags
km.receiverParameterType = function.receiver?.type?.map()
function.typeParameters.mapTo(km.typeParameters) { it.map() }
function.parameters.mapTo(km.valueParameters) { it.map() }
@@ -176,7 +178,10 @@ internal class ModuleMetadataEmitter(
else -> element.copy(kind = bridgeSupportedKind)
}
val name = getPropertyNameInScope(property, data.container)
KmProperty(property.flags, name, property.getterFlags, property.setterFlags).also { km ->
KmProperty(name).also { km ->
km.flags = property.flags
km.getterFlags = property.getterFlags
km.setterFlags = property.setterFlags
property.annotations.mapTo(km.annotations) { it.map() }
km.receiverParameterType = property.receiverType?.map()
km.returnType = property.type.map()
@@ -199,7 +204,8 @@ internal class ModuleMetadataEmitter(
override fun visitConstructor(constructorStub: ConstructorStub, data: VisitingContext) =
data.withMappingExtensions {
KmConstructor(constructorStub.flags).apply {
KmConstructor().apply {
flags = constructorStub.flags
constructorStub.parameters.mapTo(valueParameters, { it.map() })
constructorStub.annotations.mapTo(annotations, { it.map() })
}
@@ -483,12 +489,14 @@ private class MappingExtensions(
is AbbreviatedType -> {
val typeAliasClassifier = KmClassifier.TypeAlias(abbreviatedClassifier.fqNameSerialized)
val typeArguments = typeArguments.map { it.map(shouldExpandTypeAliases) }
val abbreviatedType = KmType(flags).also { km ->
val abbreviatedType = KmType().also { km ->
km.flags = flags
km.classifier = typeAliasClassifier
km.arguments += typeArguments
}
if (shouldExpandTypeAliases) {
KmType(expandedTypeFlags).also { km ->
KmType().also { km ->
km.flags = expandedTypeFlags
km.abbreviatedType = abbreviatedType
val kmUnderlyingType = underlyingType.map(true)
km.arguments += kmUnderlyingType.arguments
@@ -498,21 +506,25 @@ private class MappingExtensions(
abbreviatedType
}
}
is ClassifierStubType -> KmType(flags).also { km ->
is ClassifierStubType -> KmType().also { km ->
km.flags = flags
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
is FunctionalType -> KmType(flags).also { km ->
is FunctionalType -> KmType().also { km ->
km.flags = flags
typeArguments.mapTo(km.arguments) { it.map(shouldExpandTypeAliases) }
km.classifier = KmClassifier.Class(classifier.fqNameSerialized)
}
is TypeParameterType -> KmType(flags).also { km ->
is TypeParameterType -> KmType().also { km ->
km.flags = flags
km.classifier = KmClassifier.TypeParameter(id)
}
}
fun FunctionParameterStub.map(): KmValueParameter =
KmValueParameter(flags, name).also { km ->
KmValueParameter(name).also { km ->
km.flags = flags
val kmType = type.map()
if (isVararg) {
km.varargElementType = kmType
@@ -527,7 +539,7 @@ private class MappingExtensions(
}
fun TypeParameterStub.map(): KmTypeParameter =
KmTypeParameter(flagsOf(), name, id, KmVariance.INVARIANT).also { km ->
KmTypeParameter(name, id, KmVariance.INVARIANT).also { km ->
km.upperBounds.addIfNotNull(upperBound?.map())
}
@@ -1,3 +1,131 @@
public final class kotlinx/metadata/Attributes {
public static final fun getDeclaresDefaultValue (Lkotlinx/metadata/KmValueParameter;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmClass;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmConstructor;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmFunction;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmProperty;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmTypeAlias;)Z
public static final fun getHasAnnotations (Lkotlinx/metadata/KmValueParameter;)Z
public static final fun getHasConstant (Lkotlinx/metadata/KmProperty;)Z
public static final fun getHasEnumEntries (Lkotlinx/metadata/KmClass;)Z
public static final fun getHasGetter (Lkotlinx/metadata/KmProperty;)Z
public static final fun getHasNonStableParameterNames (Lkotlinx/metadata/KmConstructor;)Z
public static final fun getHasNonStableParameterNames (Lkotlinx/metadata/KmFunction;)Z
public static final fun getHasSetter (Lkotlinx/metadata/KmProperty;)Z
public static final fun getKind (Lkotlinx/metadata/KmClass;)Lkotlinx/metadata/ClassKind;
public static final fun getKind (Lkotlinx/metadata/KmFunction;)Lkotlinx/metadata/MemberKind;
public static final fun getKind (Lkotlinx/metadata/KmProperty;)Lkotlinx/metadata/MemberKind;
public static final fun getModality (Lkotlinx/metadata/KmClass;)Lkotlinx/metadata/Modality;
public static final fun getModality (Lkotlinx/metadata/KmFunction;)Lkotlinx/metadata/Modality;
public static final fun getModality (Lkotlinx/metadata/KmProperty;)Lkotlinx/metadata/Modality;
public static final fun getModality (Lkotlinx/metadata/KmPropertyAccessorAttributes;)Lkotlinx/metadata/Modality;
public static final fun getVisibility (Lkotlinx/metadata/KmClass;)Lkotlinx/metadata/Visibility;
public static final fun getVisibility (Lkotlinx/metadata/KmConstructor;)Lkotlinx/metadata/Visibility;
public static final fun getVisibility (Lkotlinx/metadata/KmFunction;)Lkotlinx/metadata/Visibility;
public static final fun getVisibility (Lkotlinx/metadata/KmProperty;)Lkotlinx/metadata/Visibility;
public static final fun getVisibility (Lkotlinx/metadata/KmPropertyAccessorAttributes;)Lkotlinx/metadata/Visibility;
public static final fun getVisibility (Lkotlinx/metadata/KmTypeAlias;)Lkotlinx/metadata/Visibility;
public static final fun isConst (Lkotlinx/metadata/KmProperty;)Z
public static final fun isCrossinline (Lkotlinx/metadata/KmValueParameter;)Z
public static final fun isData (Lkotlinx/metadata/KmClass;)Z
public static final fun isDefinitelyNonNull (Lkotlinx/metadata/KmType;)Z
public static final fun isDelegated (Lkotlinx/metadata/KmProperty;)Z
public static final fun isExpect (Lkotlinx/metadata/KmClass;)Z
public static final fun isExpect (Lkotlinx/metadata/KmFunction;)Z
public static final fun isExpect (Lkotlinx/metadata/KmProperty;)Z
public static final fun isExternal (Lkotlinx/metadata/KmClass;)Z
public static final fun isExternal (Lkotlinx/metadata/KmFunction;)Z
public static final fun isExternal (Lkotlinx/metadata/KmProperty;)Z
public static final fun isExternal (Lkotlinx/metadata/KmPropertyAccessorAttributes;)Z
public static final fun isFunInterface (Lkotlinx/metadata/KmClass;)Z
public static final fun isInfix (Lkotlinx/metadata/KmFunction;)Z
public static final fun isInline (Lkotlinx/metadata/KmFunction;)Z
public static final fun isInline (Lkotlinx/metadata/KmPropertyAccessorAttributes;)Z
public static final fun isInner (Lkotlinx/metadata/KmClass;)Z
public static final fun isLateinit (Lkotlinx/metadata/KmProperty;)Z
public static final fun isNegated (Lkotlinx/metadata/KmEffectExpression;)Z
public static final fun isNoinline (Lkotlinx/metadata/KmValueParameter;)Z
public static final fun isNotDefault (Lkotlinx/metadata/KmPropertyAccessorAttributes;)Z
public static final fun isNullCheckPredicate (Lkotlinx/metadata/KmEffectExpression;)Z
public static final fun isNullable (Lkotlinx/metadata/KmType;)Z
public static final fun isOperator (Lkotlinx/metadata/KmFunction;)Z
public static final fun isReified (Lkotlinx/metadata/KmTypeParameter;)Z
public static final fun isSecondary (Lkotlinx/metadata/KmConstructor;)Z
public static final fun isSuspend (Lkotlinx/metadata/KmFunction;)Z
public static final fun isSuspend (Lkotlinx/metadata/KmType;)Z
public static final fun isTailrec (Lkotlinx/metadata/KmFunction;)Z
public static final fun isValue (Lkotlinx/metadata/KmClass;)Z
public static final fun isVar (Lkotlinx/metadata/KmProperty;)Z
public static final fun setConst (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setCrossinline (Lkotlinx/metadata/KmValueParameter;Z)V
public static final fun setData (Lkotlinx/metadata/KmClass;Z)V
public static final fun setDeclaresDefaultValue (Lkotlinx/metadata/KmValueParameter;Z)V
public static final fun setDefinitelyNonNull (Lkotlinx/metadata/KmType;Z)V
public static final fun setDelegated (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setExpect (Lkotlinx/metadata/KmClass;Z)V
public static final fun setExpect (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setExpect (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setExternal (Lkotlinx/metadata/KmClass;Z)V
public static final fun setExternal (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setExternal (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setFunInterface (Lkotlinx/metadata/KmClass;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmClass;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmConstructor;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmTypeAlias;Z)V
public static final fun setHasAnnotations (Lkotlinx/metadata/KmValueParameter;Z)V
public static final fun setHasConstant (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setHasEnumEntries (Lkotlinx/metadata/KmClass;Z)V
public static final fun setHasGetter (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setHasNonStableParameterNames (Lkotlinx/metadata/KmConstructor;Z)V
public static final fun setHasNonStableParameterNames (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setHasSetter (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setInfix (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setInline (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setInner (Lkotlinx/metadata/KmClass;Z)V
public static final fun setKind (Lkotlinx/metadata/KmClass;Lkotlinx/metadata/ClassKind;)V
public static final fun setKind (Lkotlinx/metadata/KmFunction;Lkotlinx/metadata/MemberKind;)V
public static final fun setKind (Lkotlinx/metadata/KmProperty;Lkotlinx/metadata/MemberKind;)V
public static final fun setLateinit (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setModality (Lkotlinx/metadata/KmClass;Lkotlinx/metadata/Modality;)V
public static final fun setModality (Lkotlinx/metadata/KmFunction;Lkotlinx/metadata/Modality;)V
public static final fun setModality (Lkotlinx/metadata/KmProperty;Lkotlinx/metadata/Modality;)V
public static final fun setModality (Lkotlinx/metadata/KmPropertyAccessorAttributes;Lkotlinx/metadata/Modality;)V
public static final fun setNegated (Lkotlinx/metadata/KmEffectExpression;Z)V
public static final fun setNoinline (Lkotlinx/metadata/KmValueParameter;Z)V
public static final fun setNotDefault (Lkotlinx/metadata/KmPropertyAccessorAttributes;Z)V
public static final fun setNullCheckPredicate (Lkotlinx/metadata/KmEffectExpression;Z)V
public static final fun setNullable (Lkotlinx/metadata/KmType;Z)V
public static final fun setOperator (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setReified (Lkotlinx/metadata/KmTypeParameter;Z)V
public static final fun setSecondary (Lkotlinx/metadata/KmConstructor;Z)V
public static final fun setSuspend (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setSuspend (Lkotlinx/metadata/KmType;Z)V
public static final fun setTailrec (Lkotlinx/metadata/KmFunction;Z)V
public static final fun setValue (Lkotlinx/metadata/KmClass;Z)V
public static final fun setVar (Lkotlinx/metadata/KmProperty;Z)V
public static final fun setVisibility (Lkotlinx/metadata/KmClass;Lkotlinx/metadata/Visibility;)V
public static final fun setVisibility (Lkotlinx/metadata/KmConstructor;Lkotlinx/metadata/Visibility;)V
public static final fun setVisibility (Lkotlinx/metadata/KmFunction;Lkotlinx/metadata/Visibility;)V
public static final fun setVisibility (Lkotlinx/metadata/KmProperty;Lkotlinx/metadata/Visibility;)V
public static final fun setVisibility (Lkotlinx/metadata/KmPropertyAccessorAttributes;Lkotlinx/metadata/Visibility;)V
public static final fun setVisibility (Lkotlinx/metadata/KmTypeAlias;Lkotlinx/metadata/Visibility;)V
}
public final class kotlinx/metadata/ClassKind : java/lang/Enum {
public static final field ANNOTATION_CLASS Lkotlinx/metadata/ClassKind;
public static final field CLASS Lkotlinx/metadata/ClassKind;
public static final field COMPANION_OBJECT Lkotlinx/metadata/ClassKind;
public static final field ENUM_CLASS Lkotlinx/metadata/ClassKind;
public static final field ENUM_ENTRY Lkotlinx/metadata/ClassKind;
public static final field INTERFACE Lkotlinx/metadata/ClassKind;
public static final field OBJECT Lkotlinx/metadata/ClassKind;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lkotlinx/metadata/ClassKind;
public static fun values ()[Lkotlinx/metadata/ClassKind;
}
public final class kotlinx/metadata/ClassNameKt {
public static final fun isLocal (Ljava/lang/String;)Z
public static final fun isLocalClassName (Ljava/lang/String;)Z
@@ -462,6 +590,7 @@ public final class kotlinx/metadata/KmConstantValue {
}
public final class kotlinx/metadata/KmConstructor : kotlinx/metadata/KmConstructorVisitor {
public fun <init> ()V
public fun <init> (I)V
public final fun accept (Lkotlinx/metadata/KmConstructorVisitor;)V
public final fun getFlags ()I
@@ -623,6 +752,7 @@ public final class kotlinx/metadata/KmFlexibleTypeUpperBound {
public final class kotlinx/metadata/KmFunction : kotlinx/metadata/KmFunctionVisitor {
public field returnType Lkotlinx/metadata/KmType;
public fun <init> (ILjava/lang/String;)V
public fun <init> (Ljava/lang/String;)V
public final fun accept (Lkotlinx/metadata/KmFunctionVisitor;)V
public final fun getContextReceiverTypes ()Ljava/util/List;
public final fun getContract ()Lkotlinx/metadata/KmContract;
@@ -713,13 +843,16 @@ public abstract class kotlinx/metadata/KmPackageVisitor : kotlinx/metadata/KmDec
public final class kotlinx/metadata/KmProperty : kotlinx/metadata/KmPropertyVisitor {
public field returnType Lkotlinx/metadata/KmType;
public fun <init> (ILjava/lang/String;II)V
public fun <init> (Ljava/lang/String;)V
public final fun accept (Lkotlinx/metadata/KmPropertyVisitor;)V
public final fun getContextReceiverTypes ()Ljava/util/List;
public final fun getFlags ()I
public final fun getGetter ()Lkotlinx/metadata/KmPropertyAccessorAttributes;
public final fun getGetterFlags ()I
public final fun getName ()Ljava/lang/String;
public final fun getReceiverParameterType ()Lkotlinx/metadata/KmType;
public final fun getReturnType ()Lkotlinx/metadata/KmType;
public final fun getSetter ()Lkotlinx/metadata/KmPropertyAccessorAttributes;
public final fun getSetterFlags ()I
public final fun getSetterParameter ()Lkotlinx/metadata/KmValueParameter;
public final fun getTypeParameters ()Ljava/util/List;
@@ -729,6 +862,7 @@ public final class kotlinx/metadata/KmProperty : kotlinx/metadata/KmPropertyVisi
public final fun setName (Ljava/lang/String;)V
public final fun setReceiverParameterType (Lkotlinx/metadata/KmType;)V
public final fun setReturnType (Lkotlinx/metadata/KmType;)V
public final fun setSetter (Lkotlinx/metadata/KmPropertyAccessorAttributes;)V
public final fun setSetterFlags (I)V
public final fun setSetterParameter (Lkotlinx/metadata/KmValueParameter;)V
public fun visitContextReceiverType (I)Lkotlinx/metadata/KmTypeVisitor;
@@ -740,6 +874,10 @@ public final class kotlinx/metadata/KmProperty : kotlinx/metadata/KmPropertyVisi
public fun visitVersionRequirement ()Lkotlinx/metadata/KmVersionRequirementVisitor;
}
public final class kotlinx/metadata/KmPropertyAccessorAttributes {
public fun <init> ()V
}
public abstract interface class kotlinx/metadata/KmPropertyExtensionVisitor : kotlinx/metadata/KmExtensionVisitor {
}
@@ -759,6 +897,7 @@ public abstract class kotlinx/metadata/KmPropertyVisitor {
public final class kotlinx/metadata/KmType : kotlinx/metadata/KmTypeVisitor {
public field classifier Lkotlinx/metadata/KmClassifier;
public fun <init> ()V
public fun <init> (I)V
public final fun accept (Lkotlinx/metadata/KmTypeVisitor;)V
public final fun getAbbreviatedType ()Lkotlinx/metadata/KmType;
@@ -787,6 +926,7 @@ public final class kotlinx/metadata/KmTypeAlias : kotlinx/metadata/KmTypeAliasVi
public field expandedType Lkotlinx/metadata/KmType;
public field underlyingType Lkotlinx/metadata/KmType;
public fun <init> (ILjava/lang/String;)V
public fun <init> (Ljava/lang/String;)V
public final fun accept (Lkotlinx/metadata/KmTypeAliasVisitor;)V
public final fun getAnnotations ()Ljava/util/List;
public final fun getExpandedType ()Lkotlinx/metadata/KmType;
@@ -828,6 +968,7 @@ public abstract interface class kotlinx/metadata/KmTypeExtensionVisitor : kotlin
public final class kotlinx/metadata/KmTypeParameter : kotlinx/metadata/KmTypeParameterVisitor {
public fun <init> (ILjava/lang/String;ILkotlinx/metadata/KmVariance;)V
public fun <init> (Ljava/lang/String;ILkotlinx/metadata/KmVariance;)V
public final fun accept (Lkotlinx/metadata/KmTypeParameterVisitor;)V
public final fun getFlags ()I
public final fun getId ()I
@@ -893,6 +1034,7 @@ public abstract class kotlinx/metadata/KmTypeVisitor {
public final class kotlinx/metadata/KmValueParameter : kotlinx/metadata/KmValueParameterVisitor {
public field type Lkotlinx/metadata/KmType;
public fun <init> (ILjava/lang/String;)V
public fun <init> (Ljava/lang/String;)V
public final fun accept (Lkotlinx/metadata/KmValueParameterVisitor;)V
public final fun getFlags ()I
public final fun getName ()Ljava/lang/String;
@@ -991,6 +1133,47 @@ public abstract class kotlinx/metadata/KmVersionRequirementVisitor {
public fun visitVersion (III)V
}
public final class kotlinx/metadata/MemberKind : java/lang/Enum {
public static final field DECLARATION Lkotlinx/metadata/MemberKind;
public static final field DELEGATION Lkotlinx/metadata/MemberKind;
public static final field FAKE_OVERRIDE Lkotlinx/metadata/MemberKind;
public static final field SYNTHESIZED Lkotlinx/metadata/MemberKind;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lkotlinx/metadata/MemberKind;
public static fun values ()[Lkotlinx/metadata/MemberKind;
}
public final class kotlinx/metadata/Modality : java/lang/Enum {
public static final field ABSTRACT Lkotlinx/metadata/Modality;
public static final field FINAL Lkotlinx/metadata/Modality;
public static final field OPEN Lkotlinx/metadata/Modality;
public static final field SEALED Lkotlinx/metadata/Modality;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lkotlinx/metadata/Modality;
public static fun values ()[Lkotlinx/metadata/Modality;
}
public final class kotlinx/metadata/Visibility : java/lang/Enum {
public static final field INTERNAL Lkotlinx/metadata/Visibility;
public static final field LOCAL Lkotlinx/metadata/Visibility;
public static final field PRIVATE Lkotlinx/metadata/Visibility;
public static final field PRIVATE_TO_THIS Lkotlinx/metadata/Visibility;
public static final field PROTECTED Lkotlinx/metadata/Visibility;
public static final field PUBLIC Lkotlinx/metadata/Visibility;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lkotlinx/metadata/Visibility;
public static fun values ()[Lkotlinx/metadata/Visibility;
}
public final class kotlinx/metadata/jvm/JvmAttributes {
public static final fun getHasMethodBodiesInInterface (Lkotlinx/metadata/KmClass;)Z
public static final fun isCompiledInCompatibilityMode (Lkotlinx/metadata/KmClass;)Z
public static final fun isMovedFromInterfaceCompanion (Lkotlinx/metadata/KmProperty;)Z
public static final fun setCompiledInCompatibilityMode (Lkotlinx/metadata/KmClass;Z)V
public static final fun setHasMethodBodiesInInterface (Lkotlinx/metadata/KmClass;Z)V
public static final fun setMovedFromInterfaceCompanion (Lkotlinx/metadata/KmProperty;Z)V
}
public class kotlinx/metadata/jvm/JvmClassExtensionVisitor : kotlinx/metadata/jvm/JvmDeclarationContainerExtensionVisitor, kotlinx/metadata/KmClassExtensionVisitor {
public static final field Companion Lkotlinx/metadata/jvm/JvmClassExtensionVisitor$Companion;
public static final field TYPE Lkotlinx/metadata/KmExtensionType;
@@ -0,0 +1,40 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:JvmName("JvmAttributes")
package kotlinx.metadata.jvm
import kotlinx.metadata.KmClass
import kotlinx.metadata.KmProperty
import kotlinx.metadata.internal.BooleanFlagDelegate
import kotlinx.metadata.jvm.JvmFlag.booleanFlag
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmFlags as JF
/**
* Applied to a property declared in an interface's companion object, signifies that its backing field is declared as a static
* field in the interface. In Kotlin code, this usually happens if the property is annotated with [JvmField].
*
* Has no effect if the property is not declared in a companion object of some interface.
*/
var KmProperty.isMovedFromInterfaceCompanion by BooleanFlagDelegate(KmProperty::jvmFlags, booleanFlag(JF.IS_MOVED_FROM_INTERFACE_COMPANION))
/**
* Applied to an interface compiled with -Xjvm-default=all or all-compatibility.
*
* Without this flag or a `@JvmDefault` annotation on individual interface methods
* the Kotlin compiler moves all interface method bodies into a nested `DefaultImpls`
* class.
*/
var KmClass.hasMethodBodiesInInterface by BooleanFlagDelegate(KmClass::jvmFlags, booleanFlag(JF.IS_COMPILED_IN_JVM_DEFAULT_MODE))
/**
* Applied to an interface compiled with -Xjvm-default=all-compatibility.
*
* In compatibility mode we generate method bodies directly in the interface,
* but we also generate bridges in a nested `DefaultImpls` class for use by
* clients compiled without all-compatibility.
*/
var KmClass.isCompiledInCompatibilityMode by BooleanFlagDelegate(KmClass::jvmFlags, booleanFlag(JF.IS_COMPILED_IN_COMPATIBILITY_MODE))
@@ -56,6 +56,6 @@ object JvmFlag {
val IS_COMPILED_IN_COMPATIBILITY_MODE = booleanFlag(JF.IS_COMPILED_IN_COMPATIBILITY_MODE)
}
private fun booleanFlag(f: F.BooleanFlagField): Flag =
internal fun booleanFlag(f: F.BooleanFlagField): Flag =
Flag(f.offset, f.bitWidth, 1)
}
@@ -56,7 +56,8 @@ internal class JvmClassExtension : JvmClassExtensionVisitor(), KmClassExtension
override fun accept(visitor: KmClassExtensionVisitor) {
require(visitor is JvmClassExtensionVisitor)
localDelegatedProperties.forEach {
visitor.visitLocalDelegatedProperty(it.flags, it.name, it.getterFlags, it.setterFlags)?.let(it::accept)
@Suppress("INVISIBLE_MEMBER") // getter.flags
visitor.visitLocalDelegatedProperty(it.flags, it.name, it.getter.flags, it.setterFlags)?.let(it::accept)
}
moduleName?.let(visitor::visitModuleName)
anonymousObjectOriginName?.let(visitor::visitAnonymousObjectOriginName)
@@ -79,7 +80,8 @@ internal class JvmPackageExtension : JvmPackageExtensionVisitor(), KmPackageExte
override fun accept(visitor: KmPackageExtensionVisitor) {
require(visitor is JvmPackageExtensionVisitor)
localDelegatedProperties.forEach {
visitor.visitLocalDelegatedProperty(it.flags, it.name, it.getterFlags, it.setterFlags)?.let(it::accept)
@Suppress("INVISIBLE_MEMBER") // getter.flags
visitor.visitLocalDelegatedProperty(it.flags, it.name, it.getter.flags, it.setterFlags)?.let(it::accept)
}
moduleName?.let(visitor::visitModuleName)
visitor.visitEnd()
@@ -0,0 +1,162 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlinx.metadata.test
import kotlinx.metadata.*
import org.junit.Test
import kotlin.reflect.KMutableProperty0
import kotlin.test.*
class FlagDelegatesTest {
private class Private
public class Public {
public fun f(): String = ""
}
@Test
fun testVisibilityFlags() {
val p1 = Private::class.java.readMetadataAsKmClass()
val p2 = Public::class.java.readMetadataAsKmClass()
assertEquals(Visibility.PRIVATE, p1.visibility)
assertEquals(Visibility.PUBLIC, p2.visibility)
assertTrue(Flag.IS_PRIVATE(p1.flags))
assertTrue(Flag.IS_PUBLIC(p2.flags))
p1.visibility = Visibility.PUBLIC
p2.visibility = Visibility.INTERNAL
assertFalse(Flag.IS_PRIVATE(p1.flags))
assertFalse(Flag.IS_PUBLIC(p2.flags))
assertTrue(Flag.IS_PUBLIC(p1.flags))
assertTrue(Flag.IS_INTERNAL(p2.flags))
val f = assertNotNull(p2.functions.find { it.name == "f" })
assertEquals(Visibility.PUBLIC, f.visibility)
f.visibility = Visibility.PRIVATE
assertFalse(Flag.IS_PUBLIC(f.flags))
assertTrue(Flag.IS_PRIVATE(f.flags))
}
@Test
fun testBooleanFlags() {
val klass = Public::class.java.readMetadataAsKmClass()
fun doTest(prop: KMutableProperty0<Boolean>, flags: () -> Flags, rawFlag: Flag) {
assertFalse(prop.get())
assertFalse(rawFlag(flags()))
prop.set(true)
assertTrue(prop.get())
assertTrue(rawFlag(flags()))
}
doTest(klass::isData, klass::flags, Flag.Class.IS_DATA)
val f = klass.functions.single { it.name == "f" }
doTest(f::isOperator, f::flags, Flag.Function.IS_OPERATOR)
val rt = f.returnType
doTest(rt::isNullable, rt::flags, Flag.Type.IS_NULLABLE)
}
@Suppress("UNUSED_PARAMETER")
class PropertiesContainer {
val defaultVal: String = ""
var defaultVar: String = ""
val getterVal: String get() = "foo"
var getterSetterFieldVar: String = ""
get() = field + "a"
set(param) {
field = param + "b"
}
var getterSetterNoFieldVar: String
get() = ""
set(param) {
// no
}
var getterSetterNoFieldNoParamVar: String
get() = ""
set(_) {
// no
}
var defaultSetterVar: String = ""
get() = "foo"
var defaultGetterVar: String = ""
set(param) {
field = param.takeLast(0)
}
var noinlineModifierVar: String = ""
set(noinline param) {
field = param.takeLast(0)
}
}
@Test
fun testPropertyAccessors() {
val klass = PropertiesContainer::class.java.readMetadataAsKmClass()
val propMap = klass.properties.associateBy { it.name }
fun assertProperty(
name: String,
isVarProp: Boolean,
getterNotDefault: Boolean,
setterNotDefault: Boolean?,
setterParamCheck: (KmValueParameter?) -> Unit = { assertNull(it, "Should not be a setter parameter for $name") },
) {
with(propMap.getValue(name)) {
assertEquals(listOf(isVarProp, true, isVarProp), listOf(isVar, hasGetter, hasSetter), "for $name")
assertEquals(visibility, getter.visibility, "for $name")
assertEquals(getterNotDefault, getter.isNotDefault, "for $name")
assertEquals(isVarProp, setter != null, "for $name")
assertEquals(setterNotDefault, setter?.isNotDefault, "for $name")
assertEquals(if (isVarProp) visibility else null, setter?.visibility, "for $name")
setterParamCheck(setterParameter)
}
}
assertProperty("defaultVal", false, false, null)
assertProperty("defaultVar", true, false, false)
assertProperty("getterVal", false, true, null)
assertProperty("getterSetterFieldVar", true, true, true) {
assertEquals("param", it?.name)
}
// Same as with field
assertProperty("getterSetterNoFieldVar", true, true, true) {
assertEquals("param", it?.name)
}
assertProperty("getterSetterNoFieldNoParamVar", true, true, true) {
assertEquals(true, it?.name?.contains("anonymous parameter"))
}
assertProperty("defaultSetterVar", true, true, false)
assertProperty("defaultGetterVar", true, false, true) {
assertEquals("param", it?.name)
}
assertProperty("noinlineModifierVar", true, false, true) {
assertEquals("param", it?.name)
assertEquals(true, it?.isNoinline)
}
}
}
@@ -49,10 +49,13 @@ class MetadataSmokeTest {
val klass = KmClass().apply {
name = "Hello"
flags = flagsOf(Flag.IS_PUBLIC)
constructors += KmConstructor(flagsOf(Flag.IS_PUBLIC)).apply {
constructors += KmConstructor().apply {
visibility = Visibility.PUBLIC
signature = JvmMethodSignature("<init>", "()V")
}
functions += KmFunction(flagsOf(Flag.IS_PUBLIC, Flag.Function.IS_DECLARATION), "hello").apply {
functions += KmFunction("hello").apply {
visibility = Visibility.PUBLIC
kind = MemberKind.DECLARATION
returnType = KmType(flagsOf()).apply {
classifier = KmClassifier.Class("kotlin/String")
}
@@ -166,6 +169,9 @@ class MetadataSmokeTest {
classWithStableParameterNames.constructors.forEach { assertFalse(Flag.Constructor.HAS_NON_STABLE_PARAMETER_NAMES(it.flags)) }
classWithStableParameterNames.functions.forEach { assertFalse(Flag.Function.HAS_NON_STABLE_PARAMETER_NAMES(it.flags)) }
classWithStableParameterNames.constructors.forEach { assertFalse(it.hasNonStableParameterNames) }
classWithStableParameterNames.functions.forEach { assertFalse(it.hasNonStableParameterNames) }
val newMetadata = KotlinClassMetadata.writeClass(
KmClass().apply {
classWithStableParameterNames.accept(
@@ -184,6 +190,9 @@ class MetadataSmokeTest {
classWithUnstableParameterNames.constructors.forEach { assertTrue(Flag.Constructor.HAS_NON_STABLE_PARAMETER_NAMES(it.flags)) }
classWithUnstableParameterNames.functions.forEach { assertTrue(Flag.Function.HAS_NON_STABLE_PARAMETER_NAMES(it.flags)) }
classWithUnstableParameterNames.constructors.forEach { assertTrue(it.hasNonStableParameterNames) }
classWithUnstableParameterNames.functions.forEach { assertTrue(it.hasNonStableParameterNames) }
}
@Test
@@ -0,0 +1,379 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:OptIn(ExperimentalStdlibApi::class)
@file:JvmName("Attributes")
package kotlinx.metadata
import kotlinx.metadata.internal.*
import kotlinx.metadata.internal.BooleanFlagDelegate
import kotlinx.metadata.internal.EnumFlagDelegate
import kotlinx.metadata.internal.classBooleanFlag
import kotlinx.metadata.internal.constructorBooleanFlag
import kotlin.contracts.ExperimentalContracts
import org.jetbrains.kotlin.metadata.deserialization.Flags as ProtoFlags
// --- ANNOTATIONS ---
/**
* Signifies that the corresponding class 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 class has no annotations.
*/
var KmClass.hasAnnotations by annotationsOn(KmClass::flags)
/**
* Signifies that the corresponding constructor 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 constructor has no annotations.
*/
var KmConstructor.hasAnnotations by annotationsOn(KmConstructor::flags)
/**
* Signifies that the corresponding function 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 function has no annotations.
*/
var KmFunction.hasAnnotations by annotationsOn(KmFunction::flags)
/**
* Signifies that the corresponding property 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 property has no annotations.
*/
var KmProperty.hasAnnotations by annotationsOn(KmProperty::flags)
/**
* Signifies that the corresponding value parameter 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 value parameter has no annotations.
*/
var KmValueParameter.hasAnnotations by annotationsOn(KmValueParameter::flags)
/**
* Signifies that the corresponding type alias has at least one annotation.
*
* Type aliases store their annotation in metadata directly (accessible via [KmTypeAlias.annotations]) and
* in the class file at the same time.
* As a result, Kotlin compiler still writes this flag for them, and this extension is left for completeness.
*/
var KmTypeAlias.hasAnnotations by annotationsOn(KmTypeAlias::flags)
// KmType and KmTypeParameter have annotations in it, and this flag for them is not written
// --- CLASS ---
/**
* Represents modality of a corresponding class
*/
var KmClass.modality: Modality by modalityDelegate(KmClass::flags)
/**
* Represents visibility of a corresponding class
*/
var KmClass.visibility: Visibility by visibilityDelegate(KmClass::flags)
/**
* Represents kind of a corresponding class
*/
var KmClass.kind: ClassKind by EnumFlagDelegate(
KmClass::flags,
ProtoFlags.CLASS_KIND,
ClassKind.entries,
ClassKind.entries.map { it.flag },
)
/**
* Signifies that the corresponding class is `inner`.
*/
var KmClass.isInner: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_INNER))
/**
* Signifies that the corresponding class is `data`.
*/
var KmClass.isData: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_DATA))
/**
* Signifies that the corresponding class is `external`.
*/
var KmClass.isExternal: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_EXTERNAL_CLASS))
/**
* Signifies that the corresponding class is `expect`.
*/
var KmClass.isExpect: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_EXPECT_CLASS))
/**
* Signifies that the corresponding class is either a pre-Kotlin-1.5 `inline` class, or a 1.5+ `value` class.
*
* Note that it doesn't imply that the class has [JvmInline] annotation and will be inlined.
* Currently, it is impossible to declare a value class without this annotation, but this can be changed in the future.
*/
var KmClass.isValue: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_VALUE_CLASS))
/**
* Signifies that the corresponding class is a functional interface, i.e. marked with the keyword `fun`.
*/
var KmClass.isFunInterface: Boolean by classBooleanFlag(Flag(ProtoFlags.IS_FUN_INTERFACE))
/**
* Signifies that the corresponding enum class has synthetic ".entries" property in bytecode.
* Always `false` for not enum classes.
*/
var KmClass.hasEnumEntries: Boolean by classBooleanFlag(Flag(ProtoFlags.HAS_ENUM_ENTRIES))
// --- CONSTRUCTOR ---
/**
* Represents visibility of a corresponding constructor.
*/
var KmConstructor.visibility: Visibility by visibilityDelegate(KmConstructor::flags)
/**
* Signifies that the corresponding constructor is secondary, i.e. declared not in the class header, but in the class body.
*/
var KmConstructor.isSecondary: Boolean by constructorBooleanFlag(Flag(ProtoFlags.IS_SECONDARY))
/**
* Signifies that the corresponding constructor has non-stable parameter names, i.e. cannot be called with named arguments.
*/
var KmConstructor.hasNonStableParameterNames: Boolean by constructorBooleanFlag(Flag(ProtoFlags.IS_CONSTRUCTOR_WITH_NON_STABLE_PARAMETER_NAMES))
// --- FUNCTION ---
/**
* Represents kind of a corresponding function
*/
var KmFunction.kind: MemberKind by memberKindDelegate(KmFunction::flags)
/**
* Represents visibility of a corresponding function
*/
var KmFunction.visibility: Visibility by visibilityDelegate(KmFunction::flags)
/**
* Represents modality of a corresponding function.
*/
var KmFunction.modality: Modality by modalityDelegate(KmFunction::flags)
/**
* Signifies that the corresponding function is `operator`.
*/
var KmFunction.isOperator: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_OPERATOR))
/**
* Signifies that the corresponding function is `infix`.
*/
var KmFunction.isInfix: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_INFIX))
/**
* Signifies that the corresponding function is `inline`.
*/
var KmFunction.isInline: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_INLINE))
/**
* Signifies that the corresponding function is `tailrec`.
*/
var KmFunction.isTailrec: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_TAILREC))
/**
* Signifies that the corresponding function is `external`.
*/
var KmFunction.isExternal: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_EXTERNAL_FUNCTION))
/**
* Signifies that the corresponding function is `suspend`.
*/
var KmFunction.isSuspend: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_SUSPEND))
/**
* Signifies that the corresponding function is `expect`.
*/
var KmFunction.isExpect: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_EXPECT_FUNCTION))
/**
* Signifies that the corresponding function has non-stable parameter names, i.e. cannot be called with named arguments.
*/
var KmFunction.hasNonStableParameterNames: Boolean by functionBooleanFlag(Flag(ProtoFlags.IS_FUNCTION_WITH_NON_STABLE_PARAMETER_NAMES))
// --- PROPERTY ---
/**
* Represents visibility of a corresponding property
*/
var KmProperty.visibility: Visibility by visibilityDelegate(KmProperty::flags)
/**
* Represents modality of a corresponding property.
*/
var KmProperty.modality: Modality by modalityDelegate(KmProperty::flags)
/**
* Represents kind of a corresponding property
*/
var KmProperty.kind: MemberKind by memberKindDelegate(KmProperty::flags)
/**
* Signifies that the corresponding property is `var`.
*/
var KmProperty.isVar: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_VAR))
/**
* Signifies that the corresponding property has a getter.
*/
var KmProperty.hasGetter: Boolean by propertyBooleanFlag(Flag(ProtoFlags.HAS_GETTER))
/**
* Signifies that the corresponding property has a setter.
*/
var KmProperty.hasSetter: Boolean by propertyBooleanFlag(Flag(ProtoFlags.HAS_SETTER))
/**
* Signifies that the corresponding property is `const`.
*/
var KmProperty.isConst: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_CONST))
/**
* Signifies that the corresponding property is `lateinit`.
*/
var KmProperty.isLateinit: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_LATEINIT))
/**
* Signifies that the corresponding property has a constant value. On JVM, this flag allows an optimization similarly to
* [KmProperty.hasAnnotations]: 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.
*/
var KmProperty.hasConstant: Boolean by propertyBooleanFlag(Flag(ProtoFlags.HAS_CONSTANT))
/**
* Signifies that the corresponding property is `external`.
*/
var KmProperty.isExternal: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_EXTERNAL_PROPERTY))
/**
* Signifies that the corresponding property is a delegated property.
*/
var KmProperty.isDelegated: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_DELEGATED))
/**
* Signifies that the corresponding property is `expect`.
*/
var KmProperty.isExpect: Boolean by propertyBooleanFlag(Flag(ProtoFlags.IS_EXPECT_PROPERTY))
// --- PROPERTY ACCESSOR ---
/**
* Represents visibility of a corresponding property accessor.
*/
var KmPropertyAccessorAttributes.visibility: Visibility by visibilityDelegate(KmPropertyAccessorAttributes::flags)
/**
* Represents modality of a corresponding property accessor.
*/
var KmPropertyAccessorAttributes.modality: Modality by modalityDelegate(KmPropertyAccessorAttributes::flags)
/**
* Signifies that the corresponding property accessor is not default, i.e. it has a body and/or annotations in the source code.
*/
var KmPropertyAccessorAttributes.isNotDefault: Boolean by propertyAccessorBooleanFlag(Flag(ProtoFlags.IS_NOT_DEFAULT))
/**
* Signifies that the corresponding property accessor is `external`.
*/
val KmPropertyAccessorAttributes.isExternal: Boolean by propertyAccessorBooleanFlag(Flag(ProtoFlags.IS_EXTERNAL_ACCESSOR))
/**
* Signifies that the corresponding property accessor is `inline`.
*/
val KmPropertyAccessorAttributes.isInline: Boolean by propertyAccessorBooleanFlag(Flag(ProtoFlags.IS_INLINE_ACCESSOR))
// --- TYPE & TYPE_PARAM
/**
* Signifies that the corresponding type is marked as nullable, i.e. has a question mark at the end of its notation.
*/
var KmType.isNullable: Boolean by typeBooleanFlag(Flag(0, 1, 1))
/**
* Signifies that the corresponding type is `suspend`.
*/
var KmType.isSuspend: Boolean by typeBooleanFlag(Flag(ProtoFlags.SUSPEND_TYPE.offset + 1, ProtoFlags.SUSPEND_TYPE.bitWidth, 1))
/**
* Signifies that the corresponding type is [definitely non-null](https://kotlinlang.org/docs/whatsnew17.html#stable-definitely-non-nullable-types).
*/
var KmType.isDefinitelyNonNull: Boolean by typeBooleanFlag(
Flag(
ProtoFlags.DEFINITELY_NOT_NULL_TYPE.offset + 1,
ProtoFlags.DEFINITELY_NOT_NULL_TYPE.bitWidth,
1
)
)
/**
* Signifies that the corresponding type parameter is `reified`.
*/
var KmTypeParameter.isReified: Boolean by BooleanFlagDelegate(KmTypeParameter::flags, Flag(0, 1, 1))
// --- TYPE ALIAS ---
/**
* Represents visibility of a corresponding type alias.
*/
var KmTypeAlias.visibility: Visibility by visibilityDelegate(KmTypeAlias::flags)
// --- VALUE PARAMETER ---
/**
* 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, but the parameter is
* still optional at the call site because the default value from the base method is used.
*/
var KmValueParameter.declaresDefaultValue: Boolean by valueParameterBooleanFlag(Flag(ProtoFlags.DECLARES_DEFAULT_VALUE))
/**
* Signifies that the corresponding value parameter is `crossinline`.
*/
var KmValueParameter.isCrossinline: Boolean by valueParameterBooleanFlag(Flag(ProtoFlags.IS_CROSSINLINE))
/**
* Signifies that the corresponding value parameter is `noinline`.
*/
var KmValueParameter.isNoinline: Boolean by valueParameterBooleanFlag(Flag(ProtoFlags.IS_NOINLINE))
// --- EFFECT EXPRESSION ---
/**
* Signifies that the corresponding effect expression should be negated to compute the proposition or the conclusion of an effect.
*
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
* may change in a subsequent release.
*/
@ExperimentalContracts
var KmEffectExpression.isNegated: Boolean by BooleanFlagDelegate(KmEffectExpression::flags, Flag(ProtoFlags.IS_NEGATED))
/**
* Signifies that the corresponding effect expression checks whether a value of some variable is `null`.
*
* Contracts are an internal feature of the standard Kotlin library, and their behavior and/or binary format
* may change in a subsequent release.
*/
@ExperimentalContracts
var KmEffectExpression.isNullCheckPredicate: Boolean by BooleanFlagDelegate(KmEffectExpression::flags, Flag(ProtoFlags.IS_NULL_CHECK_PREDICATE))
@@ -9,6 +9,9 @@ import kotlinx.metadata.internal.IgnoreInApiDump
import org.jetbrains.kotlin.metadata.ProtoBuf.*
import org.jetbrains.kotlin.metadata.ProtoBuf.Class.Kind as ClassKind
import org.jetbrains.kotlin.metadata.deserialization.Flags as F
import org.jetbrains.kotlin.metadata.ProtoBuf.Modality as ProtoModality
import org.jetbrains.kotlin.metadata.ProtoBuf.Visibility as ProtoVisibility
import org.jetbrains.kotlin.metadata.ProtoBuf.MemberKind as ProtoMemberKind
/**
* Represents a boolean flag that is either present or not in a Kotlin declaration. A "flag" is a boolean trait that is either present
@@ -38,7 +41,7 @@ import org.jetbrains.kotlin.metadata.deserialization.Flags as F
* @see Flags
* @see flagsOf
*/
class Flag(private val offset: Int, private val bitWidth: Int, private val value: Int) {
class Flag(internal val offset: Int, internal val bitWidth: Int, internal val value: Int) {
@IgnoreInApiDump
internal constructor(field: F.FlagField<*>, value: Int) : this(field.offset, field.bitWidth, value)
@@ -71,64 +74,64 @@ class Flag(private val offset: Int, private val bitWidth: Int, private val value
* A visibility flag, signifying that the corresponding declaration is `internal`.
*/
@JvmField
val IS_INTERNAL = Flag(F.VISIBILITY, Visibility.INTERNAL_VALUE)
val IS_INTERNAL = Flag(F.VISIBILITY, ProtoVisibility.INTERNAL_VALUE)
/**
* A visibility flag, signifying that the corresponding declaration is `private`.
*/
@JvmField
val IS_PRIVATE = Flag(F.VISIBILITY, Visibility.PRIVATE_VALUE)
val IS_PRIVATE = Flag(F.VISIBILITY, ProtoVisibility.PRIVATE_VALUE)
/**
* A visibility flag, signifying that the corresponding declaration is `protected`.
*/
@JvmField
val IS_PROTECTED = Flag(F.VISIBILITY, Visibility.PROTECTED_VALUE)
val IS_PROTECTED = Flag(F.VISIBILITY, ProtoVisibility.PROTECTED_VALUE)
/**
* A visibility flag, signifying that the corresponding declaration is `public`.
*/
@JvmField
val IS_PUBLIC = Flag(F.VISIBILITY, Visibility.PUBLIC_VALUE)
val IS_PUBLIC = Flag(F.VISIBILITY, ProtoVisibility.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 = Flag(F.VISIBILITY, Visibility.PRIVATE_TO_THIS_VALUE)
val IS_PRIVATE_TO_THIS = Flag(F.VISIBILITY, ProtoVisibility.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 = Flag(F.VISIBILITY, Visibility.LOCAL_VALUE)
val IS_LOCAL = Flag(F.VISIBILITY, ProtoVisibility.LOCAL_VALUE)
/**
* A modality flag, signifying that the corresponding declaration is `final`.
*/
@JvmField
val IS_FINAL = Flag(F.MODALITY, Modality.FINAL_VALUE)
val IS_FINAL = Flag(F.MODALITY, ProtoModality.FINAL_VALUE)
/**
* A modality flag, signifying that the corresponding declaration is `open`.
*/
@JvmField
val IS_OPEN = Flag(F.MODALITY, Modality.OPEN_VALUE)
val IS_OPEN = Flag(F.MODALITY, ProtoModality.OPEN_VALUE)
/**
* A modality flag, signifying that the corresponding declaration is `abstract`.
*/
@JvmField
val IS_ABSTRACT = Flag(F.MODALITY, Modality.ABSTRACT_VALUE)
val IS_ABSTRACT = Flag(F.MODALITY, ProtoModality.ABSTRACT_VALUE)
/**
* A modality flag, signifying that the corresponding declaration is `sealed`.
*/
@JvmField
val IS_SEALED = Flag(F.MODALITY, Modality.SEALED_VALUE)
val IS_SEALED = Flag(F.MODALITY, ProtoModality.SEALED_VALUE)
}
/**
@@ -267,28 +270,28 @@ class Flag(private val offset: Int, private val bitWidth: Int, private val value
* A member kind flag, signifying that the corresponding function is explicitly declared in the containing class.
*/
@JvmField
val IS_DECLARATION = Flag(F.MEMBER_KIND, MemberKind.DECLARATION_VALUE)
val IS_DECLARATION = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.FAKE_OVERRIDE_VALUE)
val IS_FAKE_OVERRIDE = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.DELEGATION_VALUE)
val IS_DELEGATION = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.SYNTHESIZED_VALUE)
val IS_SYNTHESIZED = Flag(F.MEMBER_KIND, ProtoMemberKind.SYNTHESIZED_VALUE)
/**
@@ -351,28 +354,28 @@ class Flag(private val offset: Int, private val bitWidth: Int, private val value
* A member kind flag, signifying that the corresponding property is explicitly declared in the containing class.
*/
@JvmField
val IS_DECLARATION = Flag(F.MEMBER_KIND, MemberKind.DECLARATION_VALUE)
val IS_DECLARATION = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.FAKE_OVERRIDE_VALUE)
val IS_FAKE_OVERRIDE = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.DELEGATION_VALUE)
val IS_DELEGATION = Flag(F.MEMBER_KIND, ProtoMemberKind.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 = Flag(F.MEMBER_KIND, MemberKind.SYNTHESIZED_VALUE)
val IS_SYNTHESIZED = Flag(F.MEMBER_KIND, ProtoMemberKind.SYNTHESIZED_VALUE)
/**
@@ -0,0 +1,185 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlinx.metadata
import org.jetbrains.kotlin.metadata.deserialization.Flags as ProtoFlags
import org.jetbrains.kotlin.metadata.ProtoBuf.Class.Kind as ProtoClassKind
import org.jetbrains.kotlin.metadata.ProtoBuf.Visibility as ProtoVisibility
import org.jetbrains.kotlin.metadata.ProtoBuf.Modality as ProtoModality
import org.jetbrains.kotlin.metadata.ProtoBuf.MemberKind as ProtoMemberKind
// Do not reorder any enums in this file!
/**
* Represents visibility level (also known as access level) of a corresponding declaration.
* Some of these visibilities may be non-denotable in Kotlin.
*/
enum class Visibility(kind: Int) {
/**
* Signifies that the corresponding declaration is `internal`.
*/
INTERNAL(ProtoVisibility.INTERNAL_VALUE),
/**
* Signifies that the corresponding declaration is `private`.
*/
PRIVATE(ProtoVisibility.PRIVATE_VALUE),
/**
* Signifies that the corresponding declaration is `protected`.
*/
PROTECTED(ProtoVisibility.PROTECTED_VALUE),
/**
* Signifies that the corresponding declaration is `public`.
*/
PUBLIC(ProtoVisibility.PUBLIC_VALUE),
/**
* Signifies 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.
* Generally, this visibility is more restrictive than 'private', so for most use cases it can be treated the same.
*
* Example of 'PRIVATE_TO_THIS' declaration:
* ```
* class A<in T>(t: T) {
* private val t: T = t // visibility for t is PRIVATE_TO_THIS
*
* fun test() {
* val x: T = t // correct
* val y: T = this.t // also correct
* }
* fun foo(a: A<String>) {
* val x: String = a.t // incorrect, because a.t can be Any
* }
* }
* ```
*/
PRIVATE_TO_THIS(ProtoVisibility.PRIVATE_TO_THIS_VALUE),
/**
* Signifies that the corresponding declaration is local, i.e. declared inside a code block
* and not visible from the outside.
*/
LOCAL(ProtoVisibility.LOCAL_VALUE)
;
internal val flag = Flag(ProtoFlags.VISIBILITY, kind)
}
/**
* Represents modality of a corresponding declaration.
*/
enum class Modality(kind: Int) {
/**
* Signifies that the corresponding declaration is `final`.
*/
FINAL(ProtoModality.FINAL_VALUE),
/**
* Signifies that the corresponding declaration is `open`.
*/
OPEN(ProtoModality.OPEN_VALUE),
/**
* Signifies that the corresponding declaration is `abstract`.
*/
ABSTRACT(ProtoModality.ABSTRACT_VALUE),
/**
* Signifies that the corresponding declaration is `sealed`.
*
* Pay attention that this modality is not applicable to class' members.
* Setting it as a value for member modality leads to an undefined behaviour.
*/
SEALED(ProtoModality.SEALED_VALUE)
;
internal val flag = Flag(ProtoFlags.MODALITY, kind)
}
/**
* Represents the nature of a corresponding class.
*/
enum class ClassKind(kind: Int) {
/**
* Signifies that the corresponding class is a usual `class`.
*/
CLASS(ProtoClassKind.CLASS_VALUE),
/**
* Signifies that the corresponding class is an `interface`.
*/
INTERFACE(ProtoClassKind.INTERFACE_VALUE),
/**
* Signifies that the corresponding class is an `enum class`.
*/
ENUM_CLASS(ProtoClassKind.ENUM_CLASS_VALUE),
/**
* Signifies that the corresponding class is an enum entry.
*/
ENUM_ENTRY(ProtoClassKind.ENUM_ENTRY_VALUE),
/**
* Signifies that the corresponding class is an `annotation class`.
*/
ANNOTATION_CLASS(ProtoClassKind.ANNOTATION_CLASS_VALUE),
/**
* Signifies that the corresponding class is a non-companion `object`.
*/
OBJECT(ProtoClassKind.OBJECT_VALUE),
/**
* Signifies that the corresponding class is a `companion object`.
*/
COMPANION_OBJECT(ProtoClassKind.COMPANION_OBJECT_VALUE)
;
internal val flag = Flag(ProtoFlags.CLASS_KIND, kind)
}
/**
* Represents kind of a function or property.
*
* Kind indicates the origin of a declaration within a containing class.
* It provides information about whether a function or property was defined, generated, or something else.
*/
enum class MemberKind(kind: Int) {
/**
* Signifies that the corresponding function or property is explicitly declared in the containing class.
*/
DECLARATION(ProtoMemberKind.DECLARATION_VALUE),
/**
* Signifies that the corresponding function or property 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 normally cannot be encountered in binary metadata.
* Its effects are unspecified.
*/
FAKE_OVERRIDE(ProtoMemberKind.FAKE_OVERRIDE_VALUE),
/**
* Signifies that the corresponding function or property exists in the containing class because it has been produced
* by interface delegation.
*
* Do not confuse with property delegation which is denoted by [KmProperty.isDelegated].
*/
DELEGATION(ProtoMemberKind.DELEGATION_VALUE),
/**
* Signifies that the corresponding function or property exists in the containing class because it has been synthesized
* by the compiler or compiler plugin and has no declaration in the source code.
*
* An example of such function can be component1() of a data class.
*/
SYNTHESIZED(ProtoMemberKind.SYNTHESIZED_VALUE)
;
internal val flag = Flag(ProtoFlags.MEMBER_KIND, kind)
}
@@ -8,6 +8,7 @@
package kotlinx.metadata
import kotlinx.metadata.internal.extensions.*
import kotlinx.metadata.internal.getDefaultPropertyAccessorFlags
import kotlin.contracts.ExperimentalContracts
/**
@@ -203,7 +204,7 @@ class KmClass : KmClassVisitor(), KmDeclarationContainer {
typeParameters.forEach { visitor.visitTypeParameter(it.flags, it.name, it.id, it.variance)?.let(it::accept) }
supertypes.forEach { visitor.visitSupertype(it.flags)?.let(it::accept) }
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) }
properties.forEach { visitor.visitProperty(it.flags, it.name, it.getter.flags, it.setterFlags)?.let(it::accept) }
typeAliases.forEach { visitor.visitTypeAlias(it.flags, it.name)?.let(it::accept) }
constructors.forEach { visitor.visitConstructor(it.flags)?.let(it::accept) }
companionObject?.let(visitor::visitCompanionObject)
@@ -268,7 +269,7 @@ class KmPackage : KmPackageVisitor(), KmDeclarationContainer {
@Deprecated(VISITOR_API_MESSAGE)
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) }
properties.forEach { visitor.visitProperty(it.flags, it.name, it.getter.flags, it.setterFlags)?.let(it::accept) }
typeAliases.forEach { visitor.visitTypeAlias(it.flags, it.name)?.let(it::accept) }
extensions.forEach { visitor.visitExtensions(it.type)?.let(it::accept) }
visitor.visitEnd()
@@ -307,7 +308,10 @@ class KmLambda : KmLambdaVisitor() {
* @property flags constructor flags, consisting of [Flag.HAS_ANNOTATIONS], a visibility flag and [Flag.Constructor] flags
*/
@Suppress("DEPRECATION")
class KmConstructor(var flags: Flags) : KmConstructorVisitor() {
class KmConstructor @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(var flags: Flags) :
KmConstructorVisitor() {
constructor() : this(0)
/**
* Value parameters of the constructor.
*/
@@ -354,10 +358,13 @@ class KmConstructor(var flags: Flags) : KmConstructorVisitor() {
* @property name the name of the function
*/
@Suppress("DEPRECATION")
class KmFunction(
class KmFunction @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(
var flags: Flags,
var name: String
var name: String,
) : KmFunctionVisitor() {
constructor(name: String) : this(0, name)
/**
* Type parameters of the function.
*/
@@ -452,23 +459,84 @@ class KmFunction(
}
}
/**
* Represents a Kotlin property accessor.
* Does not contain meaningful information except attributes, such as visibility and modality.
* Attributes can be read and written using extension functions, e.g. [KmPropertyAccessorAttributes.visibility] or [KmPropertyAccessorAttributes.isNotDefault].
*/
public class KmPropertyAccessorAttributes internal constructor(internal var flags: Flags) {
public constructor() : this(0)
}
/**
* 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
*/
@Suppress("DEPRECATION")
class KmProperty(
class KmProperty @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(
var flags: Flags,
var name: String,
var getterFlags: Flags,
var setterFlags: Flags
getterFlags: Flags,
setterFlags: Flags,
) : KmPropertyVisitor() {
constructor(name: String) : this(0, name, 0, 0)
/**
* Attributes of the getter of this property.
* Attributes can be retrieved with extension functions, such as [KmPropertyAccessorAttributes.visibility] or [KmPropertyAccessorAttributes.isNotDefault].
*
* Getter for property is always present, hence return type of this function is non-nullable.
*/
val getter: KmPropertyAccessorAttributes = KmPropertyAccessorAttributes(getterFlags)
/**
* Attributes of the setter of this property.
* Attributes can be retrieved with extension functions, such as [KmPropertyAccessorAttributes.visibility] or [KmPropertyAccessorAttributes.isNotDefault].
*
* Returns null if setter is absent, i.e. [KmProperty.isVar] is false.
*/
var setter: KmPropertyAccessorAttributes? = if (this.hasSetter) KmPropertyAccessorAttributes(setterFlags) else null
set(new) {
this.hasSetter = new != null
field = new
}
/**
* A legacy accessor for getter attributes.
*
* Property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag
* and [Flag.PropertyAccessor] flags.
*/
var getterFlags: Flags
get() = getter.flags
set(value) {
getter.flags = value
}
/**
* A legacy accessor to setter attributes.
*
* Property accessor flags, consisting of [Flag.HAS_ANNOTATIONS], visibility flag, modality flag
* and [Flag.PropertyAccessor] flags.
*
* Note that, for compatibility reasons, flags are present even the property is `val` and `setter` is null.
* In that case, flags for hasAnnotation, visibility and modality are copied from properties' flag, which may lead
* to incorrect results. For example, when property is annotated, [setterFlags] will also return true for [Flag.Common.HAS_ANNOTATIONS],
* even though there is no setter nor annotations on it.
*
* Setting this property when setter is absent changes the value, but does not create new [setter].
* This behavior is for compatibility only and will be removed in future versions.
*/
var setterFlags: Flags = getDefaultPropertyAccessorFlags(flags)
get() = setter?.flags ?: field
set(value) {
setter?.flags = value
field = value
}
/**
* Type parameters of the property.
*/
@@ -486,7 +554,15 @@ class KmProperty(
val contextReceiverTypes: MutableList<KmType> = ArrayList(0)
/**
* Value parameter of the setter of this property, if this is a `var` property.
* Value parameter of the setter of this property, if this is a `var` property and parameter is present.
* Parameter is present if and only if the setter is not default:
*
* ```kotlin
* var foo: String = ""
* set(param) {
* field = param.removePrefix("bar")
* }
* ```
*/
var setterParameter: KmValueParameter? = null
@@ -558,10 +634,13 @@ class KmProperty(
* @property name the name of the type alias
*/
@Suppress("DEPRECATION")
class KmTypeAlias(
class KmTypeAlias @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(
var flags: Flags,
var name: String
var name: String,
) : KmTypeAliasVisitor() {
constructor(name: String) : this(0, name)
/**
* Type parameters of the type alias.
*/
@@ -640,10 +719,13 @@ class KmTypeAlias(
* @property name the name of the value parameter
*/
@Suppress("DEPRECATION")
class KmValueParameter(
class KmValueParameter @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(
var flags: Flags,
var name: String
var name: String,
) : KmValueParameterVisitor() {
constructor(name: String) : this(0, name)
/**
* Type of the value parameter.
* If this is a `vararg` parameter of type `X`, returns the type `Array<out X>`.
@@ -694,12 +776,15 @@ class KmValueParameter(
* @property variance the declaration-site variance of the type parameter
*/
@Suppress("DEPRECATION")
class KmTypeParameter(
class KmTypeParameter @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(
var flags: Flags,
var name: String,
var id: Int,
var variance: KmVariance
var variance: KmVariance,
) : KmTypeParameterVisitor() {
constructor(name: String, id: Int, variance: KmVariance) : this(0, name, id, variance)
/**
* Upper bounds of the type parameter.
*/
@@ -735,7 +820,10 @@ class KmTypeParameter(
* @property flags type flags, consisting of [Flag.Type] flags
*/
@Suppress("DEPRECATION")
class KmType(var flags: Flags) : KmTypeVisitor() {
class KmType @Deprecated(FLAGS_CTOR_DEPRECATED) constructor(var flags: Flags) : KmTypeVisitor() {
constructor() : this(0)
/**
* Classifier of the type.
*/
@@ -994,7 +1082,7 @@ class KmEffect(
*/
@ExperimentalContracts
@Suppress("DEPRECATION")
class KmEffectExpression : KmEffectExpressionVisitor() {
class KmEffectExpression : KmEffectExpressionVisitor() {
/**
* Effect expression flags, consisting of [Flag.EffectExpression] flags.
*/
@@ -1155,3 +1243,6 @@ internal fun <T> T.addTo(collection: MutableCollection<T>): T {
collection.add(this)
return this
}
private const val FLAGS_CTOR_DEPRECATED =
"Constructor with flags is deprecated, use constructor without flags and assign them or corresponding extension properties directly."
@@ -0,0 +1,74 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:OptIn(ExperimentalStdlibApi::class)
package kotlinx.metadata.internal
import kotlinx.metadata.*
import kotlin.enums.EnumEntries
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty
import org.jetbrains.kotlin.metadata.deserialization.Flags.FlagField as ProtoFlagSet
import org.jetbrains.kotlin.metadata.deserialization.Flags as ProtoFlags
import org.jetbrains.kotlin.protobuf.Internal.EnumLite as ProtoEnumLite
internal class EnumFlagDelegate<Node, E : Enum<E>>(
val flags: KMutableProperty1<Node, Flags>,
private val protoSet: ProtoFlagSet<out ProtoEnumLite>,
private val entries: EnumEntries<E>,
private val flagValues: List<Flag>
) {
// Pre-built permutation ProtoEnum <> E to allow reordering of enum entries?
// Concern: if new enum values are added to metadata proto, everything (including existing flags) will break
operator fun getValue(thisRef: Node, property: KProperty<*>): E = entries[protoSet.get(flags.get(thisRef)).number]
operator fun setValue(thisRef: Node, property: KProperty<*>, value: E) {
flags.set(thisRef, flagValues[value.ordinal] + flags.get(thisRef))
}
}
// Public in internal package - for reuse in JvmFlags
public class BooleanFlagDelegate<Node>(private val flags: KMutableProperty1<Node, Flags>, private val flag: Flag) {
private val mask: Int
init {
require(flag.bitWidth == 1 && flag.value == 1) { "BooleanFlagDelegate can work only with boolean flags (bitWidth = 1 and value = 1), but $flag was passed" }
mask = 1 shl flag.offset
}
operator fun getValue(thisRef: Node, property: KProperty<*>): Boolean = flag(flags.get(thisRef))
operator fun setValue(thisRef: Node, property: KProperty<*>, value: Boolean) {
val newValue = if (value) flags.get(thisRef) or mask else flags.get(thisRef) and mask.inv()
flags.set(thisRef, newValue)
}
}
internal fun <Node> visibilityDelegate(flags: KMutableProperty1<Node, Flags>) =
EnumFlagDelegate(flags, ProtoFlags.VISIBILITY, Visibility.entries, Visibility.entries.map { it.flag })
internal fun <Node> modalityDelegate(flags: KMutableProperty1<Node, Flags>) =
EnumFlagDelegate(flags, ProtoFlags.MODALITY, Modality.entries, Modality.entries.map { it.flag })
internal fun <Node> memberKindDelegate(flags: KMutableProperty1<Node, Flags>) =
EnumFlagDelegate(flags, ProtoFlags.MEMBER_KIND, MemberKind.entries, MemberKind.entries.map { it.flag })
internal fun classBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmClass::flags, flag)
internal fun functionBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmFunction::flags, flag)
internal fun constructorBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmConstructor::flags, flag)
internal fun propertyBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmProperty::flags, flag)
internal fun propertyAccessorBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmPropertyAccessorAttributes::flags, flag)
internal fun typeBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmType::flags, flag)
internal fun valueParameterBooleanFlag(flag: Flag) = BooleanFlagDelegate(KmValueParameter::flags, flag)
internal fun <Node> annotationsOn(flags: KMutableProperty1<Node, Flags>) = BooleanFlagDelegate(flags, Flag(ProtoFlags.HAS_ANNOTATIONS))
@@ -527,5 +527,5 @@ fun ProtoBuf.Property.getPropertyGetterFlags(): Flags =
fun ProtoBuf.Property.getPropertySetterFlags(): Flags =
if (hasSetterFlags()) setterFlags else getDefaultPropertyAccessorFlags(flags)
private fun getDefaultPropertyAccessorFlags(flags: Flags): Flags =
internal fun getDefaultPropertyAccessorFlags(flags: Flags): Flags =
F.getAccessorFlags(F.HAS_ANNOTATIONS.get(flags), F.VISIBILITY.get(flags), F.MODALITY.get(flags), false, false, false)
@@ -34,7 +34,7 @@ private fun visitFunction(
sb.appendLine(function.contextReceiverTypes.joinToString(prefix = " context(", postfix = ")", transform = ::printType))
}
sb.append(" ")
sb.appendFlags(function.flags, FUNCTION_FLAGS_MAP)
sb.appendFunctionModifiers(function)
sb.append("fun ")
if (function.typeParameters.isNotEmpty()) {
function.typeParameters.joinTo(sb, prefix = "<", postfix = ">", transform = { printTypeParameter(it, settings) })
@@ -58,8 +58,6 @@ private fun visitProperty(
settings: KotlinpSettings,
sb: StringBuilder
) {
val flags: Flags = property.flags
sb.appendLine()
property.versionRequirements.map(::printVersionRequirement).forEach { versionRequirement ->
sb.appendLine(" // $versionRequirement")
@@ -79,15 +77,15 @@ private fun visitProperty(
if (property.syntheticMethodForDelegate != null) {
sb.appendLine(" // synthetic method for delegate: ${property.syntheticMethodForDelegate}")
}
if (JvmFlag.Property.IS_MOVED_FROM_INTERFACE_COMPANION(property.jvmFlags)) {
if (property.isMovedFromInterfaceCompanion) {
sb.appendLine(" // is moved from interface companion")
}
if (property.contextReceiverTypes.isNotEmpty()) {
sb.appendLine(property.contextReceiverTypes.joinToString(prefix = " context(", postfix = ")", transform = ::printType))
}
sb.append(" ")
sb.appendFlags(flags, PROPERTY_FLAGS_MAP)
sb.append(if (Flag.Property.IS_VAR(flags)) "var " else "val ")
sb.appendPropertyModifiers(property)
sb.append(if (property.isVar) "var " else "val ")
if (property.typeParameters.isNotEmpty()) {
property.typeParameters.joinTo(sb, prefix = "<", postfix = ">", transform = { printTypeParameter(it, settings) })
sb.append(" ")
@@ -97,18 +95,19 @@ private fun visitProperty(
}
sb.append(property.name)
sb.append(": ").append(property.returnType.let(::printType))
if (Flag.Property.HAS_CONSTANT(flags)) {
if (property.hasConstant) {
sb.append(" /* = ... */")
}
sb.appendLine()
if (Flag.Property.HAS_GETTER(flags)) {
if (property.hasGetter) {
sb.append(" ")
sb.appendFlags(property.getterFlags, PROPERTY_ACCESSOR_FLAGS_MAP)
sb.appendPropertyAccessorModifiers(property.getter)
sb.appendLine("get")
}
if (Flag.Property.HAS_SETTER(flags)) {
val setter = property.setter
if (setter != null) {
sb.append(" ")
sb.appendFlags(property.setterFlags, PROPERTY_ACCESSOR_FLAGS_MAP)
sb.appendPropertyAccessorModifiers(setter)
sb.append("set")
property.setterParameter?.let {
sb.append("(").append(printValueParameter(it)).append(")")
@@ -127,7 +126,7 @@ private fun visitConstructor(constructor: KmConstructor, sb: StringBuilder) {
sb.appendLine(" // signature: ${constructor.signature}")
}
sb.append(" ")
sb.appendFlags(constructor.flags, CONSTRUCTOR_FLAGS_MAP)
sb.appendConstructorModifiers(constructor)
sb.append("constructor(")
constructor.valueParameters.joinTo(sb, transform = ::printValueParameter)
sb.appendLine(")")
@@ -146,7 +145,7 @@ private fun visitTypeAlias(
sb.append(" ").append("@").append(renderAnnotation(annotation)).appendLine()
}
sb.append(" ")
sb.appendFlags(typeAlias.flags, VISIBILITY_FLAGS_MAP)
sb.append(VISIBILITY_MAP[typeAlias.visibility])
sb.append("typealias ").append(typeAlias.name)
if (typeAlias.typeParameters.isNotEmpty()) {
typeAlias.typeParameters.joinTo(sb, prefix = "<", postfix = ">") { printTypeParameter(it, settings) }
@@ -157,7 +156,6 @@ private fun visitTypeAlias(
}
private fun printType(type: KmType): String {
val flags: Flags = type.flags
val classifier = when (val cls = type.classifier) {
is KmClassifier.Class -> cls.name
is KmClassifier.TypeParameter -> "T#${cls.id}"
@@ -198,7 +196,7 @@ private fun printType(type: KmType): String {
if (type.isRaw) {
append("/* raw */ ")
}
appendFlags(flags, TYPE_FLAGS_MAP)
appendFlags(type.isSuspend to "suspend")
if (outerType != null) {
append(outerType).append(".").append(classifier.substringAfterLast('.'))
} else {
@@ -207,10 +205,10 @@ private fun printType(type: KmType): String {
if (arguments.isNotEmpty()) {
arguments.joinTo(this, prefix = "<", postfix = ">")
}
if (Flag.Type.IS_NULLABLE(flags)) {
if (type.isNullable) {
append("?")
}
if (Flag.Type.IS_DEFINITELY_NON_NULL(flags)) {
if (type.isDefinitelyNonNull) {
append(" & Any")
}
if (abbreviatedType != null) {
@@ -229,7 +227,7 @@ private fun printTypeParameter(
typeParameter: KmTypeParameter,
settings: KotlinpSettings
): String = buildString {
appendFlags(typeParameter.flags, TYPE_PARAMETER_FLAGS_MAP)
appendFlags(typeParameter.isReified to "reified")
for (annotation in typeParameter.annotations) {
append("@").append(renderAnnotation(annotation)).append(" ")
}
@@ -248,17 +246,16 @@ private fun printTypeParameter(
private fun printValueParameter(
valueParameter: KmValueParameter
): String {
val flags: Flags = valueParameter.flags
val type = printType(valueParameter.type)
val varargElementType = valueParameter.varargElementType?.let(::printType)
return buildString {
appendFlags(flags, VALUE_PARAMETER_FLAGS_MAP)
appendValueParameterModifiers(valueParameter)
if (varargElementType != null) {
append("vararg ").append(valueParameter.name).append(": ").append(varargElementType).append(" /* ").append(type).append(" */")
} else {
append(valueParameter.name).append(": ").append(type)
}
if (Flag.ValueParameter.DECLARES_DEFAULT_VALUE(flags)) {
if (valueParameter.declaresDefaultValue) {
append(" /* = ... */")
}
}
@@ -338,15 +335,6 @@ private fun printVersionRequirement(versionRequirement: KmVersionRequirement): S
}
}
private fun StringBuilder.appendFlags(flags: Flags, map: Map<Flag, String>) {
for ((modifier, string) in map) {
if (modifier(flags)) {
append(string)
if (string.isNotEmpty()) append(" ")
}
}
}
private fun StringBuilder.appendDeclarationContainerExtensions(
settings: KotlinpSettings,
localDelegatedProperties: List<StringBuilder>,
@@ -427,7 +415,6 @@ private fun printEffect(
@ExperimentalContracts
private fun printEffectExpression(effectExpression: KmEffectExpression): String {
val flags: Flags = effectExpression.flags
val parameterIndex: Int? = effectExpression.parameterIndex
val constantValue: List<Any?>? = effectExpression.constantValue?.let { listOf(it.value) }
val andArguments = effectExpression.andArguments.map(::printEffectExpression)
@@ -447,11 +434,11 @@ private fun printEffectExpression(effectExpression: KmEffectExpression): String
)
if (effectExpression.isInstanceType != null) {
append(" ")
if (Flag.EffectExpression.IS_NEGATED(flags)) append("!")
if (effectExpression.isNegated) append("!")
append("is ${effectExpression.isInstanceType?.let(::printType)}")
}
if (Flag.EffectExpression.IS_NULL_CHECK_PREDICATE(flags)) {
append(if (Flag.EffectExpression.IS_NEGATED(flags)) " != " else " == ")
if (effectExpression.isNullCheckPredicate) {
append(if (effectExpression.isNegated) " != " else " == ")
append("null")
}
@@ -478,7 +465,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
private val sb = StringBuilder()
internal val result = StringBuilder()
private var flags: Flags? = null
private var klass: KmClass? = null
private var name: ClassName? = null
private val typeParams = mutableListOf<String>()
private val supertypes = mutableListOf<String>()
@@ -496,7 +483,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
if (contextReceiverTypes.isNotEmpty()) {
result.appendLine(contextReceiverTypes.joinToString(prefix = "context(", postfix = ")"))
}
result.appendFlags(flags!!, CLASS_FLAGS_MAP)
result.appendClassModifiers(klass!!)
result.append(name)
if (typeParams.isNotEmpty()) {
typeParams.joinTo(result, prefix = "<", postfix = ">")
@@ -506,7 +493,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
supertypes.joinTo(result)
}
result.appendLine(" {")
if (Flag.Class.HAS_ENUM_ENTRIES(flags!!)) {
if (klass!!.hasEnumEntries) {
sb.appendLine()
sb.appendLine(" // has Enum.entries")
}
@@ -547,7 +534,6 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
private fun visitExtensions(kclass: KmClass) {
val localDelegatedProperties = mutableListOf<StringBuilder>()
val moduleName: String? = kclass.moduleName
val jvmFlags: Flags = kclass.jvmFlags
anonymousObjectOriginName = kclass.anonymousObjectOriginName
kclass.localDelegatedProperties.sortIfNeededBy(settings) { it.getterSignature?.toString() ?: it.name }.forEach { p ->
@@ -557,11 +543,11 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
}
sb.appendDeclarationContainerExtensions(settings, localDelegatedProperties, moduleName)
if (JvmFlag.Class.HAS_METHOD_BODIES_IN_INTERFACE(jvmFlags)) {
if (kclass.hasMethodBodiesInInterface) {
sb.appendLine()
sb.appendLine(" // has method bodies in interface")
}
if (JvmFlag.Class.IS_COMPILED_IN_COMPATIBILITY_MODE(jvmFlags)) {
if (kclass.isCompiledInCompatibilityMode) {
sb.appendLine()
sb.appendLine(" // is compiled in compatibility mode")
}
@@ -571,7 +557,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter<Kotl
@OptIn(ExperimentalContextReceivers::class)
fun print(kmClass: KmClass): String {
flags = kmClass.flags
klass = kmClass
name = kmClass.name
kmClass.typeParameters.forEach { typeParams.add(printTypeParameter(it, settings)) }
supertypes.addAll(kmClass.supertypes.map { printType(it) })
@@ -707,89 +693,108 @@ class ModuleFilePrinter(private val settings: KotlinpSettings) {
}
}
private val VISIBILITY_FLAGS_MAP = mapOf(
Flag.IS_INTERNAL to "internal",
Flag.IS_PRIVATE to "private",
Flag.IS_PRIVATE_TO_THIS to "private",
Flag.IS_PROTECTED to "protected",
Flag.IS_PUBLIC to "public",
Flag.IS_LOCAL to "local"
private val VISIBILITY_MAP = mapOf(
Visibility.INTERNAL to "internal ",
Visibility.PRIVATE to "private ",
Visibility.PRIVATE_TO_THIS to "private ",
Visibility.PROTECTED to "protected ",
Visibility.PUBLIC to "public ",
Visibility.LOCAL to "local "
)
private val COMMON_FLAGS_MAP = VISIBILITY_FLAGS_MAP + mapOf(
Flag.IS_FINAL to "final",
Flag.IS_OPEN to "open",
Flag.IS_ABSTRACT to "abstract",
Flag.IS_SEALED to "sealed"
private val MODALITY_MAP = mapOf(
Modality.FINAL to "final ",
Modality.OPEN to "open ",
Modality.ABSTRACT to "abstract ",
Modality.SEALED to "sealed "
)
private val CLASS_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flag.Class.IS_INNER to "inner",
Flag.Class.IS_DATA to "data",
Flag.Class.IS_EXTERNAL to "external",
Flag.Class.IS_EXPECT to "expect",
Flag.Class.IS_VALUE to "value",
Flag.Class.IS_FUN to "fun",
Flag.Class.IS_CLASS to "class",
Flag.Class.IS_INTERFACE to "interface",
Flag.Class.IS_ENUM_CLASS to "enum class",
Flag.Class.IS_ENUM_ENTRY to "enum entry",
Flag.Class.IS_ANNOTATION_CLASS to "annotation class",
Flag.Class.IS_OBJECT to "object",
Flag.Class.IS_COMPANION_OBJECT to "companion object"
private val CLASS_KIND_MAP = mapOf(
ClassKind.CLASS to "class ",
ClassKind.INTERFACE to "interface ",
ClassKind.ENUM_CLASS to "enum class ",
ClassKind.ENUM_ENTRY to "enum entry ",
ClassKind.ANNOTATION_CLASS to "annotation class ",
ClassKind.OBJECT to "object ",
ClassKind.COMPANION_OBJECT to "companion object "
)
private val CONSTRUCTOR_FLAGS_MAP = VISIBILITY_FLAGS_MAP + mapOf(
Flag.Constructor.IS_SECONDARY to "/* secondary */",
Flag.Constructor.HAS_NON_STABLE_PARAMETER_NAMES to "/* non-stable parameter names */"
private val MEMBER_KIND_MAP = mapOf(
MemberKind.DECLARATION to "",
MemberKind.FAKE_OVERRIDE to "/* fake override */ ",
MemberKind.DELEGATION to "/* delegation */ ",
MemberKind.SYNTHESIZED to "/* synthesized */ ",
)
private val FUNCTION_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flag.Function.IS_DECLARATION to "",
Flag.Function.IS_FAKE_OVERRIDE to "/* fake override */",
Flag.Function.IS_DELEGATION to "/* delegation */",
Flag.Function.IS_SYNTHESIZED to "/* synthesized */",
private fun StringBuilder.appendFlags(vararg modifiers: Pair<Boolean, String>) = modifiers.forEach { (condition, s) ->
if (condition) {
append(s)
if (s.isNotEmpty()) append(" ")
}
}
Flag.Function.IS_OPERATOR to "operator",
Flag.Function.IS_INFIX to "infix",
Flag.Function.IS_INLINE to "inline",
Flag.Function.IS_TAILREC to "tailrec",
Flag.Function.IS_EXTERNAL to "external",
Flag.Function.IS_SUSPEND to "suspend",
Flag.Function.IS_EXPECT to "expect",
private fun StringBuilder.appendClassModifiers(kmClass: KmClass) {
append(VISIBILITY_MAP[kmClass.visibility])
append(MODALITY_MAP[kmClass.modality])
appendFlags(
kmClass.isInner to "inner",
kmClass.isData to "data",
kmClass.isExternal to "external",
kmClass.isExpect to "expect",
kmClass.isValue to "value",
kmClass.isFunInterface to "fun",
)
append(CLASS_KIND_MAP[kmClass.kind])
}
Flag.Function.HAS_NON_STABLE_PARAMETER_NAMES to "/* non-stable parameter names */"
)
private val PROPERTY_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flag.Property.IS_DECLARATION to "",
Flag.Property.IS_FAKE_OVERRIDE to "/* fake override */",
Flag.Property.IS_DELEGATION to "/* delegation */",
Flag.Property.IS_SYNTHESIZED to "/* synthesized */",
Flag.Property.IS_CONST to "const",
Flag.Property.IS_LATEINIT to "lateinit",
Flag.Property.IS_EXTERNAL to "external",
Flag.Property.IS_DELEGATED to "/* delegated */",
Flag.Property.IS_EXPECT to "expect"
)
private val PROPERTY_ACCESSOR_FLAGS_MAP = COMMON_FLAGS_MAP + mapOf(
Flag.PropertyAccessor.IS_NOT_DEFAULT to "/* non-default */",
Flag.PropertyAccessor.IS_EXTERNAL to "external",
Flag.PropertyAccessor.IS_INLINE to "inline"
)
private val VALUE_PARAMETER_FLAGS_MAP = mapOf(
Flag.ValueParameter.IS_CROSSINLINE to "crossinline",
Flag.ValueParameter.IS_NOINLINE to "noinline"
)
private val TYPE_PARAMETER_FLAGS_MAP = mapOf(
Flag.TypeParameter.IS_REIFIED to "reified"
)
private val TYPE_FLAGS_MAP = mapOf(
Flag.Type.IS_SUSPEND to "suspend"
private fun StringBuilder.appendConstructorModifiers(kmConstructor: KmConstructor) {
append(VISIBILITY_MAP[kmConstructor.visibility])
appendFlags(
kmConstructor.isSecondary to "/* secondary */",
kmConstructor.hasNonStableParameterNames to "/* non-stable parameter names */"
)
}
private fun StringBuilder.appendFunctionModifiers(kmFunction: KmFunction) {
append(VISIBILITY_MAP[kmFunction.visibility])
append(MODALITY_MAP[kmFunction.modality])
append(MEMBER_KIND_MAP[kmFunction.kind])
appendFlags(
kmFunction.isOperator to "operator",
kmFunction.isInfix to "infix",
kmFunction.isInline to "inline",
kmFunction.isTailrec to "tailrec",
kmFunction.isExternal to "external",
kmFunction.isSuspend to "suspend",
kmFunction.isExpect to "expect",
kmFunction.hasNonStableParameterNames to "/* non-stable parameter names */"
)
}
private fun StringBuilder.appendPropertyModifiers(kmProperty: KmProperty) {
append(VISIBILITY_MAP[kmProperty.visibility])
append(MODALITY_MAP[kmProperty.modality])
append(MEMBER_KIND_MAP[kmProperty.kind])
appendFlags(
kmProperty.isConst to "const",
kmProperty.isLateinit to "lateinit",
kmProperty.isExternal to "external",
kmProperty.isDelegated to "/* delegated */",
kmProperty.isExpect to "expect"
)
}
private fun StringBuilder.appendPropertyAccessorModifiers(accessorAttributes: KmPropertyAccessorAttributes) {
append(VISIBILITY_MAP[accessorAttributes.visibility])
append(MODALITY_MAP[accessorAttributes.modality])
appendFlags(
accessorAttributes.isNotDefault to "/* non-default */",
accessorAttributes.isExternal to "external",
accessorAttributes.isInline to "inline"
)
}
private fun StringBuilder.appendValueParameterModifiers(valueParameter: KmValueParameter) = appendFlags(
valueParameter.isCrossinline to "crossinline",
valueParameter.isNoinline to "noinline"
)
@@ -7,6 +7,9 @@ package org.jetbrains.kotlin.commonizer.metadata
import gnu.trove.THashMap
import kotlinx.metadata.*
import kotlinx.metadata.Modality as KmModality
import kotlinx.metadata.Visibility as KmVisibility
import kotlinx.metadata.ClassKind as KmClassKind
import kotlinx.metadata.klib.annotations
import kotlinx.metadata.klib.compileTimeValue
import kotlinx.metadata.klib.getterAnnotations
@@ -126,9 +126,8 @@ internal fun linkSealedClassesWithSubclasses(packageName: CirPackageName, classC
internal fun CirClassConstructor.serializeConstructor(
context: CirTreeSerializationContext
): KmConstructor = KmConstructor(
flags = classConstructorFlags()
).also { constructor ->
): KmConstructor = KmConstructor().also { constructor ->
constructor.flags = classConstructorFlags()
annotations.mapTo(constructor.annotations) { it.serializeAnnotation() }
// TODO: nowhere to write constructor type parameters
valueParameters.mapTo(constructor.valueParameters) { it.serializeValueParameter(context) }
@@ -137,9 +136,9 @@ internal fun CirClassConstructor.serializeConstructor(
internal fun CirTypeAlias.serializeTypeAlias(
context: CirTreeSerializationContext
): KmTypeAlias = KmTypeAlias(
flags = typeAliasFlags(),
name = name.name
).also { typeAlias ->
typeAlias.flags = typeAliasFlags()
annotations.mapTo(typeAlias.annotations) { it.serializeAnnotation() }
typeParameters.serializeTypeParameters(context, output = typeAlias.typeParameters)
typeAlias.underlyingType = underlyingType.serializeType(context, expansion = ONLY_ABBREVIATIONS)
@@ -148,12 +147,10 @@ internal fun CirTypeAlias.serializeTypeAlias(
internal fun CirProperty.serializeProperty(
context: CirTreeSerializationContext,
): KmProperty = KmProperty(
flags = propertyFlags(isExpect = context.isCommon && !isLiftedUp),
name = name.name,
getterFlags = getter?.propertyAccessorFlags(this, this) ?: NO_FLAGS,
setterFlags = setter?.let { setter -> setter.propertyAccessorFlags(setter, this) } ?: NO_FLAGS
).also { property ->
): KmProperty = KmProperty(name = name.name).also { property ->
property.flags = propertyFlags(isExpect = context.isCommon && !isLiftedUp)
property.getterFlags = getter?.propertyAccessorFlags(this, this) ?: NO_FLAGS
property.setterFlags = setter?.let { setter -> setter.propertyAccessorFlags(setter, this) } ?: NO_FLAGS
annotations.mapTo(property.annotations) { it.serializeAnnotation() }
getter?.annotations?.mapTo(property.getterAnnotations) { it.serializeAnnotation() }
setter?.annotations?.mapTo(property.setterAnnotations) { it.serializeAnnotation() }
@@ -181,9 +178,9 @@ internal fun CirProperty.serializeProperty(
internal fun CirFunction.serializeFunction(
context: CirTreeSerializationContext,
): KmFunction = KmFunction(
flags = functionFlags(isExpect = context.isCommon && kind != CallableMemberDescriptor.Kind.SYNTHESIZED),
name = name.name
).also { function ->
function.flags = functionFlags(isExpect = context.isCommon && kind != CallableMemberDescriptor.Kind.SYNTHESIZED)
annotations.mapTo(function.annotations) { it.serializeAnnotation() }
typeParameters.serializeTypeParameters(context, output = function.typeParameters)
valueParameters.mapTo(function.valueParameters) { it.serializeValueParameter(context) }
@@ -242,9 +239,9 @@ private fun CirConstantValue.serializeConstantValue(): KmAnnotationArgument? = w
private fun CirValueParameter.serializeValueParameter(
context: CirTreeSerializationContext
): KmValueParameter = KmValueParameter(
flags = valueParameterFlags(),
name = name.name
).also { parameter ->
parameter.flags = valueParameterFlags()
annotations.mapTo(parameter.annotations) { it.serializeAnnotation() }
parameter.type = returnType.serializeType(context)
varargElementType?.let { varargElementType ->
@@ -258,11 +255,11 @@ private fun List<CirTypeParameter>.serializeTypeParameters(
) {
mapIndexedTo(output) { index, cirTypeParameter ->
KmTypeParameter(
flags = cirTypeParameter.typeParameterFlags(),
name = cirTypeParameter.name.name,
id = context.typeParameterIndexOffset + index,
variance = cirTypeParameter.variance.serializeVariance()
).also { parameter ->
parameter.flags = cirTypeParameter.typeParameterFlags()
cirTypeParameter.upperBounds.mapTo(parameter.upperBounds) { it.serializeType(context) }
cirTypeParameter.annotations.mapTo(parameter.annotations) { it.serializeAnnotation() }
}
@@ -287,14 +284,16 @@ private fun CirType.serializeType(
}
private fun CirTypeParameterType.serializeTypeParameterType(): KmType =
KmType(typeFlags()).also { type ->
KmType().also { type ->
applyTypeFlagsTo(type)
type.classifier = KmClassifier.TypeParameter(index)
}
private fun CirClassType.serializeClassType(
context: CirTreeSerializationContext,
expansion: TypeAliasExpansion = FOR_TOP_LEVEL_TYPE
): KmType = KmType(typeFlags()).also { type ->
): KmType = KmType().also { type ->
applyTypeFlagsTo(type)
type.classifier = KmClassifier.Class(classifierId.toString())
arguments.mapTo(type.arguments) { it.serializeArgument(context, expansion) }
outerType?.let { type.outerType = it.serializeClassType(context, expansion) }
@@ -318,7 +317,7 @@ private fun CirTypeAliasType.serializeAbbreviationType(
context: CirTreeSerializationContext,
expansion: TypeAliasExpansion
): KmType {
val abbreviationType = KmType(typeFlags())
val abbreviationType = KmType().also { applyTypeFlagsTo(it) }
abbreviationType.classifier = KmClassifier.TypeAlias(classifierId.toString())
arguments.mapTo(abbreviationType.arguments) { it.serializeArgument(context, expansion) }
return abbreviationType
@@ -5,9 +5,7 @@
package org.jetbrains.kotlin.commonizer.metadata
import kotlinx.metadata.Flag
import kotlinx.metadata.Flags
import kotlinx.metadata.flagsOf
import kotlinx.metadata.*
import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
@@ -59,11 +57,13 @@ internal fun CirClassConstructor.classConstructorFlags(): Flags =
Flag.Constructor.HAS_NON_STABLE_PARAMETER_NAMES.takeIf { !hasStableParameterNames }
)
internal fun CirType.typeFlags(): Flags =
flagsOfNotNull(
nullableFlag,
//Flag.Type.IS_SUSPEND.takeIf { false }
)
internal fun CirType.applyTypeFlagsTo(type: KmType) {
type.isNullable = when (this) {
is CirSimpleType -> isMarkedNullable
is CirFlexibleType -> lowerBound.isMarkedNullable
}
//Flag.Type.IS_SUSPEND.takeIf { false }
}
internal fun CirTypeParameter.typeParameterFlags(): Flags =
flagsOfNotNull(
@@ -172,14 +172,4 @@ private inline val CirProperty.modifiersFlags: Flags
Flag.Property.IS_LATEINIT.takeIf { isLateInit },
)
private inline val CirType.nullableFlag: Flag?
get() {
val isNullable = when (this) {
is CirSimpleType -> isMarkedNullable
is CirFlexibleType -> lowerBound.isMarkedNullable
}
return if (isNullable) Flag.Type.IS_NULLABLE else null
}
private fun flagsOfNotNull(vararg flags: Flag?): Flags = flagsOf(*listOfNotNull(*flags).toTypedArray())