[java] IDEA-365317 integrate JavaDocElementType

GitOrigin-RevId: 802edc372e67d3b8ce9e09fb33b1e554d47e20ac
This commit is contained in:
Mikhail Pyltsin
2025-11-20 12:44:52 +00:00
committed by intellij-monorepo-bot
parent 157598e83a
commit de186d1625
2 changed files with 134 additions and 43 deletions
@@ -18,6 +18,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.psi.impl.source.BasicJavaDocElementType.*;
import static com.intellij.psi.impl.source.tree.JavaDocElementType.ALL_JAVADOC_ELEMENTS;
import static com.intellij.util.text.CharArrayUtil.containsOnlyWhiteSpaces;
/**
@@ -192,8 +193,7 @@ public final class JavadocTypedHandler extends TypedHandlerDelegate {
ASTNode node = element.getNode();
return node != null
&& (JavaDocTokenType.ALL_JAVADOC_TOKENS.contains(node.getElementType())
|| BASIC_ALL_JAVADOC_ELEMENTS.contains(node.getElementType()));
&& (JavaDocTokenType.ALL_JAVADOC_TOKENS.contains(node.getElementType()));
}
private static boolean isTypeParamBracketClosedAfterParamTag(PsiDocTag tag, int bracketOffset) {
@@ -1,73 +1,81 @@
// Copyright 2000-2025 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.tree;
import com.intellij.java.syntax.element.JavaDocSyntaxElementType;
import com.intellij.java.syntax.lexer.JavaDocLexer;
import com.intellij.java.syntax.lexer.JavaLexer;
import com.intellij.java.syntax.lexer.JavaTypeEscapeLexer;
import com.intellij.java.syntax.parser.JavaDocParser;
import com.intellij.java.syntax.parser.JavaParser;
import com.intellij.lang.ASTNode;
import com.intellij.psi.impl.source.BasicJavaDocElementType;
import com.intellij.lang.Language;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.impl.source.javadoc.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.ParentProviderElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.tree.*;
import com.intellij.psi.tree.java.IJavaDocElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Set;
import java.util.function.Supplier;
/**
* @see com.intellij.java.syntax.element.JavaDocSyntaxElementType
*/
public interface JavaDocElementType {
final class JavaDocCompositeElementType extends BasicJavaDocElementType.JavaDocCompositeElementType {
private JavaDocCompositeElementType(@NonNls @NotNull String debugName, @NotNull Supplier<? extends ASTNode> nodeClass, IElementType parentElementType) {
super(debugName, nodeClass, parentElementType);
}
}
final class JavaDocCompositeElementType extends IJavaDocElementType implements
ICompositeElementType {
private final Supplier<? extends ASTNode> myConstructor;
final class JavaDocParentProviderElementType extends IJavaDocElementType implements ParentProviderElementType {
private final Set<IElementType> myParentElementTypes;
public JavaDocParentProviderElementType(@NotNull String debugName, @NotNull IElementType parentElementType) {
private JavaDocCompositeElementType(@NonNls @NotNull String debugName, @NotNull Supplier<? extends ASTNode> nodeClass) {
super(debugName);
myParentElementTypes = Collections.singleton(parentElementType);
this.myConstructor = nodeClass;
}
@Override
public @NotNull Set<IElementType> getParents() {
return myParentElementTypes;
public @NotNull ASTNode createCompositeNode() {
return myConstructor.get();
}
}
IElementType DOC_TAG = new JavaDocCompositeElementType("DOC_TAG", () -> new PsiDocTagImpl(), BasicJavaDocElementType.BASIC_DOC_TAG);
IElementType DOC_INLINE_TAG = new JavaDocCompositeElementType("DOC_INLINE_TAG", () -> new PsiInlineDocTagImpl(), BasicJavaDocElementType.BASIC_DOC_INLINE_TAG);
IElementType DOC_METHOD_OR_FIELD_REF = new JavaDocCompositeElementType("DOC_METHOD_OR_FIELD_REF", () -> new PsiDocMethodOrFieldRef(), BasicJavaDocElementType.BASIC_DOC_METHOD_OR_FIELD_REF);
IElementType DOC_FRAGMENT_REF = new JavaDocCompositeElementType("DOC_FRAGMENT_REF", () -> new PsiDocFragmentRefImpl(), BasicJavaDocElementType.BASIC_DOC_FRAGMENT_REF);
IElementType DOC_FRAGMENT_NAME = new JavaDocCompositeElementType("DOC_FRAGMENT_NAME", () -> new PsiDocFragmentNameImpl(), BasicJavaDocElementType.BASIC_DOC_FRAGMENT_NAME);
IElementType DOC_PARAMETER_REF = new JavaDocCompositeElementType("DOC_PARAMETER_REF", () -> new PsiDocParamRef(), BasicJavaDocElementType.BASIC_DOC_PARAMETER_REF);
IElementType DOC_TAG_VALUE_ELEMENT = new JavaDocParentProviderElementType("DOC_TAG_VALUE_ELEMENT", BasicJavaDocElementType.BASIC_DOC_TAG_VALUE_ELEMENT);
IElementType DOC_SNIPPET_TAG = new JavaDocCompositeElementType("DOC_SNIPPET_TAG", () -> new PsiSnippetDocTagImpl(), BasicJavaDocElementType.BASIC_DOC_SNIPPET_TAG);
IElementType DOC_SNIPPET_TAG_VALUE = new JavaDocCompositeElementType("DOC_SNIPPET_TAG_VALUE", () -> new PsiSnippetDocTagValueImpl(), BasicJavaDocElementType.BASIC_DOC_SNIPPET_TAG_VALUE);
IElementType DOC_SNIPPET_BODY = new JavaDocCompositeElementType("DOC_SNIPPET_BODY", () -> new PsiSnippetDocTagBodyImpl(), BasicJavaDocElementType.BASIC_DOC_SNIPPET_BODY);
IElementType DOC_SNIPPET_ATTRIBUTE = new JavaDocCompositeElementType("DOC_SNIPPET_ATTRIBUTE", () -> new PsiSnippetAttributeImpl(), BasicJavaDocElementType.BASIC_DOC_SNIPPET_ATTRIBUTE);
IElementType DOC_SNIPPET_ATTRIBUTE_LIST =
new JavaDocCompositeElementType("DOC_SNIPPET_ATTRIBUTE_LIST", () -> new PsiSnippetAttributeListImpl(), BasicJavaDocElementType.BASIC_DOC_SNIPPET_ATTRIBUTE_LIST);
IElementType DOC_SNIPPET_ATTRIBUTE_VALUE = new JavaDocParentProviderElementType("DOC_SNIPPET_ATTRIBUTE_VALUE", BasicJavaDocElementType.BASIC_DOC_SNIPPET_ATTRIBUTE_VALUE);
IElementType DOC_MARKDOWN_CODE_BLOCK = new JavaDocCompositeElementType("DOC_CODE_BLOCK", () -> new PsiMarkdownCodeBlockImpl(), BasicJavaDocElementType.BASIC_DOC_MARKDOWN_CODE_BLOCK);
IElementType DOC_MARKDOWN_REFERENCE_LINK = new JavaDocCompositeElementType("DOC_REFERENCE_LINK", () -> new PsiMarkdownReferenceLinkImpl(), BasicJavaDocElementType.BASIC_DOC_MARKDOWN_REFERENCE_LINK);
IElementType DOC_MARKDOWN_REFERENCE_LABEL = new JavaDocCompositeElementType("DOC_REFERENCE_LABEL", () -> new PsiMarkdownReferenceLabelImpl(), BasicJavaDocElementType.BASIC_DOC_MARKDOWN_REFERENCE_LABEL);
final class JavaDocParentProviderElementType extends IJavaDocElementType {
public JavaDocParentProviderElementType(@NotNull String debugName) {
super(debugName);
}
}
ILazyParseableElementType DOC_REFERENCE_HOLDER = new BasicJavaDocElementType.DocReferenceHolderElementType();
ILazyParseableElementType DOC_TYPE_HOLDER = new BasicJavaDocElementType.DocTypeHolderElementType();
ILazyParseableElementType DOC_COMMENT = new BasicJavaDocElementType.DocCommentElementType("DOC_COMMENT") {
IElementType DOC_TAG = new JavaDocCompositeElementType("DOC_TAG", () -> new PsiDocTagImpl());
IElementType DOC_INLINE_TAG = new JavaDocCompositeElementType("DOC_INLINE_TAG", () -> new PsiInlineDocTagImpl());
IElementType DOC_METHOD_OR_FIELD_REF = new JavaDocCompositeElementType("DOC_METHOD_OR_FIELD_REF", () -> new PsiDocMethodOrFieldRef());
IElementType DOC_FRAGMENT_REF = new JavaDocCompositeElementType("DOC_FRAGMENT_REF", () -> new PsiDocFragmentRefImpl());
IElementType DOC_FRAGMENT_NAME = new JavaDocCompositeElementType("DOC_FRAGMENT_NAME", () -> new PsiDocFragmentNameImpl());
IElementType DOC_PARAMETER_REF = new JavaDocCompositeElementType("DOC_PARAMETER_REF", () -> new PsiDocParamRef());
IElementType DOC_TAG_VALUE_ELEMENT = new JavaDocParentProviderElementType("DOC_TAG_VALUE_ELEMENT");
IElementType DOC_SNIPPET_TAG = new JavaDocCompositeElementType("DOC_SNIPPET_TAG", () -> new PsiSnippetDocTagImpl());
IElementType DOC_SNIPPET_TAG_VALUE = new JavaDocCompositeElementType("DOC_SNIPPET_TAG_VALUE", () -> new PsiSnippetDocTagValueImpl());
IElementType DOC_SNIPPET_BODY = new JavaDocCompositeElementType("DOC_SNIPPET_BODY", () -> new PsiSnippetDocTagBodyImpl());
IElementType DOC_SNIPPET_ATTRIBUTE = new JavaDocCompositeElementType("DOC_SNIPPET_ATTRIBUTE", () -> new PsiSnippetAttributeImpl());
IElementType DOC_SNIPPET_ATTRIBUTE_LIST =
new JavaDocCompositeElementType("DOC_SNIPPET_ATTRIBUTE_LIST", () -> new PsiSnippetAttributeListImpl());
IElementType DOC_SNIPPET_ATTRIBUTE_VALUE = new JavaDocParentProviderElementType("DOC_SNIPPET_ATTRIBUTE_VALUE");
IElementType DOC_MARKDOWN_CODE_BLOCK = new JavaDocCompositeElementType("DOC_CODE_BLOCK", () -> new PsiMarkdownCodeBlockImpl());
IElementType DOC_MARKDOWN_REFERENCE_LINK = new JavaDocCompositeElementType("DOC_REFERENCE_LINK", () -> new PsiMarkdownReferenceLinkImpl());
IElementType DOC_MARKDOWN_REFERENCE_LABEL = new JavaDocCompositeElementType("DOC_REFERENCE_LABEL", () -> new PsiMarkdownReferenceLabelImpl());
ILazyParseableElementType DOC_REFERENCE_HOLDER = new DocReferenceHolderElementType();
ILazyParseableElementType DOC_TYPE_HOLDER = new DocTypeHolderElementType();
ILazyParseableElementType DOC_COMMENT = new DocCommentElementType("DOC_COMMENT") {
@Override
public ASTNode createNode(final CharSequence text) {
return new PsiDocCommentImpl(text);
}
};
ILazyParseableElementType DOC_MARKDOWN_COMMENT = new BasicJavaDocElementType.DocCommentElementType("DOC_MARKDOWN_COMMENT") {
ILazyParseableElementType DOC_MARKDOWN_COMMENT = new DocCommentElementType("DOC_MARKDOWN_COMMENT") {
@Override
public ASTNode createNode(final CharSequence text) {
return new PsiDocCommentImpl(text, true);
@@ -80,4 +88,87 @@ public interface JavaDocElementType {
@SuppressWarnings("unused") // used in plugins
TokenSet ALL_JAVADOC_ELEMENTS = TokenSet.create(DOC_TAG, DOC_INLINE_TAG, DOC_METHOD_OR_FIELD_REF, DOC_PARAMETER_REF, DOC_TAG_VALUE_ELEMENT,
DOC_REFERENCE_HOLDER, DOC_TYPE_HOLDER, DOC_COMMENT, DOC_MARKDOWN_COMMENT);
class JavaDocLazyElementType extends ILazyParseableElementType {
private JavaDocLazyElementType(final @NonNls String debugName) {
super(debugName, JavaLanguage.INSTANCE);
}
@Override
public ASTNode createNode(CharSequence text) {
return new LazyParseablePsiElement(this, text);
}
}
final class DocReferenceHolderElementType extends JavaDocLazyElementType {
public DocReferenceHolderElementType() {
super("DOC_REFERENCE_HOLDER");
}
@Override
public @Nullable ASTNode parseContents(final @NotNull ASTNode chameleon) {
return JavaParserUtil.parseFragment(
chameleon,
(builder, languageLevel) -> {
new JavaDocParser(builder, languageLevel).parseJavadocReference(new JavaParser(languageLevel));
},
false,
LanguageLevel.JDK_1_3);
}
}
final class DocTypeHolderElementType extends JavaDocLazyElementType {
public DocTypeHolderElementType() {
super("DOC_TYPE_HOLDER");
}
@Override
public @Nullable ASTNode parseContents(final @NotNull ASTNode chameleon) {
return JavaParserUtil.parseFragment(
chameleon,
(builder, languageLevel) -> {
new JavaDocParser(builder, languageLevel).parseJavadocType(new JavaParser(languageLevel));
},
false,
LanguageLevel.JDK_1_3,
level -> new JavaTypeEscapeLexer(new JavaLexer(level))
);
}
}
abstract class DocCommentElementType extends IReparseableElementType {
private final JavaParserUtil.ParserWrapper myParser;
public DocCommentElementType(String debugName) {
super(debugName, JavaLanguage.INSTANCE);
myParser = (builder, languageLevel) -> new JavaDocParser(builder, languageLevel).parseDocCommentText();
}
@Override
public @Nullable ASTNode parseContents(final @NotNull ASTNode chameleon) {
return JavaParserUtil.parseFragmentWithHighestLanguageLevel(chameleon, myParser, JavaDocLexer::new);
}
@Override
public boolean isReparseable(@NotNull ASTNode currentNode,
@NotNull CharSequence newText,
@NotNull Language fileLanguage,
@NotNull Project project) {
if (!StringUtil.startsWith(newText, "/**") || !StringUtil.endsWith(newText, "*/")) return false;
LanguageLevel level = LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
JavaLexer lexer = new JavaLexer(level);
lexer.start(newText);
if (lexer.getTokenType() == JavaDocSyntaxElementType.DOC_COMMENT) {
lexer.advance();
return lexer.getTokenType() == null;
}
return false;
}
}
}