diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt index 6112a9105dd..fbd8057033e 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/StubIrMetadataEmitter.kt @@ -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()) } diff --git a/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api b/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api index 63b17ad3577..c9334c339d7 100644 --- a/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api +++ b/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api @@ -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 ()V public fun (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 (ILjava/lang/String;)V + public fun (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 (ILjava/lang/String;II)V + public fun (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 ()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 ()V public fun (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 (ILjava/lang/String;)V + public fun (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 (ILjava/lang/String;ILkotlinx/metadata/KmVariance;)V + public fun (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 (ILjava/lang/String;)V + public fun (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; diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmAttributes.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmAttributes.kt new file mode 100644 index 00000000000..24dfd37c18a --- /dev/null +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmAttributes.kt @@ -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)) diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmFlag.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmFlag.kt index e560df79bd9..fd3561a097c 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmFlag.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/JvmFlag.kt @@ -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) } diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/internal/JvmExtensionNodes.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/internal/JvmExtensionNodes.kt index 1aa52d7ab5c..095146c2edf 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/internal/JvmExtensionNodes.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/internal/JvmExtensionNodes.kt @@ -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() diff --git a/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/FlagDelegatesTest.kt b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/FlagDelegatesTest.kt new file mode 100644 index 00000000000..8fb33cc0dd0 --- /dev/null +++ b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/FlagDelegatesTest.kt @@ -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, 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) + } + + } +} diff --git a/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt index 6e5c0737b8b..56a938679dd 100644 --- a/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt +++ b/libraries/kotlinx-metadata/jvm/test/kotlinx/metadata/test/MetadataSmokeTest.kt @@ -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("", "()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 diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/Attributes.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/Attributes.kt new file mode 100644 index 00000000000..57d2edda853 --- /dev/null +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/Attributes.kt @@ -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)) diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/Flag.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/Flag.kt index 194618950ef..f2204de8e40 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/Flag.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/Flag.kt @@ -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) /** diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/Modifiers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/Modifiers.kt new file mode 100644 index 00000000000..892b8226837 --- /dev/null +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/Modifiers.kt @@ -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(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) { + * 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) +} diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/Nodes.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/Nodes.kt index 531a07f5715..e12ae3fa4dc 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/Nodes.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/Nodes.kt @@ -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 = 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`. @@ -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.addTo(collection: MutableCollection): 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." diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/FlagDelegatesImpl.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/FlagDelegatesImpl.kt new file mode 100644 index 00000000000..60794603810 --- /dev/null +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/FlagDelegatesImpl.kt @@ -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>( + val flags: KMutableProperty1, + private val protoSet: ProtoFlagSet, + private val entries: EnumEntries, + private val flagValues: List +) { + // 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(private val flags: KMutableProperty1, 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 visibilityDelegate(flags: KMutableProperty1) = + EnumFlagDelegate(flags, ProtoFlags.VISIBILITY, Visibility.entries, Visibility.entries.map { it.flag }) + +internal fun modalityDelegate(flags: KMutableProperty1) = + EnumFlagDelegate(flags, ProtoFlags.MODALITY, Modality.entries, Modality.entries.map { it.flag }) + +internal fun memberKindDelegate(flags: KMutableProperty1) = + 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 annotationsOn(flags: KMutableProperty1) = BooleanFlagDelegate(flags, Flag(ProtoFlags.HAS_ANNOTATIONS)) + diff --git a/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/Readers.kt b/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/Readers.kt index e283a87a930..c4278c0a9a6 100644 --- a/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/Readers.kt +++ b/libraries/kotlinx-metadata/src/kotlinx/metadata/internal/Readers.kt @@ -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) diff --git a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt index 5c34660b65b..490d50f7b6c 100644 --- a/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt +++ b/libraries/tools/kotlinp/src/org/jetbrains/kotlin/kotlinp/printers.kt @@ -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) { - for ((modifier, string) in map) { - if (modifier(flags)) { - append(string) - if (string.isNotEmpty()) append(" ") - } - } -} - private fun StringBuilder.appendDeclarationContainerExtensions( settings: KotlinpSettings, localDelegatedProperties: List, @@ -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? = 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() private val supertypes = mutableListOf() @@ -496,7 +483,7 @@ class ClassPrinter(private val settings: KotlinpSettings) : AbstractPrinter() 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) = 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" ) diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt index b0d7d0015a7..4ee41877471 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirDeserializers.kt @@ -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 diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirSerializers.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirSerializers.kt index 640e8e9095c..516d4155825 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirSerializers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/CirSerializers.kt @@ -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.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 diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/flags.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/flags.kt index 7e485ee7f24..6f289b8ceeb 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/flags.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/commonizer/metadata/flags.kt @@ -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())