mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
[javadoc] IDEA-285556 Support language injection into snippet
Fix injection for empty snippets. The range to inject is now starts after the colon and ends when the body ends. If no colon exist, then use the whole body as an injection point. GitOrigin-RevId: c7961f13c30212f52aad45a121bcf11b70ce8f2b
This commit is contained in:
committed by
intellij-monorepo-bot
parent
06c3a7e94f
commit
715e914e30
@@ -1,18 +1,17 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.psi.impl.source.javadoc;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.intellij.psi.JavaDocTokenType;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.tree.TreeUtil;
|
||||
import com.intellij.psi.javadoc.PsiSnippetDocTagBody;
|
||||
import com.intellij.psi.javadoc.PsiSnippetDocTagValue;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
public final class SnippetDocTagManipulator extends AbstractElementManipulator<PsiSnippetDocTagImpl> {
|
||||
|
||||
@Override
|
||||
@@ -30,21 +29,34 @@ public final class SnippetDocTagManipulator extends AbstractElementManipulator<P
|
||||
final PsiSnippetDocTagBody body = valueElement.getBody();
|
||||
if (body == null) return super.getRangeInElement(element);
|
||||
|
||||
Optional<PsiElement> first = Arrays.stream(body.getChildren())
|
||||
.filter(e -> e.getNode().getElementType() == JavaDocTokenType.DOC_COMMENT_DATA)
|
||||
.findFirst();
|
||||
if (!first.isPresent()) {
|
||||
return super.getRangeInElement(element);
|
||||
}
|
||||
final PsiElement start = first.get();
|
||||
PsiElement last = start;
|
||||
for (PsiElement e = start.getNextSibling(); e != null; e = e.getNextSibling()) {
|
||||
if (e.getNode().getElementType() == JavaDocTokenType.DOC_COMMENT_DATA) {
|
||||
last = e;
|
||||
}
|
||||
}
|
||||
final TextRange elementTextRange = element.getTextRange();
|
||||
return TextRange.from(start.getTextRange().getStartOffset() - elementTextRange.getStartOffset(),
|
||||
last.getTextRange().getEndOffset() - start.getTextRange().getStartOffset());
|
||||
final PsiElement[] children = body.getChildren();
|
||||
|
||||
final int startOffset;
|
||||
if (children.length == 0) {
|
||||
startOffset = body.getTextRange().getStartOffset();
|
||||
}
|
||||
else {
|
||||
final PsiElement colon = getColonElement(children);
|
||||
startOffset = colon.getTextRange().getEndOffset();
|
||||
}
|
||||
|
||||
final TextRange snippetRange = TextRange.create(startOffset, body.getTextRange().getEndOffset());
|
||||
|
||||
return snippetRange.shiftLeft(elementTextRange.getStartOffset());
|
||||
}
|
||||
|
||||
private static @NotNull PsiElement getColonElement(PsiElement@NotNull [] children) {
|
||||
final ASTNode node = children[0].getNode();
|
||||
if (node == JavaDocTokenType.DOC_TAG_VALUE_COLON) {
|
||||
return children[0];
|
||||
}
|
||||
|
||||
final ASTNode colonNode = TreeUtil.findSibling(node, JavaDocTokenType.DOC_TAG_VALUE_COLON);
|
||||
if (colonNode == null) {
|
||||
return children[0];
|
||||
}
|
||||
|
||||
return colonNode.getPsi();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* A simple program.
|
||||
* {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> :}
|
||||
*/
|
||||
class A {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* A simple program.
|
||||
* {<warning descr="'@snippet' tag is not available at this language level">@snippet</warning> :
|
||||
*
|
||||
* }
|
||||
*/
|
||||
class A {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// "JAVA" "true"
|
||||
|
||||
/**
|
||||
* {@snippet :<caret>}
|
||||
*/
|
||||
class InjectJava {}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "JAVA" "true"
|
||||
|
||||
/**
|
||||
* A simple program.
|
||||
* {@snippet :
|
||||
* <caret>
|
||||
* }
|
||||
*/
|
||||
class InjectJava {}
|
||||
@@ -129,6 +129,9 @@ public class JavadocHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testSnippet() { doTest(); }
|
||||
public void testSnippetMethod() { doTest(); }
|
||||
public void testSnippetInstructions() { doTest(); }
|
||||
public void testEmptySnippet() { doTest(); }
|
||||
public void testOnlyEmptyLinesInSnippet() { doTest(); }
|
||||
|
||||
|
||||
public void testIssueLinksInJavaDoc() {
|
||||
IssueNavigationConfiguration navigationConfiguration = IssueNavigationConfiguration.getInstance(getProject());
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.source.tree.injected.MyTestInjector;
|
||||
import com.intellij.psi.javadoc.PsiSnippetDocTag;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -22,8 +23,6 @@ public class JavadocSnippetInjectionTest extends LightQuickFixParameterizedTestC
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
MyTestInjector testInjector = new MyTestInjector(getPsiManager());
|
||||
testInjector.injectAll(getTestRootDisposable());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,8 +38,9 @@ public class JavadocSnippetInjectionTest extends LightQuickFixParameterizedTestC
|
||||
|
||||
@NotNull
|
||||
private Language getInjectedLanguage() {
|
||||
int offset = getEditor().getCaretModel().getPrimaryCaret().getOffset();
|
||||
final PsiSnippetDocTag snippet = (PsiSnippetDocTag) PsiUtilCore.getElementAtOffset(getFile(), offset).getParent();
|
||||
final int offset = getEditor().getCaretModel().getPrimaryCaret().getOffset();
|
||||
final PsiElement element = PsiUtilCore.getElementAtOffset(getFile(), offset);
|
||||
final PsiSnippetDocTag snippet = PsiTreeUtil.getParentOfType(element, PsiSnippetDocTag.class);
|
||||
final AtomicReference<PsiElement> injected = new AtomicReference<>();
|
||||
final InjectedLanguageManager injectionManager = InjectedLanguageManager.getInstance(getProject());
|
||||
injectionManager.enumerate(snippet, (injectedPsi, places) -> { injected.set(injectedPsi); });
|
||||
|
||||
Reference in New Issue
Block a user