[java-completion] Complete final and yield inside switch rule

GitOrigin-RevId: 643a7bf62a04c9eb35bf554f3f3f5cc648188cbe
This commit is contained in:
Tagir Valeev
2022-11-11 12:17:32 +00:00
committed by intellij-monorepo-bot
parent 7ea7be6a8b
commit 2f83b31b86
6 changed files with 70 additions and 18 deletions
@@ -262,7 +262,7 @@ public class JavaKeywordCompletion {
}
PsiFile file = myPosition.getContainingFile();
if (PsiJavaModule.MODULE_INFO_FILE.equals(file.getName()) && PsiUtil.isLanguageLevel9OrHigher(file)) {
if (PsiJavaModule.MODULE_INFO_FILE.equals(file.getName()) && HighlightingFeature.MODULES.isAvailable(file)) {
addModuleKeywords();
return;
}
@@ -329,6 +329,9 @@ public class JavaKeywordCompletion {
if (rule.getEnclosingSwitchBlock() instanceof PsiSwitchStatement) {
addKeyword(wrapRuleIntoBlock(createReturnKeyword()));
}
else {
addKeyword(wrapRuleIntoBlock(new OverridableSpace(createKeyword(PsiKeyword.YIELD), TailType.INSERT_SPACE)));
}
}
private static LookupElement wrapRuleIntoBlock(LookupElement element) {
@@ -336,18 +339,27 @@ public class JavaKeywordCompletion {
@Override
public void handleInsert(@NotNull InsertionContext context) {
PsiStatement statement = PsiTreeUtil.getParentOfType(context.getFile().findElementAt(context.getStartOffset()), PsiStatement.class);
if (statement != null && statement.getParent() instanceof PsiCodeBlock) {
PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(statement);
if (PsiUtil.isJavaToken(prevLeaf, JavaTokenType.ARROW) && prevLeaf.getParent() instanceof PsiSwitchLabeledRuleStatement) {
CaretModel model = context.getEditor().getCaretModel();
int origPos = model.getOffset();
int start = statement.getTextRange().getStartOffset();
PsiStatement updatedStatement = BlockUtils.expandSingleStatementToBlockStatement(statement);
int updatedStart = updatedStatement.getTextRange().getStartOffset();
model.moveToOffset(origPos + updatedStart - start);
PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(context.getDocument());
context.setTailOffset(model.getOffset());
boolean isAfterArrow = false;
if (statement != null) {
if (statement.getParent() instanceof PsiCodeBlock) {
PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(statement);
if (PsiUtil.isJavaToken(prevLeaf, JavaTokenType.ARROW) && prevLeaf.getParent() instanceof PsiSwitchLabeledRuleStatement) {
isAfterArrow = true;
}
}
else if (statement.getParent() instanceof PsiSwitchLabeledRuleStatement) {
isAfterArrow = true;
}
}
if (isAfterArrow) {
CaretModel model = context.getEditor().getCaretModel();
int origPos = model.getOffset();
int start = statement.getTextRange().getStartOffset();
PsiStatement updatedStatement = BlockUtils.expandSingleStatementToBlockStatement(statement);
int updatedStart = updatedStatement.getTextRange().getStartOffset();
model.moveToOffset(origPos + updatedStart - start);
PsiDocumentManager.getInstance(context.getProject()).doPostponedOperationsAndUnblockDocument(context.getDocument());
context.setTailOffset(model.getOffset());
}
super.handleInsert(context);
}
@@ -386,11 +398,11 @@ public class JavaKeywordCompletion {
}
private boolean isVarAllowed() {
if (PsiUtil.isLanguageLevel11OrHigher(myPosition) && isLambdaParameterType()) {
if (HighlightingFeature.VAR_LAMBDA_PARAMETER.isAvailable(myPosition) && isLambdaParameterType()) {
return true;
}
if (!PsiUtil.isLanguageLevel10OrHigher(myPosition)) return false;
if (!HighlightingFeature.LVTI.isAvailable(myPosition)) return false;
if (isAtCatchOrResourceVariableStart(myPosition) && PsiTreeUtil.getParentOfType(myPosition, PsiCatchSection.class) == null) {
return true;
@@ -540,7 +552,11 @@ public class JavaKeywordCompletion {
if (tryStatement == null ||
tryStatement.getCatchSections().length > 0 ||
tryStatement.getFinallyBlock() != null || tryStatement.getResourceList() != null) {
addKeyword(new OverridableSpace(createKeyword(PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD));
LookupElement finalKeyword = new OverridableSpace(createKeyword(PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD);
if (statement.getParent() instanceof PsiSwitchLabeledRuleStatement) {
finalKeyword = wrapRuleIntoBlock(finalKeyword);
}
addKeyword(finalKeyword);
return;
}
}
@@ -557,7 +573,7 @@ public class JavaKeywordCompletion {
if (SUPER_OR_THIS_PATTERN.accepts(myPosition)) {
final boolean afterDot = AFTER_DOT.accepts(myPosition);
final boolean insideQualifierClass = isInsideQualifierClass();
final boolean insideInheritorClass = PsiUtil.isLanguageLevel8OrHigher(myPosition) && isInsideInheritorClass();
final boolean insideInheritorClass = HighlightingFeature.EXTENSION_METHODS.isAvailable(myPosition) && isInsideInheritorClass();
if (!afterDot || insideQualifierClass || insideInheritorClass) {
if (!afterDot || insideQualifierClass) {
addKeyword(createKeyword(PsiKeyword.THIS));
@@ -652,7 +668,7 @@ public class JavaKeywordCompletion {
}
}
if (PsiUtil.isLanguageLevel5OrHigher(file) && myPrevLeaf != null && myPrevLeaf.textMatches(PsiKeyword.IMPORT)) {
if (HighlightingFeature.STATIC_IMPORTS.isAvailable(file) && myPrevLeaf != null && myPrevLeaf.textMatches(PsiKeyword.IMPORT)) {
addKeyword(new OverridableSpace(createKeyword(PsiKeyword.STATIC), TailType.HUMBLE_SPACE_BEFORE_WORD));
}
}
@@ -1057,7 +1073,7 @@ public class JavaKeywordCompletion {
addKeyword(br);
}
else if (psiElement().inside(PsiSwitchExpression.class).accepts(myPosition) &&
PsiUtil.getLanguageLevel(myPosition).isAtLeast(LanguageLevel.JDK_14)) {
HighlightingFeature.SWITCH_EXPRESSION.isAvailable(myPosition)) {
addKeyword(TailTypeDecorator.withTail(createKeyword(PsiKeyword.YIELD), TailType.INSERT_SPACE));
}
@@ -0,0 +1,7 @@
class Foo {
public int foo(String str) {
return switch (str) {
case "x" -> fina<caret>
};
}
}
@@ -0,0 +1,9 @@
class Foo {
public int foo(String str) {
return switch (str) {
case "x" -> {
final <caret>
}
};
}
}
@@ -0,0 +1,7 @@
class Foo {
public int foo(String str) {
return switch (str) {
case "x" -> yiel<caret>
};
}
}
@@ -0,0 +1,9 @@
class Foo {
public int foo(String str) {
return switch (str) {
case "x" -> {
yield <caret>
}
};
}
}
@@ -63,6 +63,10 @@ class NormalSwitchCompletionTest extends NormalCompletionTestCase {
doTest()
}
@NeedsIndex.ForStandardLibrary
void testCompleteFinalInsideSwitch() { doTest('\n') }
void testCompleteYieldInsideSwitch() { doTest() }
private void doTestPostfixCompletion() {
LiveTemplateCompletionContributor.setShowTemplatesInTests(true, myFixture.testRootDisposable)
configure()