diff --git a/core/util.runtime/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt b/core/util.runtime/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt index 1d4fb453367..102eefcdcbc 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/load/java/JavaNullabilityAnnotationSettings.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.load.java import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.isChildOf +import org.jetbrains.kotlin.name.findValueForMostSpecificFqname val JSPECIFY_ANNOTATIONS_PACKAGE = FqName("org.jspecify.nullness") val CHECKER_FRAMEWORK_COMPATQUAL_ANNOTATIONS_PACKAGE = FqName("org.checkerframework.checker.nullness.compatqual") @@ -38,21 +38,10 @@ val jsr305Settings = JavaNullabilityAnnotationsStatus( fun getDefaultReportLevelForAnnotation(annotationFqName: FqName) = getReportLevelForAnnotation(annotationFqName, emptyMap()) -fun getReportLevelForAnnotation(annotationFqName: FqName, configuredReportLevels: Map): ReportLevel { - val configuredReportLevel = configuredReportLevels.entries.find { (fqName, _) -> - annotationFqName == fqName || annotationFqName.isChildOf(fqName) - }?.value +fun getReportLevelForAnnotation(annotation: FqName, configuredReportLevels: Map): ReportLevel { + annotation.findValueForMostSpecificFqname(configuredReportLevels)?.let { return it } - if (configuredReportLevel != null) return configuredReportLevel - - val defaultReportLevel = nullabilityAnnotationSettings.entries.find { (fqName, _) -> - annotationFqName == fqName || annotationFqName.isChildOf(fqName) - }?.value - - require(defaultReportLevel != null) { - println(nullabilityAnnotationSettings) - "Default settings for nullability annotation ${annotationFqName.asString()} must be described" - } + val defaultReportLevel = annotation.findValueForMostSpecificFqname(nullabilityAnnotationSettings) ?: return ReportLevel.IGNORE return if (defaultReportLevel.sinceVersion != null && defaultReportLevel.sinceVersion <= KotlinVersion.CURRENT) { defaultReportLevel.reportLevelAfter diff --git a/core/util.runtime/src/org/jetbrains/kotlin/name/FqNamesUtil.kt b/core/util.runtime/src/org/jetbrains/kotlin/name/FqNamesUtil.kt index b71e4f5a67e..8adaa267b57 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/name/FqNamesUtil.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/name/FqNamesUtil.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2010-2021 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.name @@ -72,11 +61,17 @@ fun isValidJavaFqName(qualifiedName: String?): Boolean { State.MIDDLE -> { if (c == '.') { state = State.AFTER_DOT - } - else if (!Character.isJavaIdentifierPart(c)) return false + } else if (!Character.isJavaIdentifierPart(c)) return false } } } return state != State.AFTER_DOT } + +fun FqName.findValueForMostSpecificFqname(values: Map): V? { + val suitableItems = values.filter { (fqName, _) -> this == fqName || this.isChildOf(fqName) } + .takeIf { it.isNotEmpty() } ?: return null + + return suitableItems.minByOrNull { (fqName, _) -> fqName.tail(this).asString().length }?.value +}