fix(javadoc): Missing character on new lines within snippets

#IDEA-358874 Fixed

GitOrigin-RevId: e03874f588e31c106d3a25518c05e0850b3fcd24
This commit is contained in:
Mathias Boulay
2024-09-12 12:31:37 +02:00
committed by intellij-monorepo-bot
parent f5cfb35bc8
commit e05667345c
8 changed files with 86 additions and 27 deletions

View File

@@ -1172,7 +1172,7 @@
<testFinder implementation="com.intellij.testIntegration.JavaTestFinder"/>
<filePasteProvider implementation="com.intellij.ide.JavaFilePasteProvider" order="before fileList"/>
<enterHandlerDelegate implementation="com.intellij.javadoc.EnterInJavadocParamDescriptionHandler"/>
<enterHandlerDelegate implementation="com.intellij.javadoc.JavadocSnippetEnterHandler" order="before EnterBetweenBracesHandler"/>
<enterHandlerDelegate implementation="com.intellij.javadoc.JavadocSnippetEnterHandler" order="before EnterBetweenBracesHandler, before EnterInPropertiesFileHandler"/>
<enterHandlerDelegate implementation="com.intellij.javadoc.JavaDocMarkdownEnterHandler" order="after EnterInLineCommentHandler" />
<editorNavigation implementation="com.intellij.javadoc.JavadocNavigationDelegate"/>
<methodNavigationOffsetProvider implementation="com.intellij.codeInsight.navigation.JavaMethodNavigationOffsetProvider"/>

View File

@@ -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<Integer> caretOffset,
@NotNull Ref<Integer> 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();
}

View File

@@ -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<Integer> 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;
}
}

View File

@@ -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() {}
}

View File

@@ -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() {}
}

View File

@@ -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<caret>
* }
*/
void f() {}
}

View File

@@ -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<caret>
/// }
void foo() {}
}

View File

@@ -55,7 +55,7 @@
<lang.ast.factory language="Properties" implementationClass="com.intellij.lang.properties.psi.impl.PropertiesASTFactory"/>
<joinLinesHandler implementation="com.intellij.lang.properties.PropertiesJoinLinesHandler"/>
<enterHandlerDelegate implementation="com.intellij.lang.properties.EnterInPropertiesFileHandler"/>
<enterHandlerDelegate implementation="com.intellij.lang.properties.EnterInPropertiesFileHandler" id="EnterInPropertiesFileHandler"/>
<lang.syntaxHighlighter language="Properties" implementationClass="com.intellij.lang.properties.PropertiesHighlighter"/>
<lang.parserDefinition language="Properties" implementationClass="com.intellij.lang.properties.parsing.PropertiesParserDefinition"/>