mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-22971 Fixed: Support @typing.overload in regular Python files, not only in Python stubs
Update PyRedeclarationInspection to not consider preceding overloads as write elements for the following implementation.
This commit is contained in:
committed by
Semyon Proshev
parent
f0ab4154ef
commit
c13fbf623a
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,7 +26,6 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
@@ -35,6 +34,7 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.inspections.quickfix.PyRenameElementQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.pyi.PyiTypeProvider;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -49,6 +49,7 @@ import java.util.List;
|
||||
* @author vlan
|
||||
*/
|
||||
public class PyRedeclarationInspection extends PyInspection {
|
||||
@Override
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
@@ -136,8 +137,11 @@ public class PyRedeclarationInspection extends PyInspection {
|
||||
if (rwInstruction.getAccess().isReadAccess()) {
|
||||
readElementRef.set(originalElement);
|
||||
}
|
||||
if (rwInstruction.getAccess().isWriteAccess()) {
|
||||
if (originalElement != element) {
|
||||
if (rwInstruction.getAccess().isWriteAccess() && originalElement != element) {
|
||||
if (element instanceof PyCallable && isOverload(originalElement)) {
|
||||
return ControlFlowUtil.Operation.NEXT;
|
||||
}
|
||||
else {
|
||||
writeElementRef.set(originalElement);
|
||||
}
|
||||
}
|
||||
@@ -163,6 +167,10 @@ public class PyRedeclarationInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOverload(@NotNull PsiElement element) {
|
||||
return element instanceof PyCallable && PyiTypeProvider.isOverload((PyCallable)element, myTypeEvalContext);
|
||||
}
|
||||
|
||||
private static boolean suggestRename(@NotNull PsiNameIdentifierOwner element, @NotNull PsiElement originalElement) {
|
||||
// Target expressions in the same scope are treated as the same variable
|
||||
if ((element instanceof PyTargetExpression) && originalElement instanceof PyTargetExpression) {
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
class A:
|
||||
@overload
|
||||
def foo(self, value: int) -> str:
|
||||
pass
|
||||
|
||||
def foo(self, value):
|
||||
return None
|
||||
|
||||
@overload
|
||||
def foo(self, value: str) -> str:
|
||||
pass
|
||||
|
||||
def <warning descr="Redeclared 'foo' defined above without usage">foo</warning>(self, value):
|
||||
return None
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
class A:
|
||||
@overload
|
||||
def utf8(self, value: None) -> None:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def utf8(self, value: bytes) -> bytes:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def utf8(self, value: str) -> bytes:
|
||||
pass
|
||||
|
||||
def utf8(self, value):
|
||||
return None
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
class A:
|
||||
@overload
|
||||
def utf8(self, value: None) -> None:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def utf8(self, value: bytes) -> bytes:
|
||||
pass
|
||||
|
||||
@overload
|
||||
def utf8(self, value: str) -> bytes:
|
||||
pass
|
||||
|
||||
def utf8(self, value):
|
||||
return None
|
||||
|
||||
def <warning descr="Redeclared 'utf8' defined above without usage">utf8</warning>(self, value):
|
||||
return None
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
@overload
|
||||
def foo(value: int) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def foo(value):
|
||||
return None
|
||||
|
||||
|
||||
@overload
|
||||
def foo(value: str) -> str:
|
||||
pass
|
||||
|
||||
|
||||
def <warning descr="Redeclared 'foo' defined above without usage">foo</warning>(value):
|
||||
return None
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: None) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: bytes) -> bytes:
|
||||
pass
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: str) -> bytes:
|
||||
pass
|
||||
|
||||
|
||||
def utf8(value):
|
||||
return None
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
from typing import overload
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: None) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: bytes) -> bytes:
|
||||
pass
|
||||
|
||||
|
||||
@overload
|
||||
def utf8(value: str) -> bytes:
|
||||
pass
|
||||
|
||||
|
||||
def utf8(value):
|
||||
return None
|
||||
|
||||
|
||||
def <warning descr="Redeclared 'utf8' defined above without usage">utf8</warning>(value):
|
||||
return None
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
|
||||
public class PyRedeclarationInspectionTest extends PyTestCase {
|
||||
|
||||
@@ -63,6 +64,36 @@ public class PyRedeclarationInspectionTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testTopLevelOverloadsAndImplementation() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testOverloadsAndImplementationInClass() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testTopLevelOverloadsAndImplementations() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testOverloadsAndImplementationsInClass() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testTopLevelOverloadImplementationOverloadImplementation() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
// PY-22971
|
||||
public void testOverloadImplementationOverloadImplementationInClass() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, this::doTest);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
final String path = "inspections/PyRedeclarationInspection/" + getTestName(true) + ".py";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user