From 13b6bac7afcaa3798f4fb672886d6ad844ee7ad4 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 22 Jul 2019 15:39:01 +0300 Subject: [PATCH] PY-7711 PY-36912 Don't spell check strings containing injections rather delegating to the spell checker of the injected language. Otherwise, we either just report typos twice (PY-36912) or, worse, report numerous false positives since we try to apply tokenization rules for Python to a different language as we notoriously have been doing all this time for injected regular expressions. Implementations of spell checkers for other languages such as Java or JavaScript have been using this policy for ages. GitOrigin-RevId: d1a2a3d48b7a5efff0dbb32ec2847fba1482f3a8 --- .../spellchecker/PythonSpellcheckerStrategy.java | 5 +++++ .../spelling/typosInDoctestsReportedOnce.py | 3 +++ .../typosInInjectedPythonStringsReportedOnce.py | 2 ++ .../inspections/spelling/typosInRegexIgnored.py | 2 ++ .../com/jetbrains/python/PySpellCheckerTest.java | 14 ++++++++++++++ 5 files changed, 26 insertions(+) create mode 100644 python/testData/inspections/spelling/typosInDoctestsReportedOnce.py create mode 100644 python/testData/inspections/spelling/typosInInjectedPythonStringsReportedOnce.py create mode 100644 python/testData/inspections/spelling/typosInRegexIgnored.py diff --git a/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java b/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java index e335bf20af0c..8162a81df75c 100644 --- a/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java +++ b/python/src/com/jetbrains/python/spellchecker/PythonSpellcheckerStrategy.java @@ -15,6 +15,7 @@ */ package com.jetbrains.python.spellchecker; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.spellchecker.inspections.PlainTextSplitter; @@ -94,6 +95,10 @@ public class PythonSpellcheckerStrategy extends SpellcheckingStrategy { @Override public Tokenizer getTokenizer(PsiElement element) { if (element instanceof PyStringLiteralExpression) { + final InjectedLanguageManager injectionManager = InjectedLanguageManager.getInstance(element.getProject()); + if (element.getTextLength() >= 2 && injectionManager.getInjectedPsiFiles(element) != null) { + return EMPTY_TOKENIZER; + } PsiElement parent = element.getParent(); if (parent instanceof PyBinaryExpression) { PyBinaryExpression binaryExpression = (PyBinaryExpression)parent; diff --git a/python/testData/inspections/spelling/typosInDoctestsReportedOnce.py b/python/testData/inspections/spelling/typosInDoctestsReportedOnce.py new file mode 100644 index 000000000000..9041a40a92df --- /dev/null +++ b/python/testData/inspections/spelling/typosInDoctestsReportedOnce.py @@ -0,0 +1,3 @@ +""" +>>> 'There are also always two inspection messags.' +""" \ No newline at end of file diff --git a/python/testData/inspections/spelling/typosInInjectedPythonStringsReportedOnce.py b/python/testData/inspections/spelling/typosInInjectedPythonStringsReportedOnce.py new file mode 100644 index 000000000000..99e9e217d6d9 --- /dev/null +++ b/python/testData/inspections/spelling/typosInInjectedPythonStringsReportedOnce.py @@ -0,0 +1,2 @@ +# language=Python +s = '"mstyped"' \ No newline at end of file diff --git a/python/testData/inspections/spelling/typosInRegexIgnored.py b/python/testData/inspections/spelling/typosInRegexIgnored.py new file mode 100644 index 000000000000..0053805b4686 --- /dev/null +++ b/python/testData/inspections/spelling/typosInRegexIgnored.py @@ -0,0 +1,2 @@ +import re +re_sth = re.compile(r'(\w+)\stells\syou') diff --git a/python/testSrc/com/jetbrains/python/PySpellCheckerTest.java b/python/testSrc/com/jetbrains/python/PySpellCheckerTest.java index 356aec5e156f..3f2a3927d7c3 100644 --- a/python/testSrc/com/jetbrains/python/PySpellCheckerTest.java +++ b/python/testSrc/com/jetbrains/python/PySpellCheckerTest.java @@ -66,6 +66,20 @@ public class PySpellCheckerTest extends PyTestCase { doTest(); } + public void testTyposInInjectedPythonStringsReportedOnce() { + doTest(); + } + + // PY-36912 + public void testTyposInDoctestsReportedOnce() { + doTest(); + } + + // PY-7711 + public void testTyposInRegexIgnored() { + doTest(); + } + private void doTest() { myFixture.enableInspections(SpellCheckingInspection.class); myFixture.configureByFile("inspections/spelling/" + getTestName(true) + ".py");