mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[inspection] Support opt-in from @WasExperimental in RangeUntil inspection
The logic is similar to Enum.values() inspection. No new tests added because current tests were broken and are now fixed. Broken tests are tests in ReplaceRangeToWithRangeUntil and "noOptIn" in ReplaceUntilWithRangeUntil. ^KTIJ-25447 GitOrigin-RevId: c51e1095379b2fed4908327fdb62251dfdd45f09
This commit is contained in:
committed by
intellij-monorepo-bot
parent
9129250a49
commit
b9a9d826bf
+9
-1
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.intentions.getArguments
|
||||
import org.jetbrains.kotlin.idea.intentions.receiverType
|
||||
import org.jetbrains.kotlin.idea.statistics.KotlinLanguageFeaturesFUSCollector
|
||||
@@ -17,6 +18,7 @@ import org.jetbrains.kotlin.idea.statistics.NewAndDeprecatedFeaturesInspectionDa
|
||||
import org.jetbrains.kotlin.idea.util.RangeKtExpressionType
|
||||
import org.jetbrains.kotlin.idea.util.RangeKtExpressionType.RANGE_UNTIL
|
||||
import org.jetbrains.kotlin.idea.util.RangeKtExpressionType.UNTIL
|
||||
import org.jetbrains.kotlin.idea.util.WasExperimentalOptInsNecessityCheckerFe10
|
||||
import org.jetbrains.kotlin.idea.util.projectStructure.module
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -91,7 +93,13 @@ class ReplaceUntilWithRangeUntilInspection : AbstractRangeInspection(
|
||||
private fun KtElement.isOtpInRequiredForRangeUntil(annotationFqName: FqName, context: BindingContext): Boolean {
|
||||
val rangeUntilFunctionDescriptor = findRangeUntilFunctionDescriptor(context)
|
||||
?: return false
|
||||
return rangeUntilFunctionDescriptor.annotations.hasAnnotation(annotationFqName)
|
||||
if (rangeUntilFunctionDescriptor.annotations.hasAnnotation(annotationFqName)) {
|
||||
return true
|
||||
}
|
||||
val necessaryOptIns = WasExperimentalOptInsNecessityCheckerFe10.getNecessaryOptInsFromWasExperimental(
|
||||
rangeUntilFunctionDescriptor.annotations, findModuleDescriptor(), languageVersionSettings.apiVersion
|
||||
)
|
||||
return annotationFqName in necessaryOptIns
|
||||
}
|
||||
|
||||
private fun KtElement.findRangeUntilFunctionDescriptor(context: BindingContext): CallableDescriptor? {
|
||||
|
||||
+6
-13
@@ -11,32 +11,33 @@ import com.intellij.psi.util.parentOfType
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.base.psi.KotlinPsiHeuristics
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.base.util.names.FqNames
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.core.OPT_IN_FQ_NAMES
|
||||
import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
|
||||
import org.jetbrains.kotlin.idea.inspections.CanSealedSubClassBeObjectInspection.Companion.asKtClass
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
|
||||
import org.jetbrains.kotlin.idea.references.ReadWriteAccessChecker
|
||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.idea.util.WasExperimentalOptInsNecessityCheckerFe10
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.SINCE_KOTLIN_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.checkers.OptInNames
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
@@ -54,12 +55,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
* any names. For these redundant markers, the inspection proposes a quick fix to remove the marker
|
||||
* or the entire unnecessary `@OptIn` annotation if it contains a single marker.
|
||||
*/
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
|
||||
import org.jetbrains.kotlin.idea.inspections.CanSealedSubClassBeObjectInspection.Companion.asKtClass
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||
import org.jetbrains.kotlin.idea.util.WasExperimentalOptInsNecessityCheckerFe10
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.*
|
||||
|
||||
class UnnecessaryOptInAnnotationInspection : AbstractKotlinInspection() {
|
||||
|
||||
/**
|
||||
@@ -314,8 +309,6 @@ private class MarkerCollector(private val resolutionFacade: ResolutionFacade) {
|
||||
*/
|
||||
private fun KtReferenceExpression.isSetterCall(): Boolean =
|
||||
readWriteAccessChecker.readWriteAccessWithFullExpression(this, true).first.isWrite
|
||||
|
||||
private val VERSION_ARGUMENT = Name.identifier("version")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-17
@@ -1,20 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -XXLanguage:+RangeUntilOperator
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE_VERSION: 1.9
|
||||
package kotlin
|
||||
|
||||
class MyObj {
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@SinceKotlin("1.9")
|
||||
@WasExperimental(ExperimentalStdlibApi::class)
|
||||
@kotlin.internal.InlineOnly
|
||||
operator inline fun rangeUntil(o: MyObj) = Unit
|
||||
}
|
||||
|
||||
// Since `until` is only defined for primitives, we create this fake function in kotlin package
|
||||
// to activate the inspection and make it look at MyObj.rangeUntil, which is without opt-in.
|
||||
infix fun MyObj.until(o: MyObj) = Unit
|
||||
|
||||
// API_VERSION: 1.9
|
||||
fun main() {
|
||||
MyObj() un<caret>til MyObj()
|
||||
0 u<caret>ntil 10
|
||||
}
|
||||
+3
-18
@@ -1,20 +1,5 @@
|
||||
// COMPILER_ARGUMENTS: -XXLanguage:+RangeUntilOperator
|
||||
// WITH_STDLIB
|
||||
// LANGUAGE_VERSION: 1.9
|
||||
package kotlin
|
||||
|
||||
class MyObj {
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@SinceKotlin("1.9")
|
||||
@WasExperimental(ExperimentalStdlibApi::class)
|
||||
@kotlin.internal.InlineOnly
|
||||
operator inline fun rangeUntil(o: MyObj) = Unit
|
||||
}
|
||||
|
||||
// Since `until` is only defined for primitives, we create this fake function in kotlin package
|
||||
// to activate the inspection and make it look at MyObj.rangeUntil, which is without opt-in.
|
||||
infix fun MyObj.until(o: MyObj) = Unit
|
||||
|
||||
// WITH_STDLIB
|
||||
fun main() {
|
||||
MyObj()..<MyObj()
|
||||
}
|
||||
0..<10
|
||||
}
|
||||
Reference in New Issue
Block a user