mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[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:
committed by
intellij-monorepo-bot
parent
dc35cf8dec
commit
c2e3cb4b9c
@@ -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();
|
||||
|
||||
+5
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
+56
-31
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user