[grazie] Highlight style and grammar warnings in one pass

Merge-request: IJ-MR-176614
Merged-by: Ilia Permiashkin <ilia.permiashkin@jetbrains.com>

GitOrigin-RevId: cf68888cb903b396ff59feee6d00dff720b19534
This commit is contained in:
Ilia Permiashkin
2025-09-26 00:30:23 +00:00
committed by intellij-monorepo-bot
parent dc35cf8dec
commit c2e3cb4b9c
14 changed files with 251 additions and 132 deletions
+3
View File
@@ -204,6 +204,9 @@ com.intellij.codeInspection.InspectionToolResultExporter
- a:suppressProblem(com.intellij.codeInspection.CommonProblemDescriptor):V
- a:suppressProblem(com.intellij.codeInspection.reference.RefEntity):V
- a:updateContent():V
c:com.intellij.codeInspection.ProblemDescriptorBase
- <init>(com.intellij.psi.PsiElement,com.intellij.psi.PsiElement,java.lang.String,com.intellij.codeInspection.LocalQuickFix[],com.intellij.codeInspection.ProblemHighlightType,Z,com.intellij.openapi.util.TextRange,Z,Z,java.lang.String):V
- getTooltipTemplate():java.lang.String
com.intellij.codeInspection.dataFlow.interpreter.DataFlowInterpreter
- a:cancel():V
- a:createClosureState(com.intellij.psi.PsiElement,com.intellij.codeInspection.dataFlow.memory.DfaMemoryState):V
@@ -8,6 +8,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
@@ -35,6 +36,7 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement
private TextAttributesKey myEnforcedTextAttributes;
private int myLineNumber = -1;
private ProblemGroup myProblemGroup;
private @NlsSafe @Nullable String tooltip;
public ProblemDescriptorBase(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@@ -95,6 +97,20 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement
myOnTheFly = onTheFly;
}
public ProblemDescriptorBase(@NotNull PsiElement startElement,
@NotNull PsiElement endElement,
@NotNull @InspectionMessage String descriptionTemplate,
@NotNull LocalQuickFix @Nullable [] fixes,
@NotNull ProblemHighlightType highlightType,
boolean isAfterEndOfLine,
@Nullable TextRange rangeInElement,
boolean showTooltip,
boolean onTheFly,
@Nullable String tooltip) {
this(startElement, endElement, descriptionTemplate, fixes, highlightType, isAfterEndOfLine, rangeInElement, showTooltip, onTheFly);
this.tooltip = tooltip;
}
private static @NotNull LocalQuickFix @Nullable [] filterFixes(LocalQuickFix @Nullable [] fixes, boolean onTheFly) {
if (onTheFly || fixes == null) return fixes;
List<LocalQuickFix> filtered = ContainerUtil.filter(fixes, fix -> fix != null && fix.availableInBatchMode());
@@ -267,6 +283,11 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement
return myShowTooltip;
}
@Override
public @NotNull String getTooltipTemplate() {
return tooltip == null ? getDescriptionTemplate() : tooltip;
}
@Override
public String toString() {
PsiElement element = getPsiElement();
@@ -16,8 +16,11 @@ public final class ProblemDescriptorWithReporterName extends ProblemDescriptorBa
private final String myReportingToolShortName;
public ProblemDescriptorWithReporterName(@NotNull ProblemDescriptorBase pd, @NotNull String reportingToolShortName) {
super(pd.getStartElement(), pd.getEndElement(), pd.getDescriptionTemplate(), pd.getFixes(),
pd.getHighlightType(), pd.isAfterEndOfLine(), pd.getTextRangeInElement(), pd.showTooltip(), pd.isOnTheFly());
super(
pd.getStartElement(), pd.getEndElement(), pd.getDescriptionTemplate(), pd.getFixes(),
pd.getHighlightType(), pd.isAfterEndOfLine(), pd.getTextRangeInElement(), pd.showTooltip(),
pd.isOnTheFly(), pd.getTooltipTemplate()
);
myReportingToolShortName = reportingToolShortName;
}
+10 -5
View File
@@ -51,10 +51,19 @@
<backgroundPostStartupActivity implementation="com.intellij.grazie.ide.notification.GrazieNotificationComponent"/>
<!-- getDisplayName is overridden in GrazieInspection itself! Placeholder is required to suppress validation. -->
<localInspection bundle="messages.GrazieBundle" groupKey="grazie.group.name" enabledByDefault="true" shortName="GrazieInspection"
<localInspection bundle="messages.GrazieBundle" groupKey="grazie.group.name" enabledByDefault="true" shortName="GrazieInspectionRunner"
implementationClass="com.intellij.grazie.ide.inspection.grammar.GrazieInspection"
level="NON_SWITCHABLE_WARNING" key="grazie.grammar.inspection.grammar.text" language=""/>
<localInspection bundle="messages.GrazieBundle" groupKey="grazie.group.name" enabledByDefault="true" shortName="GrazieInspection"
implementationClass="com.intellij.grazie.ide.inspection.grammar.GrazieInspection$Grammar"
level="GRAMMAR_ERROR" key="grazie.grammar.inspection.grammar.text" language=""/>
<localInspection groupKey="grazie.group.name" enabledByDefault="true" shortName="GrazieStyle"
implementationClass="com.intellij.grazie.ide.inspection.grammar.GrazieInspection$Style"
level="STYLE_SUGGESTION" key="grazie.style.inspection.display.name" language=""
bundle="messages.GrazieBundle"/>
<localInspection bundle="messages.GrazieBundle" groupKey="grazie.group.name" enabledByDefault="true"
shortName="LanguageDetectionInspection"
implementationClass="com.intellij.grazie.ide.inspection.detection.LanguageDetectionInspection"
@@ -99,10 +108,6 @@
<registryKey key="grazie.skip.precommit.checks"
defaultValue="true"
description="Controls whether expensive linguistic checks should be performed during pre-commit code analysis"/>
<localInspection groupKey="grazie.group.name" enabledByDefault="true" shortName="GrazieStyle"
implementationClass="com.intellij.grazie.style.StyleInspection"
level="STYLE_SUGGESTION" key="grazie.style.inspection.display.name" language=""
bundle="messages.GrazieBundle"/>
<grazie.textChecker implementation="com.intellij.grazie.text.AsyncTreeRuleChecker$Grammar" id="treeRules"
order="before languageTool"/>
@@ -1,18 +0,0 @@
<html>
<body>
Check the writing style defined in:
<ul>
<li>
Grazie rule files (e.g. <code>.grazie.en.yaml</code> for English)
for this project or its specific subdirectories.
To create such a file, invoke <b>New</b> menu on any (e.g. root) directory of the project.
</li>
<li>
<i>Style</i> rules in <i>Editor | Natural languages | Rules</i> settings
</li>
</ul>
This inspection only returns results via <b>Code | Analyze Code | Run Inspection By Name...</b> or in offline analysis.
Editor highlighting of style issues is performed independently of this inspection's settings.
</body>
</html>
@@ -16,7 +16,7 @@ class TextProblemSeverities : SeveritiesProvider() {
override fun getSeveritiesHighlightInfoTypes(): List<HighlightInfoType> {
return listOf(
TextHighlightInfoType(STYLE_SUGGESTION, STYLE_SUGGESTION_ATTRIBUTES, GrazieIcons.StyleSuggestion),
TextHighlightInfoType(GRAMMAR_ERROR, GRAMMAR_ERROR_ATTRIBUTES, AllIcons.General.InspectionsGrammar, applicableToInspections = true)
TextHighlightInfoType(GRAMMAR_ERROR, GRAMMAR_ERROR_ATTRIBUTES, AllIcons.General.InspectionsGrammar)
)
}
@@ -24,10 +24,8 @@ class TextProblemSeverities : SeveritiesProvider() {
severity: HighlightSeverity,
attributesKey: TextAttributesKey,
private val icon: Icon,
private val applicableToInspections: Boolean = false,
) : HighlightInfoTypeImpl(severity, attributesKey), HighlightInfoType.Iconable {
override fun getIcon(): Icon = icon
override fun isApplicableToInspections() = applicableToInspections
}
@Suppress("CompanionObjectInExtension")
@@ -7,11 +7,8 @@ import com.intellij.codeInspection.LocalInspectionToolSession
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.grazie.GrazieBundle
import com.intellij.grazie.GrazieConfig
import com.intellij.grazie.text.CheckerRunner
import com.intellij.grazie.text.TextContent
import com.intellij.grazie.text.TextExtractor
import com.intellij.grazie.text.*
import com.intellij.grazie.text.TextExtractor.findAllTextContents
import com.intellij.grazie.text.TextProblem
import com.intellij.lang.Language
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.util.TextRange
@@ -22,36 +19,85 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.CachedValuesManager
import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization
import org.jetbrains.annotations.NonNls
import java.util.*
class GrazieInspection : LocalInspectionTool(), DumbAware {
override fun getDisplayName() = GrazieBundle.message("grazie.grammar.inspection.grammar.text")
class Grammar: LocalInspectionTool(), DumbAware {
override fun getShortName(): @NonNls String = GRAMMAR_INSPECTION
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return PsiElementVisitor.EMPTY_VISITOR
}
}
class Style: LocalInspectionTool(), DumbAware {
override fun getShortName(): @NonNls String = STYLE_INSPECTION
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
return PsiElementVisitor.EMPTY_VISITOR
}
}
override fun getDisplayName(): String = GrazieBundle.message("grazie.grammar.inspection.grammar.text")
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
val file = holder.file
if (ignoreGrammarChecking(file) || InspectionProfileManager.hasTooLowSeverity(session, this)) {
return PsiElementVisitor.EMPTY_VISITOR
}
if (ignoreGrammarChecking(file) || hasTooLowSeverity(session)) return PsiElementVisitor.EMPTY_VISITOR
val checkedDomains = checkedDomains()
val areChecksDisabled = getDisabledChecker(file)
return object : PsiElementVisitor() {
override fun visitWhiteSpace(space: PsiWhiteSpace) {}
override fun visitElement(element: PsiElement) {
if (element is PsiWhiteSpace || areChecksDisabled(element)) return
inspectElement(element, { !it.isStyleLike }, session, holder, checkedDomains)
if (areChecksDisabled(element)) return
val texts = TextExtractor.findUniqueTextsAt(element, checkedDomains)
if (skipCheckingTooLargeTexts(texts)) return
sortByPriority(texts, session.priorityRange)
.map { CheckerRunner(it) }
.map { it to it.run() }
.forEach { (runner, problems) ->
problems.forEach { problem ->
runner.toProblemDescriptors(problem, holder.isOnTheFly).forEach(holder::registerProblem)
}
}
if (element == file) {
checkTextLevel(file, holder)
}
}
}
}
private fun checkTextLevel(file: PsiFile, holder: ProblemsHolder) {
TreeRuleChecker.checkTextLevelProblems(file).forEach { reportProblem(it, holder) }
}
private fun reportProblem(problem: TextProblem, holder: ProblemsHolder) {
CheckerRunner(problem.text).toProblemDescriptors(problem, holder.isOnTheFly)
.forEach { holder.registerProblem(it) }
}
private fun hasTooLowSeverity(session: LocalInspectionToolSession): Boolean {
return inspections.all { InspectionProfileManager.hasTooLowSeverity(session, it) }
}
/**
* Most of those methods are used in Grazie Pro.
*/
@Suppress("CompanionObjectInExtension")
companion object {
private val inspections: List<LocalInspectionTool> = listOf(Grammar(), Style())
private const val MAX_TEXT_LENGTH_IN_PSI_ELEMENT = 50_000
private const val MAX_TEXT_LENGTH_IN_FILE = 200_000
const val GRAMMAR_INSPECTION: String = "GrazieInspection"
const val STYLE_INSPECTION: String = "GrazieStyle"
private val hasSpellChecking: Boolean by lazy {
try {
@@ -115,27 +161,6 @@ class GrazieInspection : LocalInspectionTool(), DumbAware {
}
}
@JvmStatic
fun inspectElement(
element: PsiElement,
problemFilter: (TextProblem) -> Boolean,
session: LocalInspectionToolSession,
problemsHolder: ProblemsHolder,
checkedDomains: Set<TextContent.TextDomain>,
) {
val texts = TextExtractor.findUniqueTextsAt(element, checkedDomains)
if (skipCheckingTooLargeTexts(texts)) return
sortByPriority(texts, session.priorityRange)
.map { CheckerRunner(it) }
.map { it to it.run().filter(problemFilter) }
.forEach { (runner, problems) ->
problems.forEach { problem ->
runner.toProblemDescriptors(problem, problemsHolder.isOnTheFly).forEach(problemsHolder::registerProblem)
}
}
}
@JvmStatic
fun sortByPriority(texts: List<TextContent>, priorityRange: TextRange): List<TextContent> {
return texts.sortedBy { text ->
@@ -1,60 +0,0 @@
package com.intellij.grazie.style;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.grazie.text.CheckerRunner;
import com.intellij.grazie.text.TextContent.TextDomain;
import com.intellij.grazie.text.TextProblem;
import com.intellij.grazie.text.TreeRuleChecker;
import com.intellij.grazie.utils.HighlightingUtil;
import com.intellij.profile.codeInspection.InspectionProfileManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
import static com.intellij.grazie.ide.inspection.grammar.GrazieInspection.*;
public class StyleInspection extends LocalInspectionTool {
@Override
public @NotNull PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly,
@NotNull LocalInspectionToolSession session) {
PsiFile file = session.getFile();
if (ignoreGrammarChecking(file) || InspectionProfileManager.hasTooLowSeverity(session, this)) {
return PsiElementVisitor.EMPTY_VISITOR;
}
Set<TextDomain> checkedDomains = HighlightingUtil.checkedDomains();
Function1<PsiElement, Boolean> areChecksDisabled = getDisabledChecker(file);
return new PsiElementVisitor() {
@Override
public void visitElement(@NotNull PsiElement element) {
if (element instanceof PsiWhiteSpace || areChecksDisabled.invoke(element)) return;
inspectElement(element, TextProblem::isStyleLike, session, holder, checkedDomains);
if (element == file) {
checkTextLevel(file, holder);
}
}
};
}
private static void checkTextLevel(PsiFile file, ProblemsHolder holder) {
TreeRuleChecker.checkTextLevelProblems(file)
.stream()
.filter(TextProblem::isStyleLike)
.forEach(problem -> reportProblem(problem, holder));
}
private static void reportProblem(TextProblem problem, ProblemsHolder holder) {
new CheckerRunner(problem.getText()).toProblemDescriptors(problem, holder.isOnTheFly())
.forEach(holder::registerProblem);
}
}
@@ -5,6 +5,7 @@ package com.intellij.grazie.text
import ai.grazie.nlp.tokenizer.Tokenizer
import ai.grazie.nlp.tokenizer.sentence.StandardSentenceTokenizer
import ai.grazie.utils.toLinkedSet
import com.intellij.codeInsight.daemon.impl.ProblemDescriptorWithReporterName
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemDescriptorBase
@@ -13,6 +14,7 @@ import com.intellij.codeInspection.util.InspectionMessage
import com.intellij.grazie.GrazieConfig
import com.intellij.grazie.ide.fus.AcceptanceRateTracker
import com.intellij.grazie.ide.fus.GrazieFUSCounter
import com.intellij.grazie.ide.inspection.grammar.GrazieInspection
import com.intellij.grazie.ide.inspection.grammar.quickfix.GrazieAddExceptionQuickFix
import com.intellij.grazie.ide.inspection.grammar.quickfix.GrazieCustomFixWrapper
import com.intellij.grazie.ide.inspection.grammar.quickfix.GrazieReplaceTypoQuickFix
@@ -139,7 +141,10 @@ class CheckerRunner(val text: TextContent) {
if (isOnTheFly) {
descriptor.quickFixes = toFixes(problem, descriptor)
}
descriptor
ProblemDescriptorWithReporterName(
descriptor,
if (problem.isStyleLike) GrazieInspection.STYLE_INSPECTION else GrazieInspection.GRAMMAR_INSPECTION
)
}
}
@@ -151,15 +156,11 @@ class CheckerRunner(val text: TextContent) {
@NlsContexts.Tooltip private val tooltip: String
): ProblemDescriptorBase(
psi, psi, descriptionTemplate, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false,
rangeInElement, true, onTheFly
rangeInElement, true, onTheFly, tooltip
) {
var quickFixes: Array<LocalQuickFix> = LocalQuickFix.EMPTY_ARRAY
override fun getFixes(): Array<LocalQuickFix> = quickFixes
override fun getTooltipTemplate(): String {
return tooltip
}
}
private fun isIgnoredByStrategies(descriptor: TextProblem): Boolean {
@@ -0,0 +1,26 @@
<html>
<body>
Write your description here.
Start the description with a verb in 3rd person singular, like reports, detects, highlights.
In the first sentence, briefly explain what exactly the inspection helps you detect.
Make sure the sentence is not very long and complicated.
<p>
The first sentence must be in a dedicated paragraph separated from the rest of the text. This will make the description easier to read.
Make sure the description doesn’t just repeat the inspection title.
</p>
<p>
See https://plugins.jetbrains.com/docs/intellij/inspections.html#descriptions for more information.
</p>
<p>
Embed code snippets:
</p>
<pre><code>
// automatically highlighted according to inspection registration 'language' attribute
</code></pre>
<!-- tooltip end -->
<p>Text after this comment will only be shown in the settings of the inspection.</p>
<p>To open related settings directly from the description, add a link with `settings://$` optionally followed by `?$` to pre-select a UI
element.</p>
</body>
</html>
@@ -0,0 +1,18 @@
<html>
<body>
Check the writing style defined in:
<ul>
<li>
Grazie rule files (e.g. <code>.grazie.en.yaml</code> for English)
for this project or its specific subdirectories.
To create such a file, invoke <b>New</b> menu on any (e.g. root) directory of the project.
</li>
<li>
<i>Style</i> rules in <i>Editor | Natural languages | Rules</i> settings
</li>
</ul>
This inspection only returns results via <b>Code | Analyze Code | Run Inspection By Name...</b> or in offline analysis.
Editor highlighting of style issues is performed independently of this inspection's settings.
</body>
</html>
@@ -10,7 +10,6 @@ import com.intellij.grazie.jlanguage.Lang
import com.intellij.grazie.remote.HunspellDescriptor
import com.intellij.grazie.spellcheck.GrazieCheckers
import com.intellij.grazie.spellcheck.GrazieSpellCheckingInspection
import com.intellij.grazie.style.StyleInspection
import com.intellij.grazie.text.TextChecker
import com.intellij.grazie.text.TextContent
import com.intellij.grazie.text.TextExtractor
@@ -39,8 +38,8 @@ import kotlin.io.path.Path
abstract class GrazieTestBase : BasePlatformTestCase() {
companion object {
val inspectionTools by lazy {
arrayOf<LocalInspectionTool>(GrazieInspection(), GrazieSpellCheckingInspection(), StyleInspection())
val inspectionTools: Array<LocalInspectionTool> by lazy {
arrayOf(GrazieInspection(), GrazieInspection.Grammar(), GrazieInspection.Style(), GrazieSpellCheckingInspection())
}
/**
@@ -10,6 +10,7 @@ import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.grazie.GrazieBundle
import com.intellij.grazie.GrazieTestBase
import com.intellij.grazie.ide.TextProblemSeverities
import com.intellij.grazie.ide.inspection.grammar.GrazieInspection
import com.intellij.grazie.ide.inspection.grammar.quickfix.GrazieReplaceTypoQuickFix
import com.intellij.grazie.text.*
@@ -33,9 +34,11 @@ class ReportingTest : BasePlatformTestCase() {
fun `test tooltip and description texts in inspection`() {
val inspection = GrazieInspection()
myFixture.enableInspections(inspection)
myFixture.enableInspections(inspection, GrazieInspection.Grammar())
myFixture.configureByText("a.txt", "I have an new apple here.")
val info = assertOneElement(myFixture.doHighlighting().filter { it.inspectionToolId == inspection.id })
val highlightings = myFixture.doHighlighting().filter { it.inspectionToolId == inspection.id }
val info = assertOneElement(highlightings)
assertEquals(TextProblemSeverities.GRAMMAR_ERROR_ATTRIBUTES, info.type.attributesKey)
val message = "Use a instead of 'an' if the following word doesn't start with a vowel sound, e.g. 'a sentence', 'a university'."
assertEquals(info.description, message)
assertTrue(info.toolTip, info.toolTip!!.matches(Regex(".*" + Regex.escape(message) + ".*Powered by LanguageTool.*")))
@@ -50,7 +53,7 @@ class ReportingTest : BasePlatformTestCase() {
}
fun `test changed range highlighting`() {
myFixture.enableInspections(GrazieInspection::class.java)
myFixture.enableInspections(GrazieInspection::class.java, GrazieInspection.Grammar::class.java)
myFixture.configureByText("a.txt", "Hello there! You <GRAMMAR_ERROR>are <caret>best</GRAMMAR_ERROR> person!")
myFixture.checkHighlighting()
@@ -101,7 +104,7 @@ class ReportingTest : BasePlatformTestCase() {
}
fun `test quick fix sorting`() {
myFixture.enableInspections(GrazieInspection())
myFixture.enableInspections(GrazieInspection(), GrazieInspection.Grammar())
val testChecker = object: TextChecker() {
override fun getRules(locale: Locale) = emptyList<Rule>()
@@ -0,0 +1,95 @@
package com.intellij.grazie.suppression
import com.intellij.grazie.GrazieTestBase
import com.intellij.grazie.ide.inspection.grammar.GrazieInspection
import com.intellij.testFramework.LightProjectDescriptor
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_LATEST
class SuppressionTests: GrazieTestBase() {
override fun getProjectDescriptor(): LightProjectDescriptor = JAVA_LATEST
fun `test suppressing style inspection doesn't affect grammar issues`() {
myFixture.configureByText("A.java", """
class A {
// Show is cancelled because of <GRAMMAR_ERROR descr="EN_A_VS_AN">an</GRAMMAR_ERROR> cat
@SuppressWarnings("GrazieStyle")
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
}
fun `test suppressing grammar inspection doesn't affect style issues`() {
myFixture.configureByText("A.java", """
class A {
// Show is <STYLE_SUGGESTION descr="American English does not double '-l-' in suffixes">can<caret>celled</STYLE_SUGGESTION> because of an cat
@SuppressWarnings("GrazieInspection")
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
}
fun `test suppress style action generates necessary inspection id`() {
myFixture.configureByText("Class.java", """
public class Class {
// Show is <STYLE_SUGGESTION descr="American English does not double '-l-' in suffixes">can<caret>celled</STYLE_SUGGESTION>
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
val intention = myFixture.getAvailableIntention("Suppress for method")
assertNotNull(intention)
myFixture.launchAction(intention!!)
myFixture.checkResult("""
public class Class {
// Show is cancelled
@SuppressWarnings("GrazieStyle")
public static void main() {}
}
""".trimIndent())
}
fun `test suppress grammar action generates necessary inspection id`() {
myFixture.configureByText("Class.java", """
public class Class {
// There is <GRAMMAR_ERROR descr="EN_A_VS_AN">a<caret>n</GRAMMAR_ERROR> cat
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
val intention = myFixture.getAvailableIntention("Suppress for class")
assertNotNull(intention)
myFixture.launchAction(intention!!)
myFixture.checkResult("""
@SuppressWarnings("GrazieInspection")
public class Class {
// There is an cat
public static void main() {}
}
""".trimIndent())
}
fun `test disabling grammar inspection`() {
myFixture.disableInspections(GrazieInspection.Grammar())
myFixture.configureByText("Class.java", """
public class Class {
// Show is <STYLE_SUGGESTION descr="American English does not double '-l-' in suffixes">can<caret>celled</STYLE_SUGGESTION> because of an cat
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
}
fun `test disabling style inspection`() {
myFixture.disableInspections(GrazieInspection.Style())
myFixture.configureByText("Class.java", """
public class Class {
// Show is cancelled because of <GRAMMAR_ERROR descr="EN_A_VS_AN">an</GRAMMAR_ERROR> cat
public static void main() {}
}
""".trimIndent())
myFixture.checkHighlighting()
}
}