Reparse lambda expression after removing parameter comma (KT-21497)
Without the parameter it can become block. #KT-21497 Fixed
This commit is contained in:
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.parsing.KotlinParser;
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression;
|
||||
import org.jetbrains.kotlin.psi.KtParameterList;
|
||||
|
||||
class LambdaExpressionElementType extends IErrorCounterReparseableElementType {
|
||||
public LambdaExpressionElementType() {
|
||||
@@ -55,7 +56,7 @@ class LambdaExpressionElementType extends IErrorCounterReparseableElementType {
|
||||
@Override
|
||||
public boolean isParsable(@Nullable ASTNode parent, CharSequence buffer, Language fileLanguage, Project project) {
|
||||
return super.isParsable(parent, buffer, fileLanguage, project) &&
|
||||
!wasArrowMovedOrDeleted(parent, buffer);
|
||||
!wasArrowMovedOrDeleted(parent, buffer) && !wasParameterCommaMovedOrDeleted(parent, buffer);
|
||||
}
|
||||
|
||||
private static boolean wasArrowMovedOrDeleted(@Nullable ASTNode parent, CharSequence buffer) {
|
||||
@@ -75,6 +76,27 @@ class LambdaExpressionElementType extends IErrorCounterReparseableElementType {
|
||||
return hasTokenMoved(lambdaExpression.getText(), buffer, arrowOffset, KtTokens.ARROW);
|
||||
}
|
||||
|
||||
private static boolean wasParameterCommaMovedOrDeleted(@Nullable ASTNode parent, CharSequence buffer) {
|
||||
KtLambdaExpression lambdaExpression = findLambdaExpression(parent);
|
||||
if (lambdaExpression == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
KtFunctionLiteral literal = lambdaExpression.getFunctionLiteral();
|
||||
KtParameterList valueParameterList = literal.getValueParameterList();
|
||||
if (valueParameterList == null || valueParameterList.getParameters().size() <= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiElement comma = valueParameterList.getFirstComma();
|
||||
if (comma == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int commaOffset = comma.getTextOffset() - lambdaExpression.getTextOffset();
|
||||
return hasTokenMoved(lambdaExpression.getText(), buffer, commaOffset, KtTokens.COMMA);
|
||||
}
|
||||
|
||||
private static KtLambdaExpression findLambdaExpression(@Nullable ASTNode parent) {
|
||||
if (parent == null) return null;
|
||||
|
||||
|
||||
@@ -89,4 +89,9 @@ public class KtParameterList extends KtElementImplStub<KotlinPlaceHolderStub<KtP
|
||||
public PsiElement getLeftParenthesis() {
|
||||
return findChildByType(KtTokens.LPAR);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getFirstComma() {
|
||||
return findChildByType(KtTokens.COMMA);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.editor
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.EditorTestUtil
|
||||
import com.intellij.testFramework.EditorTestUtil.*
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCaseBase
|
||||
@@ -27,14 +28,24 @@ import org.junit.Assert
|
||||
|
||||
class LazyElementTypeTest : KotlinLightCodeInsightFixtureTestCaseBase() {
|
||||
fun testSplitArrow() = reparse("val t = { a: Int -<caret>> }", ' ')
|
||||
fun testDeleteArrow() = reparse("val t = { a: Int -><caret> }", EditorTestUtil.BACKSPACE_FAKE_CHAR)
|
||||
fun testDeleteArrow() = reparse("val t = { a: Int -><caret> }", BACKSPACE_FAKE_CHAR)
|
||||
|
||||
fun testReformatNearArrow() = noReparse("val t = { a: Int<caret>-> }", ' ')
|
||||
fun testChangeAfterArrow() = noReparse("val t = { a: Int -> <caret> }", 'a')
|
||||
fun testDeleteIrrelevantArrow() = noReparse("val t = { a: Int -> (1..3).filter { b -><caret> b > 2 } }", EditorTestUtil.BACKSPACE_FAKE_CHAR)
|
||||
fun testDeleteIrrelevantArrow() = noReparse("val t = { a: Int -> (1..3).filter { b -><caret> b > 2 } }", BACKSPACE_FAKE_CHAR)
|
||||
fun testReformatNearLambdaStart() = noReparse("val t = {<caret>a: Int -> }", ' ')
|
||||
fun testNoArrow() = noReparse("val t = { <caret> }", 'a')
|
||||
|
||||
fun testAfterRemovingParameterComma() = reparse(inIf("{t,<caret>}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterRemovingNoParameterComma() = noReparse(inIf("{,<caret>}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterRemovingNotLastParameterComma() = noReparse(inIf("{a, b,<caret>}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterRemovingSecondParameter() = noReparse(inIf("{a,b<caret>}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterFirstParameterRenamed() = noReparse(inIf("{a<caret>,}"), 'b')
|
||||
|
||||
fun testAfterRemovingFirstParameterWithOther() = reparse(inIf("{a<caret>,b}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterRemovingFirstParameter() = reparse(inIf("{a<caret>,}"), BACKSPACE_FAKE_CHAR)
|
||||
fun testAfterTypeComma() = reparse(inIf("{a<caret>}"), ',')
|
||||
|
||||
fun reparse(text: String, char: Char): Unit = doTest(text, char, true)
|
||||
fun noReparse(text: String, char: Char): Unit = doTest(text, char, false)
|
||||
|
||||
@@ -43,7 +54,7 @@ class LazyElementTypeTest : KotlinLightCodeInsightFixtureTestCaseBase() {
|
||||
|
||||
val lambdaExpressionBefore = PsiTreeUtil.findChildOfType(file, KtLambdaExpression::class.java)
|
||||
|
||||
EditorTestUtil.performTypingAction(myFixture.editor, char)
|
||||
performTypingAction(myFixture.editor, char)
|
||||
PsiDocumentManager.getInstance(LightPlatformTestCase.getProject()).commitDocument(myFixture.getDocument(file))
|
||||
|
||||
val lambdaExpressionAfter = PsiTreeUtil.findChildOfType(file, KtLambdaExpression::class.java)
|
||||
@@ -53,5 +64,7 @@ class LazyElementTypeTest : KotlinLightCodeInsightFixtureTestCaseBase() {
|
||||
Assert.assertEquals("Lazy element behaviour was unexpected", reparse, actualReparse)
|
||||
}
|
||||
|
||||
private fun inIf(lambda: String) = "val t: Unit = if (true) $lambda else {}"
|
||||
|
||||
override fun getProjectDescriptor() = LightProjectDescriptor.EMPTY_PROJECT_DESCRIPTOR
|
||||
}
|
||||
Reference in New Issue
Block a user