diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/JavaTypeEnhancementStateParser.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/JavaTypeEnhancementStateParser.kt index 8291b93b956..e429e7cd7fe 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/JavaTypeEnhancementStateParser.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/JavaTypeEnhancementStateParser.kt @@ -65,25 +65,30 @@ class JavaTypeEnhancementStateParser( } } - private fun parseNullabilityAnnotationReportLevels(nullabilityAnnotations: Array?): NullabilityAnnotationStates { + private fun parseNullabilityAnnotationReportLevels(item: String): Pair? { + if (!item.startsWith("@")) { + reportUnrecognizedReportLevel(item, NULLABILITY_ANNOTATIONS_COMPILER_OPTION) + return null + } + + val (name, state) = parseAnnotationWithReportLevel(item, NULLABILITY_ANNOTATIONS_COMPILER_OPTION) ?: return null + + return name to state + } + + private fun parseNullabilityAnnotationReportLevels(nullabilityAnnotations: Array?): NullabilityAnnotationStates { if (nullabilityAnnotations.isNullOrEmpty()) return NullabilityAnnotationStates.EMPTY val annotationsWithReportLevels = mutableMapOf() - val compilerOption = "-Xnullability-annotations" for (item in nullabilityAnnotations) { - if (!item.startsWith("@")) { - reportUnrecognizedReportLevel(item, compilerOption) - continue - } - - val (name, state) = parseAnnotationWithReportLevel(item, compilerOption) ?: continue + val (name, state) = parseNullabilityAnnotationReportLevels(item) ?: continue val current = annotationsWithReportLevels[name] if (current == null) { annotationsWithReportLevels[name] = state } else if (current != state) { - reportDuplicateAnnotation("@$name:${current.description}", item, compilerOption) + reportDuplicateAnnotation("@$name:${current.description}", item, NULLABILITY_ANNOTATIONS_COMPILER_OPTION) continue } } @@ -93,7 +98,7 @@ class JavaTypeEnhancementStateParser( private fun parseJspecifyReportLevel( jspecifyState: String?, - nullabilityAnnotationReportLevels: NullabilityAnnotationStates + nullabilityAnnotationReportLevels: NullabilityAnnotationStates ): ReportLevel { if (jspecifyState == null) return getReportLevelForAnnotation(JSPECIFY_ANNOTATIONS_PACKAGE, nullabilityAnnotationReportLevels, kotlinVersion) @@ -198,8 +203,9 @@ class JavaTypeEnhancementStateParser( companion object { private val DEFAULT = JavaTypeEnhancementStateParser(MessageCollector.NONE, KotlinVersion.CURRENT) + private const val NULLABILITY_ANNOTATIONS_COMPILER_OPTION = "-Xnullability-annotations" - fun parsePlainNullabilityAnnotationReportLevels(nullabilityAnnotations: String) = - DEFAULT.parseNullabilityAnnotationReportLevels(arrayOf(nullabilityAnnotations)).singleOrNull() + fun parsePlainNullabilityAnnotationReportLevels(nullabilityAnnotations: String): Pair = + DEFAULT.parseNullabilityAnnotationReportLevels(nullabilityAnnotations)!! } } diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AllNullabilityAnnotationsAreSetUp.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AllNullabilityAnnotationsAreSetUp.kt index 1499c7f834f..007fa8bea57 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AllNullabilityAnnotationsAreSetUp.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/AllNullabilityAnnotationsAreSetUp.kt @@ -16,7 +16,7 @@ class AllNullabilityAnnotationsAreSetUpTest : KtUsefulTestCase() { val annotationsRawMap = (NULLABILITY_ANNOTATION_SETTINGS as NullabilityAnnotationStatesImpl).states assert(NULLABILITY_ANNOTATIONS.all { annotation -> annotationsRawMap.keys.any { annotation.isChildOf(it) } }) { val missedAnnotations = NULLABILITY_ANNOTATIONS.filter { annotation -> - annotationsRawMap.keys.none { annotation.isChildOf(it) } + annotationsRawMap.keys.none { annotation == it || annotation.isChildOf(it) } } "Not all nullability annotations are presented in `nullabilityAnnotationSettings`. Missed annotations: $missedAnnotations" } @@ -24,8 +24,8 @@ class AllNullabilityAnnotationsAreSetUpTest : KtUsefulTestCase() { fun testAllSetUpAnnotationsArePresent() { val annotationsRawMap = (NULLABILITY_ANNOTATION_SETTINGS as NullabilityAnnotationStatesImpl).states - assert(annotationsRawMap.keys.all { annotationsPackage -> - NULLABILITY_ANNOTATIONS.any { it.isChildOf(annotationsPackage) } + assert(annotationsRawMap.keys.all { annotations -> + NULLABILITY_ANNOTATIONS.any { it == annotations || it.isChildOf(annotations) } }) { val missedAnnotations = annotationsRawMap.keys.filter { annotationsPackage -> NULLABILITY_ANNOTATIONS.none { it.isChildOf(annotationsPackage) } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt index 487a8887a6c..96d510f4e43 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.load.java import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.findValueForMostSpecificFqname import org.jetbrains.kotlin.storage.LockBasedStorageManager +import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable import org.jetbrains.kotlin.storage.StorageManager val JSPECIFY_ANNOTATIONS_PACKAGE = FqName("org.jspecify.nullness") @@ -72,7 +73,7 @@ fun getDefaultReportLevelForAnnotation(annotationFqName: FqName) = fun getReportLevelForAnnotation( annotation: FqName, - configuredReportLevels: NullabilityAnnotationStates, + configuredReportLevels: NullabilityAnnotationStates, configuredKotlinVersion: KotlinVersion = KotlinVersion.CURRENT ): ReportLevel { configuredReportLevels[annotation]?.let { return it } @@ -89,8 +90,6 @@ fun getReportLevelForAnnotation( interface NullabilityAnnotationStates { operator fun get(fqName: FqName): T? - fun singleOrNull(): Pair? - companion object { val EMPTY: NullabilityAnnotationStates = NullabilityAnnotationStatesImpl(emptyMap()) } @@ -104,6 +103,4 @@ class NullabilityAnnotationStatesImpl(val states: Map) : Nul } override operator fun get(fqName: FqName) = cache(fqName) - - override fun singleOrNull() = states.entries.singleOrNull()?.toPair() } diff --git a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt index c27b295858c..66c94c38d16 100644 --- a/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt +++ b/kotlin-native/backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt @@ -314,8 +314,8 @@ class K2NativeCompilerArguments : CommonCompilerArguments() { @Argument(value="-Xgc-aggressive", description = "Make GC agressive. Works only with -memory-model experimental") var gcAggressive: Boolean = false - override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> = - super.configureAnalysisFlags(collector).also { + override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> = + super.configureAnalysisFlags(collector, languageVersion).also { val useExperimental = it[AnalysisFlags.useExperimental] as List<*> it[AnalysisFlags.useExperimental] = useExperimental + listOf("kotlin.ExperimentalUnsignedTypes") if (printIr)