Refine expression kind definition in postfix templates
- Do not treat if without else as values - Some statements aren't contained in block (see tests) #KT-14107 Fixed #KT-14110 Fixed
This commit is contained in:
+11
-3
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.intentions.negate
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -128,16 +129,23 @@ private class KtExpressionPostfixTemplateSelector(
|
||||
// Both KtLambdaExpression and KtFunctionLiteral have the same offset, so we add only one of them -> KtLambdaExpression
|
||||
if (it is KtFunctionLiteral) return@Condition false
|
||||
|
||||
if (statementsOnly && it.parent !is KtBlockExpression) return@Condition false
|
||||
val context by lazy { it.analyze(BodyResolveMode.PARTIAL_FOR_COMPLETION) }
|
||||
|
||||
if (statementsOnly && it.parent !is KtBlockExpression && !it.isUsedAsStatement(context)) return@Condition false
|
||||
if (checkCanBeUsedAsValue && !it.canBeUsedAsValue()) return@Condition false
|
||||
|
||||
typePredicate == null || it.getType(it.analyze(BodyResolveMode.PARTIAL_FOR_COMPLETION))?.let { typePredicate(it) } ?: false
|
||||
typePredicate == null || it.getType(context)?.let { typePredicate(it) } ?: false
|
||||
}
|
||||
|
||||
private fun KtExpression.canBeUsedAsValue() =
|
||||
!KtPsiUtil.isAssignment(this) &&
|
||||
!this.isNamedDeclaration &&
|
||||
this !is KtLoopExpression
|
||||
this !is KtLoopExpression &&
|
||||
// if's only with else may be treated as expressions
|
||||
!isIfWithoutElse
|
||||
|
||||
private val KtExpression.isIfWithoutElse: Boolean
|
||||
get() = (this is KtIfExpression && this.elseKeyword == null)
|
||||
}
|
||||
|
||||
override fun getExpressions(context: PsiElement, document: Document, offset: Int): List<PsiElement> {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo() {
|
||||
for (i in 1..9)
|
||||
i.return<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo() {
|
||||
for (i in 1..9)
|
||||
return i
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo(x: Int, y: Int) {
|
||||
if (x > y)
|
||||
x.sout<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo(x: Int, y: Int) {
|
||||
if (x > y)
|
||||
println(x)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo() {
|
||||
for (i in 1..9)
|
||||
i.sout<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun foo() {
|
||||
for (i in 1..9)
|
||||
println(i)
|
||||
}
|
||||
+18
@@ -137,12 +137,30 @@ public class PostfixTemplateProviderTestGenerated extends AbstractPostfixTemplat
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromLoop.kt")
|
||||
public void testReturnFromLoop() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/returnFromLoop.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("sout.kt")
|
||||
public void testSout() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/sout.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("soutInIf.kt")
|
||||
public void testSoutInIf() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/soutInIf.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("soutInLoop.kt")
|
||||
public void testSoutInLoop() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/soutInLoop.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("try.kt")
|
||||
public void testTry() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/postfix/try.kt");
|
||||
|
||||
Reference in New Issue
Block a user