[java-inspections] JavadocLinkAsPlainText and JavaDocReference: extract and unify UrlToHtmlFix for both inspections

IJ-CR-21142

GitOrigin-RevId: 64d01c0308d19de5c2e22eaefa8e1d7772e3fca4
This commit is contained in:
Andrey.Cherkasov
2022-04-13 10:09:41 +00:00
committed by intellij-monorepo-bot
parent 38fb2fe104
commit 88a009e6be
10 changed files with 94 additions and 100 deletions
@@ -1,4 +1,4 @@
// 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.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.javaDoc;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
@@ -142,7 +142,13 @@ public class JavaDocReferenceInspection extends LocalInspectionTool {
if (adjacent instanceof PsiDocToken &&
((PsiDocToken)adjacent).getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA &&
adjacent.getText().startsWith(URLUtil.SCHEME_SEPARATOR)) {
fix = new UrlToHtmlFix(refHolder, adjacent);
PsiDocComment docComment = PsiTreeUtil.getParentOfType(reference, PsiDocComment.class);
if (docComment != null) {
int startOffsetInDocComment = refHolder.getTextOffset() - docComment.getTextOffset();
int endOffsetInDocComment =
refHolder.getTextOffset() + refText.length() + adjacent.getTextLength() - docComment.getTextOffset();
fix = new UrlToHtmlFix(docComment, startOffsetInDocComment, endOffsetInDocComment);
}
}
}
}
@@ -362,48 +368,4 @@ public class JavaDocReferenceInspection extends LocalInspectionTool {
}
}
}
private static class UrlToHtmlFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private UrlToHtmlFix(PsiElement startElement, PsiElement endElement) {
super(startElement, endElement);
}
@Override
public @NotNull String getText() {
return JavaBundle.message("quickfix.text.replace.url.with.html");
}
@Override
public @NotNull String getFamilyName() {
return getText();
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement refHolder,
@NotNull PsiElement adjacent) {
String text = adjacent.getText(), url;
int urlEnd = text.indexOf(' ');
if (urlEnd > 0) {
url = refHolder.getText() + text.substring(0, urlEnd);
text = text.substring(urlEnd).trim();
}
else {
url = refHolder.getText() + text;
text = "...";
}
PsiDocTag tag = PsiElementFactory.getInstance(project).createDocTagFromText("@see <a href=\"" + url + "\">" + text + "</a>");
PsiElement replacement = tag.getLastChild();
assert replacement instanceof PsiDocToken : Arrays.toString(tag.getChildren());
refHolder.delete();
replacement = adjacent.replace(replacement);
if (editor != null) {
int start = replacement.getTextRange().getStartOffset() + url.length() + 11, end = start + text.length();
editor.getCaretModel().moveToOffset(start);
editor.getSelectionModel().setSelection(start, end);
}
}
}
}
@@ -2,22 +2,20 @@
package com.intellij.codeInspection.javaDoc;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.paths.WebReference;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiReference;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.io.URLUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -67,47 +65,4 @@ public class JavadocLinkAsPlainTextInspection extends LocalInspectionTool {
}
};
}
private static class UrlToHtmlFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final int myStartOffset;
private final int myEndOffset;
protected UrlToHtmlFix(@Nullable PsiElement element, int startOffset, int endOffset) {
super(element);
myStartOffset = startOffset;
myEndOffset = endOffset;
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
String commentText = startElement.getText();
String prefix = commentText.substring(0, myStartOffset);
String url = commentText.substring(myStartOffset, myEndOffset);
String suffix = commentText.substring(myEndOffset);
String dummyText = "...";
String wrappedLink = "<a href=\"" + url + "\">" + dummyText + "</a>";
CommentTracker ct = new CommentTracker();
PsiElement replacement = ct.replace(startElement, prefix + wrappedLink + suffix);
if (editor != null) {
int start = replacement.getTextRange().getStartOffset() + prefix.length() + url.length() + 11;
int end = start + dummyText.length();
editor.getCaretModel().moveToOffset(start);
editor.getSelectionModel().setSelection(start, end);
}
}
@Override
public @NotNull String getText() {
return JavaBundle.message("inspection.javadoc.link.as.plain.text.fix.name");
}
@Override
public @NotNull String getFamilyName() {
return JavaBundle.message("inspection.javadoc.link.as.plain.text.family.name");
}
}
}
@@ -0,0 +1,67 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.javaDoc;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.javadoc.PsiDocComment;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
class UrlToHtmlFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final int myStartOffsetInDocComment;
// if you want to use "..." as the HTML link text, use the end URL offset in a JavaDoc comment as `myEndOffsetInDocComment`
// if you want to use a substring after the URL as the HTML link text, use the end of that substring
private final int myEndOffsetInDocComment;
UrlToHtmlFix(@Nullable PsiDocComment element, int startOffsetInDocComment, int endOffsetInDocComment) {
super(element);
myStartOffsetInDocComment = startOffsetInDocComment;
myEndOffsetInDocComment = endOffsetInDocComment;
}
@Override
public @NotNull String getText() {
return JavaBundle.message("quickfix.text.replace.url.with.html");
}
@Override
public @NotNull String getFamilyName() {
return getText();
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
String commentText = startElement.getText();
String prefix = commentText.substring(0, myStartOffsetInDocComment);
String urlAndMaybeText = commentText.substring(myStartOffsetInDocComment, myEndOffsetInDocComment);
String suffix = commentText.substring(myEndOffsetInDocComment);
int urlEnd = urlAndMaybeText.indexOf(' ');
String text;
if (urlEnd > 0) {
text = urlAndMaybeText.substring(urlEnd).trim();
urlAndMaybeText = urlAndMaybeText.substring(0, urlEnd);
}
else {
text = "...";
}
String wrappedLink = "<a href=\"" + urlAndMaybeText + "\">" + text + "</a>";
CommentTracker ct = new CommentTracker();
PsiElement replacement = ct.replace(startElement, prefix + wrappedLink + suffix);
if (editor != null) {
int start = replacement.getTextRange().getStartOffset() + prefix.length() + urlAndMaybeText.length() + 11;
int end = start + text.length();
editor.getCaretModel().moveToOffset(start);
editor.getSelectionModel().setSelection(start, end);
}
}
}
@@ -1,6 +1,6 @@
// "Wrap in <a> tag" "true"
// "Replace URL with HTML link" "true"
/**
* abc <a href="https://en.wikipedia.org/">...</a> def
* abc <a href="https://en.wikipedia.org/"><caret><selection>...</selection></a> def
*/
class Main { }
@@ -1,4 +1,4 @@
// "Wrap in <a> tag" "true"
// "Replace URL with HTML link" "true"
/**
* abc https://en.wikipedia.org/<caret> def
@@ -0,0 +1,6 @@
// "Replace URL with HTML link" "true"
/**
* @see <a href="https://www.nowhere.net"><caret><selection>...</selection></a>
*/
class C { }
@@ -0,0 +1,6 @@
// "Replace URL with HTML link" "true"
/**
* @see <caret>https://www.nowhere.net
*/
class C { }
@@ -516,8 +516,6 @@ inspection.javadoc.blank.lines.fix.name=Insert <p>
inspection.javadoc.blank.lines.fix.family.name=Replace blank lines with <p>
inspection.javadoc.link.as.plain.text.display.name=Link specified as plain text
inspection.javadoc.link.as.plain.text.message=Link specified as plain text
inspection.javadoc.link.as.plain.text.fix.name=Wrap in <a> tag
inspection.javadoc.link.as.plain.text.family.name=Wrap links in <a> tag
inspection.javadoc.required.tags.option.title=Required Tags
inspection.javadoc.throws.or.exception.option=@throws or @exception
inspection.join.declaration.and.assignment.display.name=Assignment can be joined with declaration