deduplicate JavaParsingTestConfigurators

GitOrigin-RevId: 45f575f84c6d725976831f69d48a1f0338a4ec24
This commit is contained in:
Max Medvedev
2025-08-23 18:42:54 +00:00
committed by intellij-monorepo-bot
parent 5ceb77bfce
commit c024fa9240
4 changed files with 139 additions and 139 deletions
@@ -2,9 +2,8 @@
package com.intellij.java.frontback.psi.impl.syntax
import com.intellij.java.syntax.JavaSyntaxDefinition
import com.intellij.platform.syntax.SyntaxElementTypeSet
import com.intellij.platform.syntax.lexer.Lexer
import com.intellij.platform.syntax.LanguageSyntaxDefinition
import com.intellij.pom.java.LanguageLevel
import org.jetbrains.annotations.ApiStatus
internal class JavaSyntaxDefinitionExtension : LanguageSyntaxDefinition by JavaSyntaxDefinition
@ApiStatus.Internal
class JavaSyntaxDefinitionExtension : LanguageSyntaxDefinition by JavaSyntaxDefinition
@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// 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.java.parser;
import com.intellij.lang.ParserDefinition;
@@ -21,9 +21,11 @@ public interface AbstractBasicJavaParsingTestConfigurator {
PsiFile createPsiFile(@NotNull AbstractBasicJavaParsingTestCase thinJavaParsingTestCase,
@NotNull String name,
@NotNull String text,
@NotNull BasicJavaParserUtil.ParserWrapper parser);
@NotNull BasicJavaParserUtil.ParserWrapper parser);
boolean checkPsi();
void setLanguageLevel(@NotNull LanguageLevel level);
@NotNull LanguageLevel getLanguageLevel();
}
@@ -0,0 +1,125 @@
// 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.java.parser
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.java.frontback.psi.impl.syntax.JavaSyntaxDefinitionExtension
import com.intellij.lang.ASTNode
import com.intellij.lang.LanguageASTFactory
import com.intellij.lang.ParserDefinition
import com.intellij.lang.java.JavaLanguage
import com.intellij.lang.java.JavaParserDefinition
import com.intellij.lang.java.parser.BasicJavaParserUtil
import com.intellij.lang.java.parser.JavaParserUtil
import com.intellij.lang.java.syntax.JavaElementTypeConverterExtension
import com.intellij.platform.syntax.LanguageSyntaxDefinition
import com.intellij.platform.syntax.SyntaxElementType
import com.intellij.platform.syntax.parser.SyntaxTreeBuilder
import com.intellij.platform.syntax.psi.*
import com.intellij.pom.java.LanguageLevel
import com.intellij.psi.*
import com.intellij.psi.impl.source.PsiJavaFileImpl
import com.intellij.psi.impl.source.tree.FileElement
import com.intellij.psi.impl.source.tree.JavaASTFactory
import com.intellij.psi.tree.IFileElementType
import com.intellij.testFramework.LightVirtualFile
abstract class JavaParsingTestConfiguratorBase(
private var level: LanguageLevel,
) : AbstractBasicJavaParsingTestConfigurator {
override fun setUp(testCase: AbstractBasicJavaParsingTestCase) {
val java = JavaLanguage.INSTANCE
ElementTypeConverters.instance.let { elementTypeConverters ->
testCase.addExplicit(elementTypeConverters, java, JavaTestElementTypeConverterExtension())
testCase.addExplicit(elementTypeConverters, java, JavaElementTypeConverterExtension())
testCase.clearCachesOfLanguageExtension(java, elementTypeConverters)
}
LanguageASTFactory.INSTANCE.let { languageASTFactory ->
testCase.addExplicit(languageASTFactory, java, JavaASTFactory())
testCase.clearCachesOfLanguageExtension(java, languageASTFactory)
}
}
override fun getJavaParserDefinition(): ParserDefinition = JavaParserDefinition()
override fun getJavaSyntaxDefinition(): LanguageSyntaxDefinition = JavaSyntaxDefinitionExtension()
override fun setLanguageLevel(level: LanguageLevel) {
this.level = level
}
override fun getLanguageLevel(): LanguageLevel {
return level
}
override fun configure(file: PsiFile) {
file.putUserData(LanguageLevelKey.FILE_LANGUAGE_LEVEL_KEY, languageLevel)
LANGUAGE_LEVEL = languageLevel
}
override fun createPsiFile(
thinJavaParsingTestCase: AbstractBasicJavaParsingTestCase,
name: String,
text: String,
parser: BasicJavaParserUtil.ParserWrapper,
): PsiFile {
TEST_PARSER = parser
val virtualFile = LightVirtualFile("$name.java", JavaFileType.INSTANCE, text, -1)
val psiManager = PsiManager.getInstance(thinJavaParsingTestCase.getProject())
val viewProvider: FileViewProvider = SingleRootFileViewProvider(psiManager, virtualFile, true)
val file: PsiJavaFileImpl = MyTestPsiJavaFileImpl(viewProvider)
configure(file)
return file
}
}
private class MyIFileElementType : IFileElementType("test.java.file", JavaLanguage.INSTANCE) {
override fun parseContents(chameleon: ASTNode): ASTNode? {
val psiBuilder: PsiSyntaxBuilder = createBuilder(chameleon)
val builder = psiBuilder.getSyntaxTreeBuilder()
doParse(builder, TEST_PARSER!!)
val rootNode = psiBuilder.getTreeBuilt()
return rootNode.getFirstChildNode()
}
}
private fun createBuilder(chameleon: ASTNode?): PsiSyntaxBuilder {
val builder = JavaParserUtil.createSyntaxBuilder(chameleon).builder
builder.setDebugMode(true)
return builder
}
private fun doParse(builder: SyntaxTreeBuilder, parser: BasicJavaParserUtil.ParserWrapper) {
val root = builder.mark()
parser.parse(builder, LANGUAGE_LEVEL!!)
if (!builder.eof()) {
val unparsed = builder.mark()
while (!builder.eof()) builder.advanceLexer()
unparsed.error("Unparsed tokens")
}
root.done(mySyntaxElementType)
}
private var LANGUAGE_LEVEL: LanguageLevel? = null
private val mySyntaxElementType = SyntaxElementType("test.java.file")
val myTestFileElementType: IFileElementType = MyIFileElementType()
private var TEST_PARSER: BasicJavaParserUtil.ParserWrapper? = null
private val CONVERTER = elementTypeConverterOf(mySyntaxElementType to myTestFileElementType)
private class JavaTestElementTypeConverterExtension : ElementTypeConverterFactory {
override fun getElementTypeConverter(): ElementTypeConverter = CONVERTER
}
private class MyTestPsiJavaFileImpl(viewProvider: FileViewProvider) : PsiJavaFileImpl(viewProvider) {
override fun createFileElement(text: CharSequence): FileElement {
return FileElement(myTestFileElementType, text)
}
}
@@ -2,151 +2,25 @@
package com.intellij.java.parser;
import com.intellij.JavaTestUtil;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.java.frontback.psi.impl.syntax.JavaSyntaxDefinitionExtension;
import com.intellij.lang.ASTNode;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.lang.LanguageExtension;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.lang.java.parser.BasicJavaParserUtil;
import com.intellij.lang.java.parser.JavaParserUtil;
import com.intellij.lang.java.syntax.JavaElementTypeConverterExtension;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.impl.LanguageLevelProjectExtensionImpl;
import com.intellij.platform.syntax.LanguageSyntaxDefinition;
import com.intellij.platform.syntax.SyntaxElementType;
import com.intellij.platform.syntax.SyntaxElementTypeKt;
import com.intellij.platform.syntax.parser.SyntaxTreeBuilder;
import com.intellij.platform.syntax.psi.*;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.SingleRootFileViewProvider;
import com.intellij.psi.impl.source.PsiJavaFileImpl;
import com.intellij.psi.impl.source.tree.FileElement;
import com.intellij.psi.impl.source.tree.JavaASTFactory;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.util.PsiUtil;
import com.intellij.testFramework.LightVirtualFile;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull;
public class JavaParsingTestConfigurator implements AbstractBasicJavaParsingTestConfigurator {
private LanguageLevel myLanguageLevel = JavaTestUtil.getMaxRegisteredLanguageLevel();
@Override
public ParserDefinition getJavaParserDefinition() {
return new JavaParserDefinition();
public class JavaParsingTestConfigurator extends JavaParsingTestConfiguratorBase {
public JavaParsingTestConfigurator() {
super(JavaTestUtil.getMaxRegisteredLanguageLevel());
}
@Override
public LanguageSyntaxDefinition getJavaSyntaxDefinition() {
return new JavaSyntaxDefinitionExtension();
}
public void setUp(@NotNull AbstractBasicJavaParsingTestCase testCase) {
super.setUp(testCase);
@Override
public void setUp(@NotNull AbstractBasicJavaParsingTestCase thinJavaParsingTestCase) {
thinJavaParsingTestCase.getProject()
.registerService(LanguageLevelProjectExtension.class, new LanguageLevelProjectExtensionImpl(thinJavaParsingTestCase.getProject()));
JavaLanguage language = JavaLanguage.INSTANCE;
LanguageASTFactory languageASTFactory = LanguageASTFactory.INSTANCE;
thinJavaParsingTestCase.addExplicit(languageASTFactory, language, new JavaASTFactory());
LanguageExtension<ElementTypeConverterFactory> elementTypeConverters = ElementTypeConverters.getInstance();
thinJavaParsingTestCase.addExplicit(elementTypeConverters, language, new JavaElementTypeConverterExtension());
thinJavaParsingTestCase.addExplicit(elementTypeConverters, language, new JavaTestElementTypeConverterExtension());
thinJavaParsingTestCase.clearCachesOfLanguageExtension(language, languageASTFactory);
thinJavaParsingTestCase.clearCachesOfLanguageExtension(language, elementTypeConverters);
}
@Override
public void configure(@NotNull PsiFile file) {
file.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, myLanguageLevel);
LANGUAGE_LEVEL = myLanguageLevel;
}
private static final MyIFileElementType myTestFileElementType = new MyIFileElementType();
private static final SyntaxElementType mySyntaxElementType = SyntaxElementTypeKt.SyntaxElementType("test.java.file");
private static BasicJavaParserUtil.ParserWrapper TEST_PARSER;
private static LanguageLevel LANGUAGE_LEVEL;
@Override
public @NotNull PsiFile createPsiFile(@NotNull AbstractBasicJavaParsingTestCase thinJavaParsingTestCase,
@NotNull String name,
@NotNull String text,
BasicJavaParserUtil.@NotNull ParserWrapper parser) {
TEST_PARSER = parser;
LightVirtualFile virtualFile = new LightVirtualFile(name + '.' + "java", JavaFileType.INSTANCE, text, -1);
PsiManager psiManager = PsiManager.getInstance(thinJavaParsingTestCase.getProject());
FileViewProvider viewProvider = new SingleRootFileViewProvider(psiManager, virtualFile, true);
PsiJavaFileImpl file = new MyTestPsiJavaFileImpl(viewProvider);
configure(file);
return file;
testCase.getProject().registerService(LanguageLevelProjectExtension.class,
new LanguageLevelProjectExtensionImpl(testCase.getProject()));
}
@Override
public boolean checkPsi() {
return true;
}
@Override
public void setLanguageLevel(@NotNull com.intellij.pom.java.LanguageLevel level) {
myLanguageLevel = level;
}
private static PsiSyntaxBuilder createBuilder(ASTNode chameleon) {
PsiSyntaxBuilder builder = JavaParserUtil.createSyntaxBuilder(chameleon).getBuilder();
builder.setDebugMode(true);
return builder;
}
private static final class MyIFileElementType extends IFileElementType {
MyIFileElementType() {
super("test.java.file", JavaLanguage.INSTANCE);
}
@Override
public ASTNode parseContents(@NotNull ASTNode chameleon) {
PsiSyntaxBuilder psiBuilder = createBuilder(chameleon);
SyntaxTreeBuilder builder = psiBuilder.getSyntaxTreeBuilder();
SyntaxTreeBuilder.Marker root = builder.mark();
TEST_PARSER.parse(builder, LANGUAGE_LEVEL);
if (!builder.eof()) {
SyntaxTreeBuilder.@NotNull Marker unparsed = builder.mark();
while (!builder.eof()) builder.advanceLexer();
unparsed.error("Unparsed tokens");
}
root.done(mySyntaxElementType);
ASTNode rootNode = psiBuilder.getTreeBuilt();
return rootNode.getFirstChildNode();
}
}
private static final class JavaTestElementTypeConverterExtension implements ElementTypeConverterFactory {
private static final @NotNull ElementTypeConverter CONVERTER =
ElementTypeConverterKt.elementTypeConverterOf(new Pair<>(mySyntaxElementType, myTestFileElementType));
@Override
public @NotNull ElementTypeConverter getElementTypeConverter() {
return CONVERTER;
}
}
private static final class MyTestPsiJavaFileImpl extends PsiJavaFileImpl {
private MyTestPsiJavaFileImpl(@NotNull FileViewProvider viewProvider) { super(viewProvider); }
@NotNull
@Override
protected FileElement createFileElement(@NotNull CharSequence text) {
return new FileElement(myTestFileElementType, text);
}
}
}