From eae23b548f8a5e4796251e00bc1891c1dc01d66b Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Fri, 14 Oct 2016 21:43:47 +0300 Subject: [PATCH] KT-14294 for to stdlib to firstOrNull/lastOrNull: intention is absent if there is additional var before for loop #KT-14294 Fixed --- .../loopToCallChain/baseTransformations.kt | 45 +++++++++++++++---- .../intentions/loopToCallChain/interfaces.kt | 2 +- .../loopToCallChain/matchAndConvert.kt | 4 +- .../result/FindTransformationMatcher.kt | 5 ++- .../idea/intentions/loopToCallChain/utils.kt | 10 ++--- .../loopToCallChain/firstOrNull/KT14292.kt | 18 ++++++++ .../firstOrNull/KT14292.kt.after | 13 ++++++ .../firstOrNull/KT14292.kt.after2 | 14 ++++++ .../smartCasts/smartCastNotBroken3.kt | 16 +++++++ .../smartCasts/smartCastNotBroken3.kt.after | 11 +++++ .../smartCasts/smartCastNotBroken3.kt.after2 | 12 +++++ .../smartCasts/smartCastNotBroken4.kt | 17 +++++++ .../smartCasts/smartCastNotBroken4.kt.after | 12 +++++ .../smartCasts/smartCastNotBroken4.kt.after2 | 13 ++++++ .../smartCasts/smartCastNotBroken5.kt | 14 ++++++ .../smartCasts/smartCastNotBroken5.kt.after | 11 +++++ .../smartCasts/smartCastNotBroken5.kt.after2 | 12 +++++ .../smartCasts/smartCastRequired6.kt | 16 +++++++ .../intentions/IntentionTest2Generated.java | 30 +++++++++++++ .../intentions/IntentionTestGenerated.java | 30 +++++++++++++ 20 files changed, 287 insertions(+), 18 deletions(-) create mode 100644 idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt create mode 100644 idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after2 create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after2 create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after2 create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after2 create mode 100644 idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/baseTransformations.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/baseTransformations.kt index 589c3e8bf95..577b372ce80 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/baseTransformations.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/baseTransformations.kt @@ -16,12 +16,18 @@ package org.jetbrains.kotlin.idea.intentions.loopToCallChain +import org.jetbrains.kotlin.idea.core.KotlinNameSuggester +import org.jetbrains.kotlin.idea.core.copied import org.jetbrains.kotlin.idea.core.replaced -import org.jetbrains.kotlin.psi.KtBlockExpression -import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtForExpression -import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.idea.util.getResolutionScope +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.PsiChildRange +import org.jetbrains.kotlin.resolve.scopes.utils.findClassifier +import org.jetbrains.kotlin.resolve.scopes.utils.findFunction +import org.jetbrains.kotlin.resolve.scopes.utils.findPackage +import org.jetbrains.kotlin.resolve.scopes.utils.findVariable /** * Base class for [ResultTransformation]'s that replaces the loop-expression with the result call chain @@ -30,8 +36,9 @@ abstract class ReplaceLoopResultTransformation(final override val loop: KtForExp override val commentSavingRange = PsiChildRange.singleElement(loop.unwrapIfLabeled()) - override val expressionToBeReplacedByResultCallChain: KtExpression - get() = loop.unwrapIfLabeled() + override fun generateExpressionToReplaceLoopAndCheckErrors(resultCallChain: KtExpression): KtExpression { + return resultCallChain + } override fun convertLoop(resultCallChain: KtExpression, commentSavingRangeHolder: CommentSavingRangeHolder): KtExpression { return loop.unwrapIfLabeled().replaced(resultCallChain) @@ -48,8 +55,30 @@ abstract class AssignToVariableResultTransformation( override val commentSavingRange = PsiChildRange(initialization.initializationStatement, loop.unwrapIfLabeled()) - override val expressionToBeReplacedByResultCallChain: KtExpression - get() = initialization.initializer + override fun generateExpressionToReplaceLoopAndCheckErrors(resultCallChain: KtExpression): KtExpression { + val psiFactory = KtPsiFactory(resultCallChain) + val initializationStatement = initialization.initializationStatement + if (initializationStatement is KtVariableDeclaration) { + val resolutionScope = loop.getResolutionScope() + + fun isUniqueName(name: String): Boolean { + val identifier = Name.identifier(name) + return resolutionScope.findVariable(identifier, NoLookupLocation.FROM_IDE) == null + && resolutionScope.findFunction(identifier, NoLookupLocation.FROM_IDE) == null + && resolutionScope.findClassifier(identifier, NoLookupLocation.FROM_IDE) == null + && resolutionScope.findPackage(identifier) == null + } + val uniqueName = KotlinNameSuggester.suggestNameByName("test", ::isUniqueName) + + val copy = initializationStatement.copied() + copy.initializer!!.replace(resultCallChain) + copy.setName(uniqueName) + return copy + } + else { + return psiFactory.createExpressionByPattern("$0 = $1", initialization.variable.nameAsSafeName, resultCallChain) + } + } override fun convertLoop(resultCallChain: KtExpression, commentSavingRangeHolder: CommentSavingRangeHolder): KtExpression { initialization.initializer.replace(resultCallChain) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/interfaces.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/interfaces.kt index 05c919bf7d1..15928d506f4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/interfaces.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/interfaces.kt @@ -79,7 +79,7 @@ interface ResultTransformation : Transformation { val commentSavingRange: PsiChildRange - val expressionToBeReplacedByResultCallChain: KtExpression + fun generateExpressionToReplaceLoopAndCheckErrors(resultCallChain: KtExpression): KtExpression /** * Implementations of this method are obliged to update [commentSavingRangeHolder] when deleting or adding any element into the tree diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/matchAndConvert.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/matchAndConvert.kt index 218d81a0609..39e514b369d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/matchAndConvert.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/matchAndConvert.kt @@ -293,8 +293,8 @@ private fun checkSmartCastsPreserved(loop: KtForExpression, matchResult: MatchRe if (preservedSmartCastCount == smartCastCount) return true // not all smart cast expressions has been found in the result or have the same type after conversion, perform more expensive check - val expressionToBeReplaced = matchResult.transformationMatch.resultTransformation.expressionToBeReplacedByResultCallChain - if (!tryChangeAndCheckErrors(expressionToBeReplaced, loop) { it.replace(callChain) }) return false + val expression = matchResult.transformationMatch.resultTransformation.generateExpressionToReplaceLoopAndCheckErrors(callChain) + if (!tryChangeAndCheckErrors(loop) { it.replace(expression) }) return false return true } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt index fae975b1208..a3c9a48496d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/result/FindTransformationMatcher.kt @@ -135,8 +135,9 @@ object FindTransformationMatcher : TransformationMatcher { return generator.generate(chainedCallGenerator) } - override val expressionToBeReplacedByResultCallChain: KtExpression - get() = endReturn.returnedExpression!! + override fun generateExpressionToReplaceLoopAndCheckErrors(resultCallChain: KtExpression): KtExpression { + return KtPsiFactory(resultCallChain).createExpressionByPattern("return $0", resultCallChain) + } override fun convertLoop(resultCallChain: KtExpression, commentSavingRangeHolder: CommentSavingRangeHolder): KtExpression { endReturn.returnedExpression!!.replace(resultCallChain) diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt index 7e175cae495..ba5223ddcbc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/loopToCallChain/utils.kt @@ -230,7 +230,7 @@ fun canChangeLocalVariableType(variable: KtProperty, newTypeText: String, loop: fun tryChangeAndCheckErrors( expressionToChange: TExpression, - scopeToExclude: KtElement, + scopeToExclude: KtElement? = null, performChange: (TExpression) -> Unit ): Boolean { val bindingContext = expressionToChange.analyze(BodyResolveMode.FULL) @@ -246,19 +246,19 @@ fun tryChangeAndCheckErrors( val SCOPE_TO_EXCLUDE = Key("SCOPE_TO_EXCLUDE") expressionToChange.putCopyableUserData(EXPRESSION, Unit) - scopeToExclude.putCopyableUserData(SCOPE_TO_EXCLUDE, Unit) + scopeToExclude?.putCopyableUserData(SCOPE_TO_EXCLUDE, Unit) val blockCopy = block.copied() val expressionCopy: TExpression - val scopeToExcludeCopy: KtElement + val scopeToExcludeCopy: KtElement? @Suppress("UNCHECKED_CAST") try { expressionCopy = blockCopy.findDescendantOfType { it.getCopyableUserData(EXPRESSION) != null } as TExpression - scopeToExcludeCopy = blockCopy.findDescendantOfType { it.getCopyableUserData(SCOPE_TO_EXCLUDE) != null }!! + scopeToExcludeCopy = blockCopy.findDescendantOfType { it.getCopyableUserData(SCOPE_TO_EXCLUDE) != null } } finally { expressionToChange.putCopyableUserData(EXPRESSION, null) - scopeToExclude.putCopyableUserData(SCOPE_TO_EXCLUDE, null) + scopeToExclude?.putCopyableUserData(SCOPE_TO_EXCLUDE, null) } performChange(expressionCopy) diff --git a/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt new file mode 100644 index 00000000000..6fec8279dbd --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'" + +fun getFirstValue() = "value" + +fun foo(list: List): String? { + var found: String? = null + val value = getFirstValue() + for (s in list) + if (s != null) + if(!s.startsWith("IMG:")) + if (s.contains(value)) { + found = s + break + } + return found +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after new file mode 100644 index 00000000000..cfb76214fcf --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'" + +fun getFirstValue() = "value" + +fun foo(list: List): String? { + val value = getFirstValue() + val found: String? = list + .filterNotNull() + .firstOrNull { !it.startsWith("IMG:") && it.contains(value) } + return found +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after2 b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after2 new file mode 100644 index 00000000000..6d7b044b169 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt.after2 @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'filterNotNull().firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().filterNotNull().firstOrNull{}'" + +fun getFirstValue() = "value" + +fun foo(list: List): String? { + val value = getFirstValue() + val found: String? = list + .asSequence() + .filterNotNull() + .firstOrNull { !it.startsWith("IMG:") && it.contains(value) } + return found +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt new file mode 100644 index 00000000000..ad7c679c325 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + if (o is CharSequence) { + var result: Any? = null + for (s in list) { + val a = s.length + (o as String).capitalize().hashCode() + val x = a * o.length + if (x > 1000) { + result = x + break + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after new file mode 100644 index 00000000000..98ebc3b54c8 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after @@ -0,0 +1,11 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + if (o is CharSequence) { + val result: Any? = list + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .firstOrNull { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after2 b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after2 new file mode 100644 index 00000000000..b5e46442f4f --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt.after2 @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + if (o is CharSequence) { + val result: Any? = list + .asSequence() + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .firstOrNull { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt new file mode 100644 index 00000000000..8814b1b275f --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + var result: Any? = "" + if (o is CharSequence) { + result = null + for (s in list) { + val a = s.length + (o as String).capitalize().hashCode() + val x = a * o.length + if (x > 1000) { + result = x + break + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after new file mode 100644 index 00000000000..3a46ded84df --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + var result: Any? = "" + if (o is CharSequence) { + result = list + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .firstOrNull { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after2 b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after2 new file mode 100644 index 00000000000..78a956b96a1 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt.after2 @@ -0,0 +1,13 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.firstOrNull{}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.firstOrNull{}'" +fun foo(list: List, o: Any) { + var result: Any? = "" + if (o is CharSequence) { + result = list + .asSequence() + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .firstOrNull { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt new file mode 100644 index 00000000000..9f0366b391c --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.filterTo(){}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.filterTo(){}'" +fun foo(list: List, o: Any, result: MutableCollection) { + if (o is CharSequence) { + for (s in list) { + val a = s.length + (o as String).capitalize().hashCode() + val x = a * o.length + if (x > 1000) { + result.add(x) + } + } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after new file mode 100644 index 00000000000..c5110362daf --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after @@ -0,0 +1,11 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.filterTo(){}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.filterTo(){}'" +fun foo(list: List, o: Any, result: MutableCollection) { + if (o is CharSequence) { + list + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .filterTo(result) { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after2 b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after2 new file mode 100644 index 00000000000..8222d415488 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt.after2 @@ -0,0 +1,12 @@ +// WITH_RUNTIME +// INTENTION_TEXT: "Replace with 'map{}.map{}.filterTo(){}'" +// INTENTION_TEXT_2: "Replace with 'asSequence().map{}.map{}.filterTo(){}'" +fun foo(list: List, o: Any, result: MutableCollection) { + if (o is CharSequence) { + list + .asSequence() + .map { it.length + (o as String).capitalize().hashCode() } + .map { it * o.length } + .filterTo(result) { it > 1000 } + } +} \ No newline at end of file diff --git a/idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt new file mode 100644 index 00000000000..c052674e370 --- /dev/null +++ b/idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt @@ -0,0 +1,16 @@ +// WITH_RUNTIME +// IS_APPLICABLE: false +// IS_APPLICABLE_2: false +fun foo(list: List) { + var v: String? + + v = null + for (o in list) { + if (bar(o as String)) { + v = o + break + } + } +} + +fun bar(s: String): Boolean = true \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java index e9876f48dbe..eef30d01086 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTest2Generated.java @@ -613,6 +613,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 { doTest(fileName); } + @TestMetadata("KT14292.kt") + public void testKT14292() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt"); + doTest(fileName); + } + @TestMetadata("let.kt") public void testLet() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/firstOrNull/let.kt"); @@ -1174,6 +1180,24 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 { doTest(fileName); } + @TestMetadata("smartCastNotBroken3.kt") + public void testSmartCastNotBroken3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotBroken4.kt") + public void testSmartCastNotBroken4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotBroken5.kt") + public void testSmartCastNotBroken5() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt"); + doTest(fileName); + } + @TestMetadata("smartCastNotNullRequired.kt") public void testSmartCastNotNullRequired() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotNullRequired.kt"); @@ -1216,6 +1240,12 @@ public class IntentionTest2Generated extends AbstractIntentionTest2 { doTest(fileName); } + @TestMetadata("smartCastRequired6.kt") + public void testSmartCastRequired6() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt"); + doTest(fileName); + } + @TestMetadata("smartCastThisRequired.kt") public void testSmartCastThisRequired() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastThisRequired.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 647063714aa..e185c88e892 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -8521,6 +8521,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("KT14292.kt") + public void testKT14292() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/firstOrNull/KT14292.kt"); + doTest(fileName); + } + @TestMetadata("let.kt") public void testLet() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/firstOrNull/let.kt"); @@ -9082,6 +9088,24 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("smartCastNotBroken3.kt") + public void testSmartCastNotBroken3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken3.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotBroken4.kt") + public void testSmartCastNotBroken4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken4.kt"); + doTest(fileName); + } + + @TestMetadata("smartCastNotBroken5.kt") + public void testSmartCastNotBroken5() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotBroken5.kt"); + doTest(fileName); + } + @TestMetadata("smartCastNotNullRequired.kt") public void testSmartCastNotNullRequired() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastNotNullRequired.kt"); @@ -9124,6 +9148,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("smartCastRequired6.kt") + public void testSmartCastRequired6() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastRequired6.kt"); + doTest(fileName); + } + @TestMetadata("smartCastThisRequired.kt") public void testSmartCastThisRequired() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/loopToCallChain/smartCasts/smartCastThisRequired.kt");