From 846ab7d97bbf5c7ff15041f2f892448d58b691c0 Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 9 Aug 2022 02:03:41 -0700 Subject: [PATCH] AA: revamp standalone-mode tests --- ...edPsiDeclarationProviderTestGenerated.java | 66 ++++++++++++++++++ .../fir/test/StandaloneModeConfigurator.kt | 3 +- .../StandaloneModeTestServiceRegistrar.kt | 45 ++++++++++++ ...actDecompiledPsiDeclarationProviderTest.kt | 68 +++++++++++++++++++ .../TestPsiElementRenderer.kt | 16 +++++ .../standalone/singleModule/multipleFiles.txt | 1 - .../standalone/singleModule/singleFile.txt | 1 - .../testData/standalone/singleModule/todo.txt | 2 +- ...bstractAnalysisApiBasedSingleModuleTest.kt | 4 -- .../tests/analysis/api/analysisApi.kt | 7 ++ .../analysis/api/dsl/AnalysisApiTestGroup.kt | 6 +- 11 files changed, 208 insertions(+), 11 deletions(-) create mode 100644 analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/psiDeclarationProvider/FirStandaloneNormalAnalysisSourceModuleDecompiledPsiDeclarationProviderTestGenerated.java create mode 100644 analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeTestServiceRegistrar.kt create mode 100644 analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/AbstractDecompiledPsiDeclarationProviderTest.kt create mode 100644 analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/TestPsiElementRenderer.kt diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/psiDeclarationProvider/FirStandaloneNormalAnalysisSourceModuleDecompiledPsiDeclarationProviderTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/psiDeclarationProvider/FirStandaloneNormalAnalysisSourceModuleDecompiledPsiDeclarationProviderTestGenerated.java new file mode 100644 index 00000000000..3bfb61adf1e --- /dev/null +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/psiDeclarationProvider/FirStandaloneNormalAnalysisSourceModuleDecompiledPsiDeclarationProviderTestGenerated.java @@ -0,0 +1,66 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.generated.cases.components.psiDeclarationProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.standalone.fir.test.AnalysisApiFirStandaloneModeTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider.AbstractDecompiledPsiDeclarationProviderTest; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/standalone/singleModule") +@TestDataPath("$PROJECT_ROOT") +public class FirStandaloneNormalAnalysisSourceModuleDecompiledPsiDeclarationProviderTestGenerated extends AbstractDecompiledPsiDeclarationProviderTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirStandaloneModeTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Normal, + AnalysisApiMode.Standalone + ) + ); + } + + @Test + public void testAllFilesPresentInSingleModule() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/standalone/singleModule"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("multipleFiles.kt") + public void testMultipleFiles() throws Exception { + runTest("analysis/analysis-api/testData/standalone/singleModule/multipleFiles.kt"); + } + + @Test + @TestMetadata("singleFile.kt") + public void testSingleFile() throws Exception { + runTest("analysis/analysis-api/testData/standalone/singleModule/singleFile.kt"); + } + + @Test + @TestMetadata("todo.kt") + public void testTodo() throws Exception { + runTest("analysis/analysis-api/testData/standalone/singleModule/todo.kt"); + } +} diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt index 6d158153494..6547a2c3bf0 100644 --- a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeConfigurator.kt @@ -26,7 +26,8 @@ object StandaloneModeConfigurator : AnalysisApiTestConfigurator() { } override val serviceRegistrars: List - get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars + get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars + + listOf(StandaloneModeTestServiceRegistrar) override fun createModules( moduleStructure: TestModuleStructure, diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeTestServiceRegistrar.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeTestServiceRegistrar.kt new file mode 100644 index 00000000000..f300d103f0f --- /dev/null +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/StandaloneModeTestServiceRegistrar.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.standalone.fir.test + +import com.intellij.mock.MockApplication +import com.intellij.mock.MockProject +import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem +import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory +import org.jetbrains.kotlin.analysis.decompiled.light.classes.ClsJavaStubByVirtualFileCache +import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider +import org.jetbrains.kotlin.analysis.providers.KotlinPsiDeclarationProviderFactory +import org.jetbrains.kotlin.analysis.providers.impl.KotlinStaticPsiDeclarationProviderFactory +import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar +import org.jetbrains.kotlin.test.services.TestServices + +object StandaloneModeTestServiceRegistrar : AnalysisApiTestServiceRegistrar() { + override fun registerProjectExtensionPoints(project: MockProject, testServices: TestServices) { + } + + override fun registerProjectServices(project: MockProject, testServices: TestServices) { + val projectStructureProvider = project.getService(ProjectStructureProvider::class.java) + val binaryModules = projectStructureProvider.getKtBinaryModules().toList() + val projectEnvironment = testServices.environmentManager.getProjectEnvironment() + val binaryRoots = StandaloneProjectFactory.getAllBinaryRoots(binaryModules, projectEnvironment) + project.apply { + registerService(ClsJavaStubByVirtualFileCache::class.java, ClsJavaStubByVirtualFileCache()) + registerService( + KotlinPsiDeclarationProviderFactory::class.java, + KotlinStaticPsiDeclarationProviderFactory( + this, + StandaloneProjectFactory.createPackagePartsProvider(project, binaryRoots), + binaryModules, + projectEnvironment.environment.jarFileSystem as CoreJarFileSystem + ) + ) + } + } + + override fun registerApplicationServices(application: MockApplication, testServices: TestServices) { + } +} \ No newline at end of file diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/AbstractDecompiledPsiDeclarationProviderTest.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/AbstractDecompiledPsiDeclarationProviderTest.kt new file mode 100644 index 00000000000..6ba75b3088d --- /dev/null +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/AbstractDecompiledPsiDeclarationProviderTest.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider + +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin +import org.jetbrains.kotlin.analysis.providers.DecompiledPsiDeclarationProvider.findPsi +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedSingleModuleTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider +import org.jetbrains.kotlin.analysis.test.framework.utils.unwrapMultiReferences +import org.jetbrains.kotlin.idea.references.KtReference +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.assertions + +abstract class AbstractDecompiledPsiDeclarationProviderTest : AbstractAnalysisApiBasedSingleModuleTest() { + override fun doTestByFileStructure(ktFiles: List, module: TestModule, testServices: TestServices) { + val mainKtFile = ktFiles.singleOrNull() ?: ktFiles.firstOrNull { it.name == "main.kt" } ?: ktFiles.first() + val caretPosition = testServices.expressionMarkerProvider.getCaretPosition(mainKtFile) + val ktReferences = findReferencesAtCaret(mainKtFile, caretPosition) + if (ktReferences.isEmpty()) { + testServices.assertions.fail { "No references at caret found" } + } + + val element = ktReferences.first().element + val resolvedTo = + analyseForTest(element) { + val symbols = ktReferences.flatMap { it.resolveToSymbols() } + val psiElements = symbols.mapNotNull { psiForDecompiled(it, element.project) } + psiElements.joinToString(separator = "\n") { TestPsiElementRenderer.render(it) } + } + + if (Directives.UNRESOLVED_REFERENCE in module.directives) { + return + } + + val actual = "Resolved to:\n$resolvedTo" + testServices.assertions.assertEqualsToTestDataFileSibling(actual) + } + + private fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List = + mainKtFile.findReferenceAt(caretPosition)?.unwrapMultiReferences().orEmpty().filterIsInstance() + + // Mimic [psiForUast] in FIR UAST + private fun KtAnalysisSession.psiForDecompiled(symbol: KtSymbol, project: Project): PsiElement? { + return when (symbol.origin) { + KtSymbolOrigin.LIBRARY -> { + findPsi(symbol, project) + } + // NB: This test is checking declarations from libraries (hence decompiled stub) only + else -> null + } + } + + private object Directives : SimpleDirectivesContainer() { + val UNRESOLVED_REFERENCE by directive( + "Reference should be unresolved", + ) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/TestPsiElementRenderer.kt b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/TestPsiElementRenderer.kt new file mode 100644 index 00000000000..65c187bb102 --- /dev/null +++ b/analysis/analysis-api-standalone/tests/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/components/psiDeclarationProvider/TestPsiElementRenderer.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtElement + +object TestPsiElementRenderer { + fun render(psiElement: PsiElement): String = when (psiElement) { + is KtElement -> psiElement.text + else -> psiElement.toString() + } +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/standalone/singleModule/multipleFiles.txt b/analysis/analysis-api/testData/standalone/singleModule/multipleFiles.txt index 18d920f4ac8..5450dae9b91 100644 --- a/analysis/analysis-api/testData/standalone/singleModule/multipleFiles.txt +++ b/analysis/analysis-api/testData/standalone/singleModule/multipleFiles.txt @@ -1,2 +1 @@ Resolved to: -0: (in test.pkg.ColorSpace.Companion) internal const val MinId: kotlin.Int diff --git a/analysis/analysis-api/testData/standalone/singleModule/singleFile.txt b/analysis/analysis-api/testData/standalone/singleModule/singleFile.txt index 0c4b9135fe5..5450dae9b91 100644 --- a/analysis/analysis-api/testData/standalone/singleModule/singleFile.txt +++ b/analysis/analysis-api/testData/standalone/singleModule/singleFile.txt @@ -1,2 +1 @@ Resolved to: -0: (in test.MyAnno) constructor() diff --git a/analysis/analysis-api/testData/standalone/singleModule/todo.txt b/analysis/analysis-api/testData/standalone/singleModule/todo.txt index f3436bcd847..4f08d159515 100644 --- a/analysis/analysis-api/testData/standalone/singleModule/todo.txt +++ b/analysis/analysis-api/testData/standalone/singleModule/todo.txt @@ -1,2 +1,2 @@ Resolved to: -0: (in kotlin) inline fun TODO(reason: kotlin.String): kotlin.Nothing +PsiMethod:TODO \ No newline at end of file diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt index 40a8ef16bdd..59f7f39febb 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedSingleModuleTest.kt @@ -5,11 +5,7 @@ package org.jetbrains.kotlin.analysis.test.framework.base -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.util.Computable -import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider -import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestModuleStructure diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt index c3350db46cd..43721a0d104 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSy import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSymbolByPsiTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.AbstractSymbolByReferenceTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest +import org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider.AbstractDecompiledPsiDeclarationProviderTest import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind @@ -137,6 +138,12 @@ private fun AnalysisApiTestGroup.generateAnalysisApiNonComponentsTests() { model("typeSubstitution") } } + + group("standalone", filter = analysisApiModeIs(AnalysisApiMode.Standalone)) { + test(AbstractDecompiledPsiDeclarationProviderTest::class) { + model("singleModule") + } + } } diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt index ee26830a4a5..667189b870a 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/dsl/AnalysisApiTestGroup.kt @@ -93,14 +93,14 @@ private fun getTestNameSuffix(data: AnalysisApiTestConfiguratorFactoryData): Str private fun getPackageName(data: AnalysisApiTestConfiguratorFactoryData, testClass: KClass<*>): String { val basePrefix = buildString { append("org.jetbrains.kotlin.analysis.api.") - if (data.analysisApiMode ==AnalysisApiMode.Standalone) { + if (data.analysisApiMode == AnalysisApiMode.Standalone) { append("standalone.") } append(data.frontend.suffix.lowercase()) append(".test.cases.generated") } - val packagePrefix = testClass.java.name - .substringAfter("org.jetbrains.kotlin.analysis.api.impl.base.test.") + val packagePrefix = "cases." + testClass.java.name + .substringAfter("test.cases.") .substringBeforeLast('.', "") return if (packagePrefix.isEmpty()) "$basePrefix." else "$basePrefix.$packagePrefix."