From db82797f58fbe039ec9e8363c75021d1daef16f9 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Sun, 25 Apr 2021 21:39:25 +0000 Subject: [PATCH] FIR IDE: Enable AddExclExclCallFix for UNSAFE_CALL, UNSAFE_OPERATOR_CALL, UNSAFE_INFIX_CALL, ITERATOR_ON_NULLABLE, ARGUMENT_TYPE_MISMATCH, RETURN_TYPE_MISMATCH. TODO: Don't offer fix when target is known to be null (from data flow analysis). --- .../idea/quickfix/MainKtQuickFixRegistrar.kt | 6 ++ .../fixes/AddExclExclCallFixFactories.kt | 96 +++++++++++++++++++ .../quickfix/fixes/TypeMismatchFactories.kt | 39 ++++++++ .../HighLevelQuickFixTestGenerated.java | 25 +++++ .../frontend/api/components/KtTypeProvider.kt | 6 ++ ...omponent.kt => KtFirSubtypingComponent.kt} | 0 .../api/fir/components/KtFirTypeProvider.kt | 15 ++- .../idea/frontend/api/fir/utils/firUtils.kt | 7 ++ .../addExclExclCall/functionReference.kt | 4 +- .../functionReference.kt.after | 4 +- .../addExclExclCall/functionReference2.kt | 4 +- .../functionReference2.kt.after | 4 +- .../addExclExclCall/functionReference3.kt | 4 +- .../functionReference3.kt.after | 4 +- .../quickfix/addExclExclCall/infixCall.kt | 7 ++ .../addExclExclCall/infixCall.kt.after | 7 ++ .../quickfix/addExclExclCall/operationPlus.kt | 5 + .../addExclExclCall/operationPlus.kt.after | 5 + .../addExclExclCall/operationUnary.kt | 5 + .../addExclExclCall/operationUnary.kt.after | 5 + .../typeMismatch/argumentAfterNullCheck.kt | 18 ++++ .../typeMismatch/assignmentRValue.kt | 2 + .../typeMismatch/assignmentRValue.kt.after | 2 + ...mberAccessInExtensionAsAssignmentRValue.kt | 2 + ...cessInExtensionAsAssignmentRValue.kt.after | 2 + .../typeMismatch/nullArgument.kt | 10 ++ ...moveNullabilityDisabledWhenItCannotHelp.kt | 4 +- .../typeMismatch/whenSmartCastImpossible.kt | 3 +- .../whenSmartCastImpossible.kt.after | 3 +- .../fixNullableBinaryWithExclExcl.kt | 1 - .../fixNullableBinaryWithExclExcl.kt.after | 1 - .../fixNullableInfixWithExclExcl.kt | 1 - .../fixNullableInfixWithExclExcl.kt.after | 1 - .../fixNullableIterableGenericWithExclExcl.kt | 1 - ...llableIterableGenericWithExclExcl.kt.after | 1 - .../fixNullableIterableWithExclExcl.kt | 1 - .../fixNullableIterableWithExclExcl.kt.after | 1 - .../fixNullableUnaryWithExclExcl.kt | 1 - .../fixNullableUnaryWithExclExcl.kt.after | 1 - ...llableWithExclExclAbsentWithBadIterator.kt | 2 +- .../fixNullableWithIteratorWithExclExcl.kt | 2 - ...xNullableWithIteratorWithExclExcl.kt.after | 2 - idea/testData/quickfix/expressions/kt11594.kt | 1 - .../quickfix/expressions/kt11594.kt.after | 1 - .../quickfix/expressions/unsafeCall2.kt | 2 - .../quickfix/expressions/unsafeCall2.kt.after | 2 - .../quickfix/expressions/unsafeCall3.kt | 2 - .../quickfix/expressions/unsafeCall3.kt.after | 2 - .../quickfix/expressions/unsafeCall4.kt | 1 - .../quickfix/expressions/unsafeCall4.kt.after | 1 - .../quickfix/expressions/unsafeCall5.kt | 1 - .../quickfix/expressions/unsafeCall5.kt.after | 1 - .../idea/quickfix/QuickFixTestGenerated.java | 25 +++++ 53 files changed, 311 insertions(+), 42 deletions(-) create mode 100644 idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/AddExclExclCallFixFactories.kt create mode 100644 idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/TypeMismatchFactories.kt rename idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/{KtFirSubtyppingComponent.kt => KtFirSubtypingComponent.kt} (100%) create mode 100644 idea/testData/quickfix/addExclExclCall/infixCall.kt create mode 100644 idea/testData/quickfix/addExclExclCall/infixCall.kt.after create mode 100644 idea/testData/quickfix/addExclExclCall/operationPlus.kt create mode 100644 idea/testData/quickfix/addExclExclCall/operationPlus.kt.after create mode 100644 idea/testData/quickfix/addExclExclCall/operationUnary.kt create mode 100644 idea/testData/quickfix/addExclExclCall/operationUnary.kt.after create mode 100644 idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt create mode 100644 idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt index 339123db67b..b36340b028a 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt @@ -103,6 +103,12 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() { registerPsiQuickFixes(KtFirDiagnostic.UnnecessarySafeCall::class, ReplaceWithDotCallFix) registerPsiQuickFixes(KtFirDiagnostic.UnnecessaryNotNullAssertion::class, RemoveExclExclCallFix) registerApplicator(ReplaceCallFixFactories.unsafeCallFactory) + registerApplicator(AddExclExclCallFixFactories.unsafeCallFactory) + registerApplicator(AddExclExclCallFixFactories.unsafeInfixCallFactory) + registerApplicator(AddExclExclCallFixFactories.unsafeOperatorCallFactory) + registerApplicator(AddExclExclCallFixFactories.iteratorOnNullableFactory) + registerApplicator(TypeMismatchFactories.argumentTypeMismatchFactory) + registerApplicator(TypeMismatchFactories.returnTypeMismatchFactory) // TODO: NON_EXHAUSTIVE_WHEN[_ON_SEALED_CLASS] will be replaced in future. We need to register the fix for those diagnostics as well registerPsiQuickFixes(KtFirDiagnostic.NoElseInWhen::class, AddWhenElseBranchFix) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/AddExclExclCallFixFactories.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/AddExclExclCallFixFactories.kt new file mode 100644 index 00000000000..9407da4e99d --- /dev/null +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/AddExclExclCallFixFactories.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.quickfix.fixes + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic +import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.util.OperatorNameConventions + +object AddExclExclCallFixFactories { + val unsafeCallFactory = diagnosticFixFactory { diagnostic -> + getFixForUnsafeCall(diagnostic.psi) + } + + val unsafeInfixCallFactory = diagnosticFixFactory { diagnostic -> + getFixForUnsafeCall(diagnostic.psi) + } + + val unsafeOperatorCallFactory = diagnosticFixFactory { diagnostic -> + getFixForUnsafeCall(diagnostic.psi) + } + + private fun KtAnalysisSession.getFixForUnsafeCall(psi: PsiElement): List { + val (target, hasImplicitReceiver) = when (psi) { + // `foo.bar` -> `foo!!.bar` + is KtDotQualifiedExpression -> psi.receiverExpression to false + + // `foo[bar]` -> `foo!![bar]` + is KtArrayAccessExpression -> psi.arrayExpression to false + + is KtCallableReferenceExpression -> psi.lhs.let { lhs -> + if (lhs != null) { + // `foo::bar` -> `foo!!::bar` + lhs to false + } else { + // `::bar -> this!!::bar` + psi to true + } + } + + // `bar` -> `this!!.bar` + is KtNameReferenceExpression -> psi to true + + // `bar()` -> `this!!.bar()` + is KtCallExpression -> psi to true + + // `-foo` -> `-foo!!` + // NOTE: Unsafe unary operator call is reported as UNSAFE_CALL, _not_ UNSAFE_OPERATOR_CALL + is KtUnaryExpression -> psi.baseExpression to false + + is KtBinaryExpression -> { + val receiver = if (KtPsiUtil.isInOrNotInOperation(psi)) { + // `bar in foo` -> `bar in foo!!` + psi.right + } else { + // `foo + bar` -> `foo!! + bar` OR `foo infixFun bar` -> `foo!! infixFun bar` + psi.left + } + receiver to false + } + + // UNSAFE_INFIX_CALL/UNSAFE_OPERATOR_CALL on KtBinaryExpression is reported on the child KtOperationReferenceExpression + is KtOperationReferenceExpression -> return getFixForUnsafeCall(psi.parent) + + else -> return emptyList() + } + + return listOfNotNull(target.asAddExclExclCallFix(hasImplicitReceiver = hasImplicitReceiver)) + } + + val iteratorOnNullableFactory = diagnosticFixFactory { diagnostic -> + val expression = diagnostic.psi as? KtExpression ?: return@diagnosticFixFactory emptyList() + val type = expression.getKtType() + if (!type.canBeNull) return@diagnosticFixFactory emptyList() + + val typeScope = type.getTypeScope() ?: return@diagnosticFixFactory emptyList() + val hasValidIterator = typeScope.getCallableSymbols { it == OperatorNameConventions.ITERATOR } + .filter { it is KtFunctionSymbol && it.isOperator && it.valueParameters.isEmpty() }.singleOrNull() != null + if (hasValidIterator) { + listOfNotNull(expression.asAddExclExclCallFix()) + } else { + emptyList() + } + } +} + +internal fun PsiElement?.asAddExclExclCallFix(hasImplicitReceiver: Boolean = false) = + this?.let { AddExclExclCallFix(it, hasImplicitReceiver) } ?: null diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/TypeMismatchFactories.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/TypeMismatchFactories.kt new file mode 100644 index 00000000000..69775896704 --- /dev/null +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/fixes/TypeMismatchFactories.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.quickfix.fixes + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic +import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability + +object TypeMismatchFactories { + val argumentTypeMismatchFactory = diagnosticFixFactory { diagnostic -> + getFixesForTypeMismatch(diagnostic.psi, diagnostic.expectedType, diagnostic.actualType) + } + + val returnTypeMismatchFactory = diagnosticFixFactory { diagnostic -> + getFixesForTypeMismatch(diagnostic.psi, diagnostic.expectedType, diagnostic.actualType) + } + + private fun KtAnalysisSession.getFixesForTypeMismatch( + psi: PsiElement, + expectedType: KtType, + actualType: KtType + ): List { + // TODO: Add more fixes than just AddExclExclCallFix when available. + if (!expectedType.canBeNull && actualType.canBeNull) { + val nullableExpectedType = expectedType.withNullability(KtTypeNullability.NULLABLE) + if (actualType isSubTypeOf nullableExpectedType) { + return listOfNotNull(psi.asAddExclExclCallFix()) + } + } + return emptyList() + } +} diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/quickfix/HighLevelQuickFixTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/quickfix/HighLevelQuickFixTestGenerated.java index 37ebd4bd18e..ae2a12ca005 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/quickfix/HighLevelQuickFixTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/quickfix/HighLevelQuickFixTestGenerated.java @@ -264,6 +264,11 @@ public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTes runTest("idea/testData/quickfix/addExclExclCall/implicitFunctionCall.kt"); } + @TestMetadata("infixCall.kt") + public void testInfixCall() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/infixCall.kt"); + } + @TestMetadata("iterable.kt") public void testIterable() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/iterable.kt"); @@ -299,6 +304,16 @@ public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTes runTest("idea/testData/quickfix/addExclExclCall/operationIn.kt"); } + @TestMetadata("operationPlus.kt") + public void testOperationPlus() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/operationPlus.kt"); + } + + @TestMetadata("operationUnary.kt") + public void testOperationUnary() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/operationUnary.kt"); + } + @TestMetadata("idea/testData/quickfix/addExclExclCall/typeMismatch") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -311,6 +326,11 @@ public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/addExclExclCall/typeMismatch"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); } + @TestMetadata("argumentAfterNullCheck.kt") + public void testArgumentAfterNullCheck() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt"); + } + @TestMetadata("assignmentRValue.kt") public void testAssignmentRValue() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt"); @@ -326,6 +346,11 @@ public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTes runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt"); } + @TestMetadata("nullArgument.kt") + public void testNullArgument() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt"); + } + @TestMetadata("qualifiedArgument.kt") public void testQualifiedArgument() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/qualifiedArgument.kt"); diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt index b4f22852c0c..1928f951801 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.frontend.api.components import org.jetbrains.kotlin.idea.frontend.api.ValidityTokenOwner import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability abstract class KtTypeProvider : KtAnalysisSessionComponent() { abstract val builtinTypes: KtBuiltinTypes @@ -15,6 +16,8 @@ abstract class KtTypeProvider : KtAnalysisSessionComponent() { abstract fun approximateToSuperPublicDenotableType(type: KtType): KtType? abstract fun buildSelfClassType(symbol: KtNamedClassOrObjectSymbol): KtType + + abstract fun withNullability(type: KtType, newNullability: KtTypeNullability): KtType } interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { @@ -32,6 +35,9 @@ interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { fun KtNamedClassOrObjectSymbol.buildSelfClassType(): KtType = analysisSession.typeProvider.buildSelfClassType(this) + + fun KtType.withNullability(newNullability: KtTypeNullability): KtType = + analysisSession.typeProvider.withNullability(this, newNullability) } @Suppress("PropertyName") diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtyppingComponent.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtypingComponent.kt similarity index 100% rename from idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtyppingComponent.kt rename to idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirSubtypingComponent.kt diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt index b394ab19f2e..33d2d050f8e 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt @@ -6,25 +6,27 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.components import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl -import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken +import org.jetbrains.kotlin.fir.types.withNullability import org.jetbrains.kotlin.idea.frontend.api.components.KtBuiltinTypes import org.jetbrains.kotlin.idea.frontend.api.components.KtTypeProvider import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirNamedClassOrObjectSymbol import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType import org.jetbrains.kotlin.idea.frontend.api.fir.types.PublicTypeApproximator -import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.idea.frontend.api.fir.utils.toConeNullability import org.jetbrains.kotlin.idea.frontend.api.symbols.KtNamedClassOrObjectSymbol +import org.jetbrains.kotlin.idea.frontend.api.tokens.ValidityToken import org.jetbrains.kotlin.idea.frontend.api.types.KtType +import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability internal class KtFirTypeProvider( override val analysisSession: KtFirAnalysisSession, override val token: ValidityToken, ) : KtTypeProvider(), KtFirAnalysisSessionComponent { - override val builtinTypes: KtBuiltinTypes = - KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token) + override val builtinTypes: KtBuiltinTypes = KtFirBuiltInTypes(rootModuleSession.builtinTypes, firSymbolBuilder, token) override fun approximateToSuperPublicDenotableType(type: KtType): KtType? { require(type is KtFirType) @@ -49,5 +51,10 @@ internal class KtFirTypeProvider( } return type.asKtType() } + + override fun withNullability(type: KtType, newNullability: KtTypeNullability): KtType { + require(type is KtFirType) + return type.coneType.withNullability(newNullability.toConeNullability(), rootModuleSession.typeContext).asKtType() + } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt index 49f6cb5293b..76f2106e5ab 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/utils/firUtils.kt @@ -13,10 +13,12 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.ConeNullability import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtConstantValue import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSimpleConstantValue import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtUnsupportedConstantValue +import org.jetbrains.kotlin.idea.frontend.api.types.KtTypeNullability internal fun mapAnnotationParameters(annotationCall: FirAnnotationCall, session: FirSession): Map { @@ -55,3 +57,8 @@ internal fun FirExpression.convertConstantExpression(): KtConstantValue = is FirConstExpression<*> -> convertConstantExpression() else -> KtUnsupportedConstantValue } + +internal fun KtTypeNullability.toConeNullability() = when (this) { + KtTypeNullability.NULLABLE -> ConeNullability.NULLABLE + KtTypeNullability.NON_NULLABLE -> ConeNullability.NOT_NULL +} diff --git a/idea/testData/quickfix/addExclExclCall/functionReference.kt b/idea/testData/quickfix/addExclExclCall/functionReference.kt index a7becab8230..a0f1a190e79 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference.kt +++ b/idea/testData/quickfix/addExclExclCall/functionReference.kt @@ -5,4 +5,6 @@ class Foo { fun test(foo: Foo?) { val f = foo::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/functionReference.kt.after b/idea/testData/quickfix/addExclExclCall/functionReference.kt.after index bae9309032e..f2ce9d61e0f 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference.kt.after +++ b/idea/testData/quickfix/addExclExclCall/functionReference.kt.after @@ -5,4 +5,6 @@ class Foo { fun test(foo: Foo?) { val f = foo!!::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/functionReference2.kt b/idea/testData/quickfix/addExclExclCall/functionReference2.kt index 402ad17b4ad..db0704a0d09 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference2.kt +++ b/idea/testData/quickfix/addExclExclCall/functionReference2.kt @@ -9,4 +9,6 @@ class Bar { fun test(foo: Foo?) { val f = foo?.bar::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/functionReference2.kt.after b/idea/testData/quickfix/addExclExclCall/functionReference2.kt.after index 443f80786c2..3ff9ea4ef21 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference2.kt.after +++ b/idea/testData/quickfix/addExclExclCall/functionReference2.kt.after @@ -9,4 +9,6 @@ class Bar { fun test(foo: Foo?) { val f = foo?.bar!!::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/functionReference3.kt b/idea/testData/quickfix/addExclExclCall/functionReference3.kt index 47c982cc7be..883c6d2699b 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference3.kt +++ b/idea/testData/quickfix/addExclExclCall/functionReference3.kt @@ -5,4 +5,6 @@ class Foo { fun Foo?.test() { val f = ::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/functionReference3.kt.after b/idea/testData/quickfix/addExclExclCall/functionReference3.kt.after index 6ba8cfc8c13..228e5fede3a 100644 --- a/idea/testData/quickfix/addExclExclCall/functionReference3.kt.after +++ b/idea/testData/quickfix/addExclExclCall/functionReference3.kt.after @@ -5,4 +5,6 @@ class Foo { fun Foo?.test() { val f = this!!::f -} \ No newline at end of file +} +// TODO: Enable when FIR reports UNSAFE_CALL for function reference on nullable (currently UNRESOLVED_REFERENCE) +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/infixCall.kt b/idea/testData/quickfix/addExclExclCall/infixCall.kt new file mode 100644 index 00000000000..cea7bb40cb5 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/infixCall.kt @@ -0,0 +1,7 @@ +// "Add non-null asserted (!!) call" "true" + +infix fun Int.bar(i: Int) = this + +fun foo(i: Int?) { + i bar 1 +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/infixCall.kt.after b/idea/testData/quickfix/addExclExclCall/infixCall.kt.after new file mode 100644 index 00000000000..943dc64cfe1 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/infixCall.kt.after @@ -0,0 +1,7 @@ +// "Add non-null asserted (!!) call" "true" + +infix fun Int.bar(i: Int) = this + +fun foo(i: Int?) { + i!! bar 1 +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationPlus.kt b/idea/testData/quickfix/addExclExclCall/operationPlus.kt new file mode 100644 index 00000000000..eab3cb0bb73 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationPlus.kt @@ -0,0 +1,5 @@ +// "Add non-null asserted (!!) call" "true" + +fun foo(i: Int?) { + i + 1 +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationPlus.kt.after b/idea/testData/quickfix/addExclExclCall/operationPlus.kt.after new file mode 100644 index 00000000000..901d3ab6a47 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationPlus.kt.after @@ -0,0 +1,5 @@ +// "Add non-null asserted (!!) call" "true" + +fun foo(i: Int?) { + i!! + 1 +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationUnary.kt b/idea/testData/quickfix/addExclExclCall/operationUnary.kt new file mode 100644 index 00000000000..118f843043c --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationUnary.kt @@ -0,0 +1,5 @@ +// "Add non-null asserted (!!) call" "true" + +fun foo(i: Int?) { + -i +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationUnary.kt.after b/idea/testData/quickfix/addExclExclCall/operationUnary.kt.after new file mode 100644 index 00000000000..285266b9a4b --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationUnary.kt.after @@ -0,0 +1,5 @@ +// "Add non-null asserted (!!) call" "true" + +fun foo(i: Int?) { + -i!! +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt new file mode 100644 index 00000000000..da55e096765 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt @@ -0,0 +1,18 @@ +// "Add non-null asserted (!!) call" "false" +// ACTION: Add 'i =' to argument +// ACTION: Change parameter 'i' type of function 'other' to 'Int?' +// ACTION: Create function 'other' +// ACTION: Remove braces from 'if' statement +// ACTION: Surround with null check +// ACTION: Wrap with '?.let { ... }' call +// ERROR: Type mismatch: inferred type is Nothing? but Int was expected +fun test(i: Int?) { + if (i == null) { + other(i) + } +} + +fun other(i: Int) {} + +// TODO: Need data flow info from null check +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt index ddeefe7975b..bc2edd5fe04 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt @@ -3,3 +3,5 @@ fun test() { val s: String? = null val z: String = s } +// TODO: Enable when FIR reports TYPE_MISMATCH for assignments +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt.after b/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt.after index caa14525d65..c799da27992 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt.after +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt.after @@ -3,3 +3,5 @@ fun test() { val s: String? = null val z: String = s!! } +// TODO: Enable when FIR reports TYPE_MISMATCH for assignments +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt index f1e101430f4..a544a022cb9 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt @@ -7,3 +7,5 @@ class C { fun C.test() { val z: String = s } +// TODO: Enable when FIR reports TYPE_MISMATCH for assignments +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt.after b/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt.after index aa40d3412f3..0d0f94a3d03 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt.after +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt.after @@ -7,3 +7,5 @@ class C { fun C.test() { val z: String = s!! } +// TODO: Enable when FIR reports TYPE_MISMATCH for assignments +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt new file mode 100644 index 00000000000..e8372f9d8b7 --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt @@ -0,0 +1,10 @@ +// "Add non-null asserted (!!) call" "false" +// ACTION: Add 'i =' to argument +// ACTION: Change parameter 'i' type of function 'other' to 'Int?' +// ACTION: Do not show hints for current method +// ERROR: Null can not be a value of a non-null type Int +fun test() { + other(null) +} + +fun other(i: Int) {} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/removeNullabilityDisabledWhenItCannotHelp.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/removeNullabilityDisabledWhenItCannotHelp.kt index 493f3ac9c75..be9258f526c 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/removeNullabilityDisabledWhenItCannotHelp.kt +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/removeNullabilityDisabledWhenItCannotHelp.kt @@ -1,6 +1,8 @@ -// "class org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix" "false" +// "Add non-null asserted (!!) call" "false" // ACTION: Change parameter 's' type of function 'other' to 'String?' // ACTION: Create function 'other' +// ACTION: Convert to also +// ACTION: Convert to apply // ERROR: Type mismatch: inferred type is String? but Int was expected fun test() { val s: String? = "" diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt b/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt index 4a10cbdae93..8ca054b7262 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt @@ -14,4 +14,5 @@ open class MyClass { } } } - +// TODO: Enable when FIR reports SMARTCAST_IMPOSSIBLE +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt.after b/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt.after index 2e1a2252502..8f257a0270f 100644 --- a/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt.after +++ b/idea/testData/quickfix/addExclExclCall/typeMismatch/whenSmartCastImpossible.kt.after @@ -14,4 +14,5 @@ open class MyClass { } } } - +// TODO: Enable when FIR reports SMARTCAST_IMPOSSIBLE +/* IGNORE_FIR */ diff --git a/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt index 92b0ed56fb8..b3cd5d91a0f 100644 --- a/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = p + 42 } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt.after index 73701431d53..0c06ec7be96 100644 --- a/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableBinaryWithExclExcl.kt.after @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = p!! + 42 } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt index 024da4d5ca6..39b8006b961 100644 --- a/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = p op 42 } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt.after index 67b5bcbddfb..0849e2ee069 100644 --- a/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableInfixWithExclExcl.kt.after @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = p!! op 42 } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt index d50d7f1699e..19dbf8a9318 100644 --- a/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt @@ -3,4 +3,3 @@ fun ?> foo(c: T) { for (i in c) { } } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt.after index 397093c3d02..1f70bf434a0 100644 --- a/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableIterableGenericWithExclExcl.kt.after @@ -3,4 +3,3 @@ fun ?> foo(c: T) { for (i in c!!) { } } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt index a545177a312..5301cd62e10 100644 --- a/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt @@ -4,4 +4,3 @@ fun foo() { for (i in test) { } } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt.after index 180c3fb10bf..fd82e0d5ddf 100644 --- a/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableIterableWithExclExcl.kt.after @@ -4,4 +4,3 @@ fun foo() { for (i in test!!) { } } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt index 45628cb31ed..5d68ef20ca0 100644 --- a/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = -p } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt.after index d0cf0abdd92..8a09c7a1464 100644 --- a/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableUnaryWithExclExcl.kt.after @@ -7,4 +7,3 @@ class SafeType { fun safeB(p: SafeType?) { val v = -p!! } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableWithExclExclAbsentWithBadIterator.kt b/idea/testData/quickfix/expressions/fixNullableWithExclExclAbsentWithBadIterator.kt index 1fe4c8366b0..23187cbaec2 100644 --- a/idea/testData/quickfix/expressions/fixNullableWithExclExclAbsentWithBadIterator.kt +++ b/idea/testData/quickfix/expressions/fixNullableWithExclExclAbsentWithBadIterator.kt @@ -1,4 +1,4 @@ -// "class org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix" "false" +// "Add non-null asserted (!!) call" "false" // ACTION: Replace with a 'forEach' function call // ACTION: Surround with null check // ERROR: Not nullable value required to call an 'iterator()' method on for-loop range diff --git a/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt b/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt index 0505fe32c19..217cce1350a 100644 --- a/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt +++ b/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt @@ -7,5 +7,3 @@ fun foo() { val test: Some? = Some() for (i in test) { } } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt.after b/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt.after index 961c3bf2814..68e9b442fa3 100644 --- a/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt.after +++ b/idea/testData/quickfix/expressions/fixNullableWithIteratorWithExclExcl.kt.after @@ -7,5 +7,3 @@ fun foo() { val test: Some? = Some() for (i in test!!) { } } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/kt11594.kt b/idea/testData/quickfix/expressions/kt11594.kt index b0af268840c..2e034b7a603 100644 --- a/idea/testData/quickfix/expressions/kt11594.kt +++ b/idea/testData/quickfix/expressions/kt11594.kt @@ -5,4 +5,3 @@ fun callMe(p: String) {} fun callIt(p: Any) { callMe(p as String?) } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/kt11594.kt.after b/idea/testData/quickfix/expressions/kt11594.kt.after index fd57789ce6c..34309b501a6 100644 --- a/idea/testData/quickfix/expressions/kt11594.kt.after +++ b/idea/testData/quickfix/expressions/kt11594.kt.after @@ -5,4 +5,3 @@ fun callMe(p: String) {} fun callIt(p: Any) { callMe((p as String?)!!) } -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall2.kt b/idea/testData/quickfix/expressions/unsafeCall2.kt index 8f0680d3468..25866b37c4b 100644 --- a/idea/testData/quickfix/expressions/unsafeCall2.kt +++ b/idea/testData/quickfix/expressions/unsafeCall2.kt @@ -2,5 +2,3 @@ fun foo(a: Int?) { a.plus(1) } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall2.kt.after b/idea/testData/quickfix/expressions/unsafeCall2.kt.after index 0f9e9f3a652..656198dc506 100644 --- a/idea/testData/quickfix/expressions/unsafeCall2.kt.after +++ b/idea/testData/quickfix/expressions/unsafeCall2.kt.after @@ -2,5 +2,3 @@ fun foo(a: Int?) { a!!.plus(1) } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall3.kt b/idea/testData/quickfix/expressions/unsafeCall3.kt index 487c19ceb62..946185f33ea 100644 --- a/idea/testData/quickfix/expressions/unsafeCall3.kt +++ b/idea/testData/quickfix/expressions/unsafeCall3.kt @@ -2,5 +2,3 @@ fun foo(a: Int?) { a.plus(1) } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall3.kt.after b/idea/testData/quickfix/expressions/unsafeCall3.kt.after index 0f9e9f3a652..656198dc506 100644 --- a/idea/testData/quickfix/expressions/unsafeCall3.kt.after +++ b/idea/testData/quickfix/expressions/unsafeCall3.kt.after @@ -2,5 +2,3 @@ fun foo(a: Int?) { a!!.plus(1) } - -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall4.kt b/idea/testData/quickfix/expressions/unsafeCall4.kt index d1b03fba852..9118f2749b5 100644 --- a/idea/testData/quickfix/expressions/unsafeCall4.kt +++ b/idea/testData/quickfix/expressions/unsafeCall4.kt @@ -2,4 +2,3 @@ operator fun Int.get(row: Int, column: Int) = this fun foo(arg: Int?) = arg[42, 13] -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall4.kt.after b/idea/testData/quickfix/expressions/unsafeCall4.kt.after index 8e62dc9572e..3d9d87c4d01 100644 --- a/idea/testData/quickfix/expressions/unsafeCall4.kt.after +++ b/idea/testData/quickfix/expressions/unsafeCall4.kt.after @@ -2,4 +2,3 @@ operator fun Int.get(row: Int, column: Int) = this fun foo(arg: Int?) = arg!![42, 13] -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall5.kt b/idea/testData/quickfix/expressions/unsafeCall5.kt index c39b8c2fc31..d79837a5dc6 100644 --- a/idea/testData/quickfix/expressions/unsafeCall5.kt +++ b/idea/testData/quickfix/expressions/unsafeCall5.kt @@ -2,4 +2,3 @@ operator fun Int.get(row: Int, column: Int) = if (row == column) this else null fun foo(arg: Int) = arg[42, 13].hashCode() -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/expressions/unsafeCall5.kt.after b/idea/testData/quickfix/expressions/unsafeCall5.kt.after index aee70c522a6..0499c885b36 100644 --- a/idea/testData/quickfix/expressions/unsafeCall5.kt.after +++ b/idea/testData/quickfix/expressions/unsafeCall5.kt.after @@ -2,4 +2,3 @@ operator fun Int.get(row: Int, column: Int) = if (row == column) this else null fun foo(arg: Int) = arg[42, 13]!!.hashCode() -/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index c777a06f2c5..7698c12f7c9 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -677,6 +677,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/addExclExclCall/implicitFunctionCall.kt"); } + @TestMetadata("infixCall.kt") + public void testInfixCall() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/infixCall.kt"); + } + @TestMetadata("iterable.kt") public void testIterable() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/iterable.kt"); @@ -712,6 +717,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/addExclExclCall/operationIn.kt"); } + @TestMetadata("operationPlus.kt") + public void testOperationPlus() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/operationPlus.kt"); + } + + @TestMetadata("operationUnary.kt") + public void testOperationUnary() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/operationUnary.kt"); + } + @TestMetadata("idea/testData/quickfix/addExclExclCall/typeMismatch") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -724,6 +739,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/addExclExclCall/typeMismatch"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); } + @TestMetadata("argumentAfterNullCheck.kt") + public void testArgumentAfterNullCheck() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/argumentAfterNullCheck.kt"); + } + @TestMetadata("assignmentRValue.kt") public void testAssignmentRValue() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/assignmentRValue.kt"); @@ -739,6 +759,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/memberAccessInExtensionAsAssignmentRValue.kt"); } + @TestMetadata("nullArgument.kt") + public void testNullArgument() throws Exception { + runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/nullArgument.kt"); + } + @TestMetadata("qualifiedArgument.kt") public void testQualifiedArgument() throws Exception { runTest("idea/testData/quickfix/addExclExclCall/typeMismatch/qualifiedArgument.kt");