From 6dbdc8338eb6bbbd2685c59e1edac20eb0c78663 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Fri, 9 May 2025 14:31:02 +0200 Subject: [PATCH] [javadoc] IDEA-372322 Refactor FixDocCommentAction#generateComment to avoid Editor dependency Also convert AddJavadocIntention to ModCommand GitOrigin-RevId: f33816159a5805395a63ad3107f4b895659f375b --- .../intention/impl/AddJavadocIntention.java | 41 +++++---- .../javaDoc/MissingJavadocInspection.java | 7 +- .../codeInsight/addJavadoc/afterClass.java | 2 +- .../addJavadoc/afterDifferentParamNames.java | 2 +- .../codeInsight/addJavadoc/afterField.java | 2 +- .../codeInsight/addJavadoc/afterField2.java | 2 +- .../codeInsight/addJavadoc/afterField3.java | 2 +- .../codeInsight/addJavadoc/afterMethod.java | 2 +- .../codeInsight/addJavadoc/afterMethod2.java | 2 +- .../afterMethodCommentInheritance.java | 2 +- .../afterMultiFieldDeclaration.java | 2 +- .../afterMultiFieldDeclaration2.java | 2 +- .../codeInsight/addJavadoc/afterRecord.java | 2 +- .../codeInsight/addJavadoc/beforeClass.java | 2 +- .../addJavadoc/beforeDifferentParamNames.java | 2 +- .../codeInsight/addJavadoc/beforeField.java | 2 +- .../codeInsight/addJavadoc/beforeField2.java | 2 +- .../codeInsight/addJavadoc/beforeField3.java | 2 +- .../codeInsight/addJavadoc/beforeMethod.java | 2 +- .../codeInsight/addJavadoc/beforeMethod2.java | 2 +- .../beforeMethodCommentInheritance.java | 2 +- .../beforeMultiFieldDeclaration.java | 2 +- .../beforeMultiFieldDeclaration2.java | 2 +- .../codeInsight/addJavadoc/beforeRecord.java | 2 +- platform/lang-impl/api-dump-unreviewed.txt | 1 + .../editorActions/FixDocCommentAction.java | 90 ++++++++++++------- 26 files changed, 111 insertions(+), 72 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java index a541b7b68534..76daec1559c8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddJavadocIntention.java @@ -2,27 +2,38 @@ package com.intellij.codeInsight.intention.impl; import com.intellij.codeInsight.editorActions.FixDocCommentAction; -import com.intellij.codeInsight.intention.BaseElementAtCaretIntentionAction; -import com.intellij.codeInsight.intention.LowPriorityAction; +import com.intellij.codeInsight.intention.PriorityAction; import com.intellij.ide.util.PackageUtil; import com.intellij.java.JavaBundle; import com.intellij.lang.java.JavaDocumentationProvider; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; +import com.intellij.modcommand.ActionContext; +import com.intellij.modcommand.ModPsiUpdater; +import com.intellij.modcommand.Presentation; +import com.intellij.modcommand.PsiUpdateModCommandAction; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class AddJavadocIntention extends BaseElementAtCaretIntentionAction implements LowPriorityAction, DumbAware { - @Override - public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement element) { - FixDocCommentAction.generateOrFixComment(element, project, editor); +public class AddJavadocIntention extends PsiUpdateModCommandAction { + public AddJavadocIntention() { + super(PsiElement.class); } @Override - public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiElement element) { + protected void invoke(@NotNull ActionContext context, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) { + FixDocCommentAction.generateComment(element, context.project(), updater); + } + + @Override + protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiElement element) { + //noinspection DialogTitleCapitalization + return Presentation.of(getFamilyName()).withPriority(PriorityAction.Priority.LOW); + } + + @Override + protected boolean isElementApplicable(@NotNull PsiElement element, @NotNull ActionContext context) { if (element instanceof PsiIdentifier || element instanceof PsiJavaCodeReferenceElement || element instanceof PsiJavaModuleReferenceElement) { @@ -33,10 +44,10 @@ public class AddJavadocIntention extends BaseElementAtCaretIntentionAction imple if ( targetElement instanceof PsiClass aClass && PsiUtil.isLocalClass(aClass)) { return false; } - if (targetElement instanceof PsiJavaDocumentedElement && + if (targetElement instanceof PsiJavaDocumentedElement documentedElement && !(targetElement instanceof PsiTypeParameter) && !(targetElement instanceof PsiAnonymousClass)) { - return ((PsiJavaDocumentedElement)targetElement).getDocComment() == null; + return documentedElement.getDocComment() == null; } if (targetElement instanceof PsiPackageStatement) { @@ -55,10 +66,4 @@ public class AddJavadocIntention extends BaseElementAtCaretIntentionAction imple //noinspection DialogTitleCapitalization return JavaBundle.message("intention.family.add.javadoc"); } - - @Override - public @NotNull String getText() { - //noinspection DialogTitleCapitalization - return getFamilyName(); - } } diff --git a/java/java-impl/src/com/intellij/codeInspection/javaDoc/MissingJavadocInspection.java b/java/java-impl/src/com/intellij/codeInspection/javaDoc/MissingJavadocInspection.java index d5ffae208faf..2cb762c9c1aa 100644 --- a/java/java-impl/src/com/intellij/codeInspection/javaDoc/MissingJavadocInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/javaDoc/MissingJavadocInspection.java @@ -2,7 +2,10 @@ package com.intellij.codeInspection.javaDoc; import com.intellij.codeInsight.intention.impl.AddJavadocIntention; -import com.intellij.codeInspection.*; +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.LocalQuickFix; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.codeInspection.ProblemsHolder; import com.intellij.codeInspection.options.*; import com.intellij.codeInspection.reference.RefJavaUtil; import com.intellij.ide.nls.NlsMessages; @@ -444,7 +447,7 @@ public final class MissingJavadocInspection extends LocalInspectionTool { private static void reportMissingJavadoc(@NotNull PsiElement toHighlight, @NotNull ProblemsHolder holder, boolean isOnTheFly) { String message = JavaBundle.message("inspection.javadoc.problem.descriptor"); - LocalQuickFix fix = isOnTheFly ? IntentionWrapper.wrapToQuickFix(new AddJavadocIntention(), holder.getFile()) : null; + LocalQuickFix fix = isOnTheFly ? LocalQuickFix.from(new AddJavadocIntention()) : null; problem(holder, toHighlight, message, fix); } diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterClass.java b/java/java-tests/testData/codeInsight/addJavadoc/afterClass.java index c8afa98295ce..6a1faa96b7bc 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterClass.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterClass.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" /** * diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterDifferentParamNames.java b/java/java-tests/testData/codeInsight/addJavadoc/afterDifferentParamNames.java index 54527f2f7803..5915f5ee104d 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterDifferentParamNames.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterDifferentParamNames.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { /** diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterField.java b/java/java-tests/testData/codeInsight/addJavadoc/afterField.java index 96c53712f0b2..7daccdd24acd 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterField.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterField.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterField2.java b/java/java-tests/testData/codeInsight/addJavadoc/afterField2.java index 9c67b503bee2..2501aa8c1a02 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterField2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterField2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Test { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterField3.java b/java/java-tests/testData/codeInsight/addJavadoc/afterField3.java index a0b9494e4d69..95250a7e91c8 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterField3.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterField3.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Test { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterMethod.java b/java/java-tests/testData/codeInsight/addJavadoc/afterMethod.java index d5d21088c837..67dd12228619 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterMethod.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterMethod.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { /** diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterMethod2.java b/java/java-tests/testData/codeInsight/addJavadoc/afterMethod2.java index 502b0b1b99bf..2fade818ba66 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterMethod2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterMethod2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { /** diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterMethodCommentInheritance.java b/java/java-tests/testData/codeInsight/addJavadoc/afterMethodCommentInheritance.java index 10abf4616e11..dec974d971cc 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterMethodCommentInheritance.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterMethodCommentInheritance.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" //Method Comments Algorithm // diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration.java b/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration.java index c1640ea84f0d..fac425f51a50 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Foo { int x = 2, /** * diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration2.java b/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration2.java index 74092b4fa877..abeb213bda89 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterMultiFieldDeclaration2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Foo { /** * diff --git a/java/java-tests/testData/codeInsight/addJavadoc/afterRecord.java b/java/java-tests/testData/codeInsight/addJavadoc/afterRecord.java index 65cf6f591e35..7a9a94d18237 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/afterRecord.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/afterRecord.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" /** diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeClass.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeClass.java index c6c284928e24..36d6dda48764 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeClass.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeClass.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Foo { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeDifferentParamNames.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeDifferentParamNames.java index 8eb751222799..6ec2a8772539 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeDifferentParamNames.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeDifferentParamNames.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { /** diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeField.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeField.java index cf27dadb93e5..dd822f3bd13b 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeField.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeField.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeField2.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeField2.java index 33ac41944180..792cedfa2a7b 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeField2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeField2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Test { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeField3.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeField3.java index 93499340382e..24f17bab8231 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeField3.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeField3.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Test { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod.java index c428f80c85cd..e8fed15ad118 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { public void foo() { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod2.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod2.java index a9d2f3b839b0..ff63fb79ea0f 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethod2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class A { public int foo(final String s) throws Exception { diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethodCommentInheritance.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethodCommentInheritance.java index f58d44c9ac66..db757cb4ac4a 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeMethodCommentInheritance.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeMethodCommentInheritance.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" //Method Comments Algorithm // diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration.java index 9d59fb5de669..0b973323f689 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Foo { int x = 2, y = 1; } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration2.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration2.java index 17e60f6d01c0..f5f3ddc0b774 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration2.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeMultiFieldDeclaration2.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" class Foo { int x = 2, y = 1; } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/addJavadoc/beforeRecord.java b/java/java-tests/testData/codeInsight/addJavadoc/beforeRecord.java index 6bbdc64149a3..ff0ae83b20d2 100644 --- a/java/java-tests/testData/codeInsight/addJavadoc/beforeRecord.java +++ b/java/java-tests/testData/codeInsight/addJavadoc/beforeRecord.java @@ -1,4 +1,4 @@ -// "Add Javadoc" "true" +// "Add Javadoc" "true-preview" record Test(int u) { diff --git a/platform/lang-impl/api-dump-unreviewed.txt b/platform/lang-impl/api-dump-unreviewed.txt index 6b2f7c00be66..bfae096874d9 100644 --- a/platform/lang-impl/api-dump-unreviewed.txt +++ b/platform/lang-impl/api-dump-unreviewed.txt @@ -2974,6 +2974,7 @@ f:com.intellij.codeInsight.editorActions.FixDocCommentAction - com.intellij.openapi.editor.actionSystem.EditorAction - sf:ACTION_ID:java.lang.String - ():V +- s:generateComment(com.intellij.psi.PsiElement,com.intellij.openapi.project.Project,com.intellij.modcommand.ModPsiNavigator):V - s:generateOrFixComment(com.intellij.psi.PsiElement,com.intellij.openapi.project.Project,com.intellij.openapi.editor.Editor):V f:com.intellij.codeInsight.editorActions.IndentTransferableData - com.intellij.codeInsight.editorActions.TextBlockTransferableData diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/FixDocCommentAction.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/FixDocCommentAction.java index d10a08855bf5..568f98e1bb1b 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/FixDocCommentAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/FixDocCommentAction.java @@ -9,18 +9,20 @@ import com.intellij.lang.*; import com.intellij.lang.documentation.CodeDocumentationProvider; import com.intellij.lang.documentation.CompositeDocumentationProvider; import com.intellij.lang.documentation.DocumentationProvider; +import com.intellij.modcommand.ModPsiNavigator; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Caret; -import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.ex.util.EditorUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; @@ -72,6 +74,47 @@ public final class FixDocCommentAction extends EditorAction { generateOrFixComment(elementAtOffset, project, editor); } + /** + * Generates a comment if it does not exist + * + * @param element target element for which a comment should be generated + * @param project current project + * @param navigator navigator to use to set caret position + */ + public static void generateComment(final @NotNull PsiElement element, final @NotNull Project project, final @NotNull ModPsiNavigator navigator) { + Language language = element.getLanguage(); + final CodeDocumentationProvider docProvider = getDocumentationProvider(language); + if (docProvider == null) { + return; + } + + final Pair pair = docProvider.parseContext(element); + if (pair == null || pair.second != null) { + return; + } + + Commenter c = LanguageCommenters.INSTANCE.forLanguage(language); + if (!(c instanceof CodeDocumentationAwareCommenter commenter)) { + return; + } + generateComment(pair.first, navigator, docProvider, commenter, project); + } + + private static @Nullable CodeDocumentationProvider getDocumentationProvider(Language language) { + final CodeDocumentationProvider docProvider; + final DocumentationProvider langDocumentationProvider = LanguageDocumentation.INSTANCE.forLanguage(language); + if (langDocumentationProvider instanceof CompositeDocumentationProvider provider) { + docProvider = provider.getFirstCodeDocumentationProvider(); + } + else if (langDocumentationProvider instanceof CodeDocumentationProvider provider) { + docProvider = provider; + } + else { + docProvider = null; + } + return docProvider; + } + /** * Generates comment if it's not exist or try to fix if exists * @@ -81,17 +124,7 @@ public final class FixDocCommentAction extends EditorAction { */ public static void generateOrFixComment(final @NotNull PsiElement element, final @NotNull Project project, final @NotNull Editor editor) { Language language = element.getLanguage(); - final CodeDocumentationProvider docProvider; - final DocumentationProvider langDocumentationProvider = LanguageDocumentation.INSTANCE.forLanguage(language); - if (langDocumentationProvider instanceof CompositeDocumentationProvider) { - docProvider = ((CompositeDocumentationProvider)langDocumentationProvider).getFirstCodeDocumentationProvider(); - } - else if (langDocumentationProvider instanceof CodeDocumentationProvider) { - docProvider = (CodeDocumentationProvider)langDocumentationProvider; - } - else { - docProvider = null; - } + final CodeDocumentationProvider docProvider = getDocumentationProvider(language); if (docProvider == null) { return; } @@ -107,7 +140,7 @@ public final class FixDocCommentAction extends EditorAction { } final Runnable task; if (pair.second == null || pair.second.getTextRange().isEmpty()) { - task = () -> generateComment(pair.first, editor, docProvider, commenter, project); + task = () -> generateComment(pair.first, EditorUtil.asPsiNavigator(editor), docProvider, commenter, project); } else { final DocCommentFixer fixer = DocCommentFixer.EXTENSION.forLanguage(language); @@ -133,19 +166,19 @@ public final class FixDocCommentAction extends EditorAction { * changes during the processing. * * @param anchor target element for which a comment should be generated - * @param editor target editor + * @param navigator navigator to use * @param commenter commenter to use * @param project current project */ private static void generateComment(@NotNull PsiElement anchor, - @NotNull Editor editor, + @NotNull ModPsiNavigator navigator, @NotNull CodeDocumentationProvider documentationProvider, @NotNull CodeDocumentationAwareCommenter commenter, - @NotNull Project project) - { - Document document = editor.getDocument(); + @NotNull Project project) { + Document document = anchor.getContainingFile().getFileDocument(); int commentStartOffset = anchor.getTextRange().getStartOffset(); int lineStartOffset = document.getLineStartOffset(document.getLineNumber(commentStartOffset)); + CharSequence charSequence = document.getCharsSequence(); if (lineStartOffset > 0 && lineStartOffset < commentStartOffset) { // Example: // void test1() { @@ -154,16 +187,17 @@ public final class FixDocCommentAction extends EditorAction { // // } // We want to insert the comment at the start of the line where 'test2()' is declared. - int nonWhiteSpaceOffset = CharArrayUtil.shiftBackward(document.getCharsSequence(), lineStartOffset, commentStartOffset - 1, " \t") + 1; + int nonWhiteSpaceOffset = CharArrayUtil.shiftBackward(charSequence, lineStartOffset, commentStartOffset - 1, " \t") + 1; commentStartOffset = Math.max(nonWhiteSpaceOffset, lineStartOffset); } int commentBodyRelativeOffset = 0; - int caretOffsetToSet = -1; + int caretLineOffset = 0; StringBuilder buffer = new StringBuilder(); String commentPrefix = commenter.getDocumentationCommentPrefix(); if (commentPrefix != null) { buffer.append(commentPrefix).append("\n"); + caretLineOffset++; commentBodyRelativeOffset += commentPrefix.length() + 1; } @@ -171,7 +205,6 @@ public final class FixDocCommentAction extends EditorAction { if (linePrefix != null) { buffer.append(linePrefix); commentBodyRelativeOffset += linePrefix.length(); - caretOffsetToSet = commentStartOffset + commentBodyRelativeOffset; } buffer.append("\n"); commentBodyRelativeOffset++; @@ -195,7 +228,6 @@ public final class FixDocCommentAction extends EditorAction { } String stub = documentationProvider.generateDocumentationContentStub(pair.second); - CaretModel caretModel = editor.getCaretModel(); if (stub != null) { int insertionOffset = commentStartOffset + commentBodyRelativeOffset; document.insertString(insertionOffset, stub); @@ -203,10 +235,8 @@ public final class FixDocCommentAction extends EditorAction { pair = documentationProvider.parseContext(anchor); } - if (caretOffsetToSet >= 0) { - caretModel.moveToOffset(caretOffsetToSet); - editor.getSelectionModel().removeSelection(); - } + navigator.moveCaretTo(commentStartOffset); + navigator.select(TextRange.from(commentStartOffset, 0)); if (pair == null || pair.second == null) { return; @@ -216,14 +246,14 @@ public final class FixDocCommentAction extends EditorAction { int end = pair.second.getTextRange().getEndOffset(); reformatCommentKeepingEmptyTags(anchor.getContainingFile(), project, start, end); - editor.getCaretModel().moveToOffset(document.getLineEndOffset(document.getLineNumber(editor.getCaretModel().getOffset()))); + int caretOffset = document.getLineEndOffset(document.getLineNumber(navigator.getCaretOffset()) + caretLineOffset); + navigator.moveCaretTo(caretOffset); - int caretOffset = caretModel.getOffset(); if (caretOffset > 0 && caretOffset <= document.getTextLength()) { - char c = document.getCharsSequence().charAt(caretOffset - 1); + char c = charSequence.charAt(caretOffset - 1); if (!StringUtil.isWhiteSpace(c)) { document.insertString(caretOffset, " "); - caretModel.moveToOffset(caretOffset + 1); + navigator.moveCaretTo(caretOffset + 1); } } }