diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt index f9a2366ba72..956c0920518 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt @@ -177,8 +177,7 @@ private class KlibMetadataDependencyContainer( KlibMetadataModuleDescriptorFactoryImpl( MetadataFactories.DefaultDescriptorFactory, MetadataFactories.DefaultPackageFragmentsFactory, - MetadataFactories.flexibleTypeDeserializer, - MetadataFactories.platformDependentTypeTransformer + MetadataFactories.flexibleTypeDeserializer ) } @@ -209,6 +208,5 @@ private class KlibMetadataDependencyContainer( private val MetadataFactories = KlibMetadataFactories( { DefaultBuiltIns.Instance }, - NullFlexibleTypeDeserializer, - NativeTypeTransformer() + NullFlexibleTypeDeserializer ) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt index 4c3f8b9dd26..8a213e27eff 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/mangle/descriptor/DescriptorMangleComputer.kt @@ -91,21 +91,10 @@ open class DescriptorMangleComputer(builder: StringBuilder, mode: MangleMode) : when (val type = wrappedType.unwrap()) { is SimpleType -> { - if (type is SupposititiousSimpleType) { - val classId = type.overwrittenClass - classId.packageFqName.let { - if (!it.isRoot) { - builder.appendSignature(it.asString()) - builder.appendSignature(MangleConstant.FQN_SEPARATOR) - } - builder.appendSignature(classId.relativeClassName.asString()) - } - } else { - when (val classifier = type.constructor.declarationDescriptor) { - is ClassDescriptor -> with(copy(MangleMode.FQNAME)) { classifier.visit() } - is TypeParameterDescriptor -> tBuilder.mangleTypeParameterReference(classifier) - else -> error("Unexpected classifier: $classifier") - } + when (val classifier = type.constructor.declarationDescriptor) { + is ClassDescriptor -> with(copy(MangleMode.FQNAME)) { classifier.visit() } + is TypeParameterDescriptor -> tBuilder.mangleTypeParameterReference(classifier) + else -> error("Unexpected classifier: $classifier") } mangleTypeArguments(tBuilder, type, null) diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt index d88ee9e1439..36238dd88a8 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt @@ -27,7 +27,6 @@ import org.jetbrains.kotlin.library.impl.KotlinLibraryLayoutForWriter import org.jetbrains.kotlin.library.impl.KotlinLibraryWriterImpl import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.KlibMetadataVersion -import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer import org.jetbrains.kotlin.library.resolveSingleFileKlib import org.jetbrains.kotlin.name.Name @@ -114,7 +113,7 @@ object KlibTestUtil { strategy = ToolingSingleFileKlibResolveStrategy ) - val metadataFactories = KlibMetadataFactories({ DefaultBuiltIns.Instance }, NullFlexibleTypeDeserializer, NativeTypeTransformer()) + val metadataFactories = KlibMetadataFactories({ DefaultBuiltIns.Instance }, NullFlexibleTypeDeserializer) val module = metadataFactories.DefaultDeserializedDescriptorFactory.createDescriptor( library = library, diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataFactories.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataFactories.kt index 83b88d80b56..47358385561 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataFactories.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataFactories.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.library.metadata import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer +import org.jetbrains.kotlin.descriptors.deserialization.* import org.jetbrains.kotlin.library.metadata.impl.KlibMetadataDeserializedPackageFragmentsFactoryImpl import org.jetbrains.kotlin.library.metadata.impl.KlibMetadataModuleDescriptorFactoryImpl import org.jetbrains.kotlin.library.metadata.impl.KlibModuleDescriptorFactoryImpl @@ -19,13 +19,8 @@ import org.jetbrains.kotlin.storage.StorageManager */ class KlibMetadataFactories( createBuiltIns: (StorageManager) -> KotlinBuiltIns, - val flexibleTypeDeserializer: FlexibleTypeDeserializer, - val platformDependentTypeTransformer: PlatformDependentTypeTransformer + val flexibleTypeDeserializer: FlexibleTypeDeserializer ) { - - constructor(createBuiltIns:(StorageManager) -> KotlinBuiltIns, flexibleTypeDeserializer: FlexibleTypeDeserializer) : - this(createBuiltIns, flexibleTypeDeserializer, PlatformDependentTypeTransformer.None) - /** * The default [KlibModuleDescriptorFactory] factory instance. */ @@ -58,8 +53,7 @@ class KlibMetadataFactories( KlibMetadataModuleDescriptorFactoryImpl( descriptorFactory, packageFragmentsFactory, - flexibleTypeDeserializer, - platformDependentTypeTransformer + flexibleTypeDeserializer ) fun createDefaultKonanResolvedModuleDescriptorsFactory( diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataModuleDescriptorFactory.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataModuleDescriptorFactory.kt index 290f0dbee40..75e6f537270 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataModuleDescriptorFactory.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/KlibMetadataModuleDescriptorFactory.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.library.KotlinLibrary @@ -22,7 +21,6 @@ interface KlibMetadataModuleDescriptorFactory { val descriptorFactory: KlibModuleDescriptorFactory val packageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory val flexibleTypeDeserializer: FlexibleTypeDeserializer - val platformDependentTypeTransformer: PlatformDependentTypeTransformer fun createDescriptor( library: KotlinLibrary, diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/NativeTypeTransformer.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/NativeTypeTransformer.kt deleted file mode 100644 index dfbbecacd8a..00000000000 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/NativeTypeTransformer.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2010-2020 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 org.jetbrains.kotlin.library.metadata - -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.NativeForwardDeclarationKind -import org.jetbrains.kotlin.types.SimpleType -import org.jetbrains.kotlin.types.SupposititiousSimpleType - -class NativeTypeTransformer : PlatformDependentTypeTransformer { - override fun transformPlatformType(classId: ClassId, computedType: SimpleType): SimpleType { - val originalPackageFqn = classId.packageFqName - if (originalPackageFqn in forwardPackagesSet) { - // This hack is about keeping original class id written into proto which is required for correct IR linkage - val constructor = computedType.constructor - val classDescriptor = constructor.declarationDescriptor as ClassDescriptor - val realPackageFqn = (classDescriptor.containingDeclaration as PackageFragmentDescriptor).fqName - if (originalPackageFqn != realPackageFqn) { - return SupposititiousSimpleType(computedType, classId) - } - } - - return computedType - } - - companion object { - private val forwardPackagesSet = NativeForwardDeclarationKind.entries.map { it.packageFqName }.toSet() - } -} \ No newline at end of file diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt index 03d1b318fa2..817ab7ff4c3 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/impl/KlibMetadataModuleDescriptorFactoryImpl.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentP import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.contracts.ContractDeserializerImpl import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl @@ -33,8 +32,7 @@ private val ModuleDescriptorImpl.isStdlibModule class KlibMetadataModuleDescriptorFactoryImpl( override val descriptorFactory: KlibModuleDescriptorFactory, override val packageFragmentsFactory: KlibMetadataDeserializedPackageFragmentsFactory, - override val flexibleTypeDeserializer: FlexibleTypeDeserializer, - override val platformDependentTypeTransformer: PlatformDependentTypeTransformer + override val flexibleTypeDeserializer: FlexibleTypeDeserializer ) : KlibMetadataModuleDescriptorFactory { override fun createDescriptorOptionalBuiltIns( @@ -173,7 +171,6 @@ class KlibMetadataModuleDescriptorFactoryImpl( ContractDeserializerImpl(configuration, storageManager), extensionRegistryLite = KlibMetadataSerializerProtocol.extensionRegistry, samConversionResolver = SamConversionResolverImpl(storageManager, samWithReceiverResolvers = emptyList()), - platformDependentTypeTransformer = platformDependentTypeTransformer, enumEntriesDeserializationSupport = enumEntriesDeserializationSupport, ) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/deserialization/PlatformDependentTypeTransformer.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/deserialization/PlatformDependentTypeTransformer.kt deleted file mode 100644 index 2bb6b276bab..00000000000 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/deserialization/PlatformDependentTypeTransformer.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2010-2020 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 org.jetbrains.kotlin.descriptors.deserialization - -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.types.SimpleType - -interface PlatformDependentTypeTransformer { - fun transformPlatformType(classId: ClassId, computedType: SimpleType): SimpleType - - object None : PlatformDependentTypeTransformer { - override fun transformPlatformType(classId: ClassId, computedType: SimpleType): SimpleType = computedType - } -} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt index 99300903431..948f031b93f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/types/KotlinTypeFactory.kt @@ -237,31 +237,6 @@ private class SimpleTypeImpl( } } -// Note: a hack to support class descriptor overwriting in case of K/N forward declaration replacement and other such cases -class SupposititiousSimpleType(private val realType: SimpleType, val overwrittenClass: ClassId) : SimpleType() { - - private fun maybeWrap(newType: SimpleType): SupposititiousSimpleType { - return if (newType === realType) this - else SupposititiousSimpleType(newType, overwrittenClass) - } - - override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType = - maybeWrap(realType.replaceAttributes(newAttributes)) - - override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = - maybeWrap(realType.makeNullableAsSpecified(newNullability)) - - @TypeRefinement - override fun refine(kotlinTypeRefiner: KotlinTypeRefiner): SimpleType = - maybeWrap(realType.refine(kotlinTypeRefiner)) - - override val constructor: TypeConstructor = realType.constructor - override val arguments: List = realType.arguments - override val isMarkedNullable: Boolean = realType.isMarkedNullable - override val memberScope: MemberScope = realType.memberScope - override val attributes: TypeAttributes get() = realType.attributes -} - abstract class DelegatingSimpleTypeImpl(override val delegate: SimpleType) : DelegatingSimpleType() { override fun replaceAttributes(newAttributes: TypeAttributes): SimpleType = if (newAttributes !== attributes) diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt index 578e92ade62..6dd08d6a66a 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/TypeDeserializer.kt @@ -137,11 +137,6 @@ class TypeDeserializer( simpleType.withAbbreviation(simpleType(it, expandTypeAliases = false)) } ?: simpleType - if (proto.hasClassName()) { - val classId = c.nameResolver.getClassId(proto.className) - return c.components.platformDependentTypeTransformer.transformPlatformType(classId, computedType) - } - return computedType } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt index 8e8eb7708ed..ae40a62e0d9 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/context.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.deserialization.AdditionalClassPartsProvider import org.jetbrains.kotlin.descriptors.deserialization.ClassDescriptorFactory import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentDeclarationFilter -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.* @@ -54,7 +53,6 @@ class DeserializationComponents( val extensionRegistryLite: ExtensionRegistryLite, val kotlinTypeChecker: NewKotlinTypeChecker = NewKotlinTypeChecker.Default, val samConversionResolver: SamConversionResolver, - val platformDependentTypeTransformer: PlatformDependentTypeTransformer = PlatformDependentTypeTransformer.None, val typeAttributeTranslators: List = listOf(DefaultTypeAttributeTranslator), val enumEntriesDeserializationSupport: EnumEntriesDeserializationSupport = EnumEntriesDeserializationSupport.Default, ) { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt index e8a1bb960c3..aa32d40ed9f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Fir2Ir.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.constant.EvaluatedConstTracker -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.descriptors.isEmpty import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.fir.backend.Fir2IrConfiguration @@ -39,7 +38,7 @@ import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.name.* -internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None) +internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer) internal fun PhaseContext.fir2Ir( input: FirOutput.Full, diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt index 9288fadecc4..7ab2312799a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/TopDownAnalyzerFacadeForKonan.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.library.metadata.CurrentKlibModuleOrigin import org.jetbrains.kotlin.library.metadata.KlibMetadataFactories -import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtFile @@ -29,7 +28,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid internal object TopDownAnalyzerFacadeForKonan { - private val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer()) + private val nativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer) fun analyzeFiles(files: Collection, context: FrontendContext): AnalysisResult { val config = context.config diff --git a/kotlin-native/backend.native/tests/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt b/kotlin-native/backend.native/tests/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt index ec65851f152..ea0bf680d73 100644 --- a/kotlin-native/backend.native/tests/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt +++ b/kotlin-native/backend.native/tests/samples/tensorflow/src/tensorflowMain/kotlin/HelloTensorflow.kt @@ -8,6 +8,11 @@ package sample.tensorflow import kotlinx.cinterop.* import platform.posix.size_t import tensorflow.* +import cnames.structs.TF_Status +import cnames.structs.TF_Operation +import cnames.structs.TF_Tensor +import cnames.structs.TF_OperationDescription +import cnames.structs.TF_Session typealias Status = CPointer typealias Operation = CPointer diff --git a/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt b/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt index b50c62b69e8..30365dd212e 100644 --- a/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt +++ b/kotlin-native/klib/src/main/kotlin/org/jetbrains/kotlin/cli/klib/main.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.konan.file.File @@ -33,7 +32,7 @@ import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.util.removeSuffixIfPresent import kotlin.system.exitProcess -internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer, PlatformDependentTypeTransformer.None) +internal val KlibFactories = KlibMetadataFactories(::KonanBuiltIns, DynamicTypeDeserializer) fun printUsage() { println("Usage: klib ")