From f88eeb51015b08cb17339e0d36a61bbf71604434 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 29 Apr 2020 14:32:12 +0300 Subject: [PATCH] Look for string literals with mixed languages and repair some found violations to fix IDEA-239390 Inspection to detect mixed characters in strings (strings containing both ASCII and non-ASCII) GitOrigin-RevId: 312b7bcfd4e9c8ae438ae3d08aa0a60188fa226a --- .../nonAsciiCharacters/Groovy.groovy | 2 +- .../nonAsciiCharacters/Simple.java | 5 ++- .../daemon/NonAsciiCharactersTest.java | 1 + .../messages/CodeInsightBundle.properties | 2 + .../resources/messages/LangBundle.properties | 2 +- .../NonAsciiCharactersInspection.form | 24 +++++++++-- .../NonAsciiCharactersInspection.java | 40 ++++++++++--------- .../NonAsciiCharactersInspectionForm.java | 9 +++-- .../ui/EditorColorSchemesUsagesCollector.java | 2 +- .../src/themes/highContrastScheme.xml | 4 +- .../IntentionPowerPackBundle.properties | 2 +- .../ipp/types/MakeMethodDefaultIntention.java | 2 +- 12 files changed, 62 insertions(+), 33 deletions(-) diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Groovy.groovy b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Groovy.groovy index 42c434cce987..6b81f6869e01 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Groovy.groovy +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Groovy.groovy @@ -1,6 +1,6 @@ class X { int Ж = 0; - class InnerП {} + class InnerП {} // commentжп 234 String s = "12л3орыва0"; void жжж() { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Simple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Simple.java index 42c434cce987..816a2eb2c236 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Simple.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/nonAsciiCharacters/Simple.java @@ -1,9 +1,12 @@ class X { int Ж = 0; - class InnerП {} + class InnerП {} // commentжп 234 String s = "12л3орыва0"; void жжж() { жжж(); + String s = "Сore"; + System.out.println("Сore"); + String u = "\5\0\51\2\3\0\136\2\21\0\33\2\65\0\20\2\u0200\0\u19b6\2"; // ignore slash u } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/NonAsciiCharactersTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/NonAsciiCharactersTest.java index beb811beeee1..0aed65e10aff 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/NonAsciiCharactersTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/NonAsciiCharactersTest.java @@ -30,6 +30,7 @@ public class NonAsciiCharactersTest extends DaemonAnalyzerTestCase { protected LocalInspectionTool @NotNull [] configureLocalInspectionTools() { NonAsciiCharactersInspection inspection = new NonAsciiCharactersInspection(); inspection.CHECK_FOR_DIFFERENT_LANGUAGES_IN_IDENTIFIER_NAME = true; + inspection.CHECK_FOR_DIFFERENT_LANGUAGES_IN_STRING = true; inspection.CHECK_FOR_NOT_ASCII_IDENTIFIER_NAME = true; inspection.CHECK_FOR_NOT_ASCII_COMMENT = true; inspection.CHECK_FOR_NOT_ASCII_STRING_LITERAL = true; diff --git a/platform/lang-api/resources/messages/CodeInsightBundle.properties b/platform/lang-api/resources/messages/CodeInsightBundle.properties index ef38c55985b1..9929f8878c9f 100644 --- a/platform/lang-api/resources/messages/CodeInsightBundle.properties +++ b/platform/lang-api/resources/messages/CodeInsightBundle.properties @@ -578,7 +578,9 @@ label.non.ascii.chars.example.characters.in.comments=E.g.: // hello label.non.ascii.chars.example.characters.in.identifiers=E.g.: int \u041F\u043E\u043B\u0435 = 0; label.non.ascii.chars.example.characters.in.strings=E.g.: println("\u0E29 \u0E24\u0E45\u0E29\u0E35") label.non.ascii.chars.example.different.languages.in.identifiers=E.g.: void print\u0415\u0440\u0443\u043D\u0434\u0430() +label.non.ascii.chars.example.different.languages.in.string=E.g.: foo("\u0421ore"); //cyrillic \u0421 checkbox.non.ascii.option.different.languages.in.identifiers=Different languages in identifiers +checkbox.non.ascii.option.different.languages.in.string=Different languages in strings checkbox.non.ascii.option.files.containing.bom=Files containing BOM checkbox.non.ascii.option.characters.in.identifiers=Non-ASCII characters in Identifiers checkbox.non.ascii.option.characters.in.comments=Non-ASCII characters in comments diff --git a/platform/lang-api/resources/messages/LangBundle.properties b/platform/lang-api/resources/messages/LangBundle.properties index cc0a911396c9..b560cc35d4b6 100644 --- a/platform/lang-api/resources/messages/LangBundle.properties +++ b/platform/lang-api/resources/messages/LangBundle.properties @@ -129,7 +129,7 @@ popup.advertisement.press.or.to.replace=Press {0} or {1} to replace inspection.message.file.contains.bom=File contains BOM: ''{0}''{1} inspection.message.charset.signature=\ (charset ''{0}'' signature) inspection.message.non.ascii.characters.in=Non-ASCII characters in {0} -inspection.message.identifier.contains.symbols.from.different.languages=Identifier contains symbols from different languages: {0} +inspection.message.symbols.from.different.languages.found=Symbols from different languages found: {0} hint.text.unfortunately.currently.available.for.batch.mode=Unfortunately ''{0}'' is currently not available for batch mode\n User interaction is required for each problem found progress.title.inspect.code=Inspect Code... hint.text.can.t.modify.decompiled.code=Can't modify decompiled code diff --git a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.form b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.form index f808520208b4..2cc4808a2aaf 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.form +++ b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.form @@ -1,6 +1,6 @@
- + @@ -23,7 +23,7 @@ - + @@ -58,10 +58,18 @@ - + + + + + + + + + @@ -98,10 +106,18 @@ - + + + + + + + + + diff --git a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.java b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.java index 06fdf27e821c..a08601ce15c5 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspection.java @@ -29,7 +29,6 @@ import com.intellij.util.io.IOUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.nio.charset.Charset; @@ -46,6 +45,7 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { public boolean CHECK_FOR_NOT_ASCII_COMMENT; public boolean CHECK_FOR_DIFFERENT_LANGUAGES_IN_IDENTIFIER_NAME = true; + public boolean CHECK_FOR_DIFFERENT_LANGUAGES_IN_STRING; public boolean CHECK_FOR_FILES_CONTAINING_BOM; @Override @@ -94,9 +94,13 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { checkAsciiRange(element, element.getText(), holder, "a comment"); } } - if (CHECK_FOR_NOT_ASCII_STRING_LITERAL) { - if (element instanceof PsiLiteralValue) { - checkAsciiRange(element, element.getText(), holder, "a string literal"); + if (element instanceof PsiLiteralValue) { + String text = element.getText(); + if (CHECK_FOR_NOT_ASCII_STRING_LITERAL) { + checkAsciiRange(element, text, holder, "a string literal"); + } + if (CHECK_FOR_DIFFERENT_LANGUAGES_IN_STRING) { + checkSameLanguage(element, text, holder); } } } @@ -126,7 +130,7 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { }; } - private static boolean isFileWorthIt(PsiFile file) { + private static boolean isFileWorthIt(@NotNull PsiFile file) { if (InjectedLanguageManager.getInstance(file.getProject()).isInjectedFragment(file)) return false; VirtualFile virtualFile = file.getVirtualFile(); if (virtualFile == null) return false; @@ -139,9 +143,9 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { } - private static void checkSameLanguage(PsiElement element, - String text, - ProblemsHolder holder) { + private static void checkSameLanguage(@NotNull PsiElement element, + @NotNull String text, + @NotNull ProblemsHolder holder) { Set scripts = text.codePoints() .mapToObj(Character.UnicodeScript::of) .filter(script -> !script.equals(Character.UnicodeScript.COMMON)) @@ -149,23 +153,23 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { if (scripts.size() > 1) { List list = new ArrayList<>(scripts); Collections.sort(list); // a little bit of stability - holder.registerProblem(element, LangBundle.message("inspection.message.identifier.contains.symbols.from.different.languages", list), + holder.registerProblem(element, LangBundle.message("inspection.message.symbols.from.different.languages.found", list), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } - private static void checkAscii(PsiElement element, - String text, - ProblemsHolder holder, - String where) { + private static void checkAscii(@NotNull PsiElement element, + @NotNull String text, + @NotNull ProblemsHolder holder, + @NotNull String where) { if (!IOUtil.isAscii(text)) { holder.registerProblem(element, LangBundle.message("inspection.message.non.ascii.characters.in", where), ProblemHighlightType.GENERIC_ERROR_OR_WARNING); } } - private static void checkAsciiRange(PsiElement element, - String text, - ProblemsHolder holder, - String where) { + private static void checkAsciiRange(@NotNull PsiElement element, + @NotNull String text, + @NotNull ProblemsHolder holder, + @NotNull String where) { int errorCount = 0; int start = -1; for (int i = 0; i <= text.length(); i++) { @@ -186,7 +190,7 @@ public class NonAsciiCharactersInspection extends LocalInspectionTool { } } - @Nullable + @NotNull @Override public JComponent createOptionsPanel() { return new NonAsciiCharactersInspectionForm(this).myPanel; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspectionForm.java b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspectionForm.java index b374c9727512..4ccda87cd3ed 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspectionForm.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/NonAsciiCharactersInspectionForm.java @@ -18,6 +18,7 @@ package com.intellij.codeInspection; import com.intellij.ui.components.JBCheckBox; import com.intellij.util.ReflectionUtil; import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.util.Map; @@ -30,20 +31,22 @@ class NonAsciiCharactersInspectionForm { private JBCheckBox myAlienIdentifiers; JPanel myPanel; private JBCheckBox myFilesContainingBOM; + private JBCheckBox myDifferentLanguagesInStrings; private final Map myBindings = new THashMap<>(); - NonAsciiCharactersInspectionForm(NonAsciiCharactersInspection inspection) { + NonAsciiCharactersInspectionForm(@NotNull NonAsciiCharactersInspection inspection) { myInspection = inspection; bind(myASCIIIdentifiers, "CHECK_FOR_NOT_ASCII_IDENTIFIER_NAME"); bind(myASCIIStringLiterals, "CHECK_FOR_NOT_ASCII_STRING_LITERAL"); bind(myASCIIComments, "CHECK_FOR_NOT_ASCII_COMMENT"); bind(myAlienIdentifiers, "CHECK_FOR_DIFFERENT_LANGUAGES_IN_IDENTIFIER_NAME"); + bind(myDifferentLanguagesInStrings, "CHECK_FOR_DIFFERENT_LANGUAGES_IN_STRING"); bind(myFilesContainingBOM, "CHECK_FOR_FILES_CONTAINING_BOM"); reset(); } - private void bind(JCheckBox checkBox, String property) { + private void bind(@NotNull JCheckBox checkBox, @NotNull String property) { myBindings.put(checkBox, property); reset(checkBox, property); checkBox.addChangeListener(__ -> { @@ -52,7 +55,7 @@ class NonAsciiCharactersInspectionForm { }); } - private void reset(JCheckBox checkBox, String property) { + private void reset(@NotNull JCheckBox checkBox, @NotNull String property) { checkBox.setSelected(ReflectionUtil.getField(myInspection.getClass(), myInspection, boolean.class, property)); } diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java index 56b0589029da..864a233a08c5 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/collectors/fus/ui/EditorColorSchemesUsagesCollector.java @@ -40,7 +40,7 @@ public class EditorColorSchemesUsagesCollector extends ApplicationUsagesCollecto "Aptana", "Flash Builder", "IdeaLight", - "High сontrast", + "High contrast", "ReSharper", "Rider" }; diff --git a/platform/platform-resources/src/themes/highContrastScheme.xml b/platform/platform-resources/src/themes/highContrastScheme.xml index db83737053ac..4ed00404f4ee 100644 --- a/platform/platform-resources/src/themes/highContrastScheme.xml +++ b/platform/platform-resources/src/themes/highContrastScheme.xml @@ -1,10 +1,10 @@ - + 2018-11-06T13:11:44 idea 2019.1.0.0 2018-11-06T13:11:49 - _@user_High сontrast + _@user_High contrast