mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-16412 Don't suggest the intention for targets that doesn't allow annotations
This commit is contained in:
committed by
Andrey Vlasovskikh
parent
95227c365b
commit
fc3d1b7beb
+15
-3
@@ -63,10 +63,22 @@ public class PyAnnotateVariableTypeIntention extends PyBaseIntentionAction {
|
||||
return StreamEx.of(PyUtil.multiResolveTopPriority(elementAtCaret, resolveContext))
|
||||
.select(PyTargetExpression.class)
|
||||
.filter(target -> !index.isInLibraryClasses(target.getContainingFile().getVirtualFile()))
|
||||
.filter(target -> canBeAnnotated(target))
|
||||
.filter(target -> !isAnnotated(target, typeEvalContext))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private static boolean canBeAnnotated(@NotNull PyTargetExpression target) {
|
||||
final PsiElement directParent = target.getParent();
|
||||
if (directParent instanceof PyImportElement ||
|
||||
directParent instanceof PyComprehensionForComponent ||
|
||||
directParent instanceof PyGlobalStatement ||
|
||||
directParent instanceof PyNonlocalStatement) {
|
||||
return false;
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(target, PyWithItem.class, PyAssignmentStatement.class, PyForPart.class) != null;
|
||||
}
|
||||
|
||||
private static boolean isAnnotated(@NotNull PyTargetExpression target, @NotNull TypeEvalContext context) {
|
||||
// TODO filter out fields explicitly annotated as Any
|
||||
return new PyTypingTypeProvider().getReferenceType(target, context, null) != null;
|
||||
@@ -105,9 +117,9 @@ public class PyAnnotateVariableTypeIntention extends PyBaseIntentionAction {
|
||||
private static String generateNestedTypeHint(@NotNull PyTargetExpression target) {
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(target.getProject(), target.getContainingFile());
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
final PyElement validTargetContainer = PsiTreeUtil.getParentOfType(target, PyForPart.class, PyWithItem.class, PyAssignmentStatement.class);
|
||||
assert validTargetContainer != null;
|
||||
final PsiElement topmostTarget = PsiTreeUtil.findPrevParent(validTargetContainer, target);
|
||||
final PyElement validTargetParent = PsiTreeUtil.getParentOfType(target, PyForPart.class, PyWithItem.class, PyAssignmentStatement.class);
|
||||
assert validTargetParent != null;
|
||||
final PsiElement topmostTarget = PsiTreeUtil.findPrevParent(validTargetParent, target);
|
||||
generateNestedTypeHint(topmostTarget, context, builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
[v<caret>ar for var in range(10)]
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
def func():
|
||||
global var
|
||||
v<caret>ar
|
||||
+1
@@ -0,0 +1 @@
|
||||
from sys import path as v<caret>ar
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
def func(x):
|
||||
var: int
|
||||
var = x
|
||||
v<caret>ar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
def func(x):
|
||||
var: int = x
|
||||
v<caret>ar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
def func(x):
|
||||
var = x # type: int
|
||||
v<caret>ar
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
def func():
|
||||
nonlocal var
|
||||
v<caret>ar
|
||||
+33
@@ -9,6 +9,35 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author Mikhail Golubev
|
||||
*/
|
||||
public class PyAnnotateVariableTypeIntentionTest extends PyIntentionTestCase {
|
||||
|
||||
public void testNotSuggestedForLocalAssignmentTargetWithAnnotation() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForLocalAssignmentTargetWithAheadOfTimeAnnotation() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForLocalAssignmentTargetWithTypeComment() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForComprehensionTarget() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForImportTarget() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForGlobalTarget() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testNotSuggestedForNonlocalTarget() {
|
||||
doNegativeTest();
|
||||
}
|
||||
|
||||
public void testAnnotationLocalSimpleAssignmentTarget() {
|
||||
doTestAnnotation();
|
||||
}
|
||||
@@ -68,4 +97,8 @@ public class PyAnnotateVariableTypeIntentionTest extends PyIntentionTestCase {
|
||||
private void doTest(@NotNull LanguageLevel languageLevel) {
|
||||
doTest(PyBundle.message("INTN.annotate.types"), languageLevel);
|
||||
}
|
||||
|
||||
private void doNegativeTest() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON36, () -> doNegativeTest(PyBundle.message("INTN.annotate.types")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user