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
This commit is contained in:
Nikita Bobko
2022-08-25 18:31:13 +00:00
committed by intellij-monorepo-bot
parent a4adc6110f
commit 6dc34fb050
3 changed files with 24 additions and 15 deletions
@@ -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
@@ -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<BindingContext>?): 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
}
}
}
@@ -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<BindingContext>?): 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)