From 6dc34fb050a9bc83a2fcee319ac8ff12fb5acf7a Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Thu, 25 Aug 2022 15:37:31 +0200 Subject: [PATCH] J2K: fix not working isPossibleToUseRangeUntil check ^KTIJ-22394 Fixed Invoking `isPossibleToUseRangeUntil` on `from.psi` is a bad idea because `from.psi` can be located in a different module. But most importanlty, `from.psi` is a Java psi and `languageVersionSettings` invoked on Java psi returns garbage. GitOrigin-RevId: 53dd19da66204e0463f19a06db4a755a0e8d3b77 --- .../ReplaceRangeToWithUntilInspection.kt | 2 +- .../ReplaceUntilWithRangeUntilInspection.kt | 16 ++++++++++++++ .../org/jetbrains/kotlin/nj2k/expressions.kt | 21 +++++++------------ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceRangeToWithUntilInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceRangeToWithUntilInspection.kt index 5eb23e8d218c..42fc4e485163 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceRangeToWithUntilInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceRangeToWithUntilInspection.kt @@ -11,9 +11,9 @@ import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.codeInsight.hints.RangeKtExpressionType import org.jetbrains.kotlin.idea.codeInsight.hints.RangeKtExpressionType.* +import org.jetbrains.kotlin.idea.inspections.ReplaceUntilWithRangeUntilInspection.Companion.isPossibleToUseRangeUntil import org.jetbrains.kotlin.idea.intentions.getArguments import org.jetbrains.kotlin.lexer.KtTokens -import org.jetbrains.kotlin.nj2k.isPossibleToUseRangeUntil import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.util.getType diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceUntilWithRangeUntilInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceUntilWithRangeUntilInspection.kt index 9d7cd063f121..708a2e231a24 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceUntilWithRangeUntilInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/ReplaceUntilWithRangeUntilInspection.kt @@ -5,15 +5,21 @@ import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.ProblemDescriptor import com.intellij.codeInspection.ProblemsHolder import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings import org.jetbrains.kotlin.idea.base.resources.KotlinBundle import org.jetbrains.kotlin.idea.codeInsight.hints.RangeKtExpressionType import org.jetbrains.kotlin.idea.codeInsight.hints.RangeKtExpressionType.* import org.jetbrains.kotlin.idea.intentions.getArguments +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.nj2k.EXPERIMENTAL_STDLIB_API_ANNOTATION import org.jetbrains.kotlin.nj2k.isPossibleToUseRangeUntil +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtPsiFactory import org.jetbrains.kotlin.psi.createExpressionByPattern import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.checkers.OptInUsageChecker.Companion.isOptInAllowed /** * Tests: @@ -43,4 +49,14 @@ class ReplaceUntilWithRangeUntilInspection : AbstractRangeInspection() { element.replace(KtPsiFactory(element).createExpressionByPattern("$0..<$1", left, right)) } } + + companion object { + fun KtElement.isPossibleToUseRangeUntil(context: Lazy?): Boolean { + val annotationFqName = FqName(EXPERIMENTAL_STDLIB_API_ANNOTATION) + val languageVersionSettings = languageVersionSettings + return languageVersionSettings.isPossibleToUseRangeUntil() || + languageVersionSettings.supportsFeature(LanguageFeature.RangeUntilOperator) && + context?.let { isOptInAllowed(annotationFqName, languageVersionSettings, it.value) } == true + } + } } diff --git a/plugins/kotlin/j2k/new/src/org/jetbrains/kotlin/nj2k/expressions.kt b/plugins/kotlin/j2k/new/src/org/jetbrains/kotlin/nj2k/expressions.kt index f5bd8a080e23..1e8a551c52b1 100644 --- a/plugins/kotlin/j2k/new/src/org/jetbrains/kotlin/nj2k/expressions.kt +++ b/plugins/kotlin/j2k/new/src/org/jetbrains/kotlin/nj2k/expressions.kt @@ -6,8 +6,8 @@ import com.intellij.psi.PsiElement import com.intellij.psi.tree.TokenSet import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings -import org.jetbrains.kotlin.idea.base.util.module import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.nj2k.conversions.RecursiveApplicableConversionBase @@ -15,16 +15,11 @@ import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol import org.jetbrains.kotlin.nj2k.symbols.JKSymbol import org.jetbrains.kotlin.nj2k.symbols.JKUnresolvedMethod import org.jetbrains.kotlin.nj2k.tree.* - - import org.jetbrains.kotlin.nj2k.types.JKNoType import org.jetbrains.kotlin.nj2k.types.JKType import org.jetbrains.kotlin.nj2k.types.JKTypeFactory import org.jetbrains.kotlin.nj2k.types.replaceJavaClassWithKotlinClassType -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.annotations.KOTLIN_THROWS_ANNOTATION_FQ_NAME -import org.jetbrains.kotlin.resolve.checkers.OptInUsageChecker.Companion.isOptInAllowed import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -48,7 +43,7 @@ fun untilToExpression( rangeExpression( from, to, - if (from.psi?.isPossibleToUseRangeUntil(context = null) == true) "..<" else "until", + if (conversionContext.converter.targetModule?.languageVersionSettings?.isPossibleToUseRangeUntil() == true) "..<" else "until", conversionContext ) @@ -374,10 +369,8 @@ val JKTreeElement.identifier: JKSymbol? val JKClass.isObjectOrCompanionObject get() = classKind == JKClass.ClassKind.OBJECT || classKind == JKClass.ClassKind.COMPANION -fun PsiElement.isPossibleToUseRangeUntil(context: Lazy?): Boolean { - val annotationFqName = FqName("kotlin.ExperimentalStdlibApi") - val languageVersionSettings = languageVersionSettings - return languageVersionSettings.supportsFeature(LanguageFeature.RangeUntilOperator) && - (annotationFqName.asString() in languageVersionSettings.getFlag(AnalysisFlags.optIn) || - context?.let { isOptInAllowed(annotationFqName, languageVersionSettings, it.value) } == true) -} +const val EXPERIMENTAL_STDLIB_API_ANNOTATION = "kotlin.ExperimentalStdlibApi" + +fun LanguageVersionSettings.isPossibleToUseRangeUntil(): Boolean = + supportsFeature(LanguageFeature.RangeUntilOperator) && + FqName(EXPERIMENTAL_STDLIB_API_ANNOTATION).asString() in getFlag(AnalysisFlags.optIn)