PY-24969 Don't keep PyAnnotationStubs for assignments and type declarations

Namely, retain them only for function return type annotations and
named parameters, since for these two PSI nodes we use
getStubOrPsiChild() in getAnnotation() as a way to quickly check
whether there is annotation at all. Otherwise, stubs for annotations
of local variables might be stored directly in a function stub and
thus falsely recognized as a type hint for its return value.
This commit is contained in:
Mikhail Golubev
2017-08-30 18:50:19 +03:00
parent 9b92a5cabe
commit ef615cb4a4
4 changed files with 22 additions and 1 deletions

View File

@@ -62,7 +62,7 @@ public class PyFileElementType extends IStubFileElementType<PyFileStub> {
@Override
public int getStubVersion() {
// Don't forget to update versions of indexes that use the updated stub-based elements
return 64;
return 65;
}
@Nullable

View File

@@ -24,7 +24,9 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.stubs.StubInputStream;
import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.python.PyElementTypes;
import com.jetbrains.python.PythonDialectsTokenSetProvider;
import com.jetbrains.python.psi.PyAnnotation;
import com.jetbrains.python.psi.PyStubElementType;
import com.jetbrains.python.psi.impl.PyAnnotationImpl;
@@ -66,4 +68,11 @@ public class PyAnnotationElementType extends PyStubElementType<PyAnnotationStub,
throws IOException {
return new PyAnnotationStubImpl(parentStub, PyElementTypes.ANNOTATION);
}
@Override
public boolean shouldCreateStub(ASTNode node) {
final IElementType parentType = node.getTreeParent().getElementType();
return PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens().contains(parentType)
|| PythonDialectsTokenSetProvider.INSTANCE.getParameterTokens().contains(parentType);
}
}

View File

@@ -0,0 +1,2 @@
def func():
x: int = 42

View File

@@ -871,4 +871,14 @@ public class PyStubsTest extends PyTestCase {
assertNotParsed(libFile);
});
}
// PY-24969
public void testFunctionStubDoesNotContainLocalVariableAnnotation() {
runWithLanguageLevel(LanguageLevel.PYTHON36, () -> {
final PyFile file = getTestFile();
final PyFunction func = file.findTopLevelFunction("func");
final PyFunctionStub funcStub = func.getStub();
assertNull(funcStub.findChildStubByType(PyElementTypes.ANNOTATION));
});
}
}