From 0d9bf8ebff6af83a8ac2611c2ead94b14782eb81 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Tue, 22 May 2018 15:33:39 +0300 Subject: [PATCH] Enable highlighting error elements in type hints (PY-20530) --- .../typing/PyTypingTypeProvider.java | 16 +++++++++++++++ .../doctest/PyDocstringErrorFilter.java | 6 ++++-- .../inspections/PyTypeHintsInspection.kt | 6 +----- .../highlighting/unparsedTypeHints.py | 20 +++++++++++++++++++ .../python/PythonHighlightingTest.java | 5 +++++ 5 files changed, 46 insertions(+), 7 deletions(-) create mode 100644 python/testData/highlighting/unparsedTypeHints.py diff --git a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java index c9b2ce8107b6..fe8f8b5d4446 100644 --- a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingTypeProvider.java @@ -9,6 +9,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.ResolveResult; @@ -1407,6 +1408,21 @@ public class PyTypingTypeProvider extends PyTypeProviderBase { return "r"; } + public static boolean isInAnnotationOrTypeComment(@NotNull PsiElement element) { + final PsiElement realContext = PyPsiUtils.getRealContext(element); + + if (PsiTreeUtil.getParentOfType(realContext, PyAnnotation.class, false, ScopeOwner.class) != null) { + return true; + } + + final PsiComment comment = PsiTreeUtil.getParentOfType(realContext, PsiComment.class, false, ScopeOwner.class); + if (comment != null && getTypeCommentValue(comment.getText()) != null) { + return true; + } + + return false; + } + static class Context { @NotNull private final TypeEvalContext myContext; @NotNull private final Set myCache = new HashSet<>(); diff --git a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringErrorFilter.java b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringErrorFilter.java index 82a4d5aff8be..bb0723dbdbe6 100644 --- a/python/src/com/jetbrains/python/documentation/doctest/PyDocstringErrorFilter.java +++ b/python/src/com/jetbrains/python/documentation/doctest/PyDocstringErrorFilter.java @@ -18,6 +18,7 @@ package com.jetbrains.python.documentation.doctest; import com.intellij.codeInsight.highlighting.HighlightErrorFilter; import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiFile; +import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider; import org.jetbrains.annotations.NotNull; /** @@ -27,8 +28,9 @@ import org.jetbrains.annotations.NotNull; */ public class PyDocstringErrorFilter extends HighlightErrorFilter { - public boolean shouldHighlightErrorElement(@NotNull final PsiErrorElement element) { + @Override + public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { final PsiFile file = element.getContainingFile(); - return !(file instanceof PyDocstringFile); + return !(file instanceof PyDocstringFile) || PyTypingTypeProvider.isInAnnotationOrTypeComment(element); } } diff --git a/python/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt b/python/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt index a9b9a418f8d7..513faba92009 100644 --- a/python/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt +++ b/python/src/com/jetbrains/python/inspections/PyTypeHintsInspection.kt @@ -3,17 +3,14 @@ package com.jetbrains.python.inspections import com.intellij.codeInsight.controlflow.ControlFlowUtil import com.intellij.codeInspection.* -import com.intellij.lang.injection.InjectedLanguageManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiFileFactory -import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.QualifiedName import com.jetbrains.python.PyNames import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache import com.jetbrains.python.codeInsight.controlflow.ReadWriteInstruction -import com.jetbrains.python.codeInsight.controlflow.ScopeOwner import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil import com.jetbrains.python.codeInsight.functionTypeComments.PyFunctionTypeAnnotationDialect import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider @@ -283,8 +280,7 @@ class PyTypeHintsInspection : PyInspection() { null, ReplaceWithSubscriptionQuickFix()) } - else if (InjectedLanguageManager.getInstance(call.project).isInjectedFragment(call.containingFile) || - PsiTreeUtil.getParentOfType(call, PyAnnotation::class.java, true, ScopeOwner::class.java) != null) { + else if (PyTypingTypeProvider.isInAnnotationOrTypeComment(call)) { multiFollowAssignmentsChain(callee) .asSequence() .map { if (it is PyFunction) it.containingClass else it } diff --git a/python/testData/highlighting/unparsedTypeHints.py b/python/testData/highlighting/unparsedTypeHints.py new file mode 100644 index 000000000000..c7ff73689943 --- /dev/null +++ b/python/testData/highlighting/unparsedTypeHints.py @@ -0,0 +1,20 @@ +from typing import Union + + +def a(b: 'Union[int') -> 'Union[str': + pass + + +def c(d): + # type: (Union[int) -> Union[str + pass + + +e = None # type: Union[str + + +def f(g: Union[int) -> Union[str: + pass + + +h: Union[str \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java index 45cec15ab57b..26f01065f8d1 100644 --- a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java @@ -406,6 +406,11 @@ public class PythonHighlightingTest extends PyTestCase { doTest(); } + // PY-20530 + public void testUnparsedTypeHints() { + doTest(LanguageLevel.PYTHON36, false, false); + } + @NotNull private static EditorColorsScheme createTemporaryColorScheme() { EditorColorsManager manager = EditorColorsManager.getInstance();