[java-completion] Complete statement: complete to method instead of field

Fixes IDEA-23781 Complete statement: missing method body

GitOrigin-RevId: 8d37de51bc4e90f36fbf2bbb30e0e50edc79f763
This commit is contained in:
Tagir Valeev
2022-04-20 18:25:36 +02:00
committed by intellij-monorepo-bot
parent b5838faa84
commit 6c28bb7296
8 changed files with 44 additions and 2 deletions

View File

@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.editorActions.smartEnter;
import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.*;
@@ -28,6 +29,31 @@ import static com.intellij.psi.PsiModifier.*;
public class MissingMethodBodyFixer implements Fixer {
@Override
public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException {
if (psiElement instanceof PsiField) {
// replace something like `int x` with `int x() {...}`
// while it's ambiguous whether user wants a field or a method, declaring a field is easier (just append a semicolon),
// so completing a method looks more useful
PsiField field = (PsiField)psiElement;
if (field.hasInitializer()) return;
PsiElement lastChild = field.getLastChild();
if (!(lastChild instanceof PsiErrorElement)) return;
if (!((PsiErrorElement)lastChild).getErrorDescription().equals(JavaErrorBundle.message("expected.semicolon"))) return;
PsiModifierList modifiers = field.getModifierList();
if (modifiers == null) return;
// Impossible modifiers for a method
if (modifiers.hasExplicitModifier(TRANSIENT) || modifiers.hasExplicitModifier(VOLATILE)) return;
// Modifier combination which is unlikely to see on methods but quite reasonable on fields
if ((modifiers.hasExplicitModifier(STATIC) || modifiers.hasExplicitModifier(PRIVATE)) &&
modifiers.hasExplicitModifier(FINAL)) {
return;
}
int endOffset = field.getTextRange().getEndOffset();
editor.getDocument().insertString(endOffset, "(){}");
editor.getCaretModel().moveToOffset(endOffset + 1);
processor.registerUnresolvedError(endOffset + 1);
processor.setSkipEnter(true);
return;
}
if (!(psiElement instanceof PsiMethod)) return;
PsiMethod method = (PsiMethod) psiElement;
if (!shouldHaveBody(method)) return;

View File

@@ -1,6 +1,7 @@
public class Test {
private String s;<caret>
private String s(<caret>) {
}
@Deprecated private String foo;
}

View File

@@ -0,0 +1,3 @@
public class FieldWithEquals {
int test=<caret>
}

View File

@@ -0,0 +1,3 @@
public class FieldWithEquals {
int test = <caret>;
}

View File

@@ -1,3 +1,4 @@
public class Test {
String s;<caret>
String s(<caret>) {
}
}

View File

@@ -0,0 +1,3 @@
public class FieldWithEquals {
static final int foo<caret>
}

View File

@@ -0,0 +1,3 @@
public class FieldWithEquals {
static final int foo;<caret>
}

View File

@@ -84,6 +84,8 @@ public class CompleteStatementTest extends EditorActionTestCase {
public void testIncompleteElseIf() { doTest(); }
public void testField() { doTest(); }
public void testMethod() { doTest(); }
public void testLikelyField() { doTest(); }
public void testFieldWithEquals() { doTest(); }
public void testClass() { doTest(); }
public void testInnerEnumBeforeMethod() { doTest(); }
public void testInnerEnumBeforeMethodWithSpace() { doTest(); }