diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightErrorFilter.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightErrorFilter.java index a1fd0ee74608..029f4486d012 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightErrorFilter.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightErrorFilter.java @@ -5,15 +5,22 @@ import com.intellij.codeInsight.highlighting.HighlightErrorFilter; import com.intellij.core.JavaPsiBundle; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.tree.JavaDocElementType; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocTag; +import com.intellij.psi.javadoc.PsiDocTagValue; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; public final class JavaHighlightErrorFilter extends HighlightErrorFilter { + + @Override public boolean shouldHighlightErrorElement(@NotNull PsiErrorElement element) { String description = element.getErrorDescription(); + if (isJavaDocProblem(element)) return false; if (description.equals(JavaPsiBundle.message("expected.semicolon"))) { PsiElement parent = element.getParent(); if (parent instanceof PsiExpressionStatement && !PsiUtil.isStatement(parent)) { @@ -41,6 +48,16 @@ public final class JavaHighlightErrorFilter extends HighlightErrorFilter { return true; } + /** + * @param element error element to check + * @return true if this error is javadoc parsing problem. In this case, it's covered by JavadocParsingInspection. + */ + public static boolean isJavaDocProblem(@NotNull PsiErrorElement element) { + PsiElement parent = element.getParent(); + return parent instanceof PsiDocComment || parent instanceof PsiDocTag || parent instanceof PsiDocTagValue || + parent != null && parent.getNode().getElementType() == JavaDocElementType.DOC_REFERENCE_HOLDER; + } + private static boolean isAfterUnclosedStringLiteral(@NotNull PsiErrorElement element) { PsiElement prevLeaf = PsiTreeUtil.prevCodeLeaf(element); if (prevLeaf instanceof PsiJavaToken token) { diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocDeclarationInspection.java index d6f5d97aa4da..4d07cc37a6e6 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocDeclarationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocDeclarationInspection.java @@ -2,6 +2,7 @@ package com.intellij.codeInspection.javaDoc; import com.intellij.codeInsight.daemon.impl.analysis.IncreaseLanguageLevelFix; +import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightErrorFilter; import com.intellij.codeInsight.daemon.impl.quickfix.DeleteElementFix; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.codeInsight.javadoc.SnippetMarkup; @@ -13,6 +14,8 @@ import com.intellij.modcommand.ModPsiUpdater; import com.intellij.modcommand.PsiUpdateModCommandQuickFix; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.HtmlChunk; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.JavaFeature; import com.intellij.psi.*; @@ -44,6 +47,7 @@ public final class JavadocDeclarationInspection extends LocalInspectionTool { public boolean IGNORE_PERIOD_PROBLEM = true; public boolean IGNORE_SELF_REFS = false; public boolean IGNORE_DEPRECATED_ELEMENTS = false; + public boolean IGNORE_SYNTAX_ERRORS = false; private boolean myIgnoreEmptyDescriptions = false; @@ -66,11 +70,18 @@ public final class JavadocDeclarationInspection extends LocalInspectionTool { @Override public @NotNull OptPane getOptionsPane() { return pane( - expandableString("ADDITIONAL_TAGS", JavaBundle.message("inspection.javadoc.label.text"), ","), - checkbox("IGNORE_THROWS_DUPLICATE", JavaBundle.message("inspection.javadoc.option.ignore.throws")), - checkbox("IGNORE_PERIOD_PROBLEM", JavaBundle.message("inspection.javadoc.option.ignore.period")), - checkbox("IGNORE_SELF_REFS", JavaBundle.message("inspection.javadoc.option.ignore.self.ref")), + expandableString("ADDITIONAL_TAGS", JavaBundle.message("inspection.javadoc.additional.tags"), ",") + .description(JavaBundle.message("inspection.javadoc.additional.tags.description")), + checkbox("IGNORE_THROWS_DUPLICATE", JavaBundle.message("inspection.javadoc.option.ignore.throws")) + .description(HtmlChunk.raw(JavaBundle.message("inspection.javadoc.option.ignore.throws.description"))), + checkbox("IGNORE_PERIOD_PROBLEM", JavaBundle.message("inspection.javadoc.option.ignore.period")) + .description(JavaBundle.message("inspection.javadoc.option.ignore.period.description")), + checkbox("IGNORE_SELF_REFS", JavaBundle.message("inspection.javadoc.option.ignore.self.ref")) + .description(JavaBundle.message("inspection.javadoc.option.ignore.self.ref.description")), checkbox("IGNORE_DEPRECATED_ELEMENTS", JavaBundle.message("inspection.javadoc.option.ignore.deprecated")) + .description(JavaBundle.message("inspection.javadoc.option.ignore.deprecated.description")), + checkbox("IGNORE_SYNTAX_ERRORS", JavaBundle.message("inspection.javadoc.option.ignore.syntax.errors")) + .description(JavaBundle.message("inspection.javadoc.option.ignore.syntax.errors.description")) ); } @@ -84,6 +95,25 @@ public final class JavadocDeclarationInspection extends LocalInspectionTool { } } + @Override + public void visitErrorElement(@NotNull PsiErrorElement element) { + if (IGNORE_SYNTAX_ERRORS || !JavaHighlightErrorFilter.isJavaDocProblem(element)) return; + PsiElement parent = element.getParent(); + TextRange range = element.getTextRangeInParent(); + if (range.isEmpty()) { + range = new TextRange(range.getStartOffset(), range.getEndOffset() + 1); + if (range.getEndOffset() > parent.getTextLength()) { + range = range.shiftLeft(1); + } + } + holder.problem(parent, element.getErrorDescription()) + .range(range) + .highlight(ProblemHighlightType.GENERIC_ERROR) + .fix(new UpdateInspectionOptionFix(JavadocDeclarationInspection.this, "IGNORE_SYNTAX_ERRORS", + JavaBundle.message("inspection.javadoc.option.ignore.syntax.errors"), true)) + .register(); + } + @Override public void visitModule(@NotNull PsiJavaModule module) { checkModule(module, holder); diff --git a/java/java-impl/src/inspectionDescriptions/JavadocDeclaration.html b/java/java-impl/src/inspectionDescriptions/JavadocDeclaration.html index ec2c702d55b5..258f11dd19e2 100644 --- a/java/java-impl/src/inspectionDescriptions/JavadocDeclaration.html +++ b/java/java-impl/src/inspectionDescriptions/JavadocDeclaration.html @@ -26,9 +26,5 @@ Reports Javadoc comments and tags with the following problems:

Quick-fix adds the unknown Javadoc tag to the list of user defined additional tags.

-

Use textfield below to define additional Javadoc tags.

-

Use first checkbox to ignore duplicated 'throws' tag.

-

Use second checkbox to ignore problem with missing or incomplete first sentence in the description.

-

Use third checkbox to ignore references pointing to itself.

\ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDot.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDot.java new file mode 100644 index 000000000000..fc89495d19ad --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDot.java @@ -0,0 +1,7 @@ +class Foo { + /** + * @throws RuntimeException. + */ + void foo() { + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDotIgnored.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDotIgnored.java new file mode 100644 index 000000000000..fa7732407de3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/javadocDeclaration/ExceptionWrongDotIgnored.java @@ -0,0 +1,7 @@ +class Foo { + /** + * @throws RuntimeException. + */ + void foo() { + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocDeclarationHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocDeclarationHighlightingTest.java index 678d4adf2d23..889742b581d3 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocDeclarationHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/JavadocDeclarationHighlightingTest.java @@ -74,6 +74,8 @@ public class JavadocDeclarationHighlightingTest extends LightDaemonAnalyzerTestC public void testException2() { doTest(); } public void testException3() { doTest(); } public void testException4() { doTest(); } + public void testExceptionWrongDot() { doTest(); } + public void testExceptionWrongDotIgnored() { myInspection.IGNORE_SYNTAX_ERRORS = true; doTest(); } public void testInheritJavaDoc() { setLanguageLevel(LanguageLevel.JDK_1_3); doTest(); } public void testLink0() { doTest(); } public void testLinkFromInnerClassToSelfMethod() { doTest(); } diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties index c8686bcfe569..7faa10dff92f 100644 --- a/java/openapi/resources/messages/JavaBundle.properties +++ b/java/openapi/resources/messages/JavaBundle.properties @@ -498,15 +498,22 @@ inspection.replace.javadoc.display.name=Comment replaceable with Javadoc inspection.missingJavadoc.label.minimalVisibility=Minimal visibility: inspection.missingJavadoc.label.requiredTags=Required tags: inspection.javadocDeclaration.display.name=Javadoc declaration problems -inspection.javadoc.label.text=Additional Javadoc tags: +inspection.javadoc.additional.tags=Additional Javadoc tags: +inspection.javadoc.additional.tags.description=List of known non-standard tags inspection.javadoc.lint.display.name=HTML problems in Javadoc (DocLint) inspection.javadoc.method.problem.missing.param.tag=Required tag @param is missing for parameter {0} inspection.javadoc.method.problem.missing.tag.description={0} tag description is missing inspection.javadoc.option.ignore.deprecated=Ignore elements marked as @deprecated +inspection.javadoc.option.ignore.deprecated.description=Do not report any problems in Javadoc describing deprecated classes or members +inspection.javadoc.option.ignore.syntax.errors=Ignore Javadoc syntax errors +inspection.javadoc.option.ignore.syntax.errors.description=Do not report Javadoc parse errors, such as malformed references inspection.javadoc.option.ignore.period=Ignore period problems +inspection.javadoc.option.ignore.period.description=Do not report problems related to missing or incomplete first sentence of the description. inspection.javadoc.option.ignore.self.ref=Ignore Javadoc pointing to itself +inspection.javadoc.option.ignore.self.ref.description=Do not report references in Javadoc pointing to the same element inspection.javadoc.option.ignore.simple=Ignore simple property accessors inspection.javadoc.option.ignore.throws=Ignore duplicate 'throws' tag +inspection.javadoc.option.ignore.throws.description=Do not report repeating @throws tags describing the same exception inspection.javadoc.option.tab.title=Class inspection.javadoc.option.tab.title.field=Field inspection.javadoc.option.tab.title.inner.class=Inner class