Skip to content

Commit 6e2eea4

Browse files
authored
Merge pull request #18 from unv-unv/query-executor-refactoring
Query executor refactoring
2 parents 798869a + 0751917 commit 6e2eea4

File tree

9 files changed

+288
-293
lines changed

9 files changed

+288
-293
lines changed

iron-python/src/main/java/consulo/ironPython/psi/impl/PyDotNetSuperMethodsSearchExecutor.java

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,36 @@
1616

1717
package consulo.ironPython.psi.impl;
1818

19+
import com.jetbrains.python.impl.psi.search.PySuperMethodsSearch;
1920
import com.jetbrains.python.psi.PyClass;
2021
import com.jetbrains.python.psi.PyFunction;
21-
import com.jetbrains.python.impl.psi.search.PySuperMethodsSearch;
22-
import consulo.application.util.function.Processor;
2322
import consulo.application.util.query.QueryExecutor;
2423
import consulo.language.psi.PsiElement;
25-
2624
import jakarta.annotation.Nonnull;
2725

26+
import java.util.function.Predicate;
27+
2828
/**
2929
* @author yole
3030
*/
31-
public class PyDotNetSuperMethodsSearchExecutor implements QueryExecutor<PsiElement, PySuperMethodsSearch.SearchParameters>
32-
{
33-
@Override
34-
public boolean execute(@Nonnull final PySuperMethodsSearch.SearchParameters queryParameters, @Nonnull final Processor<? super PsiElement> consumer)
35-
{
36-
PyFunction func = queryParameters.getDerivedMethod();
37-
PyClass containingClass = func.getContainingClass();
38-
/*if (containingClass != null) {
39-
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback())) {
40-
if (type instanceof PyDotNetClassType) {
41-
final DotNetTypeDeclaration psiClass = ((PyDotNetClassType)type).getPsiClass();
42-
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
43-
// the Python method actually does override/implement all of Java super methods with the same name
44-
if (!ContainerUtil.process(methods, consumer)) return false;
45-
}
46-
}
47-
} */
48-
return true;
49-
}
31+
public class PyDotNetSuperMethodsSearchExecutor implements QueryExecutor<PsiElement, PySuperMethodsSearch.SearchParameters> {
32+
@Override
33+
public boolean execute(
34+
@Nonnull final PySuperMethodsSearch.SearchParameters queryParameters,
35+
@Nonnull final Predicate<? super PsiElement> consumer
36+
) {
37+
PyFunction func = queryParameters.getDerivedMethod();
38+
PyClass containingClass = func.getContainingClass();
39+
/*if (containingClass != null) {
40+
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback())) {
41+
if (type instanceof PyDotNetClassType) {
42+
final DotNetTypeDeclaration psiClass = ((PyDotNetClassType)type).getPsiClass();
43+
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
44+
// the Python method actually does override/implement all of Java super methods with the same name
45+
if (!ContainerUtil.process(methods, consumer)) return false;
46+
}
47+
}
48+
}*/
49+
return true;
50+
}
5051
}

jython/src/main/java/com/jetbrains/python/jython/psi/impl/PyJavaSuperMethodsSearchExecutor.java

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,32 @@
3030

3131
import jakarta.annotation.Nonnull;
3232

33+
import java.util.function.Predicate;
34+
3335
/**
3436
* @author yole
3537
*/
3638
@ExtensionImpl
37-
public class PyJavaSuperMethodsSearchExecutor implements PySuperMethodsSearchExecutor
38-
{
39-
public boolean execute(@Nonnull final PySuperMethodsSearch.SearchParameters queryParameters, @Nonnull final Processor<? super PsiElement> consumer)
40-
{
41-
PyFunction func = queryParameters.getDerivedMethod();
42-
PyClass containingClass = func.getContainingClass();
43-
if(containingClass != null)
44-
{
45-
for(PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback(containingClass.getProject())))
46-
{
47-
if(type instanceof PyJavaClassType)
48-
{
49-
final PsiClass psiClass = ((PyJavaClassType) type).getPsiClass();
50-
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
51-
// the Python method actually does override/implement all of Java super methods with the same name
52-
if(!ContainerUtil.process(methods, consumer))
53-
{
54-
return false;
55-
}
56-
}
57-
}
58-
}
59-
return true;
60-
}
39+
public class PyJavaSuperMethodsSearchExecutor implements PySuperMethodsSearchExecutor {
40+
@Override
41+
public boolean execute(
42+
@Nonnull PySuperMethodsSearch.SearchParameters queryParameters,
43+
@Nonnull Predicate<? super PsiElement> consumer
44+
) {
45+
PyFunction func = queryParameters.getDerivedMethod();
46+
PyClass containingClass = func.getContainingClass();
47+
if (containingClass != null) {
48+
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback(containingClass.getProject()))) {
49+
if (type instanceof PyJavaClassType javaClassType) {
50+
PsiClass psiClass = javaClassType.getPsiClass();
51+
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
52+
// the Python method actually does override/implement all of Java super methods with the same name
53+
if (!ContainerUtil.process(methods, consumer)) {
54+
return false;
55+
}
56+
}
57+
}
58+
}
59+
return true;
60+
}
6161
}

python-impl/src/main/java/com/jetbrains/python/impl/psi/search/DefaultPyClassInheritorsSearchExecutor.java

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,68 +18,73 @@
1818
import com.google.common.collect.ImmutableSet;
1919
import com.jetbrains.python.impl.psi.stubs.PySuperClassIndex;
2020
import com.jetbrains.python.psi.PyClass;
21+
import consulo.annotation.access.RequiredReadAction;
2122
import consulo.annotation.component.ExtensionImpl;
22-
import consulo.application.ReadAction;
23-
import consulo.application.util.function.Processor;
23+
import consulo.application.AccessRule;
2424
import consulo.language.psi.stub.StubIndex;
2525
import consulo.project.Project;
2626
import consulo.project.content.scope.ProjectScopes;
27-
2827
import jakarta.annotation.Nonnull;
28+
2929
import java.util.Collection;
3030
import java.util.HashSet;
3131
import java.util.Set;
32+
import java.util.function.Predicate;
3233

3334
/**
3435
* @author yole
3536
*/
3637
@ExtensionImpl
3738
public class DefaultPyClassInheritorsSearchExecutor implements PyClassInheritorsSearchExecutor {
39+
/**
40+
* These base classes are to general to look for inheritors list.
41+
*/
42+
protected static final ImmutableSet<String> IGNORED_BASES = ImmutableSet.of("object", "BaseException", "Exception");
3843

39-
/**
40-
* These base classes are to general to look for inheritors list.
41-
*/
42-
protected static final ImmutableSet<String> IGNORED_BASES = ImmutableSet.of("object", "BaseException", "Exception");
43-
44-
public boolean execute(@Nonnull final PyClassInheritorsSearch.SearchParameters queryParameters,
45-
@Nonnull final Processor<? super PyClass> consumer) {
46-
Set<PyClass> processed = new HashSet<>();
47-
48-
return ReadAction.compute(() -> processDirectInheritors(queryParameters.getSuperClass(),
49-
consumer,
50-
queryParameters.isCheckDeepInheritance(),
51-
processed));
52-
}
44+
@Override
45+
public boolean execute(
46+
@Nonnull PyClassInheritorsSearch.SearchParameters queryParameters,
47+
@Nonnull Predicate<? super PyClass> consumer
48+
) {
49+
Set<PyClass> processed = new HashSet<>();
5350

54-
private static boolean processDirectInheritors(final PyClass superClass,
55-
final Processor<? super PyClass> consumer,
56-
final boolean checkDeep,
57-
final Set<PyClass> processed) {
58-
final String superClassName = superClass.getName();
59-
if (superClassName == null || IGNORED_BASES.contains(superClassName)) {
60-
return true; // we don't want to look for inheritors of overly general classes
51+
return AccessRule.read(() -> processDirectInheritors(
52+
queryParameters.getSuperClass(),
53+
consumer,
54+
queryParameters.isCheckDeepInheritance(),
55+
processed
56+
));
6157
}
62-
if (processed.contains(superClass)) {
63-
return true;
64-
}
65-
processed.add(superClass);
66-
Project project = superClass.getProject();
67-
final Collection<PyClass> candidates =
68-
StubIndex.getElements(PySuperClassIndex.KEY, superClassName, project, ProjectScopes.getAllScope(project), PyClass.class);
69-
for (PyClass candidate : candidates) {
70-
final PyClass[] classes = candidate.getSuperClasses(null);
71-
for (PyClass superClassCandidate : classes) {
72-
if (superClassCandidate.isEquivalentTo(superClass)) {
73-
if (!consumer.process(candidate)) {
74-
return false;
75-
}
76-
if (checkDeep && !processDirectInheritors(candidate, consumer, checkDeep, processed)) {
77-
return false;
78-
}
79-
break;
58+
59+
@RequiredReadAction
60+
private static boolean processDirectInheritors(
61+
PyClass superClass,
62+
Predicate<? super PyClass> consumer,
63+
boolean checkDeep,
64+
Set<PyClass> processed
65+
) {
66+
String superClassName = superClass.getName();
67+
if (superClassName == null || IGNORED_BASES.contains(superClassName)) {
68+
return true; // we don't want to look for inheritors of overly general classes
69+
}
70+
if (processed.contains(superClass)) {
71+
return true;
72+
}
73+
processed.add(superClass);
74+
Project project = superClass.getProject();
75+
Collection<PyClass> candidates =
76+
StubIndex.getElements(PySuperClassIndex.KEY, superClassName, project, ProjectScopes.getAllScope(project), PyClass.class);
77+
for (PyClass candidate : candidates) {
78+
PyClass[] classes = candidate.getSuperClasses(null);
79+
for (PyClass superClassCandidate : classes) {
80+
if (superClassCandidate.isEquivalentTo(superClass)) {
81+
if (!consumer.test(candidate) || checkDeep && !processDirectInheritors(candidate, consumer, checkDeep, processed)) {
82+
return false;
83+
}
84+
break;
85+
}
86+
}
8087
}
81-
}
88+
return true;
8289
}
83-
return true;
84-
}
8590
}

python-impl/src/main/java/com/jetbrains/python/impl/psi/search/DefaultPyOverridingMethodsSearchExecutor.java

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,42 @@
1818
import com.jetbrains.python.impl.psi.PyUtil;
1919
import com.jetbrains.python.psi.*;
2020
import consulo.annotation.component.ExtensionImpl;
21-
import consulo.application.ReadAction;
22-
import consulo.application.util.function.Processor;
23-
21+
import consulo.application.AccessRule;
2422
import jakarta.annotation.Nonnull;
2523

24+
import java.util.function.Predicate;
25+
2626
/**
2727
* @author yole
2828
*/
2929
@ExtensionImpl
3030
public class DefaultPyOverridingMethodsSearchExecutor implements PyOverridingMethodsSearchExecutor {
31-
@Override
32-
public boolean execute(@Nonnull final PyOverridingMethodsSearch.SearchParameters queryParameters,
33-
@Nonnull final Processor<? super PyFunction> consumer) {
34-
final PyFunction baseMethod = queryParameters.getFunction();
31+
@Override
32+
public boolean execute(
33+
@Nonnull PyOverridingMethodsSearch.SearchParameters queryParameters,
34+
@Nonnull Predicate<? super PyFunction> consumer
35+
) {
36+
PyFunction baseMethod = queryParameters.getFunction();
3537

36-
final PyClass containingClass = ReadAction.compute(baseMethod::getContainingClass);
38+
PyClass containingClass = AccessRule.read(baseMethod::getContainingClass);
3739

38-
return PyClassInheritorsSearch.search(containingClass, queryParameters.isCheckDeep()).forEach(pyClass -> {
39-
PyFunction overridingMethod = ReadAction.compute(() -> {
40-
PyFunction func = pyClass.findMethodByName(baseMethod.getName(), false, null);
41-
if (func != null) {
42-
final Property baseProperty = baseMethod.getProperty();
43-
final Property overridingProperty = func.getProperty();
44-
if (baseProperty != null && overridingProperty != null) {
45-
final AccessDirection direction = PyUtil.getPropertyAccessDirection(baseMethod);
46-
final PyCallable callable = overridingProperty.getByDirection(direction).valueOrNull();
47-
func = (callable instanceof PyFunction) ? (PyFunction)callable : null;
48-
}
49-
}
40+
return PyClassInheritorsSearch.search(containingClass, queryParameters.isCheckDeep()).forEach(pyClass -> {
41+
PyFunction overridingMethod = AccessRule.read(() -> {
42+
PyFunction func = pyClass.findMethodByName(baseMethod.getName(), false, null);
43+
if (func != null) {
44+
Property baseProperty = baseMethod.getProperty();
45+
Property overridingProperty = func.getProperty();
46+
if (baseProperty != null && overridingProperty != null) {
47+
AccessDirection direction = PyUtil.getPropertyAccessDirection(baseMethod);
48+
PyCallable callable = overridingProperty.getByDirection(direction).valueOrNull();
49+
func = callable instanceof PyFunction function ? function : null;
50+
}
51+
}
5052

51-
return func;
52-
});
53+
return func;
54+
});
5355

54-
//noinspection SimplifiableIfStatement
55-
if (overridingMethod != null) {
56-
return consumer.process(overridingMethod);
57-
}
58-
return true;
59-
});
60-
}
56+
return overridingMethod == null || consumer.test(overridingMethod);
57+
});
58+
}
6159
}

0 commit comments

Comments
 (0)