mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-72951 'break' keyword is not suggested by completion in a loop with single statement body
This commit is contained in:
@@ -36,19 +36,6 @@ public class JavaAwareCompletionData extends CompletionData{
|
||||
static TailType analyzeItem(final Object completion, final PsiElement position) {
|
||||
if(completion instanceof PsiKeyword){
|
||||
final String text = ((PsiKeyword)completion).getText();
|
||||
if(PsiKeyword.BREAK.equals(text) || PsiKeyword.CONTINUE.equals(text)) {
|
||||
PsiElement scope = position;
|
||||
while(true){
|
||||
if (scope instanceof PsiFile || scope instanceof PsiMethod || scope instanceof PsiClassInitializer){
|
||||
return TailType.SEMICOLON;
|
||||
}
|
||||
|
||||
if (scope instanceof PsiLabeledStatement){
|
||||
return TailType.NONE;
|
||||
}
|
||||
scope = scope.getParent();
|
||||
}
|
||||
}
|
||||
if(PsiKeyword.RETURN.equals(text)){
|
||||
PsiElement scope = position;
|
||||
while(true){
|
||||
|
||||
@@ -112,6 +112,19 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
|
||||
static final AndFilter START_SWITCH = new AndFilter(END_OF_BLOCK, new LeftNeighbour(
|
||||
new AndFilter(new TextFilter("{"), new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 2))));
|
||||
private static final OrFilter INSIDE_SWITCH = new OrFilter(START_SWITCH,
|
||||
new AndFilter(
|
||||
END_OF_BLOCK,
|
||||
new NotFilter(START_SWITCH),
|
||||
new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchLabelStatement.class)),
|
||||
new LeftNeighbour(new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 2),
|
||||
new AndFilter(new TextFilter(";", ":"), new ParentElementFilter(
|
||||
new ClassFilter(PsiSwitchStatement.class), 3)),
|
||||
new AndFilter(new TextFilter("}"), new ParentElementFilter(
|
||||
new ClassFilter(PsiSwitchStatement.class), 4))
|
||||
)))));
|
||||
|
||||
private static final ElementPattern<Object> SUPER_OR_THIS_PATTERN =
|
||||
and(JavaSmartCompletionContributor.INSIDE_EXPRESSION,
|
||||
@@ -444,57 +457,12 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
}
|
||||
|
||||
{
|
||||
// break completion
|
||||
final CompletionVariant variant = new CompletionVariant(new AndFilter(END_OF_BLOCK, new OrFilter(
|
||||
new ScopeFilter(new ClassFilter(PsiSwitchStatement.class)),
|
||||
new InsideElementFilter(new ClassFilter(PsiBlockStatement.class)))));
|
||||
|
||||
variant.includeScopeClass(PsiForStatement.class, false);
|
||||
variant.includeScopeClass(PsiForeachStatement.class, false);
|
||||
variant.includeScopeClass(PsiWhileStatement.class, false);
|
||||
variant.includeScopeClass(PsiDoWhileStatement.class, false);
|
||||
variant.includeScopeClass(PsiSwitchStatement.class, false);
|
||||
variant.addCompletion(PsiKeyword.BREAK);
|
||||
registerVariant(variant);
|
||||
}
|
||||
{
|
||||
// continue completion
|
||||
final CompletionVariant variant = new CompletionVariant(new AndFilter(END_OF_BLOCK, new InsideElementFilter(new ClassFilter(PsiBlockStatement.class))));
|
||||
variant.includeScopeClass(PsiForeachStatement.class, false);
|
||||
variant.includeScopeClass(PsiForStatement.class, false);
|
||||
variant.includeScopeClass(PsiWhileStatement.class, false);
|
||||
variant.includeScopeClass(PsiDoWhileStatement.class, false);
|
||||
|
||||
variant.addCompletion(PsiKeyword.CONTINUE);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
{
|
||||
final CompletionVariant variant = new CompletionVariant(
|
||||
new AndFilter(
|
||||
END_OF_BLOCK,
|
||||
new NotFilter(START_SWITCH),
|
||||
new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchLabelStatement.class)),
|
||||
new LeftNeighbour(new OrFilter(
|
||||
new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 2),
|
||||
new AndFilter(new TextFilter(";", ":"),new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 3)),
|
||||
new AndFilter(new TextFilter("}"), new ParentElementFilter(new ClassFilter(PsiSwitchStatement.class), 4))
|
||||
)))));
|
||||
variant.includeScopeClass(PsiElement.class, false);
|
||||
variant.addCompletion(PsiKeyword.CASE, TailType.SPACE);
|
||||
variant.addCompletion(PsiKeyword.DEFAULT, TailType.CASE_COLON);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
{
|
||||
final CompletionVariant variant = new CompletionVariant(START_SWITCH);
|
||||
final CompletionVariant variant = new CompletionVariant(INSIDE_SWITCH);
|
||||
variant.includeScopeClass(PsiElement.class, true);
|
||||
variant.addCompletion(PsiKeyword.CASE, TailType.SPACE);
|
||||
variant.addCompletion(PsiKeyword.DEFAULT, TailType.CASE_COLON);
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void addPrimitiveTypes(CompletionVariant variant){
|
||||
@@ -535,6 +503,10 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
result.addElement(createKeyword(position, PsiKeyword.FINAL));
|
||||
}
|
||||
}
|
||||
|
||||
if (isStatementPosition(position) && !INSIDE_SWITCH.isAcceptable(position, position)) {
|
||||
addBreakContinue(result, position);
|
||||
}
|
||||
|
||||
if (SUPER_OR_THIS_PATTERN.accepts(position)) {
|
||||
if (!AFTER_DOT.accepts(position) || isInsideQualifierClass(position)) {
|
||||
@@ -626,6 +598,43 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
||||
}
|
||||
}
|
||||
|
||||
private static void addBreakContinue(CompletionResultSet result, PsiElement position) {
|
||||
PsiLoopStatement loop = PsiTreeUtil.getParentOfType(position, PsiLoopStatement.class);
|
||||
|
||||
LookupElement br = createKeyword(position, PsiKeyword.BREAK);
|
||||
LookupElement cont = createKeyword(position, PsiKeyword.CONTINUE);
|
||||
if (!psiElement().insideSequence(true, psiElement(PsiLabeledStatement.class),
|
||||
or(psiElement(PsiFile.class), psiElement(PsiMethod.class),
|
||||
psiElement(PsiClassInitializer.class))).accepts(position)) {
|
||||
br = TailTypeDecorator.withTail(br, TailType.SEMICOLON);
|
||||
cont = TailTypeDecorator.withTail(cont, TailType.SEMICOLON);
|
||||
}
|
||||
|
||||
if (loop != null && new InsideElementFilter(new ClassFilter(PsiStatement.class)).isAcceptable(position, loop)) {
|
||||
result.addElement(br);
|
||||
result.addElement(cont);
|
||||
}
|
||||
if (psiElement().inside(PsiSwitchStatement.class).accepts(position)) {
|
||||
result.addElement(br);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isStatementPosition(PsiElement position) {
|
||||
if (END_OF_BLOCK.isAcceptable(position, position)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (psiElement().withParents(PsiReferenceExpression.class, PsiExpressionStatement.class, PsiIfStatement.class).accepts(position)) {
|
||||
PsiElement stmt = position.getParent().getParent();
|
||||
PsiIfStatement ifStatement = (PsiIfStatement)stmt.getParent();
|
||||
if (ifStatement.getElseBranch() == stmt || ifStatement.getThenBranch() == stmt) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static LookupElement createKeyword(PsiElement position, String keyword) {
|
||||
return BasicExpressionCompletionContributor.createKeywordLookupItem(position, keyword);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Main {
|
||||
{
|
||||
while(true)
|
||||
if (cond) br<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class Main {
|
||||
{
|
||||
while(true)
|
||||
if (cond) break;<caret>
|
||||
}
|
||||
}
|
||||
+2
@@ -441,6 +441,8 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testBreakInIfCondition() throws Throwable { doTest(); }
|
||||
|
||||
public void testNoThisInComment() throws Throwable { doAntiTest() }
|
||||
|
||||
public void testLastExpressionInFor() throws Throwable { doTest(); }
|
||||
|
||||
Reference in New Issue
Block a user