mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-18 20:41:22 +07:00
PY-77168 Allow flow-sensitive resolve from unmatched version checks to reachable outer blocks
Also, don't query LanguageLevel for each element of each instruction,
only once per scope traversal.
This doesn't fix the problem with unreachable definition *inside* blocks under
unmatched version checks, i.e.
if sys.version_info < (3, 8):
Alias = int
expr: Alias # unresolved
but it's a more difficult problem how to handle those consistently with the idea
of unreachable version checks under the *current* interpreter version, and hopefully
it occurs rarer than, say, unresolved top-level imports of common names from typing.
(cherry picked from commit 55fd4597c6d0860d290caba15fbf4d313e985a86)
IJ-CR-149696
GitOrigin-RevId: 357ada7e10618aef75c470e6cd878f7672109e83
This commit is contained in:
committed by
intellij-monorepo-bot
parent
22cae80f9d
commit
535af53f05
@@ -86,9 +86,6 @@ public final class PyDefUseUtil {
|
||||
final HashMap<PyCallSiteExpression, ConditionalInstruction> pendingTypeGuard = new HashMap<>();
|
||||
ControlFlowUtil.iteratePrev(startNum, instructions,
|
||||
instruction -> {
|
||||
if (unreachableDueToVersionGuard(instruction)) {
|
||||
return ControlFlowUtil.Operation.CONTINUE;
|
||||
}
|
||||
if (acceptTypeAssertions && instruction instanceof CallInstruction callInstruction) {
|
||||
var typeGuardInstruction = pendingTypeGuard.get(instruction.getElement());
|
||||
if (typeGuardInstruction != null) {
|
||||
@@ -123,14 +120,18 @@ public final class PyDefUseUtil {
|
||||
if (access.isWriteAccess() || acceptTypeAssertions && access.isAssertTypeAccess()) {
|
||||
final String name = elementName(element);
|
||||
if (Comparing.strEqual(name, varName)) {
|
||||
result.add(rwInstruction);
|
||||
if (isReachableWithVersionChecks(rwInstruction)) {
|
||||
result.add(rwInstruction);
|
||||
}
|
||||
return ControlFlowUtil.Operation.CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (acceptImplicitImports && element instanceof PyImplicitImportNameDefiner implicit) {
|
||||
if (!implicit.multiResolveName(varName).isEmpty()) {
|
||||
result.add(instruction);
|
||||
if (isReachableWithVersionChecks(instruction)) {
|
||||
result.add(instruction);
|
||||
}
|
||||
return ControlFlowUtil.Operation.CONTINUE;
|
||||
}
|
||||
}
|
||||
@@ -139,12 +140,12 @@ public final class PyDefUseUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean unreachableDueToVersionGuard(@NotNull Instruction instruction) {
|
||||
private static boolean isReachableWithVersionChecks(@NotNull Instruction instruction) {
|
||||
PsiElement element = instruction.getElement();
|
||||
if (element == null) return false;
|
||||
if (element == null) return true;
|
||||
LanguageLevel languageLevel = PythonLanguageLevelPusher.getLanguageLevelForFile(element.getContainingFile());
|
||||
Version version = new Version(languageLevel.getMajorVersion(), languageLevel.getMinorVersion(), 0);
|
||||
return !evaluateVersionsForElement(element).contains(version);
|
||||
return evaluateVersionsForElement(element).contains(version);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user