From e05667345c1fa3bb1a1c91c424077e51387cf534 Mon Sep 17 00:00:00 2001 From: Mathias Boulay Date: Thu, 12 Sep 2024 12:31:37 +0200 Subject: [PATCH] fix(javadoc): Missing character on new lines within snippets #IDEA-358874 Fixed GitOrigin-RevId: e03874f588e31c106d3a25518c05e0850b3fcd24 --- java/java-impl/src/META-INF/JavaPlugin.xml | 2 +- .../javadoc/JavaDocMarkdownEnterHandler.java | 12 +++++- .../javadoc/JavadocSnippetEnterHandler.java | 41 ++++++++----------- .../afterEnterInNonJavaSnippet.java | 15 +++++++ .../afterMarkdownEnterInNonJavaSnippet.java | 14 +++++++ .../beforeEnterInNonJavaSnippet.java | 14 +++++++ .../beforeMarkdownEnterInNonJavaSnippet.java | 13 ++++++ plugins/properties/src/META-INF/plugin.xml | 2 +- 8 files changed, 86 insertions(+), 27 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterEnterInNonJavaSnippet.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterMarkdownEnterInNonJavaSnippet.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeEnterInNonJavaSnippet.java create mode 100644 java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeMarkdownEnterInNonJavaSnippet.java diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml index 876b2ce67817..7f971ccc9b09 100644 --- a/java/java-impl/src/META-INF/JavaPlugin.xml +++ b/java/java-impl/src/META-INF/JavaPlugin.xml @@ -1172,7 +1172,7 @@ - + diff --git a/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java b/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java index 7ef8b8fdaf4b..95fa6636e276 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java +++ b/java/java-impl/src/com/intellij/javadoc/JavaDocMarkdownEnterHandler.java @@ -12,6 +12,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter { @@ -24,6 +25,16 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter { EditorActionHandler originalHandler) { if (!(file instanceof PsiJavaFile) || !file.isValid()) return Result.Continue; + return preProcessEnterImpl(file, editor, caretOffset, caretAdvance, dataContext, originalHandler); + } + + @ApiStatus.Internal + static Result preProcessEnterImpl(@NotNull PsiFile file, + @NotNull Editor editor, + @NotNull Ref caretOffset, + @NotNull Ref caretAdvance, + @NotNull DataContext dataContext, + EditorActionHandler originalHandler) { PsiElement caretElement = file.findElementAt(caretOffset.get()); if (caretElement == null) return Result.Continue; @@ -35,7 +46,6 @@ public class JavaDocMarkdownEnterHandler extends EnterHandlerDelegateAdapter { if (StringUtil.countChars(whitespaces, '\n', 0, end, false) > 0) { return Result.Continue; } - caretElement = caretElement.getPrevSibling(); } diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocSnippetEnterHandler.java b/java/java-impl/src/com/intellij/javadoc/JavadocSnippetEnterHandler.java index def88448796f..65b5ee885e93 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocSnippetEnterHandler.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocSnippetEnterHandler.java @@ -13,11 +13,7 @@ import com.intellij.openapi.editor.EditorModificationUtilEx; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.SmartPsiElementPointer; import com.intellij.psi.codeStyle.JavaCodeStyleSettings; -import com.intellij.psi.impl.source.javadoc.PsiSnippetDocTagImpl; -import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.javadoc.PsiSnippetDocTag; import com.intellij.psi.util.PsiUtil; import com.intellij.util.DocumentUtil; @@ -35,12 +31,17 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte @NotNull Ref caretAdvance, @NotNull DataContext dataContext, EditorActionHandler originalHandler) { - if (!(file instanceof PsiJavaFile) || !file.isValid()) return Result.Continue; + PsiSnippetDocTag docTag = getHost(file, editor); + if (docTag == null) return Result.Continue; - final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(file.getProject()); - final PsiSnippetDocTag host = ObjectUtils.tryCast(injectedLanguageManager.getInjectionHost(file), PsiSnippetDocTag.class); + if (PsiUtil.isInMarkdownDocComment(docTag)) { + // Markdown documentation has to be done in the preprocess, otherwise the file becomes invalid due to comment splitting + final Editor hostEditor = ((EditorWindow)editor).getDelegate(); + final CaretModel caretModelHost = hostEditor.getCaretModel(); - return host == null ? Result.Continue : Result.Default; + JavaDocMarkdownEnterHandler.preProcessEnterImpl(docTag.getContainingFile(), hostEditor, new Ref<>(caretModelHost.getOffset()), caretAdvance, dataContext, originalHandler); + } + return Result.Default; } @Override @@ -48,7 +49,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte @NotNull Editor editor, @NotNull DataContext dataContext) { final PsiSnippetDocTag host = getHost(file, editor); - if (host == null) return Result.Continue; + if (host == null || PsiUtil.isInMarkdownDocComment(host)) return Result.Continue; final Editor hostEditor = ((EditorWindow)editor).getDelegate(); final Document hostDocument = hostEditor.getDocument(); @@ -60,7 +61,7 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte int firstNonWsLineOffset = CharArrayUtil.shiftForward(hostDocument.getText(), lineStartOffset, " \t"); if (hostDocument.getText().charAt(firstNonWsLineOffset) != '*') { - final String prefix = calcPrefix(host, PsiUtil.isInMarkdownDocComment(InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file))); + final String prefix = calcPrefix(host); hostDocument.insertString(lineStartOffset, prefix); caretModelHost.moveToOffset(caretOffsetHost + prefix.length()); EditorModificationUtilEx.scrollToCaret(editor); @@ -70,21 +71,14 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte } private static @Nullable PsiSnippetDocTag getHost(@NotNull PsiFile file, @NotNull Editor editor) { - if (!(file instanceof PsiJavaFile) || !file.isValid()) return null; + if (!file.isValid()) return null; + if (!(editor instanceof EditorWindow)) return null; - if (!(editor instanceof EditorWindow)) { - return null; - } - - final SmartPsiElementPointer data = file.getUserData(FileContextUtil.INJECTED_IN_ELEMENT); - if (data == null) return null; - - final PsiSnippetDocTagImpl host = ObjectUtils.tryCast(data.getElement(), PsiSnippetDocTagImpl.class); - if (host == null) return null; - return host; + final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(file.getProject()); + return ObjectUtils.tryCast(injectedLanguageManager.getInjectionHost(file), PsiSnippetDocTag.class); } - private static String calcPrefix(PsiSnippetDocTag host, boolean markdownComment) { + private static String calcPrefix(PsiSnippetDocTag host) { final PsiFile file = host.getContainingFile(); final String text = file.getText(); @@ -96,10 +90,9 @@ public final class JavadocSnippetEnterHandler extends EnterHandlerDelegateAdapte } final String whitespacesPrefix = text.substring(offset + 1, asteriskOffset); - final JavaCodeStyleSettings settings = CodeStyle.getCustomSettings(file, JavaCodeStyleSettings.class); - return (settings.JD_LEADING_ASTERISKS_ARE_ENABLED && !markdownComment) ? whitespacesPrefix + "* " : whitespacesPrefix; + return (settings.JD_LEADING_ASTERISKS_ARE_ENABLED) ? whitespacesPrefix + "* " : whitespacesPrefix; } } \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterEnterInNonJavaSnippet.java b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterEnterInNonJavaSnippet.java new file mode 100644 index 000000000000..0fd1a093005b --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterEnterInNonJavaSnippet.java @@ -0,0 +1,15 @@ +// "_ignore" "true" + +class Main { + /** + * A simple program. + * {@snippet lang = Properties: + * local.timezone=PST + * # @highlight regex="[0-9]+" : + * local.zip=94123 + * local.area-code=415 + * + * } + */ + void f() {} +} diff --git a/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterMarkdownEnterInNonJavaSnippet.java b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterMarkdownEnterInNonJavaSnippet.java new file mode 100644 index 000000000000..dc5a51da9ec3 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/afterMarkdownEnterInNonJavaSnippet.java @@ -0,0 +1,14 @@ +// "_ignore" "true" + + +class Main { + /// Here are some example properties: + /// {@snippet lang = Properties: + /// local.timezone=PST + /// # @highlight regex="[0-9]+" : + /// local.zip=94123 + /// local.area-code=415 + /// + /// } + void foo() {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeEnterInNonJavaSnippet.java b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeEnterInNonJavaSnippet.java new file mode 100644 index 000000000000..e5c902f00a2a --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeEnterInNonJavaSnippet.java @@ -0,0 +1,14 @@ +// "_ignore" "true" + +class Main { + /** + * A simple program. + * {@snippet lang = Properties: + * local.timezone=PST + * # @highlight regex="[0-9]+" : + * local.zip=94123 + * local.area-code=415 + * } + */ + void f() {} +} diff --git a/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeMarkdownEnterInNonJavaSnippet.java b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeMarkdownEnterInNonJavaSnippet.java new file mode 100644 index 000000000000..8a7e6c519a39 --- /dev/null +++ b/java/java-tests/testData/codeInsight/javadoc/snippet/enterhandler/beforeMarkdownEnterInNonJavaSnippet.java @@ -0,0 +1,13 @@ +// "_ignore" "true" + + +class Main { + /// Here are some example properties: + /// {@snippet lang = Properties: + /// local.timezone=PST + /// # @highlight regex="[0-9]+" : + /// local.zip=94123 + /// local.area-code=415 + /// } + void foo() {} +} \ No newline at end of file diff --git a/plugins/properties/src/META-INF/plugin.xml b/plugins/properties/src/META-INF/plugin.xml index 324ac3900e52..472c352ac7dc 100644 --- a/plugins/properties/src/META-INF/plugin.xml +++ b/plugins/properties/src/META-INF/plugin.xml @@ -55,7 +55,7 @@ - +