[pycharm] add type eval context to PyDefUseUtil

GitOrigin-RevId: a6973f48d9e1f5c473209df25ff507be482e8904
This commit is contained in:
Vladimir Koshelev
2024-07-10 14:21:59 +00:00
committed by intellij-monorepo-bot
parent a922b020de
commit 8a4dfe563c
4 changed files with 13 additions and 10 deletions
@@ -477,7 +477,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
final PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(anchor, PyAugAssignmentStatement.class);
final PyElement element = augAssignment != null ? augAssignment : anchor;
try {
final List<Instruction> defs = PyDefUseUtil.getLatestDefs(scopeOwner, name, element, true, false);
final List<Instruction> defs = PyDefUseUtil.getLatestDefs(scopeOwner, name, element, true, false, context);
// null means empty set of possible types, Ref(null) means Any
final @Nullable Ref<PyType> combinedType = StreamEx.of(defs)
.select(ReadWriteInstruction.class)
@@ -278,7 +278,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
if (outermostNestedClass != null) {
final List<Instruction> instructions =
PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, outermostNestedClass, false, true);
PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, outermostNestedClass, false, true, typeEvalContext);
return resolveToLatestDefs(instructions, outermostNestedClass, referencedName, typeEvalContext);
}
@@ -334,7 +334,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
protected List<Instruction> getLatestDefinitions(@NotNull String referencedName,
@Nullable ScopeOwner resolvedOwner,
@Nullable PsiElement realContext) {
return PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, realContext, false, true);
return PyDefUseUtil.getLatestDefs(resolvedOwner, referencedName, realContext, false, true, myContext.getTypeEvalContext());
}
private boolean allInOwnScopeComprehensions(@NotNull Collection<PsiElement> elements) {
@@ -28,6 +28,7 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyAugAssignmentStatementNavigator;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -42,14 +43,14 @@ public final class PyDefUseUtil {
@NotNull
public static List<Instruction> getLatestDefs(ScopeOwner block, String varName, PsiElement anchor, boolean acceptTypeAssertions,
boolean acceptImplicitImports) {
return getLatestDefs(ControlFlowCache.getControlFlow(block), varName, anchor, acceptTypeAssertions, acceptImplicitImports);
boolean acceptImplicitImports, @NotNull TypeEvalContext context) {
return getLatestDefs(ControlFlowCache.getControlFlow(block), varName, anchor, acceptTypeAssertions, acceptImplicitImports, context);
}
@NotNull
public static List<Instruction> getLatestDefs(ControlFlow controlFlow, String varName, PsiElement anchor, boolean acceptTypeAssertions,
boolean acceptImplicitImports) {
boolean acceptImplicitImports, @NotNull TypeEvalContext context) {
final Instruction[] instructions = controlFlow.getInstructions();
final PyAugAssignmentStatement augAssignment = PyAugAssignmentStatementNavigator.getStatementByTarget(anchor);
if (augAssignment != null) {
@@ -65,12 +66,13 @@ public final class PyDefUseUtil {
instr = pred.iterator().next().num();
}
}
final Collection<Instruction> result = getLatestDefs(varName, instructions, instr, acceptTypeAssertions, acceptImplicitImports);
final Collection<Instruction> result = getLatestDefs(varName, instructions, instr, acceptTypeAssertions, acceptImplicitImports, context);
return new ArrayList<>(result);
}
private static Collection<Instruction> getLatestDefs(final String varName, final Instruction[] instructions, final int instr,
final boolean acceptTypeAssertions, final boolean acceptImplicitImports) {
final boolean acceptTypeAssertions, final boolean acceptImplicitImports,
@NotNull final TypeEvalContext context) {
final Collection<Instruction> result = new LinkedHashSet<>();
ControlFlowUtil.iteratePrev(instr, instructions,
instruction -> {
@@ -34,6 +34,7 @@ import com.jetbrains.python.PythonLanguage;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.refactoring.PyDefUseUtil;
import com.jetbrains.python.refactoring.PyReplaceExpressionUtil;
import org.jetbrains.annotations.Nls;
@@ -277,7 +278,7 @@ public final class PyInlineLocalHandler extends InlineActionHandler {
for (final PsiElement ref : refsToInline) {
final List<PsiElement> elems = new ArrayList<>();
final List<Instruction> latestDefs = PyDefUseUtil.getLatestDefs(containerBlock, local.getName(), ref, false, false);
final List<Instruction> latestDefs = PyDefUseUtil.getLatestDefs(containerBlock, local.getName(), ref, false, false, TypeEvalContext.codeInsightFallback(project));
for (Instruction i : latestDefs) {
elems.add(i.getElement());
}
@@ -385,7 +386,7 @@ public final class PyInlineLocalHandler extends InlineActionHandler {
PyTargetExpression local, Project project) {
if (expr != null) {
try {
final List<Instruction> candidates = PyDefUseUtil.getLatestDefs(containerBlock, local.getName(), expr, true, true);
final List<Instruction> candidates = PyDefUseUtil.getLatestDefs(containerBlock, local.getName(), expr, true, true, TypeEvalContext.codeInsightFallback(project));
if (candidates.size() == 1) {
final PyStatement expression = getAssignmentByLeftPart((PyElement)candidates.get(0).getElement());
return Pair.create(expression, false);