mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22087 Don't mark comprehension variables used in f-strings as unused
I needed to tweak anchor element (that has the corresponding instruction in CFG) to flow-sensitively resolve names used in f-strings inside comprehensions.
This commit is contained in:
@@ -99,15 +99,20 @@ public class PyDocReference extends PyReferenceImpl {
|
||||
@Nullable
|
||||
private PsiElement getScopeControlFlowAnchor(@NotNull PsiLanguageInjectionHost host) {
|
||||
if (isInsideFormattedStringNode(host)) {
|
||||
final PsiElement comprehensionPart = PsiTreeUtil.findFirstParent(host, PyDocReference::isComprehensionResultOrComponent);
|
||||
if (comprehensionPart != null) {
|
||||
return comprehensionPart;
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(host, PyStatement.class);
|
||||
return getControlFlowAnchorForFString((PyStringLiteralExpression)host);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getControlFlowAnchorForFString(@NotNull PyStringLiteralExpression host) {
|
||||
final PsiElement comprehensionPart = PsiTreeUtil.findFirstParent(host, PyDocReference::isComprehensionResultOrComponent);
|
||||
if (comprehensionPart != null) {
|
||||
return comprehensionPart;
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(host, PyStatement.class);
|
||||
}
|
||||
|
||||
private static boolean isComprehensionResultOrComponent(@NotNull PsiElement element) {
|
||||
// Any comprehension component and its result are represented as children expressions of the comprehension element.
|
||||
// Only they have respective nodes in CFG and thus can be used as anchors for getResultsFromProcessor().
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.Scope;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.documentation.doctest.PyDocReference;
|
||||
import com.jetbrains.python.inspections.quickfix.AddFieldQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.PyRemoveParameterQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.PyRemoveStatementQuickFix;
|
||||
@@ -104,7 +105,7 @@ public class PyUnusedLocalInspectionVisitor extends PyInspectionVisitor {
|
||||
public void visitPyStringLiteralExpression(PyStringLiteralExpression pyString) {
|
||||
final ScopeOwner owner = ScopeUtil.getScopeOwner(pyString);
|
||||
if (owner != null && !(owner instanceof PsiFile)) {
|
||||
final PyStatement instrAnchor = PsiTreeUtil.getParentOfType(pyString, PyStatement.class);
|
||||
final PsiElement instrAnchor = PyDocReference.getControlFlowAnchorForFString(pyString);
|
||||
if (instrAnchor == null) return;
|
||||
final Instruction[] instructions = ControlFlowCache.getControlFlow(owner).getInstructions();
|
||||
final int startInstruction = ControlFlowUtil.findInstructionNumberByElement(instructions, instrAnchor);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
def f():
|
||||
[f'{x1}' for x1 in range(10)]
|
||||
[[f'{x2}' for _ in range(10)] for x2 in range(10)]
|
||||
[[42 for _ in range(10) if f'{x3}'] for x3 in range(10)]
|
||||
|
||||
[42 for x4 in range(10) if f'{x4}']
|
||||
[42 for x5 in range(10) if [f'{x5}' for _ in range(10)]]
|
||||
[42 for x6 in range(10) if [42 for _ in range(10) if f'{x6}']]
|
||||
|
||||
[f'{x7}' for _ in range(10) for x7 in range(10)]
|
||||
@@ -123,6 +123,11 @@ public class PythonInspectionsTest extends PyTestCase {
|
||||
doHighlightingTest(PyUnusedLocalInspection.class, LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
// PY-22087
|
||||
public void testUnusedLocalFStringReferencesInComprehensions() {
|
||||
doHighlightingTest(PyUnusedLocalInspection.class, LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
// PY-8219
|
||||
public void testUnusedLocalDoctestReference() {
|
||||
doHighlightingTest(PyUnusedLocalInspection.class);
|
||||
|
||||
Reference in New Issue
Block a user