mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
relevant method chain completion: introduce new field if completion for field initializer is called (EA-103019)
This commit is contained in:
+1
-1
@@ -105,7 +105,7 @@ public class MethodChainLookupRangingHelper {
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) return null;
|
||||
PsiNamedElement element = context.getQualifiers(qualifierClass).findFirst().orElse(null);
|
||||
if (element == null) {
|
||||
return new ChainCompletionNewVariableLookupElement(qualifierClass);
|
||||
return new ChainCompletionNewVariableLookupElement(qualifierClass, context);
|
||||
} else {
|
||||
if (element instanceof PsiVariable) {
|
||||
return new VariableLookupItem((PsiVariable)element);
|
||||
|
||||
+7
-1
@@ -125,7 +125,13 @@ public class MethodChainCompletionContributor extends CompletionContributor {
|
||||
if (parent instanceof PsiLocalVariable) {
|
||||
return extractContextFromVariable((PsiLocalVariable)parent, parameters);
|
||||
}
|
||||
PsiMethod method = ((PsiMethodCallExpression)parent).resolveMethod();
|
||||
return extractContextFromMethodCall((PsiMethodCallExpression)parent, parameters);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ChainCompletionContext extractContextFromMethodCall(PsiMethodCallExpression parent,
|
||||
CompletionParameters parameters) {
|
||||
PsiMethod method = parent.resolveMethod();
|
||||
if (method == null) return null;
|
||||
PsiExpression expression = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiExpression.class);
|
||||
PsiExpressionList expressionList = PsiTreeUtil.getParentOfType(parameters.getPosition(), PsiExpressionList.class);
|
||||
|
||||
+29
-10
@@ -19,11 +19,13 @@ import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.PreferByKindWeigher;
|
||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.compiler.chainsSearch.context.ChainCompletionContext;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -35,13 +37,17 @@ public class ChainCompletionNewVariableLookupElement extends LookupElement {
|
||||
private final PsiClass myQualifierClass;
|
||||
@NotNull
|
||||
private final String myNewVarName;
|
||||
private final boolean myField;
|
||||
|
||||
public ChainCompletionNewVariableLookupElement(@NotNull final PsiClass qualifierClass) {
|
||||
public ChainCompletionNewVariableLookupElement(@NotNull PsiClass qualifierClass,
|
||||
@NotNull ChainCompletionContext context) {
|
||||
Project project = qualifierClass.getProject();
|
||||
JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project);
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
myField = PsiTreeUtil.getParentOfType(context.getContextPsi(), PsiStatement.class, false) == null;
|
||||
VariableKind variableKind = myField ? VariableKind.FIELD : VariableKind.LOCAL_VARIABLE;
|
||||
myNewVarName = Stream
|
||||
.of(codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, elementFactory.createType(qualifierClass)).names)
|
||||
.of(codeStyleManager.suggestVariableName(variableKind, null, null, elementFactory.createType(qualifierClass)).names)
|
||||
.sorted(Comparator.comparing(String::length).reversed())
|
||||
.findFirst()
|
||||
.orElseThrow(IllegalStateException::new);
|
||||
@@ -58,18 +64,31 @@ public class ChainCompletionNewVariableLookupElement extends LookupElement {
|
||||
public void handleInsert(final InsertionContext context) {
|
||||
final PsiFile file = context.getFile();
|
||||
final PsiElement caretElement = ObjectUtils.notNull(file.findElementAt(context.getEditor().getCaretModel().getOffset()));
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(context.getProject());
|
||||
|
||||
final PsiStatement statement = PsiTreeUtil.getParentOfType(caretElement.getPrevSibling(), PsiStatement.class, false);
|
||||
final Project project = context.getProject();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
context.commitDocument();
|
||||
final PsiStatement newVarDeclarationTemplate = elementFactory.createVariableDeclarationStatement(myNewVarName,
|
||||
elementFactory.createType(myQualifierClass),
|
||||
elementFactory.createExpressionFromText(PsiKeyword.NULL, null));
|
||||
PsiElement varDeclaration = statement.getParent().addBefore(newVarDeclarationTemplate, statement);
|
||||
PsiElement newVariablePlacementAnchor;
|
||||
PsiElement newVarDeclarationTemplate;
|
||||
if (myField) {
|
||||
PsiField field = ObjectUtils.notNull(PsiTreeUtil.getParentOfType(caretElement.getPrevSibling(), PsiField.class, false));
|
||||
newVariablePlacementAnchor = field;
|
||||
PsiField newField = elementFactory.createField(myNewVarName, elementFactory.createType(myQualifierClass));
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
PsiUtil.setModifierProperty(newField, PsiModifier.STATIC, true);
|
||||
}
|
||||
newVarDeclarationTemplate = newField;
|
||||
} else {
|
||||
newVariablePlacementAnchor = ObjectUtils.notNull(PsiTreeUtil.getParentOfType(caretElement.getPrevSibling(), PsiStatement.class, false));
|
||||
newVarDeclarationTemplate = elementFactory.createVariableDeclarationStatement(myNewVarName,
|
||||
elementFactory.createType(myQualifierClass),
|
||||
elementFactory.createExpressionFromText(PsiKeyword.NULL, null));
|
||||
|
||||
}
|
||||
|
||||
PsiElement varDeclaration = newVariablePlacementAnchor.getParent().addBefore(newVarDeclarationTemplate, newVariablePlacementAnchor);
|
||||
JavaCodeStyleManager.getInstance(context.getProject()).shortenClassReferences(varDeclaration);
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLookupString() {
|
||||
|
||||
+5
@@ -113,6 +113,11 @@ public class ChainCompletionContext {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getContextPsi() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
public PsiFile getContextFile() {
|
||||
return myContext.getContainingFile();
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import java.jang.String;
|
||||
|
||||
interface PsiClass {
|
||||
PsiMethod getMethod();
|
||||
}
|
||||
|
||||
interface PsiMethod {}
|
||||
|
||||
public class TestCompletion {
|
||||
|
||||
private static PsiClass psiClass;
|
||||
static Object f = get(psiClass.getMethod());
|
||||
|
||||
static Object get(PsiMethod m) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import java.jang.String;
|
||||
|
||||
interface PsiClass {
|
||||
PsiMethod getMethod();
|
||||
}
|
||||
|
||||
interface PsiMethod {}
|
||||
|
||||
public class TestCompletion {
|
||||
|
||||
static Object f = get(<caret>);
|
||||
|
||||
static Object get(PsiMethod m) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
public class TestIndex {
|
||||
|
||||
Object o;
|
||||
|
||||
public void statMethod(PsiClass c) {
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
c.getMethod();
|
||||
}
|
||||
}
|
||||
|
||||
interface PsiClass {
|
||||
PsiMethod getMethod();
|
||||
}
|
||||
|
||||
interface PsiMethod {}
|
||||
+7
-2
@@ -226,6 +226,10 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest {
|
||||
assertEquals("f.createClass", element.getLookupString());
|
||||
}
|
||||
|
||||
public void testMethodCallInFieldInitializer() {
|
||||
doTestRendering();
|
||||
}
|
||||
|
||||
public void assertAdvisorLookupElementEquals(String lookupText,
|
||||
int unreachableParametersCount,
|
||||
int chainSize,
|
||||
@@ -255,10 +259,11 @@ public class MethodChainsCompletionTest extends AbstractCompilerAwareTest {
|
||||
if (element instanceof JavaRelevantChainLookupElement) {
|
||||
myFixture.getLookup().setCurrentItem(element);
|
||||
myFixture.finishLookup(Lookup.AUTO_INSERT_SELECT_CHAR);
|
||||
break;
|
||||
myFixture.checkResultByFile(getAfterCompletionFilePath());
|
||||
return;
|
||||
}
|
||||
}
|
||||
myFixture.checkResultByFile(getAfterCompletionFilePath());
|
||||
fail("relevant method chain isn't foun");
|
||||
}
|
||||
|
||||
private List<JavaRelevantChainLookupElement> doCompletion() {
|
||||
|
||||
Reference in New Issue
Block a user