[kotlin] Surround with null check should not be available for non-stable variables

#KTIJ-30588 Fixed

GitOrigin-RevId: f30dfd5da1172748b1bbd8136a0a8657676ec446
This commit is contained in:
Vladimir Dolzhenko
2024-07-11 16:56:33 +00:00
committed by intellij-monorepo-bot
parent 849e4d90eb
commit 98cb6d673f
5 changed files with 63 additions and 1 deletions
@@ -7,6 +7,9 @@ import com.intellij.psi.SmartPsiElementPointer
import com.intellij.psi.createSmartPointer
import org.jetbrains.kotlin.analysis.api.KaSession
import org.jetbrains.kotlin.analysis.api.fir.diagnostics.KaFirDiagnostic
import org.jetbrains.kotlin.analysis.api.symbols.KaPropertySymbol
import org.jetbrains.kotlin.analysis.api.symbols.KaSymbolLocation
import org.jetbrains.kotlin.analysis.api.symbols.KaVariableSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KaNamedSymbol
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.intentions.KotlinPsiUpdateModCommandAction
@@ -93,9 +96,19 @@ internal object SurroundWithNullCheckFixFactory {
val file = expressionTarget.containingKtFile
val scope = file.scopeContext(expressionTarget).compositeScope()
val callableSymbol = scope.getCallableSymbols(referenceSymbol.name).firstOrNull() ?: return emptyList()
val callableSymbol = scope.callables(referenceSymbol.name).firstOrNull() ?: return emptyList()
if (referenceSymbol != callableSymbol) return emptyList()
if (callableSymbol is KaVariableSymbol) {
if (callableSymbol.isVal) {
if ((callableSymbol as? KaPropertySymbol)?.getter?.isDefault == false) {
return emptyList()
}
} else if (callableSymbol.location != KaSymbolLocation.LOCAL) {
return emptyList()
}
}
val elementContext = ElementContext(nullableExpression.createSmartPointer())
return listOf(
SurroundWithNullCheckFix(expressionTarget, elementContext)
@@ -9405,6 +9405,16 @@ public abstract class HighLevelQuickFixTestGenerated extends AbstractHighLevelQu
runTest("../../../idea/tests/testData/quickfix/surroundWithNullCheck/unsafeCallInsideWhile.kt");
}
@TestMetadata("unstableTopLevelValueWithGetter.kt")
public void testUnstableTopLevelValueWithGetter() throws Exception {
runTest("../../../idea/tests/testData/quickfix/surroundWithNullCheck/unstableTopLevelValueWithGetter.kt");
}
@TestMetadata("unstableTopLevelVariable.kt")
public void testUnstableTopLevelVariable() throws Exception {
runTest("../../../idea/tests/testData/quickfix/surroundWithNullCheck/unstableTopLevelVariable.kt");
}
@TestMetadata("unstableValue.kt")
public void testUnstableValue() throws Exception {
runTest("../../../idea/tests/testData/quickfix/surroundWithNullCheck/unstableValue.kt");
@@ -17017,6 +17017,16 @@ public abstract class K1QuickFixTestGenerated extends AbstractK1QuickFixTest {
runTest("testData/quickfix/surroundWithNullCheck/unsafeCallInsideWhile.kt");
}
@TestMetadata("unstableTopLevelValueWithGetter.kt")
public void testUnstableTopLevelValueWithGetter() throws Exception {
runTest("testData/quickfix/surroundWithNullCheck/unstableTopLevelValueWithGetter.kt");
}
@TestMetadata("unstableTopLevelVariable.kt")
public void testUnstableTopLevelVariable() throws Exception {
runTest("testData/quickfix/surroundWithNullCheck/unstableTopLevelVariable.kt");
}
@TestMetadata("unstableValue.kt")
public void testUnstableValue() throws Exception {
runTest("testData/quickfix/surroundWithNullCheck/unstableValue.kt");
@@ -0,0 +1,15 @@
// "Surround with null check" "false"
// ACTION: Add non-null asserted (x!!) call
// ACTION: Convert to run
// ACTION: Convert to with
// ACTION: Introduce import alias
// ACTION: Introduce local variable
// ACTION: Replace with safe (?.) call
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int?
val x: Int?
get() = 0
fun foo() {
x<caret>.hashCode()
}
@@ -0,0 +1,14 @@
// "Surround with null check" "false"
// ACTION: Add non-null asserted (x!!) call
// ACTION: Convert to run
// ACTION: Convert to with
// ACTION: Introduce import alias
// ACTION: Introduce local variable
// ACTION: Replace with safe (?.) call
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Int?
var x: Int? = null
fun foo() {
x<caret>.hashCode()
}