mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Don't move overloads from regular Python files back in resolved elements, mark them as low-priority results
This commit is contained in:
committed by
Semyon Proshev
parent
eccfd264e3
commit
c022047f00
@@ -119,29 +119,27 @@ public class PyCallExpressionHelper {
|
||||
public static List<PyCallExpression.PyRatedMarkedCallee> multiResolveRatedCallee(@NotNull PyCallExpression call,
|
||||
@NotNull PyResolveContext resolveContext,
|
||||
int implicitOffset) {
|
||||
final LinkedHashMap<PsiElement, PyCallExpression.PyRatedMarkedCallee> result = new LinkedHashMap<>();
|
||||
final TypeEvalContext context = resolveContext.getTypeEvalContext();
|
||||
final List<PyCallExpression.PyRatedMarkedCallee> ratedMarkedCallees = new ArrayList<>();
|
||||
|
||||
for (QualifiedRatedResolveResult resolveResult : multiResolveCallee(call.getCallee(), resolveContext)) {
|
||||
final ClarifiedResolveResult clarifiedResolveResult = clarifyResolveResult(resolveResult, resolveContext, call);
|
||||
if (clarifiedResolveResult == null) continue;
|
||||
|
||||
final PyCallExpression.PyRatedMarkedCallee markedCallee =
|
||||
markResolveResult(clarifiedResolveResult, resolveContext.getTypeEvalContext(), implicitOffset);
|
||||
final PyCallExpression.PyRatedMarkedCallee markedCallee = markResolveResult(clarifiedResolveResult, context, implicitOffset);
|
||||
if (markedCallee == null) continue;
|
||||
|
||||
// while clarifying resolve results we could get duplicate callables so we have to group them and select result with highest rate
|
||||
result.put(markedCallee.getElement(),
|
||||
StreamEx
|
||||
.of(markedCallee, result.get(markedCallee.getElement()))
|
||||
.nonNull()
|
||||
.max(Comparator.comparingInt(PyCallExpression.PyRatedMarkedCallee::getRate))
|
||||
.orElse(null));
|
||||
ratedMarkedCallees.add(markedCallee);
|
||||
}
|
||||
|
||||
return StreamEx
|
||||
.of(forEveryScopeTakeOverloadsOtherwiseImplementations(result.entrySet(), Map.Entry::getKey, resolveContext.getTypeEvalContext()))
|
||||
.map(Map.Entry::getValue)
|
||||
.toList();
|
||||
return forEveryScopeTakeOverloadsOtherwiseImplementations(ratedMarkedCallees, PyCallExpression.PyRatedMarkedCallee::getElement, context)
|
||||
// while clarifying resolve results we could get duplicate callables so we have to group them and select result with highest rate
|
||||
.collect(Collectors.groupingBy(markedCallee -> markedCallee.getElement(), LinkedHashMap::new, Collectors.toList()))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(entry -> entry.getValue().stream().max(Comparator.comparingInt(PyCallExpression.PyRatedMarkedCallee::getRate)).orElse(null))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -405,11 +403,13 @@ public class PyCallExpressionHelper {
|
||||
}
|
||||
// normal cases
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
|
||||
final List<QualifiedRatedResolveResult> resolveResults =
|
||||
PyUtil.filterTopPriorityResults(multiResolveCallee(callee, resolveContext));
|
||||
|
||||
final List<QualifiedRatedResolveResult> resolveResults = multiResolveCallee(callee, resolveContext);
|
||||
final Stream<QualifiedRatedResolveResult> overloadsOtherwiseImplementations =
|
||||
forEveryScopeTakeOverloadsOtherwiseImplementations(resolveResults, RatedResolveResult::getElement, context);
|
||||
|
||||
final List<PyType> members = StreamEx
|
||||
.of(forEveryScopeTakeOverloadsOtherwiseImplementations(resolveResults, ResolveResult::getElement, context))
|
||||
.of(PyUtil.filterTopPriorityResults(overloadsOtherwiseImplementations.collect(Collectors.toList())))
|
||||
.map(ResolveResult::getElement)
|
||||
.nonNull()
|
||||
.peek(element -> PyUtil.verboseOnly(() -> PyPsiUtils.assertValid(element)))
|
||||
|
||||
@@ -54,14 +54,12 @@ import com.jetbrains.python.psi.stubs.PyFileStub;
|
||||
import com.jetbrains.python.psi.types.PyModuleType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import com.jetbrains.python.pyi.PyiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
protected PyType myType;
|
||||
@@ -183,10 +181,7 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
|
||||
}
|
||||
}
|
||||
|
||||
final Function<RatedResolveResult, PsiElement> mapper = RatedResolveResult::getElement;
|
||||
return PyiUtil.containsOverloads(resultList, mapper, typeEvalContext)
|
||||
? PyiUtil.moveOverloadsBack(resultList, mapper, typeEvalContext)
|
||||
: resultList;
|
||||
return resultList;
|
||||
}
|
||||
|
||||
synchronized (myNameDefinerNegativeCache) {
|
||||
|
||||
@@ -440,6 +440,9 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
|
||||
else if (elt instanceof PyFile) {
|
||||
rate = RatedResolveResult.RATE_HIGH;
|
||||
}
|
||||
else if (!PyiUtil.isInsideStub(elt) && PyiUtil.isOverload(elt, context)) {
|
||||
rate = RatedResolveResult.RATE_LOW;
|
||||
}
|
||||
else {
|
||||
rate = RatedResolveResult.RATE_NORMAL;
|
||||
}
|
||||
|
||||
@@ -44,13 +44,11 @@ import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveProcessor;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
import com.jetbrains.python.pyi.PyiUtil;
|
||||
import com.jetbrains.python.toolbox.Maybe;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.jetbrains.python.psi.PyUtil.as;
|
||||
@@ -561,13 +559,10 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
|
||||
}
|
||||
else {
|
||||
cls.processClassLevelDeclarations(processor);
|
||||
final Collection<PsiElement> elements = processor.getElements();
|
||||
result = PyiUtil.containsOverloads(elements, Function.identity(), context)
|
||||
? PyiUtil.moveOverloadsBack(elements, Function.identity(), context)
|
||||
: elements;
|
||||
result = processor.getElements();
|
||||
}
|
||||
|
||||
return ContainerUtil.map(result, element -> new RatedResolveResult(RatedResolveResult.RATE_NORMAL, element));
|
||||
return ContainerUtil.map(result, element -> new RatedResolveResult(PyReferenceImpl.getRate(element, context), element));
|
||||
}
|
||||
|
||||
private static Key<Set<PyClassType>> CTX_VISITED = Key.create("PyClassType.Visited");
|
||||
|
||||
@@ -28,14 +28,13 @@ import com.jetbrains.python.psi.resolve.*;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
@@ -126,22 +125,6 @@ public class PyiUtil {
|
||||
PyKnownDecoratorUtil.getKnownDecorators((PyFunction)element, context).contains(overload);
|
||||
}
|
||||
|
||||
public static <T> boolean containsOverloads(@NotNull Collection<T> elements,
|
||||
@NotNull Function<? super T, PsiElement> mapper,
|
||||
@NotNull TypeEvalContext context) {
|
||||
return ContainerUtil.exists(elements, element -> isOverload(mapper.apply(element), context));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> List<T> moveOverloadsBack(@NotNull Collection<T> elements,
|
||||
@NotNull Function<? super T, PsiElement> mapper,
|
||||
@NotNull TypeEvalContext context) {
|
||||
return StreamEx
|
||||
.of(elements)
|
||||
.sorted((e1, e2) -> Boolean.compare(isOverload(mapper.apply(e1), context), isOverload(mapper.apply(e2), context)))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private static boolean pyButNotPyiFile(@Nullable PsiFile file) {
|
||||
return file instanceof PyFile && !(file instanceof PyiFile);
|
||||
}
|
||||
@@ -190,20 +173,20 @@ public class PyiUtil {
|
||||
final PyClassLikeType instanceType = classType.toInstance();
|
||||
final List<? extends RatedResolveResult> resolveResults = instanceType.resolveMember(name, null, AccessDirection.READ,
|
||||
PyResolveContext.noImplicits(), false);
|
||||
return takeFirstElement(resolveResults);
|
||||
return takeTopPriorityElement(resolveResults);
|
||||
}
|
||||
}
|
||||
else if (originalOwner instanceof PyFile) {
|
||||
return takeFirstElement(((PyFile)originalOwner).multiResolveName(name));
|
||||
return takeTopPriorityElement(((PyFile)originalOwner).multiResolveName(name));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement takeFirstElement(@Nullable List<? extends RatedResolveResult> resolveResults) {
|
||||
private static PsiElement takeTopPriorityElement(@Nullable List<? extends RatedResolveResult> resolveResults) {
|
||||
if (!ContainerUtil.isEmpty(resolveResults)) {
|
||||
return resolveResults.get(0).getElement();
|
||||
return Collections.max(resolveResults, Comparator.comparingInt(RatedResolveResult::getRate)).getElement();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user