mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 20:39:40 +07:00
IDEA-75072 "import statically" option not provided for smart completion variants, java
This commit is contained in:
@@ -82,8 +82,8 @@ class CollectionsUtilityMethodsProvider {
|
||||
}
|
||||
|
||||
final PsiMethod method = methods[0];
|
||||
final JavaMethodCallElement item = new JavaMethodCallElement(method);
|
||||
JavaCompletionUtil.qualify(item).setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
final JavaMethodCallElement item = new JavaMethodCallElement(method, false, false);
|
||||
item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
|
||||
item.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType));
|
||||
result.consume(item);
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ public class DefaultInsertHandler extends TemplateInsertHandler implements Clone
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeEndOfIdentifier(InsertionContext context){
|
||||
public static void removeEndOfIdentifier(InsertionContext context){
|
||||
final Document document = context.getEditor().getDocument();
|
||||
JavaCompletionUtil.initOffsets(context.getFile(), context.getProject(), context.getOffsetMap());
|
||||
document.deleteString(context.getSelectionEndOffset(), context.getOffsetMap().getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));
|
||||
|
||||
@@ -16,12 +16,8 @@ import javax.swing.*;
|
||||
public class ImportStaticLookupActionProvider implements LookupActionProvider {
|
||||
@Override
|
||||
public void fillActions(final LookupElement element, Lookup lookup, Consumer<LookupElementAction> consumer) {
|
||||
if (!(element instanceof StaticallyImportable)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final StaticallyImportable item = (StaticallyImportable)element;
|
||||
if (!item.canBeImported()) {
|
||||
final StaticallyImportable item = element.as(StaticallyImportable.CLASS_CONDITION_KEY);
|
||||
if (item == null || !item.canBeImported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.codeInsight.lookup.VariableLookupItem;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -48,11 +46,9 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
shouldImport |= originalPosition != null && PsiTreeUtil.isAncestor(containingClass, originalPosition, false);
|
||||
|
||||
if (member instanceof PsiMethod) {
|
||||
final JavaMethodCallElement element = new JavaMethodCallElement((PsiMethod)member, true, false);
|
||||
element.setShouldBeImported(shouldImport);
|
||||
return element;
|
||||
return new JavaMethodCallElement((PsiMethod)member, shouldImport, false);
|
||||
}
|
||||
return new StaticFieldLookupItem((PsiField)member, shouldImport, containingClass);
|
||||
return new VariableLookupItem((PsiField)member, shouldImport);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,9 +57,8 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
boolean shouldImport) {
|
||||
shouldImport |= originalPosition != null && PsiTreeUtil.isAncestor(containingClass, originalPosition, false);
|
||||
|
||||
final JavaMethodCallElement element = new JavaMethodCallElement(overloads.get(0), true, true);
|
||||
final JavaMethodCallElement element = new JavaMethodCallElement(overloads.get(0), shouldImport, true);
|
||||
element.putUserData(JavaCompletionUtil.ALL_METHODS_ATTRIBUTE, overloads);
|
||||
element.setShouldBeImported(shouldImport);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
@@ -79,54 +74,4 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
|
||||
return processor;
|
||||
}
|
||||
|
||||
private static class StaticFieldLookupItem extends VariableLookupItem implements StaticallyImportable {
|
||||
private final MemberLookupHelper myHelper;
|
||||
private final PsiClass myContainingClass;
|
||||
|
||||
public StaticFieldLookupItem(PsiField field, boolean shouldImport, PsiClass containingClass) {
|
||||
super(field);
|
||||
myContainingClass = containingClass;
|
||||
myHelper = new MemberLookupHelper(field, containingClass, shouldImport, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShouldBeImported(boolean shouldImportStatic) {
|
||||
myHelper.setShouldBeImported(shouldImportStatic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeImported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willBeImported() {
|
||||
return myHelper.willBeImported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderElement(LookupElementPresentation presentation) {
|
||||
super.renderElement(presentation);
|
||||
myHelper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : null, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
if (willBeImported()) {
|
||||
context.commitDocument();
|
||||
final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
ref.bindToElementViaStaticImport(myContainingClass);
|
||||
PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting();
|
||||
}
|
||||
}
|
||||
super.handleInsert(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldQualify(PsiField field, InsertionContext context) {
|
||||
return !willBeImported() || super.shouldQualify(field, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,14 +39,20 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
private final MemberLookupHelper myHelper;
|
||||
|
||||
public JavaMethodCallElement(@NotNull PsiMethod method) {
|
||||
this(method, false, false);
|
||||
super(method, method.getName());
|
||||
myMethod = method;
|
||||
myHelper = null;
|
||||
myContainingClass = method.getContainingClass();
|
||||
}
|
||||
|
||||
public JavaMethodCallElement(PsiMethod method, boolean canImportStatic, boolean mergedOverloads) {
|
||||
public JavaMethodCallElement(PsiMethod method, boolean shouldImportStatic, boolean mergedOverloads) {
|
||||
super(method, method.getName());
|
||||
myMethod = method;
|
||||
myContainingClass = method.getContainingClass();
|
||||
myHelper = canImportStatic ? new MemberLookupHelper(method, myContainingClass, false, mergedOverloads) : null;
|
||||
myHelper = new MemberLookupHelper(method, myContainingClass, shouldImportStatic, mergedOverloads);
|
||||
if (!shouldImportStatic) {
|
||||
forceQualify();
|
||||
}
|
||||
}
|
||||
|
||||
public PsiType getType() {
|
||||
@@ -132,7 +138,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
return !getInferenceSubstitutor().equals(PsiSubstitutor.EMPTY) && myMethod.getParameterList().getParametersCount() == 0;
|
||||
}
|
||||
|
||||
private boolean mayNeedTypeParameters(InsertionContext context) {
|
||||
private static boolean mayNeedTypeParameters(InsertionContext context) {
|
||||
final PsiElement leaf = context.getFile().findElementAt(context.getStartOffset());
|
||||
if (PsiTreeUtil.getParentOfType(leaf, PsiExpressionList.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
|
||||
if (PsiTreeUtil.getParentOfType(leaf, PsiConditionalExpression.class, true, PsiCodeBlock.class, PsiModifierListOwner.class) == null) {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public interface StaticallyImportable {
|
||||
ClassConditionKey<StaticallyImportable> CLASS_CONDITION_KEY = ClassConditionKey.create(StaticallyImportable.class);
|
||||
|
||||
void setShouldBeImported(boolean shouldImportStatic);
|
||||
|
||||
boolean canBeImported();
|
||||
|
||||
@@ -2,22 +2,32 @@ package com.intellij.codeInsight.lookup;
|
||||
|
||||
import com.intellij.codeInsight.AutoPopupController;
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.CodeCompletionFeatures;
|
||||
import com.intellij.codeInsight.completion.CompletionUtil;
|
||||
import com.intellij.codeInsight.completion.InsertionContext;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class VariableLookupItem extends LookupItem<PsiVariable> implements TypedLookupItem {
|
||||
public class VariableLookupItem extends LookupItem<PsiVariable> implements TypedLookupItem, StaticallyImportable {
|
||||
@Nullable private final MemberLookupHelper myHelper;
|
||||
|
||||
public VariableLookupItem(PsiVariable object) {
|
||||
super(object, object.getName());
|
||||
myHelper = null;
|
||||
}
|
||||
|
||||
public VariableLookupItem(PsiField field, boolean shouldImport) {
|
||||
super(field, field.getName());
|
||||
myHelper = new MemberLookupHelper(field, field.getContainingClass(), shouldImport, false);
|
||||
if (!shouldImport) {
|
||||
forceQualify();
|
||||
}
|
||||
}
|
||||
|
||||
public PsiType getType() {
|
||||
@@ -33,6 +43,30 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
|
||||
public void setSubstitutor(@NotNull PsiSubstitutor substitutor) {
|
||||
setAttribute(SUBSTITUTOR, substitutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShouldBeImported(boolean shouldImportStatic) {
|
||||
assert myHelper != null;
|
||||
myHelper.setShouldBeImported(shouldImportStatic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeImported() {
|
||||
return myHelper != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willBeImported() {
|
||||
return myHelper != null && myHelper.willBeImported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderElement(LookupElementPresentation presentation) {
|
||||
super.renderElement(presentation);
|
||||
if (myHelper != null) {
|
||||
myHelper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null ? Boolean.TRUE : null, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LookupItem<PsiVariable> forceQualify() {
|
||||
@@ -47,14 +81,27 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
super.handleInsert(context);
|
||||
|
||||
PsiVariable variable = getObject();
|
||||
context.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), variable.getName());
|
||||
|
||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
|
||||
if (variable instanceof PsiField && shouldQualify((PsiField)variable, context)) {
|
||||
qualifyFieldReference(context, (PsiField)variable);
|
||||
context.getDocument().replaceString(context.getStartOffset(), context.getTailOffset(), variable.getName());
|
||||
context.commitDocument();
|
||||
if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
|
||||
DefaultInsertHandler.removeEndOfIdentifier(context);
|
||||
context.commitDocument();
|
||||
}
|
||||
|
||||
if (variable instanceof PsiField) {
|
||||
if (willBeImported()) {
|
||||
final PsiReferenceExpression
|
||||
ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
ref.bindToElementViaStaticImport(((PsiField)variable).getContainingClass());
|
||||
PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting();
|
||||
}
|
||||
}
|
||||
else if (shouldQualify((PsiField)variable, context)) {
|
||||
qualifyFieldReference(context, (PsiField)variable);
|
||||
}
|
||||
}
|
||||
|
||||
PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getTailOffset() - 1, PsiReferenceExpression.class, false);
|
||||
@@ -88,14 +135,19 @@ public class VariableLookupItem extends LookupItem<PsiVariable> implements Typed
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldQualify(PsiField field, InsertionContext context) {
|
||||
private boolean shouldQualify(PsiField field, InsertionContext context) {
|
||||
if (myHelper != null && !myHelper.willBeImported()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getAttribute(FORCE_QUALIFY) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PsiReference reference = context.getFile().findReferenceAt(context.getStartOffset());
|
||||
if (reference instanceof PsiReferenceExpression && !((PsiReferenceExpression) reference).isQualified()) {
|
||||
final PsiVariable target = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper().resolveReferencedVariable(field.getName(), (PsiElement)reference);
|
||||
if (reference instanceof PsiReferenceExpression && !((PsiReferenceExpression)reference).isQualified()) {
|
||||
final PsiVariable target = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper()
|
||||
.resolveReferencedVariable(field.getName(), (PsiElement)reference);
|
||||
return !field.getManager().areElementsEquivalent(target, CompletionUtil.getOriginalOrSelf(field));
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -105,7 +105,7 @@ public class JavaMembersGetter extends MembersGetter {
|
||||
return null;
|
||||
}
|
||||
|
||||
return JavaCompletionUtil.qualify(new VariableLookupItem(field));
|
||||
return new VariableLookupItem(field, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -117,8 +117,8 @@ public class JavaMembersGetter extends MembersGetter {
|
||||
}
|
||||
|
||||
|
||||
JavaMethodCallElement item = new JavaMethodCallElement(method);
|
||||
JavaMethodCallElement item = new JavaMethodCallElement(method, false, false);
|
||||
item.setInferenceSubstitutor(substitutor);
|
||||
return JavaCompletionUtil.qualify(item);
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import static Super.FOO;
|
||||
|
||||
class Super {
|
||||
public static final Super FOO = null;
|
||||
public static Super FOO2() {};
|
||||
}
|
||||
|
||||
class Intermediate {
|
||||
|
||||
Super s = FOO;<caret>
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
class Super {
|
||||
public static final Super FOO = null;
|
||||
public static Super FOO2() {};
|
||||
}
|
||||
|
||||
class Intermediate {
|
||||
|
||||
Super s = F<caret>
|
||||
}
|
||||
|
||||
|
||||
@@ -910,7 +910,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
public void testConstructorArgsSmartEnter() throws Exception { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR); }
|
||||
|
||||
private void configureByTestName() throws Exception {
|
||||
private void configureByTestName() {
|
||||
configureByFile("/" + getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
@@ -1030,6 +1030,17 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testInheritorEnumMembers() throws Throwable { doTest(); }
|
||||
public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); }
|
||||
|
||||
public void testMemberImportStatically() {
|
||||
configureByTestName();
|
||||
StaticallyImportable item = myItems[0].as(StaticallyImportable.CLASS_CONDITION_KEY);
|
||||
assertNotNull(item);
|
||||
assertTrue(item.canBeImported());
|
||||
assertTrue(myItems[1].as(StaticallyImportable.CLASS_CONDITION_KEY).canBeImported());
|
||||
item.setShouldBeImported(true);
|
||||
type('\n');
|
||||
checkResultByTestName();
|
||||
}
|
||||
|
||||
public void testNoNewEnum() throws Throwable {
|
||||
configureByTestName();
|
||||
assertStringItems("Foo");
|
||||
@@ -1127,7 +1138,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
|
||||
}
|
||||
|
||||
private void checkResultByTestName() throws Exception {
|
||||
private void checkResultByTestName() {
|
||||
checkResultByFile("/" + getTestName(false) + "-out.java");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user