mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-43317 Complete static members from classes that are already mentioned in import block as static import (groovy)
This commit is contained in:
+1
-32
@@ -1,11 +1,8 @@
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.simple.PsiMethodInsertHandler;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -13,34 +10,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
*/
|
||||
public class JavaGlobalMemberNameCompletionContributor extends CompletionContributor {
|
||||
|
||||
private static final InsertHandler<JavaGlobalMemberLookupElement> STATIC_METHOD_INSERT_HANDLER = new InsertHandler<JavaGlobalMemberLookupElement>() {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context, JavaGlobalMemberLookupElement item) {
|
||||
PsiMethodInsertHandler.INSTANCE.handleInsert(context, item);
|
||||
if (item.getObject().getReturnType() == PsiType.VOID) {
|
||||
TailType.SEMICOLON.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
final PsiClass containingClass = item.getContainingClass();
|
||||
PsiDocumentManager.getInstance(containingClass.getProject()).commitDocument(context.getDocument());
|
||||
final PsiReferenceExpression ref = PsiTreeUtil
|
||||
.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false);
|
||||
if (ref != null) {
|
||||
ref.bindToElementViaStaticImport(containingClass);
|
||||
}
|
||||
}
|
||||
};
|
||||
private static final InsertHandler<JavaGlobalMemberLookupElement> QUALIFIED_METHOD_INSERT_HANDLER = new InsertHandler<JavaGlobalMemberLookupElement>() {
|
||||
@Override
|
||||
public void handleInsert(InsertionContext context, JavaGlobalMemberLookupElement item) {
|
||||
PsiMethodInsertHandler.INSTANCE.handleInsert(context, item);
|
||||
if (item.getObject().getReturnType() == PsiType.VOID) {
|
||||
TailType.SEMICOLON.processTail(context.getEditor(), context.getTailOffset());
|
||||
}
|
||||
context.getDocument().insertString(context.getStartOffset(), ".");
|
||||
JavaCompletionUtil.insertClassReference(item.getContainingClass(), context.getFile(), context.getStartOffset());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
|
||||
if (parameters.getCompletionType() != CompletionType.CLASS_NAME) {
|
||||
@@ -67,7 +36,7 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib
|
||||
}
|
||||
|
||||
public static StaticMemberProcessor completeStaticMembers(final PsiElement position) {
|
||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_METHOD_INSERT_HANDLER) {
|
||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport) {
|
||||
|
||||
@@ -21,21 +21,15 @@ import static com.intellij.util.containers.ContainerUtil.addIfNotNull;
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class StaticMemberProcessor {
|
||||
public abstract class StaticMemberProcessor {
|
||||
private final Set<PsiClass> myStaticImportedClasses = hashSet();
|
||||
private final PsiElement myPosition;
|
||||
private final InsertHandler<JavaGlobalMemberLookupElement> myQualifiedInsert;
|
||||
private final InsertHandler<JavaGlobalMemberLookupElement> myImportInsert;
|
||||
private final Project myProject;
|
||||
private final PsiResolveHelper myResolveHelper;
|
||||
private boolean myHintShown = false;
|
||||
|
||||
public StaticMemberProcessor(final PsiElement position,
|
||||
final InsertHandler<JavaGlobalMemberLookupElement> qualifiedInsert,
|
||||
final InsertHandler<JavaGlobalMemberLookupElement> importInsert) {
|
||||
public StaticMemberProcessor(final PsiElement position) {
|
||||
myPosition = position;
|
||||
myQualifiedInsert = qualifiedInsert;
|
||||
myImportInsert = importInsert;
|
||||
myProject = myPosition.getProject();
|
||||
myResolveHelper = JavaPsiFacade.getInstance(myProject).getResolveHelper();
|
||||
}
|
||||
@@ -124,7 +118,5 @@ public class StaticMemberProcessor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport) {
|
||||
return new JavaGlobalMemberLookupElement(method, containingClass, myQualifiedInsert, myImportInsert, shouldImport);
|
||||
}
|
||||
protected abstract LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public abstract class CompletionResultSet {
|
||||
}
|
||||
}
|
||||
|
||||
public void addAll(@NotNull final Iterable<LookupElement> elements) {
|
||||
public void addAllElements(@NotNull final Iterable<LookupElement> elements) {
|
||||
for (LookupElement element : elements) {
|
||||
addElement(element);
|
||||
}
|
||||
|
||||
+48
-19
@@ -73,6 +73,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.util.containers.CollectionFactory.hashMap;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipWhitespaces;
|
||||
|
||||
/**
|
||||
@@ -144,11 +145,29 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final PsiElement reference = position.getParent();
|
||||
if (reference instanceof GrReferenceElement) {
|
||||
final Map<PsiMethod, LookupElement> staticMethods = hashMap();
|
||||
|
||||
((GrReferenceElement)reference).processVariants(new Consumer<Object>() {
|
||||
public void consume(Object element) {
|
||||
result.addElement(element instanceof PsiClass ? AllClassesGetter.createLookupItem((PsiClass)element) : GroovyCompletionUtil.getLookupElement(element));
|
||||
final LookupElement lookupElement = element instanceof PsiClass
|
||||
? AllClassesGetter.createLookupItem((PsiClass)element)
|
||||
: GroovyCompletionUtil.getLookupElement(element);
|
||||
if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
staticMethods.put((PsiMethod)element, lookupElement);
|
||||
} else {
|
||||
result.addElement(lookupElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
completeStaticMembers(position).processMethodsOfRegisteredClasses(result.getPrefixMatcher(), new Consumer<LookupElement>() {
|
||||
@Override
|
||||
public void consume(LookupElement element) {
|
||||
result.addElement(element);
|
||||
staticMethods.remove(element.getObject());
|
||||
}
|
||||
});
|
||||
result.addAllElements(staticMethods.values());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -361,29 +380,39 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
final String s = result.getPrefixMatcher().getPrefix();
|
||||
if (StringUtil.isEmpty(s) || !Character.isLowerCase(s.charAt(0))) return;
|
||||
|
||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER);
|
||||
final PsiFile file = position.getContainingFile();
|
||||
if (file instanceof GroovyFile) {
|
||||
for (GrImportStatement statement : ((GroovyFile)file).getImportStatements()) {
|
||||
if (statement.isStatic()) {
|
||||
GrCodeReferenceElement importReference = statement.getImportReference();
|
||||
if (importReference != null) {
|
||||
if (!statement.isOnDemand()) {
|
||||
importReference = importReference.getQualifier();
|
||||
}
|
||||
if (importReference != null) {
|
||||
final PsiElement target = importReference.resolve();
|
||||
if (target instanceof PsiClass) {
|
||||
processor.importMembersOf((PsiClass)target);
|
||||
}
|
||||
}
|
||||
completeStaticMembers(position).processStaticMethodsGlobally(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static StaticMemberProcessor completeStaticMembers(PsiElement position) {
|
||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport) {
|
||||
return new JavaGlobalMemberLookupElement(method, containingClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, shouldImport);
|
||||
}
|
||||
};
|
||||
final PsiFile file = position.getContainingFile();
|
||||
if (file instanceof GroovyFile) {
|
||||
for (GrImportStatement statement : ((GroovyFile)file).getImportStatements()) {
|
||||
if (statement.isStatic()) {
|
||||
GrCodeReferenceElement importReference = statement.getImportReference();
|
||||
if (importReference != null) {
|
||||
if (!statement.isOnDemand()) {
|
||||
importReference = importReference.getQualifier();
|
||||
}
|
||||
if (importReference != null) {
|
||||
final PsiElement target = importReference.resolve();
|
||||
if (target instanceof PsiClass) {
|
||||
processor.importMembersOf((PsiClass)target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
processor.processStaticMethodsGlobally(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
return processor;
|
||||
}
|
||||
|
||||
private static void addPropertiesForClass(CompletionResultSet result,
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.UserDataCache;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -30,7 +29,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.ElementBase;
|
||||
import com.intellij.psi.impl.PsiManagerEx;
|
||||
import com.intellij.psi.impl.file.impl.FileManagerImpl;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.scope.DelegatingScopeProcessor;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
@@ -139,14 +138,9 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile {
|
||||
|
||||
final String expectedName = ResolveUtil.getNameHint(processor);
|
||||
|
||||
PsiScopeProcessor importProcessor = !processClasses || expectedName == null ? processor : new BaseScopeProcessor() {
|
||||
PsiScopeProcessor importProcessor = !processClasses || expectedName == null ? processor : new DelegatingScopeProcessor(processor) {
|
||||
public boolean execute(PsiElement element, ResolveState state) {
|
||||
return isImplicitlyImported(element, expectedName) || processor.execute(element, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getHint(Key<T> hintKey) {
|
||||
return processor.getHint(hintKey);
|
||||
return isImplicitlyImported(element, expectedName) || super.execute(element, state);
|
||||
}
|
||||
};
|
||||
for (GrImportStatement importStatement : getImportStatements()) {
|
||||
|
||||
+24
@@ -237,4 +237,28 @@ public class GroovyCompletionTest extends GroovyCompletionTestBase {
|
||||
public void testSmartCastCompletion() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithoutRParenth() {doSmartTest();}
|
||||
public void testSmartCastCompletionWithRParenth() {doSmartTest();}
|
||||
|
||||
public void testWhenSiblingIsStaticallyImported() throws Exception {
|
||||
myFixture.addFileToProject "foo/Foo.groovy", """package foo
|
||||
class Foo {
|
||||
static def abcMethod() {}
|
||||
static def defMethod() {}
|
||||
}
|
||||
"""
|
||||
|
||||
myFixture.configureByText("a.groovy", """
|
||||
import static foo.Foo.abcMethod
|
||||
|
||||
abdMethod()
|
||||
defM<caret>
|
||||
""")
|
||||
myFixture.completeBasic()
|
||||
myFixture.checkResult """
|
||||
import static foo.Foo.abcMethod
|
||||
import static foo.Foo.defMethod
|
||||
|
||||
abdMethod()
|
||||
defMethod()<caret>
|
||||
"""
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user