diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt index 0786a219ffe..ab41cfeee84 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/Deprecation.kt @@ -108,19 +108,6 @@ internal sealed class DeprecatedByAnnotation( } return StandardDeprecated(deprecatedAnnotation, target, propagatesToOverrides) } - - private fun computeLevelForDeprecatedSinceKotlin(annotation: AnnotationDescriptor, apiVersion: ApiVersion): DeprecationLevelValue? { - val hiddenSince = annotation.getSinceVersion("hiddenSince") - if (hiddenSince != null && apiVersion >= hiddenSince) return HIDDEN - - val errorSince = annotation.getSinceVersion("errorSince") - if (errorSince != null && apiVersion >= errorSince) return ERROR - - val warningSince = annotation.getSinceVersion("warningSince") - if (warningSince != null && apiVersion >= warningSince) return WARNING - - return null - } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt index 5ca10484e4d..c89e7c6a6b4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/deprecation/deprecationUtil.kt @@ -26,6 +26,19 @@ fun Deprecation.deprecatedByAnnotationReplaceWithExpression(): String? = (this a fun AnnotationDescriptor.getSinceVersion(name: String): ApiVersion? = argumentValue(name)?.safeAs()?.value?.takeUnless(String::isEmpty)?.let(ApiVersion.Companion::parse) +fun computeLevelForDeprecatedSinceKotlin(annotation: AnnotationDescriptor, apiVersion: ApiVersion): DeprecationLevelValue? { + val hiddenSince = annotation.getSinceVersion("hiddenSince") + if (hiddenSince != null && apiVersion >= hiddenSince) return HIDDEN + + val errorSince = annotation.getSinceVersion("errorSince") + if (errorSince != null && apiVersion >= errorSince) return ERROR + + val warningSince = annotation.getSinceVersion("warningSince") + if (warningSince != null && apiVersion >= warningSince) return WARNING + + return null +} + internal fun createDeprecationDiagnostic( element: PsiElement, deprecation: Deprecation, languageVersionSettings: LanguageVersionSettings ): Diagnostic { diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DeclarationLookupObjectImpl.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DeclarationLookupObjectImpl.kt index e6853f764f7..51dfa19dee1 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DeclarationLookupObjectImpl.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/DeclarationLookupObjectImpl.kt @@ -9,11 +9,14 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiDocCommentOwner import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject import org.jetbrains.kotlin.idea.imports.importableFqName +import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.deprecation.computeLevelForDeprecatedSinceKotlin import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution /** @@ -56,8 +59,22 @@ abstract class DeclarationLookupObjectImpl( override val isDeprecated: Boolean get() { return if (descriptor != null) - KotlinBuiltIns.isDeprecated(descriptor) + isDeprecatedAtCallSite(descriptor, psiElement?.languageVersionSettings) else (psiElement as? PsiDocCommentOwner)?.isDeprecated == true } + +} + +// This function is kind of a hack to avoid using DeprecationResolver as it's hard to preserve same resolutionFacade for descriptor +private fun isDeprecatedAtCallSite(descriptor: DeclarationDescriptor, languageVersionSettings: LanguageVersionSettings?): Boolean { + val isDeprecatedAtDeclarationSite = KotlinBuiltIns.isDeprecated(descriptor) + if (languageVersionSettings == null) return isDeprecatedAtDeclarationSite + + if (!isDeprecatedAtDeclarationSite) return false + + return computeLevelForDeprecatedSinceKotlin( + descriptor.original.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.deprecatedSinceKotlin) ?: return true, + languageVersionSettings.apiVersion + ) != null } diff --git a/idea/idea-completion/testData/weighers/basic/DeprecatedSinceKotlinFun.kt b/idea/idea-completion/testData/weighers/basic/DeprecatedSinceKotlinFun.kt new file mode 100644 index 00000000000..0570f301507 --- /dev/null +++ b/idea/idea-completion/testData/weighers/basic/DeprecatedSinceKotlinFun.kt @@ -0,0 +1,19 @@ +fun foo1() {} + +@Suppress("DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE") +@Deprecated("") +@DeprecatedSinceKotlin(warningSince = "1.0") +fun foo2() {} + +@Suppress("DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE") +@Deprecated("") +@DeprecatedSinceKotlin(warningSince = "999.999") +fun foo3() {} + +fun foo4() {} + +fun test() { + foo +} + +// ORDER: foo1, foo3, foo4, foo2 \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java index 7c81e0095a0..471eb610940 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/weighers/BasicCompletionWeigherTestGenerated.java @@ -58,6 +58,11 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion runTest("idea/idea-completion/testData/weighers/basic/DeprecatedJavaClass.kt"); } + @TestMetadata("DeprecatedSinceKotlinFun.kt") + public void testDeprecatedSinceKotlinFun() throws Exception { + runTest("idea/idea-completion/testData/weighers/basic/DeprecatedSinceKotlinFun.kt"); + } + @TestMetadata("DslCallWithExpectedType.kt") public void testDslCallWithExpectedType() throws Exception { runTest("idea/idea-completion/testData/weighers/basic/DslCallWithExpectedType.kt"); diff --git a/idea/testData/parameterInfo/functionCall/deprecatedSinceKotlinNotApplicable.kt b/idea/testData/parameterInfo/functionCall/deprecatedSinceKotlinNotApplicable.kt index 4b10ec1c81e..be3882e4ad4 100644 --- a/idea/testData/parameterInfo/functionCall/deprecatedSinceKotlinNotApplicable.kt +++ b/idea/testData/parameterInfo/functionCall/deprecatedSinceKotlinNotApplicable.kt @@ -1,6 +1,6 @@ @Suppress("DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE") @Deprecated("") -@DeprecatedSinceKotlin(warningSince = "1.9") +@DeprecatedSinceKotlin(warningSince = "999.999") fun f(x: Int) {} fun d(x: Int) {