From c024fa92401afa0534b28d80756e4e8e045382af Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 23 Aug 2025 15:39:52 +0200 Subject: [PATCH] deduplicate JavaParsingTestConfigurators GitOrigin-RevId: 45f575f84c6d725976831f69d48a1f0338a4ec24 --- .../syntax/JavaSyntaxDefinitionExtension.kt | 7 +- ...tractBasicJavaParsingTestConfigurator.java | 6 +- .../parser/JavaParsingTestConfiguratorBase.kt | 125 ++++++++++++++++ .../parser/JavaParsingTestConfigurator.java | 140 +----------------- 4 files changed, 139 insertions(+), 139 deletions(-) create mode 100644 java/java-frontback-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfiguratorBase.kt diff --git a/java/java-frontback-psi-impl/src/com/intellij/java/frontback/psi/impl/syntax/JavaSyntaxDefinitionExtension.kt b/java/java-frontback-psi-impl/src/com/intellij/java/frontback/psi/impl/syntax/JavaSyntaxDefinitionExtension.kt index 17f35ff0cc21..7b47aa610a82 100644 --- a/java/java-frontback-psi-impl/src/com/intellij/java/frontback/psi/impl/syntax/JavaSyntaxDefinitionExtension.kt +++ b/java/java-frontback-psi-impl/src/com/intellij/java/frontback/psi/impl/syntax/JavaSyntaxDefinitionExtension.kt @@ -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 \ No newline at end of file +@ApiStatus.Internal +class JavaSyntaxDefinitionExtension : LanguageSyntaxDefinition by JavaSyntaxDefinition \ No newline at end of file diff --git a/java/java-frontback-tests/testSrc/com/intellij/java/parser/AbstractBasicJavaParsingTestConfigurator.java b/java/java-frontback-tests/testSrc/com/intellij/java/parser/AbstractBasicJavaParsingTestConfigurator.java index f29ac2441f41..1921eb6c78aa 100644 --- a/java/java-frontback-tests/testSrc/com/intellij/java/parser/AbstractBasicJavaParsingTestConfigurator.java +++ b/java/java-frontback-tests/testSrc/com/intellij/java/parser/AbstractBasicJavaParsingTestConfigurator.java @@ -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(); } diff --git a/java/java-frontback-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfiguratorBase.kt b/java/java-frontback-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfiguratorBase.kt new file mode 100644 index 000000000000..27789d78c2fb --- /dev/null +++ b/java/java-frontback-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfiguratorBase.kt @@ -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) + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfigurator.java b/java/java-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfigurator.java index ec65a861ed16..e1dfadeab961 100644 --- a/java/java-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfigurator.java +++ b/java/java-tests/testSrc/com/intellij/java/parser/JavaParsingTestConfigurator.java @@ -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 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); - } - } }