mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[javadoc] IDEA-257641 Unknown tags break rendering
Add two quickfixes when IDEA discovers unknown javadoc tags to enclose such occurrences in `{@code}` or escape the `@` symbol with @
GitOrigin-RevId: 5151bf905ca0a7c342339fc2ae0d127ebfc387d8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
bd42d1b27a
commit
0f547eebd6
@@ -1618,7 +1618,7 @@ public class JavaDocInfoGenerator {
|
||||
int pos = buffer.length();
|
||||
|
||||
StringBuilder codeSnippetBuilder = new StringBuilder();
|
||||
generateLiteralValue(codeSnippetBuilder, tag, false);
|
||||
generateLiteralValue(codeSnippetBuilder, tag, true);
|
||||
String codeSnippet = codeSnippetBuilder.toString();
|
||||
if (isCodeBlock) {
|
||||
codeSnippet = StringsKt.trimIndent(codeSnippet);
|
||||
@@ -2705,14 +2705,6 @@ public class JavaDocInfoGenerator {
|
||||
generateAnnotations(buffer, owner, SignaturePlace.ToolTip, true, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated reason.
|
||||
*
|
||||
* <pre>
|
||||
* line 1
|
||||
* line 2
|
||||
* </pre>
|
||||
*/
|
||||
private enum SignaturePlace {
|
||||
Javadoc, ToolTip
|
||||
}
|
||||
|
||||
@@ -842,10 +842,15 @@ public class JavaDocLocalInspection extends LocalInspectionTool {
|
||||
|
||||
@Override
|
||||
public void problem(@NotNull PsiElement toHighlight, @NotNull @Nls String message, @Nullable LocalQuickFix fix) {
|
||||
myHolder.registerProblem(myHolder.getManager().createProblemDescriptor(
|
||||
toHighlight, message, fix, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, myOnTheFly));
|
||||
final LocalQuickFix[] fixes = new LocalQuickFix[] { fix };
|
||||
problemWithFixes(toHighlight, message, fixes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void problemWithFixes(@NotNull PsiElement toHighlight, @NotNull @Nls String message, LocalQuickFix@NotNull [] fixes) {
|
||||
myHolder.registerProblem(myHolder.getManager().createProblemDescriptor(
|
||||
toHighlight, message, fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, myOnTheFly, false));
|
||||
}
|
||||
@Override
|
||||
public void eolProblem(@NotNull PsiElement toHighlight, @NotNull @Nls String message, @Nullable LocalQuickFix fix) {
|
||||
LocalQuickFix[] fixes = fix != null ? new LocalQuickFix[]{fix} : null;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection.javaDoc;
|
||||
|
||||
import com.intellij.codeInspection.CommonQuickFixBundle;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.reference.RefJavaUtil;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.lang.ASTNode;
|
||||
@@ -39,6 +41,7 @@ public final class JavadocHighlightUtil {
|
||||
JavaDocLocalInspection inspection();
|
||||
|
||||
void problem(@NotNull PsiElement toHighlight, @NotNull @Nls String message, @Nullable LocalQuickFix fix);
|
||||
void problemWithFixes(@NotNull PsiElement toHighlight, @NotNull @Nls String message, LocalQuickFix@NotNull [] fixes);
|
||||
void eolProblem(@NotNull PsiElement toHighlight, @NotNull @Nls String message, @Nullable LocalQuickFix fix);
|
||||
|
||||
LocalQuickFix addJavadocFix(@NotNull PsiElement nameIdentifier);
|
||||
@@ -241,7 +244,15 @@ public final class JavadocHighlightUtil {
|
||||
if (nameElement != null) {
|
||||
String key = tagInfo == null ? "inspection.javadoc.problem.wrong.tag" : "inspection.javadoc.problem.disallowed.tag";
|
||||
LocalQuickFix fix = tagInfo == null ? holder.registerTagFix(tagName) : holder.removeTagFix(tagName);
|
||||
holder.problem(nameElement, JavaBundle.message(key, "<code>" + tagName + "</code>"), fix);
|
||||
final LocalQuickFix[] fixes;
|
||||
if (tagInfo != null) {
|
||||
fixes = new LocalQuickFix[]{ fix };
|
||||
}
|
||||
else {
|
||||
final String nameElementText = nameElement.getText();
|
||||
fixes = new LocalQuickFix[]{ fix, new EncloseWithCodeFix(nameElementText), new EscapeAtQuickFix(nameElementText) };
|
||||
}
|
||||
holder.problemWithFixes(nameElement, JavaBundle.message(key, "<code>" + tagName + "</code>"), fixes);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -520,4 +531,87 @@ public final class JavadocHighlightUtil {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static abstract class AbstractUnknownTagFix implements LocalQuickFix {
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiElement element = descriptor.getPsiElement();
|
||||
if (element == null) return;
|
||||
|
||||
final PsiElement enclosingTag = element.getParent();
|
||||
if (enclosingTag == null) return;
|
||||
|
||||
final PsiElement javadoc = enclosingTag.getParent();
|
||||
if (javadoc == null) return;
|
||||
|
||||
final PsiDocComment donorJavadoc = createDonorJavadoc(element);
|
||||
final PsiElement codeTag = extractElement(donorJavadoc);
|
||||
if (codeTag == null) return;
|
||||
|
||||
for (var e = enclosingTag.getFirstChild(); e != element && e != null; e = e.getNextSibling()) {
|
||||
javadoc.addBefore(e, enclosingTag);
|
||||
}
|
||||
javadoc.addBefore(codeTag, enclosingTag);
|
||||
for (var e = element.getNextSibling(); e != null; e = e.getNextSibling()) {
|
||||
javadoc.addBefore(e, enclosingTag);
|
||||
}
|
||||
final PsiElement sibling = enclosingTag.getNextSibling();
|
||||
if (sibling != null && sibling.getNode().getElementType() == TokenType.WHITE_SPACE) {
|
||||
javadoc.addBefore(sibling, enclosingTag);
|
||||
}
|
||||
enclosingTag.delete();
|
||||
}
|
||||
|
||||
protected abstract @NotNull PsiDocComment createDonorJavadoc(@NotNull PsiElement element);
|
||||
protected abstract @Nullable PsiElement extractElement(@Nullable PsiDocComment donorJavadoc);
|
||||
}
|
||||
|
||||
private static class EncloseWithCodeFix extends AbstractUnknownTagFix {
|
||||
private final String myName;
|
||||
|
||||
private EncloseWithCodeFix(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return CommonQuickFixBundle.message("fix.replace.x.with.y", myName, "{@code " + myName + "}");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull PsiDocComment createDonorJavadoc(@NotNull PsiElement element) {
|
||||
final PsiElementFactory instance = PsiElementFactory.getInstance(element.getProject());
|
||||
return instance.createDocCommentFromText(String.format("/** {@code %s} */", element.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable PsiElement extractElement(@Nullable PsiDocComment donorJavadoc) {
|
||||
return PsiTreeUtil.findChildOfType(donorJavadoc, PsiInlineDocTag.class);
|
||||
}
|
||||
}
|
||||
|
||||
private static class EscapeAtQuickFix extends AbstractUnknownTagFix {
|
||||
private final String myName;
|
||||
|
||||
private EscapeAtQuickFix(String name) {
|
||||
myName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return CommonQuickFixBundle.message("fix.replace.x.with.y", myName, "@" + myName.substring(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull PsiDocComment createDonorJavadoc(@NotNull PsiElement element) {
|
||||
final PsiElementFactory instance = PsiElementFactory.getInstance(element.getProject());
|
||||
return instance.createDocCommentFromText("/** @" + element.getText().substring(1) + " */");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable PsiElement extractElement(@Nullable PsiDocComment donorJavadoc) {
|
||||
if (donorJavadoc == null) return null;
|
||||
return donorJavadoc.getChildren()[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace '@Override' with '{@code @Override}'" "true"
|
||||
|
||||
class Foo {
|
||||
|
||||
/**
|
||||
* {@code @Override}
|
||||
* <pre>
|
||||
* {@code hello, world}
|
||||
* </pre>
|
||||
*/
|
||||
public void foo(){
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace '@Override' with '@Override'" "true"
|
||||
|
||||
class Foo {
|
||||
|
||||
/**
|
||||
* @Override
|
||||
* <pre>
|
||||
* {@code hello, world}
|
||||
* </pre>
|
||||
*/
|
||||
public void foo(){
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace '@Override' with '{@code @Override}'" "true"
|
||||
|
||||
class Foo {
|
||||
|
||||
/**
|
||||
* @Override<caret>
|
||||
* <pre>
|
||||
* {@code hello, world}
|
||||
* </pre>
|
||||
*/
|
||||
public void foo(){
|
||||
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace '@Override' with '@Override'" "true"
|
||||
|
||||
class Foo {
|
||||
|
||||
/**
|
||||
* @Override<caret>
|
||||
* <pre>
|
||||
* {@code hello, world}
|
||||
* </pre>
|
||||
*/
|
||||
public void foo(){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<html><head><base href="placeholder"></head><body><div class='definition'><pre><span style="color:#000080;font-weight:bold;">class</span> <span style="color:#000000;">Main</span></pre></div><div class='content'>
|
||||
<code style='font-size:100%;'><span style=""><span style="">Hello&lt;World&gt; message;</span></span></code>
|
||||
</div><table class='sections'><p></table>
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* {@code
|
||||
* Hello<World> message;
|
||||
* }
|
||||
*/
|
||||
class Main {
|
||||
}
|
||||
+1
@@ -118,6 +118,7 @@ public class JavaDocInfoGeneratorTest extends JavaCodeInsightTestCase {
|
||||
public void testInlineTagSummary() { useJava10(); doTestClass(); }
|
||||
public void testLeadingSpacesInPre() { doTestClass(); }
|
||||
public void testPreInDeprecated() { doTestClass(); }
|
||||
public void testEscapeHtmlInCode() { doTestClass(); }
|
||||
|
||||
public void testRepeatableAnnotations() {
|
||||
useJava8();
|
||||
|
||||
Reference in New Issue
Block a user