AA: revamp standalone-mode tests

This commit is contained in:
Jinseong Jeon
2022-08-09 02:03:41 -07:00
committed by Ilya Kirillov
parent ab6964d32e
commit 846ab7d97b
11 changed files with 208 additions and 11 deletions
@@ -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");
}
}
@@ -26,7 +26,8 @@ object StandaloneModeConfigurator : AnalysisApiTestConfigurator() {
}
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars
get() = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false).serviceRegistrars +
listOf(StandaloneModeTestServiceRegistrar)
override fun createModules(
moduleStructure: TestModuleStructure,
@@ -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) {
}
}
@@ -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<KtFile>, 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<KtReference> =
mainKtFile.findReferenceAt(caretPosition)?.unwrapMultiReferences().orEmpty().filterIsInstance<KtReference>()
// 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",
)
}
}
@@ -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()
}
}
@@ -1,2 +1 @@
Resolved to:
0: (in test.pkg.ColorSpace.Companion) internal const val MinId: kotlin.Int
@@ -1,2 +1 @@
Resolved to:
0: (in test.MyAnno) constructor()
@@ -1,2 +1,2 @@
Resolved to:
0: (in kotlin) inline fun TODO(reason: kotlin.String): kotlin.Nothing
PsiMethod:TODO
@@ -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
@@ -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")
}
}
}
@@ -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."