From 88a009e6be570a356dc5bddfb5eaa704223ece92 Mon Sep 17 00:00:00 2001 From: "Andrey.Cherkasov" Date: Wed, 13 Apr 2022 03:01:55 +0300 Subject: [PATCH] [java-inspections] JavadocLinkAsPlainText and JavaDocReference: extract and unify UrlToHtmlFix for both inspections IJ-CR-21142 GitOrigin-RevId: 64d01c0308d19de5c2e22eaefa8e1d7772e3fca4 --- .../javaDoc/JavaDocReferenceInspection.java | 54 +++------------ .../JavadocLinkAsPlainTextInspection.java | 53 ++------------- .../codeInspection/javaDoc/UrlToHtmlFix.java | 67 +++++++++++++++++++ .../javadocLinkAsPlainText/after1.java | 4 +- .../javadocLinkAsPlainText/before1.java | 2 +- ...eLink.java => afterMalformedSeeLink1.java} | 0 .../javadocTags/afterMalformedSeeLink2.java | 6 ++ ...Link.java => beforeMalformedSeeLink1.java} | 0 .../javadocTags/beforeMalformedSeeLink2.java | 6 ++ .../resources/messages/JavaBundle.properties | 2 - 10 files changed, 94 insertions(+), 100 deletions(-) create mode 100644 java/java-impl/src/com/intellij/codeInspection/javaDoc/UrlToHtmlFix.java rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/{afterMalformedSeeLink.java => afterMalformedSeeLink1.java} (100%) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink2.java rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/{beforeMalformedSeeLink.java => beforeMalformedSeeLink1.java} (100%) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink2.java diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java index 6ae60abd3227..6e4f21407d74 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavaDocReferenceInspection.java @@ -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 " + text + ""); - 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); - } - } - } } diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocLinkAsPlainTextInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocLinkAsPlainTextInspection.java index 55423fbb84fe..c95e20c72368 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocLinkAsPlainTextInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/JavadocLinkAsPlainTextInspection.java @@ -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 = "" + dummyText + ""; - 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"); - } - } } diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/UrlToHtmlFix.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/UrlToHtmlFix.java new file mode 100644 index 000000000000..6454b0f10c56 --- /dev/null +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/UrlToHtmlFix.java @@ -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 = "" + text + ""; + 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); + } + } +} diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/after1.java index d6f7d17b5b2e..7cc6887926d7 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/after1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/after1.java @@ -1,6 +1,6 @@ -// "Wrap in tag" "true" +// "Replace URL with HTML link" "true" /** - * abc ... def + * abc ... def */ class Main { } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/before1.java index 5479f4cf5a91..72edb940b73c 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/before1.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocLinkAsPlainText/before1.java @@ -1,4 +1,4 @@ -// "Wrap in tag" "true" +// "Replace URL with HTML link" "true" /** * abc https://en.wikipedia.org/ def diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink1.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink1.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink2.java new file mode 100644 index 000000000000..09fec0039ec9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/afterMalformedSeeLink2.java @@ -0,0 +1,6 @@ +// "Replace URL with HTML link" "true" + +/** + * @see ... + */ +class C { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink1.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink1.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink2.java new file mode 100644 index 000000000000..616f0ce46a18 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/javadocTags/beforeMalformedSeeLink2.java @@ -0,0 +1,6 @@ +// "Replace URL with HTML link" "true" + +/** + * @see https://www.nowhere.net + */ +class C { } diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties index 5e72fce18b6a..c12c0219d611 100644 --- a/java/openapi/resources/messages/JavaBundle.properties +++ b/java/openapi/resources/messages/JavaBundle.properties @@ -516,8 +516,6 @@ inspection.javadoc.blank.lines.fix.name=Insert

inspection.javadoc.blank.lines.fix.family.name=Replace blank lines with

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 tag -inspection.javadoc.link.as.plain.text.family.name=Wrap links in 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