mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-66656 Suggest static fields in Class Name completion
This commit is contained in:
+1
-1
@@ -41,7 +41,7 @@ public class ExcludeFromCompletionLookupActionProvider implements LookupActionPr
|
||||
} else if (o instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)o;
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
addExcludes(consumer, method, StaticImportMethodFix.getMethodQualifiedName(method));
|
||||
addExcludes(consumer, method, StaticImportMethodFix.getMemberQualifiedName(method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-51
@@ -3,9 +3,10 @@ package com.intellij.codeInsight.completion;
|
||||
import com.intellij.codeInsight.lookup.DefaultLookupItemRenderer;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -16,92 +17,54 @@ import static com.intellij.util.ObjectUtils.assertNotNull;
|
||||
* @author peter
|
||||
*/
|
||||
public class JavaGlobalMemberLookupElement extends LookupElement implements StaticallyImportable {
|
||||
private final PsiMember myMember;
|
||||
private final boolean myMergedOverloads;
|
||||
private final PsiClass myContainingClass;
|
||||
private final MemberLookupHelper myHelper;
|
||||
private final InsertHandler<JavaGlobalMemberLookupElement> myQualifiedInsertion;
|
||||
private final InsertHandler<JavaGlobalMemberLookupElement> myImportInsertion;
|
||||
private boolean myShouldImport = false;
|
||||
|
||||
public JavaGlobalMemberLookupElement(List<PsiMethod> overloads,
|
||||
PsiClass containingClass,
|
||||
InsertHandler<JavaGlobalMemberLookupElement> qualifiedInsertion,
|
||||
InsertHandler<JavaGlobalMemberLookupElement> importInsertion, boolean shouldImport) {
|
||||
myMember = overloads.get(0);
|
||||
myContainingClass = containingClass;
|
||||
myHelper = new MemberLookupHelper(overloads, containingClass, shouldImport);
|
||||
myQualifiedInsertion = qualifiedInsertion;
|
||||
myImportInsertion = importInsertion;
|
||||
myShouldImport = shouldImport;
|
||||
myMergedOverloads = true;
|
||||
}
|
||||
|
||||
public JavaGlobalMemberLookupElement(PsiMember member,
|
||||
PsiClass containingClass,
|
||||
InsertHandler<JavaGlobalMemberLookupElement> qualifiedInsertion,
|
||||
InsertHandler<JavaGlobalMemberLookupElement> importInsertion, boolean shouldImport) {
|
||||
myMember = member;
|
||||
myContainingClass = containingClass;
|
||||
myHelper = new MemberLookupHelper(member, containingClass, shouldImport, false);
|
||||
myQualifiedInsertion = qualifiedInsertion;
|
||||
myImportInsertion = importInsertion;
|
||||
myShouldImport = shouldImport;
|
||||
myMergedOverloads = false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiMember getObject() {
|
||||
return myMember;
|
||||
return myHelper.getMember();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiClass getContainingClass() {
|
||||
return myContainingClass;
|
||||
return assertNotNull(myHelper.getContainingClass());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLookupString() {
|
||||
return assertNotNull(myMember.getName());
|
||||
return assertNotNull(getObject().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderElement(LookupElementPresentation presentation) {
|
||||
final String className = myContainingClass.getName();
|
||||
|
||||
presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(this, presentation.isReal()));
|
||||
|
||||
final String methodName = myMember.getName();
|
||||
if (Boolean.FALSE.equals(myShouldImport) && StringUtil.isNotEmpty(className)) {
|
||||
presentation.setItemText(className + "." + methodName);
|
||||
} else {
|
||||
presentation.setItemText(methodName);
|
||||
}
|
||||
|
||||
final String qname = myContainingClass.getQualifiedName();
|
||||
String location = StringUtil.isEmpty(qname) ? "" : " (" + StringUtil.getPackageName(qname) + ")";
|
||||
|
||||
final String params = myMergedOverloads
|
||||
? "(...)"
|
||||
: myMember instanceof PsiMethod
|
||||
? PsiFormatUtil.formatMethod((PsiMethod)myMember, PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE)
|
||||
: "";
|
||||
if (Boolean.TRUE.equals(myShouldImport) && StringUtil.isNotEmpty(className)) {
|
||||
presentation.setTailText(params + " in " + className + location);
|
||||
} else {
|
||||
presentation.setTailText(params + location);
|
||||
}
|
||||
|
||||
final PsiType type = myMember instanceof PsiMethod ? ((PsiMethod)myMember).getReturnType() : ((PsiField) myMember).getType();
|
||||
if (type != null) {
|
||||
presentation.setTypeText(type.getPresentableText());
|
||||
}
|
||||
myHelper.renderElement(presentation, false, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShouldBeImported(boolean shouldImportStatic) {
|
||||
myShouldImport = shouldImportStatic;
|
||||
myHelper.setShouldBeImported(shouldImportStatic);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,11 +74,12 @@ public class JavaGlobalMemberLookupElement extends LookupElement implements Stat
|
||||
|
||||
@Override
|
||||
public boolean willBeImported() {
|
||||
return myShouldImport;
|
||||
return myHelper.willBeImported();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
(myShouldImport ? myImportInsertion : myQualifiedInsertion).handleInsert(context, this);
|
||||
(willBeImported() ? myImportInsertion : myQualifiedInsertion).handleInsert(context, this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+51
-16
@@ -1,6 +1,7 @@
|
||||
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;
|
||||
@@ -20,9 +21,7 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
return;
|
||||
}
|
||||
|
||||
final PrefixMatcher matcher = result.getPrefixMatcher();
|
||||
final String prefix = matcher.getPrefix();
|
||||
if (prefix.length() == 0 || !Character.isLowerCase(prefix.charAt(0))) {
|
||||
if (result.getPrefixMatcher().getPrefix().length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -43,24 +42,13 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement createLookupElement(@NotNull PsiMember member, @NotNull final PsiClass containingClass, boolean shouldImport) {
|
||||
protected LookupElement createLookupElement(@NotNull PsiMember member, @NotNull final PsiClass containingClass, final boolean shouldImport) {
|
||||
if (member instanceof PsiMethod) {
|
||||
final JavaMethodCallElement element = new JavaMethodCallElement((PsiMethod)member, true, false);
|
||||
element.setShouldBeImported(shouldImport);
|
||||
return element;
|
||||
}
|
||||
return new VariableLookupItem((PsiVariable)member) {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context) {
|
||||
context.commitDocument();
|
||||
final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
ref.bindToElementViaStaticImport(containingClass);
|
||||
PostprocessReformattingAspect.getInstance(ref.getProject()).doPostponedFormatting();
|
||||
}
|
||||
super.handleInsert(context);
|
||||
}
|
||||
};
|
||||
return new StaticFieldLookupItem((PsiField)member, shouldImport, containingClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,4 +74,51 @@ 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, 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();
|
||||
}
|
||||
} else {
|
||||
context.getDocument().insertString(context.getStartOffset(), ".");
|
||||
JavaCompletionUtil.insertClassReference(myContainingClass, context.getFile(), context.getStartOffset());
|
||||
}
|
||||
super.handleInsert(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.ClassConditionKey;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -39,9 +37,7 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
private static final Key<PsiSubstitutor> INFERENCE_SUBSTITUTOR = Key.create("INFERENCE_SUBSTITUTOR");
|
||||
@Nullable private final PsiClass myContainingClass;
|
||||
private final PsiMethod myMethod;
|
||||
private final boolean myCanImportStatic;
|
||||
private boolean myShouldImportStatic;
|
||||
private final boolean myMergedOverloads;
|
||||
private final MemberLookupHelper myHelper;
|
||||
|
||||
public JavaMethodCallElement(@NotNull PsiMethod method) {
|
||||
this(method, false, false);
|
||||
@@ -50,9 +46,8 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
public JavaMethodCallElement(PsiMethod method, boolean canImportStatic, boolean mergedOverloads) {
|
||||
super(method, method.getName());
|
||||
myMethod = method;
|
||||
myMergedOverloads = mergedOverloads;
|
||||
myContainingClass = method.getContainingClass();
|
||||
myCanImportStatic = canImportStatic;
|
||||
myHelper = canImportStatic ? new MemberLookupHelper(method, myContainingClass, false, mergedOverloads) : null;
|
||||
}
|
||||
|
||||
public PsiType getType() {
|
||||
@@ -77,18 +72,17 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
|
||||
@Override
|
||||
public void setShouldBeImported(boolean shouldImportStatic) {
|
||||
assert myCanImportStatic;
|
||||
myShouldImportStatic = shouldImportStatic;
|
||||
myHelper.setShouldBeImported(shouldImportStatic);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeImported() {
|
||||
return myCanImportStatic;
|
||||
return myHelper != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willBeImported() {
|
||||
return myShouldImportStatic;
|
||||
return canBeImported() && myHelper.willBeImported();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,9 +102,9 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
qualifyMethodCall(file, startOffset, document);
|
||||
insertExplicitTypeParameters(context, refStart);
|
||||
}
|
||||
else if (myCanImportStatic || getAttribute(FORCE_QUALIFY) != null) {
|
||||
else if (myHelper != null || getAttribute(FORCE_QUALIFY) != null) {
|
||||
context.commitDocument();
|
||||
if (myCanImportStatic && myShouldImportStatic) {
|
||||
if (myHelper != null && willBeImported()) {
|
||||
final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(file, startOffset, PsiReferenceExpression.class, false);
|
||||
if (ref != null && myContainingClass != null) {
|
||||
ref.bindToElementViaStaticImport(myContainingClass);
|
||||
@@ -234,38 +228,12 @@ public class JavaMethodCallElement extends LookupItem<PsiMethod> implements Type
|
||||
|
||||
@Override
|
||||
public void renderElement(LookupElementPresentation presentation) {
|
||||
final String className = myContainingClass == null ? "???" : myContainingClass.getName();
|
||||
|
||||
presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(this, presentation.isReal()));
|
||||
|
||||
final String methodName = myMethod.getName();
|
||||
final boolean qualify = myCanImportStatic && !myShouldImportStatic || getAttribute(FORCE_QUALIFY) != null;
|
||||
if (qualify && StringUtil.isNotEmpty(className)) {
|
||||
presentation.setItemText(className + "." + methodName);
|
||||
} else {
|
||||
presentation.setItemText(methodName);
|
||||
}
|
||||
|
||||
final String qname = myContainingClass == null ? "" : myContainingClass.getQualifiedName();
|
||||
String location = !myCanImportStatic || StringUtil.isEmpty(qname) ? "" : " (" + StringUtil.getPackageName(qname) + ")";
|
||||
|
||||
presentation.setStrikeout(JavaElementLookupRenderer.isToStrikeout(this));
|
||||
presentation.setItemTextBold(getAttribute(HIGHLIGHTED_ATTR) != null);
|
||||
|
||||
final String params = myMergedOverloads
|
||||
? "(...)"
|
||||
: PsiFormatUtil.formatMethod(myMethod, PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE);
|
||||
if (myShouldImportStatic && StringUtil.isNotEmpty(className)) {
|
||||
presentation.setTailText(params + " in " + className + location);
|
||||
} else {
|
||||
presentation.setTailText(params + location);
|
||||
}
|
||||
|
||||
final PsiType type = myMethod.getReturnType();
|
||||
if (type != null) {
|
||||
presentation.setTypeText(getSubstitutor().substitute(type).getPresentableText());
|
||||
}
|
||||
MemberLookupHelper helper = myHelper != null ? myHelper : new MemberLookupHelper(myMethod, myContainingClass, false, false);
|
||||
helper.renderElement(presentation, getAttribute(FORCE_QUALIFY) != null, getSubstitutor());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.lookup.LookupElementPresentation;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiFormatUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class MemberLookupHelper {
|
||||
private final PsiMember myMember;
|
||||
private final boolean myMergedOverloads;
|
||||
@Nullable private final PsiClass myContainingClass;
|
||||
private boolean myShouldImport = false;
|
||||
|
||||
public MemberLookupHelper(List<PsiMethod> overloads, PsiClass containingClass, boolean shouldImport) {
|
||||
this(overloads.get(0), containingClass, shouldImport, true);
|
||||
}
|
||||
|
||||
public MemberLookupHelper(PsiMember member, PsiClass containingClass, boolean shouldImport, final boolean mergedOverloads) {
|
||||
myMember = member;
|
||||
myContainingClass = containingClass;
|
||||
myShouldImport = shouldImport;
|
||||
myMergedOverloads = mergedOverloads;
|
||||
}
|
||||
|
||||
public PsiMember getMember() {
|
||||
return myMember;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiClass getContainingClass() {
|
||||
return myContainingClass;
|
||||
}
|
||||
|
||||
public void setShouldBeImported(boolean shouldImportStatic) {
|
||||
myShouldImport = shouldImportStatic;
|
||||
}
|
||||
|
||||
public boolean willBeImported() {
|
||||
return myShouldImport;
|
||||
}
|
||||
|
||||
public void renderElement(LookupElementPresentation presentation, boolean forceQualify, PsiSubstitutor substitutor) {
|
||||
final String className = myContainingClass == null ? "???" : myContainingClass.getName();
|
||||
|
||||
final String memberName = myMember.getName();
|
||||
if (!myShouldImport && StringUtil.isNotEmpty(className) || forceQualify) {
|
||||
presentation.setItemText(className + "." + memberName);
|
||||
} else {
|
||||
presentation.setItemText(memberName);
|
||||
}
|
||||
|
||||
final String qname = myContainingClass == null ? "" : myContainingClass.getQualifiedName();
|
||||
String pkg = StringUtil.getPackageName(qname);
|
||||
String location = StringUtil.isEmpty(pkg) ? "" : " (" + pkg + ")";
|
||||
|
||||
final String params = myMergedOverloads
|
||||
? "(...)"
|
||||
: myMember instanceof PsiMethod
|
||||
? PsiFormatUtil.formatMethod((PsiMethod)myMember, PsiSubstitutor.EMPTY,
|
||||
PsiFormatUtil.SHOW_PARAMETERS,
|
||||
PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE)
|
||||
: "";
|
||||
if (myShouldImport && StringUtil.isNotEmpty(className)) {
|
||||
presentation.setTailText(params + " in " + className + location);
|
||||
} else {
|
||||
presentation.setTailText(params + location, !(myMember instanceof PsiMethod));
|
||||
}
|
||||
|
||||
final PsiType type = myMember instanceof PsiMethod ? ((PsiMethod)myMember).getReturnType() : ((PsiField) myMember).getType();
|
||||
if (type != null) {
|
||||
presentation.setTypeText(substitutor.substitute(type).getPresentableText());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -69,13 +69,7 @@ public abstract class StaticMemberProcessor {
|
||||
|
||||
if (classes.add(containingClass) && JavaCompletionUtil.isSourceLevelAccessible(myPosition, containingClass, myPackagedContext)) {
|
||||
final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
|
||||
if (!myHintShown && !shouldImport && CompletionService.getCompletionService().getAdvertisementText() == null) {
|
||||
final String shortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_SHOW_INTENTION_ACTIONS);
|
||||
if (shortcut != null) {
|
||||
CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
|
||||
}
|
||||
myHintShown = true;
|
||||
}
|
||||
showHint(shouldImport);
|
||||
|
||||
final PsiMethod[] allMethods = containingClass.getAllMethods();
|
||||
final List<PsiMethod> overloads = ContainerUtil.findAll(allMethods, new Condition<PsiMethod>() {
|
||||
@@ -100,6 +94,32 @@ public abstract class StaticMemberProcessor {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (final String fieldName : namesCache.getAllFieldNames()) {
|
||||
if (matcher.prefixMatches(fieldName)) {
|
||||
for (final PsiField field : namesCache.getFieldsByName(fieldName, scope)) {
|
||||
if (isStaticallyImportable(field)) {
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
assert containingClass != null;
|
||||
|
||||
if (JavaCompletionUtil.isSourceLevelAccessible(myPosition, containingClass, myPackagedContext)) {
|
||||
final boolean shouldImport = myStaticImportedClasses.contains(containingClass);
|
||||
showHint(shouldImport);
|
||||
consumer.consume(createLookupElement(field, containingClass, shouldImport));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showHint(boolean shouldImport) {
|
||||
if (!myHintShown && !shouldImport && CompletionService.getCompletionService().getAdvertisementText() == null) {
|
||||
final String shortcut = CompletionContributor.getActionShortcut(IdeActions.ACTION_SHOW_INTENTION_ACTIONS);
|
||||
if (shortcut != null) {
|
||||
CompletionService.getCompletionService().setAdvertisementText("To import a method statically, press " + shortcut);
|
||||
}
|
||||
myHintShown = true;
|
||||
}
|
||||
}
|
||||
|
||||
public List<PsiMember> processMembersOfRegisteredClasses(@Nullable final PrefixMatcher matcher, PairConsumer<PsiMember, PsiClass> consumer) {
|
||||
@@ -113,7 +133,7 @@ public abstract class StaticMemberProcessor {
|
||||
}
|
||||
}
|
||||
for (final PsiField field : psiClass.getAllFields()) {
|
||||
if (matcher == null || matcher.prefixMatches(field.getName())) {
|
||||
if (matcher == null || matcher.prefixMatches(field. getName())) {
|
||||
if (isStaticallyImportable(field)) {
|
||||
consumer.consume(field, psiClass);
|
||||
}
|
||||
@@ -125,17 +145,11 @@ public abstract class StaticMemberProcessor {
|
||||
|
||||
|
||||
private boolean isStaticallyImportable(final PsiMember member) {
|
||||
if (member.hasModifierProperty(PsiModifier.STATIC) && myResolveHelper.isAccessible(member, myPosition, null)) {
|
||||
final PsiClass containingClass = member.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
if (!JavaCompletionUtil.isInExcludedPackage(containingClass) &&
|
||||
(!(member instanceof PsiMethod) || !StaticImportMethodFix.isExcluded((PsiMethod)member))) {
|
||||
return true;
|
||||
}
|
||||
return member.hasModifierProperty(PsiModifier.STATIC) && isAccessible(member) && !StaticImportMethodFix.isExcluded(member);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
protected boolean isAccessible(PsiMember member) {
|
||||
return myResolveHelper.isAccessible(member, myPosition, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-4
@@ -142,8 +142,8 @@ public class StaticImportMethodFix implements IntentionAction {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isExcluded(PsiMethod method) {
|
||||
String name = getMethodQualifiedName(method);
|
||||
public static boolean isExcluded(PsiMember method) {
|
||||
String name = getMemberQualifiedName(method);
|
||||
if (name == null) return false;
|
||||
CodeInsightSettings cis = CodeInsightSettings.getInstance();
|
||||
for (String excluded : cis.EXCLUDED_PACKAGES) {
|
||||
@@ -204,7 +204,7 @@ public class StaticImportMethodFix implements IntentionAction {
|
||||
return FINAL_CHOICE;
|
||||
}
|
||||
|
||||
String qname = getMethodQualifiedName(selectedValue);
|
||||
String qname = getMemberQualifiedName(selectedValue);
|
||||
if (qname == null) return FINAL_CHOICE;
|
||||
List<String> excludableStrings = AddImportAction.getAllExcludableStrings(qname);
|
||||
return new BaseListPopupStep<String>(null, excludableStrings) {
|
||||
@@ -270,7 +270,7 @@ public class StaticImportMethodFix implements IntentionAction {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getMethodQualifiedName(PsiMethod method) {
|
||||
public static String getMemberQualifiedName(PsiMember method) {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
String className = containingClass.getQualifiedName();
|
||||
|
||||
+30
@@ -24,6 +24,36 @@ public class Foo {
|
||||
class Bar {{ abcmethod()<caret> }}"""
|
||||
}
|
||||
|
||||
public void testFieldName() throws Exception {
|
||||
myFixture.addClass("""
|
||||
package foo;
|
||||
|
||||
public class Foo {
|
||||
public static int abcfield = 2
|
||||
static final int fieldThatsNotVisible = 3
|
||||
}
|
||||
""")
|
||||
|
||||
doTest "class Bar {{ abcf<caret> }}", true, """import static foo.Foo.abcfield;
|
||||
|
||||
class Bar {{ abcfield<caret> }}"""
|
||||
}
|
||||
|
||||
public void testFieldNameQualified() throws Exception {
|
||||
myFixture.addClass("""
|
||||
package foo;
|
||||
|
||||
public class Foo {
|
||||
public static int abcfield = 2
|
||||
static final int fieldThatsNotVisible = 3
|
||||
}
|
||||
""")
|
||||
|
||||
doTest "class Bar {{ abcf<caret> }}", false, """import foo.Foo;
|
||||
|
||||
class Bar {{ Foo.abcfield<caret> }}"""
|
||||
}
|
||||
|
||||
public void testQualifiedMethodName() throws Exception {
|
||||
myFixture.addClass("""
|
||||
package foo;
|
||||
|
||||
+13
-2
@@ -235,8 +235,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
if (((GrReferenceElement)position.getParent()).getQualifier() != null) return;
|
||||
|
||||
final String s = result.getPrefixMatcher().getPrefix();
|
||||
if (StringUtil.isEmpty(s) || !Character.isLowerCase(s.charAt(0))) return;
|
||||
if (StringUtil.isEmpty(result.getPrefixMatcher().getPrefix())) return;
|
||||
|
||||
completeStaticMembers(position).processStaticMethodsGlobally(result);
|
||||
}
|
||||
@@ -493,6 +492,18 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
return new JavaGlobalMemberLookupElement(overloads, containingClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER,
|
||||
shouldImport);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isAccessible(PsiMember member) {
|
||||
boolean result = super.isAccessible(member);
|
||||
|
||||
if (!result && member instanceof GrField) {
|
||||
GrAccessorMethod[] getters = ((GrField)member).getGetters();
|
||||
return getters.length > 0 && super.isAccessible(getters[0]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
final PsiFile file = position.getContainingFile();
|
||||
if (file instanceof GroovyFile) {
|
||||
|
||||
+40
@@ -128,6 +128,46 @@ def foo() {
|
||||
|
||||
}
|
||||
|
||||
public void testImportedStaticField() throws Exception {
|
||||
myFixture.addFileToProject("b.groovy", """
|
||||
class Foo {
|
||||
static def abcfield1
|
||||
static def abcfield2
|
||||
}""")
|
||||
myFixture.configureByText("a.groovy", """def foo() {
|
||||
abcfi<caret>
|
||||
}""")
|
||||
def item = myFixture.complete(CompletionType.CLASS_NAME)[0]
|
||||
((StaticallyImportable) item).shouldBeImported = true
|
||||
myFixture.type('\n')
|
||||
myFixture.checkResult """import static Foo.abcfield1
|
||||
|
||||
def foo() {
|
||||
abcfield1<caret>
|
||||
}"""
|
||||
|
||||
}
|
||||
|
||||
public void testImportedInterfaceConstant() throws Exception {
|
||||
myFixture.addFileToProject("b.groovy", """
|
||||
interface Foo {
|
||||
static def abcfield1 = 2
|
||||
static def abcfield2 = 3
|
||||
}""")
|
||||
myFixture.configureByText("a.groovy", """def foo() {
|
||||
abcfi<caret>
|
||||
}""")
|
||||
def item = myFixture.complete(CompletionType.CLASS_NAME)[0]
|
||||
((StaticallyImportable) item).shouldBeImported = true
|
||||
myFixture.type('\n')
|
||||
myFixture.checkResult """import static Foo.abcfield1
|
||||
|
||||
def foo() {
|
||||
abcfield1<caret>
|
||||
}"""
|
||||
|
||||
}
|
||||
|
||||
public void testQualifiedStaticMethod() throws Exception {
|
||||
myFixture.addFileToProject("foo/b.groovy", """package foo
|
||||
class Foo {
|
||||
|
||||
Reference in New Issue
Block a user