IJ-CR-113485 IJ-CR-112205 [java-completion] IDEA-324073 Complete static methods with the first argument as qualifier

- added extension points for other languages. Experimental

GitOrigin-RevId: 6a0383f0137b7e8418b51a1336a16dc3389e9470
This commit is contained in:
Mikhail Pyltsin
2023-08-25 17:26:33 +00:00
committed by intellij-monorepo-bot
parent a08f8129d9
commit 81d3b3f897
4 changed files with 96 additions and 15 deletions
@@ -17,10 +17,9 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
import com.intellij.psi.impl.PsiShortNamesCacheImpl;
import com.intellij.psi.impl.java.stubs.index.JavaStaticMemberNameIndex;
import com.intellij.psi.impl.source.resolve.graphInference.FunctionalInterfaceParameterizationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.JavaStaticMethodNameCache;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.*;
import com.intellij.util.Processor;
@@ -30,10 +29,7 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.intellij.psi.util.PsiFormatUtil.formatVariable;
@@ -131,23 +127,25 @@ public class JavaQualifierAsArgumentContributor extends CompletionContributor im
}
}
//process java static separately
Collection<String> memberNames = JavaStaticMemberNameIndex.getInstance().getAllKeys(project);
for (String memberName : matcher.sortMatching(memberNames)) {
List<JavaStaticMethodNameCache> staticList = JavaStaticMethodNameCache.EP_NAME.getExtensionList(project);
Set<Class<? extends PsiShortNamesCache>> used = new HashSet<>();
for (JavaStaticMethodNameCache cache : staticList) {
ProgressManager.checkCanceled();
for (PsiMember member : JavaStaticMemberNameIndex.getInstance().getStaticMembers(memberName, project, scope)) {
used.add(cache.replaced());
boolean next = cache.processMethodsWithName(name -> matcher.prefixMatches(name), method -> {
ProgressManager.checkCanceled();
if (!psiStaticMethodProcessor.process(member)) {
return;
}
return psiStaticMethodProcessor.process(method);
}, scope, null);
if (!next) {
return;
}
}
List<PsiShortNamesCache> list = PsiShortNamesCache.EP_NAME.getExtensionList(project);
AtomicBoolean stop = new AtomicBoolean(false);
for (PsiShortNamesCache cache : list) {
//skip java
if (cache instanceof PsiShortNamesCacheImpl) {
//skip processed
if (used.contains(cache.getClass())) {
continue;
}
if (stop.get()) {
@@ -0,0 +1,26 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.search;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiMethod;
import com.intellij.util.Processor;
import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Predicate;
@ApiStatus.Experimental
public abstract class JavaStaticMethodNameCache {
public static final ExtensionPointName<JavaStaticMethodNameCache> EP_NAME =
ExtensionPointName.create("com.intellij.java.staticMethodNamesCache");
public abstract boolean processMethodsWithName(@NotNull Predicate<String> namePredicate,
@NotNull final Processor<? super PsiMethod> processor,
@NotNull GlobalSearchScope scope,
@Nullable IdFilter filter);
public abstract Class<? extends PsiShortNamesCache> replaced();
}
@@ -17,6 +17,7 @@
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.allOverridingMethodsSearch" interface="com.intellij.util.QueryExecutor" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.java.shortNamesCache" area="IDEA_PROJECT" interface="com.intellij.psi.search.PsiShortNamesCache" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.java.staticMethodNamesCache" area="IDEA_PROJECT" interface="com.intellij.psi.search.JavaStaticMethodNameCache" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.classesWithAnnotatedMembersSearch" interface="com.intellij.util.QueryExecutor" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.allClassesSearch" interface="com.intellij.util.QueryExecutor" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.overridingMethodsSearch" interface="com.intellij.util.QueryExecutor" dynamic="true"/>
@@ -48,6 +49,7 @@
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaAnonymousClassBaseRefOccurenceIndex"/>
<stubIndex implementation="com.intellij.psi.impl.java.stubs.index.JavaAnnotationIndex"/>
<java.shortNamesCache implementation="com.intellij.psi.impl.PsiShortNamesCacheImpl"/>
<java.staticMethodNamesCache implementation="com.intellij.psi.impl.JavaStaticMethodNameCacheImpl" order="first"/>
<projectService serviceInterface="com.intellij.psi.search.PsiShortNamesCache"
serviceImplementation="com.intellij.psi.impl.CompositeShortNamesCache"/>
<moduleService serviceInterface="com.intellij.openapi.roots.ModulePackageIndex"
@@ -0,0 +1,55 @@
// Copyright 2000-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.impl.java.stubs.index.JavaStaticMemberNameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.JavaStaticMethodNameCache;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.Processor;
import com.intellij.util.indexing.IdFilter;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.function.Predicate;
@ApiStatus.Experimental
public class JavaStaticMethodNameCacheImpl extends JavaStaticMethodNameCache {
@NotNull
private final Project myProject;
public JavaStaticMethodNameCacheImpl(@NotNull Project project) {
myProject = project;
}
@Override
public boolean processMethodsWithName(@NotNull Predicate<String> namePredicate,
@NotNull Processor<? super PsiMethod> processor,
@NotNull GlobalSearchScope scope,
@Nullable IdFilter filter) {
JavaStaticMemberNameIndex index = JavaStaticMemberNameIndex.getInstance();
Collection<String> memberNames = index.getAllKeys(myProject);
for (String memberName : memberNames) {
if (namePredicate.test(memberName)) {
Collection<PsiMember> members = index.getStaticMembers(memberName, myProject, scope);
for (PsiMember member : members) {
if (member instanceof PsiMethod method) {
if (!processor.process(method)) {
return false;
}
}
}
}
}
return true;
}
@Override
public Class<? extends PsiShortNamesCache> replaced() {
return PsiShortNamesCacheImpl.class;
}
}