AA standalone: introduce multi-module binary dependency test

This commit is contained in:
Jinseong Jeon
2023-11-19 00:00:53 -08:00
committed by teamcity
parent 3c775c4a42
commit 10c9b81c79
23 changed files with 339 additions and 76 deletions
@@ -0,0 +1,54 @@
/*
* Copyright 2010-2023 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.configurators.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.AbstractPsiDeclarationProviderMultiModuleBinaryTest;
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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("analysis/analysis-api/testData/standalone/multiModuleBinary")
@TestDataPath("$PROJECT_ROOT")
public class FirStandaloneNormalAnalysisLibraryBinaryModulePsiDeclarationProviderMultiModuleBinaryTestGenerated extends AbstractPsiDeclarationProviderMultiModuleBinaryTest {
@NotNull
@Override
public AnalysisApiTestConfigurator getConfigurator() {
return AnalysisApiFirStandaloneModeTestConfiguratorFactory.INSTANCE.createConfigurator(
new AnalysisApiTestConfiguratorFactoryData(
FrontendKind.Fir,
TestModuleKind.LibraryBinary,
AnalysisSessionMode.Normal,
AnalysisApiMode.Standalone
)
);
}
@Test
public void testAllFilesPresentInMultiModuleBinary() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/standalone/multiModuleBinary"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("multifileFacade.kt")
public void testMultifileFacade() throws Exception {
runTest("analysis/analysis-api/testData/standalone/multiModuleBinary/multifileFacade.kt");
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2023 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 org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest
import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider
import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
public abstract class AbstractPsiDeclarationProviderMultiModuleBinaryTest : AbstractAnalysisApiBasedTest() {
override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) {
val allKtFiles = moduleStructure.modules.flatMap {
testServices.ktModuleProvider.getModuleFiles(it).filterIsInstance<KtFile>()
}
val mainKtFile = allKtFiles.firstOrNull { it.name == "main.kt" } ?: allKtFiles.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 { psiForTest(it, element.project) }
psiElements.joinToString(separator = "\n") { TestPsiElementRenderer.render(it) }
}
val actual = "Resolved to:\n$resolvedTo"
testServices.assertions.assertEqualsToTestDataFileSibling(actual)
}
}
@@ -5,17 +5,8 @@
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.KtCallableSymbol
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
@@ -47,22 +38,6 @@ public abstract class AbstractPsiDeclarationProviderSingleModuleTest : AbstractA
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.psiForTest(symbol: KtSymbol, project: Project): PsiElement? {
return when (symbol.origin) {
KtSymbolOrigin.LIBRARY -> {
findPsi(symbol, project) ?: symbol.psi
}
KtSymbolOrigin.SUBSTITUTION_OVERRIDE, KtSymbolOrigin.INTERSECTION_OVERRIDE -> {
psiForTest((symbol as KtCallableSymbol).unwrapFakeOverrides, project)
}
else -> symbol.psi
}
}
private object Directives : SimpleDirectivesContainer() {
val UNRESOLVED_REFERENCE by directive(
"Reference should be unresolved",
@@ -0,0 +1,33 @@
/*
* Copyright 2010-2023 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.KtCallableSymbol
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.utils.unwrapMultiReferences
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.psi.KtFile
internal fun findReferencesAtCaret(mainKtFile: KtFile, caretPosition: Int): List<KtReference> =
mainKtFile.findReferenceAt(caretPosition)?.unwrapMultiReferences().orEmpty().filterIsInstance<KtReference>()
// Mimic [psiForUast] in FIR UAST
internal fun KtAnalysisSession.psiForTest(symbol: KtSymbol, project: Project): PsiElement? {
return when (symbol.origin) {
KtSymbolOrigin.LIBRARY -> {
findPsi(symbol, project) ?: symbol.psi
}
KtSymbolOrigin.SUBSTITUTION_OVERRIDE, KtSymbolOrigin.INTERSECTION_OVERRIDE -> {
psiForTest((symbol as KtCallableSymbol).unwrapFakeOverrides, project)
}
else -> symbol.psi
}
}
@@ -17,6 +17,11 @@ object AnalysisApiFirStandaloneModeTestConfiguratorFactory : AnalysisApiTestConf
AnalysisSessionMode.Dependent -> unsupportedModeError(data)
}
TestModuleKind.LibraryBinary -> when (data.analysisSessionMode) {
AnalysisSessionMode.Normal -> StandaloneModeLibraryBinaryTestConfigurator
AnalysisSessionMode.Dependent -> unsupportedModeError(data)
}
else -> {
unsupportedModeError(data)
}
@@ -29,10 +34,11 @@ object AnalysisApiFirStandaloneModeTestConfiguratorFactory : AnalysisApiTestConf
data.analysisSessionMode != AnalysisSessionMode.Normal -> false
data.analysisApiMode != AnalysisApiMode.Standalone -> false
else -> when (data.moduleKind) {
TestModuleKind.Source -> true
TestModuleKind.ScriptSource,
TestModuleKind.Source,
TestModuleKind.LibraryBinary,
TestModuleKind.LibrarySource,
-> true
TestModuleKind.ScriptSource,
TestModuleKind.LibrarySource
-> false
}
}
@@ -8,36 +8,16 @@ package org.jetbrains.kotlin.analysis.api.standalone.fir.test.configurators
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.SealedClassesInheritorsCaclulatorPreAnalysisHandler
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.configureOptionalTestCompilerPlugin
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.AnalysisApiFirSourceTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.preprocessors.ExternalAnnotationsSourcePreprocessor
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.ExternalAnnotationsEnvironmentConfigurator
object StandaloneModeConfigurator : AnalysisApiTestConfigurator() {
override val analyseInDependentSession: Boolean get() = false
override val frontendKind: FrontendKind get() = FrontendKind.Fir
override val testPrefix: String?
get() = "standalone.fir"
object StandaloneModeConfigurator : StandaloneModeConfiguratorBase() {
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
with(builder) {
useAdditionalService<KtModuleFactory> { KtSourceModuleFactory() }
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
configureOptionalTestCompilerPlugin()
useConfigurators(::ExternalAnnotationsEnvironmentConfigurator)
useSourcePreprocessor(::ExternalAnnotationsSourcePreprocessor)
}
sourceConfigurator.configureTest(builder, disposable)
}
private val sourceConfigurator = AnalysisApiFirSourceTestConfigurator(analyseInDependentSession = false)
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2023 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.configurators
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
abstract class StandaloneModeConfiguratorBase : AnalysisApiTestConfigurator() {
override val analyseInDependentSession: Boolean get() = false
override val frontendKind: FrontendKind get() = FrontendKind.Fir
override val testPrefix: String
get() = "standalone.fir"
}
@@ -0,0 +1,79 @@
/*
* Copyright 2010-2023 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.configurators
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiBaseTestServiceRegistrar
import org.jetbrains.kotlin.analysis.api.impl.base.test.configurators.AnalysisApiLibraryBaseTestServiceRegistrar
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.SealedClassesInheritorsCaclulatorPreAnalysisHandler
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.configureOptionalTestCompilerPlugin
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.KtLibraryBinaryModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtSourceModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory
import org.jetbrains.kotlin.analysis.test.framework.services.configuration.AnalysisApiJvmEnvironmentConfigurator
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.DispatchingTestModuleCompiler
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompiler
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleDecompiler
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleDecompilerJar
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.preprocessors.ExternalAnnotationsSourcePreprocessor
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.ExternalAnnotationsEnvironmentConfigurator
object StandaloneModeLibraryBinaryTestConfigurator : StandaloneModeConfiguratorBase() {
override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) {
with(builder) {
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
configureOptionalTestCompilerPlugin()
useConfigurators(::AnalysisApiJvmEnvironmentConfigurator)
useConfigurators(::ExternalAnnotationsEnvironmentConfigurator)
useSourcePreprocessor(::ExternalAnnotationsSourcePreprocessor)
useAdditionalService<KtModuleFactory> { KtCombinedModuleFactory() }
useAdditionalService<TestModuleCompiler> { DispatchingTestModuleCompiler() }
useAdditionalService<TestModuleDecompiler> { TestModuleDecompilerJar() }
}
}
override val serviceRegistrars: List<AnalysisApiTestServiceRegistrar>
get() = listOf(
AnalysisApiBaseTestServiceRegistrar,
AnalysisApiFirTestServiceRegistrar,
AnalysisApiLibraryBaseTestServiceRegistrar,
StandaloneModeTestServiceRegistrar,
)
override fun createModules(
moduleStructure: TestModuleStructure,
testServices: TestServices,
project: Project,
): KtModuleProjectStructure {
return TestModuleStructureFactory.createProjectStructureByTestStructure(moduleStructure, testServices, project)
}
}
private class KtCombinedModuleFactory : KtModuleFactory {
private val sourceModuleFactory = KtSourceModuleFactory()
private val libraryBinaryModuleFactory = KtLibraryBinaryModuleFactory()
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
return if (testModule.name == "app") {
sourceModuleFactory.createModule(testModule, testServices, project)
} else {
libraryBinaryModuleFactory.createModule(testModule, testServices, project)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -0,0 +1,31 @@
// MODULE: lib
// WITH_STDLIB
// FILE: src/my/collections/Maps.kt
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("MapsKt")
package my.collections
fun <K, V> myEmptyMap(): Map<K, V> = emptyMap()
// FILE: src/my/collections/jvm/MapsJVM.kt
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("MapsKt")
package my.collections
fun <K, V> myMapOf(vararg pairs: Pair<K, V>): Map<K, V> = mapOf(*pairs)
// MODULE: app
// DEPENDENCY: lib Binary
// FILE: main.kt
import my.collections.*
fun test() {
myMap<caret>Of<Int, String>(
2 to "2",
4 to "4",
)
}
@@ -0,0 +1,2 @@
Resolved to:
PsiMethod:myMapOf(vararg pairs: PsiType:Pair<? extends K, ? extends V>...): PsiType:Map<K, V>
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2023 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.test.framework.services.configuration
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider
import org.jetbrains.kotlin.test.model.DependencyDescription
import org.jetbrains.kotlin.test.services.ServiceRegistrationData
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.dependencyProvider
import org.jetbrains.kotlin.test.services.service
import java.io.File
class AnalysisApiJvmEnvironmentConfigurator(testServices: TestServices) : JvmEnvironmentConfigurator(testServices) {
override val additionalServices: List<ServiceRegistrationData>
get() = super.additionalServices + listOf(
service(::CompiledLibraryProvider),
)
override fun convertDependencyToFileList(dependency: DependencyDescription): List<File> {
val friendModule = testServices.dependencyProvider.getTestModule(dependency.moduleName)
testServices.compiledLibraryProvider.getCompiledLibrary(friendModule.name)?.artifact?.let {
return listOf(it.toFile())
}
return super.convertDependencyToFileList(dependency)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -22,6 +22,8 @@ class CompiledLibraryProvider(private val testServices: TestServices) : TestServ
return CompiledLibrary(libraryJar, librarySourcesJar).also { libraries[module.name] = it }
}
fun getCompiledLibrary(moduleName: String): CompiledLibrary? = libraries[moduleName]
}
val TestServices.compiledLibraryProvider: CompiledLibraryProvider by TestServices.testServiceAccessor()
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2023 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.
*/
@@ -56,7 +56,7 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator
)
}
private class KtLibraryBinaryModuleFactory : KtModuleFactory {
class KtLibraryBinaryModuleFactory : KtModuleFactory {
override fun createModule(testModule: TestModule, testServices: TestServices, project: Project): KtModuleWithFiles {
val library = testServices.compiledLibraryProvider.compileToLibrary(testModule).artifact
val decompiledFiles = testServices.testModuleDecompiler.getAllPsiFilesFromLibrary(library, project)
@@ -17,17 +17,15 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirT
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.*
import org.jetbrains.kotlin.analysis.test.framework.services.configuration.AnalysisApiJvmEnvironmentConfigurator
import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.ServiceRegistrationData
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import kotlin.contracts.contract
import kotlin.test.assertNotNull
object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator() {
override val analyseInDependentSession: Boolean get() = false
@@ -38,12 +36,11 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator
disposable: Disposable
) {
builder.apply {
useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider))
useAdditionalService<KtModuleFactory> { KtLibrarySourceModuleFactory() }
useAdditionalService<TestModuleCompiler> { DispatchingTestModuleCompiler() }
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
useConfigurators(::JvmEnvironmentConfigurator)
useConfigurators(::AnalysisApiJvmEnvironmentConfigurator)
}
}
@@ -11,7 +11,6 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles
import org.jetbrains.kotlin.analysis.low.level.api.fir.project.structure.LLFirBuiltinsSessionFactory
import org.jetbrains.kotlin.analysis.project.structure.KtBuiltinsModule
import org.jetbrains.kotlin.analysis.project.structure.KtModule
import org.jetbrains.kotlin.analysis.project.structure.KtNotUnderContentRootModule
import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.compiler.based.SealedClas
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirTestServiceRegistrar
import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.configureOptionalTestCompilerPlugin
import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory
import org.jetbrains.kotlin.analysis.test.framework.services.configuration.AnalysisApiJvmEnvironmentConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind
@@ -22,7 +23,6 @@ import org.jetbrains.kotlin.test.preprocessors.ExternalAnnotationsSourcePreproce
import org.jetbrains.kotlin.test.services.TestModuleStructure
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.ExternalAnnotationsEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
abstract class AnalysisApiFirSourceLikeTestConfigurator(override val analyseInDependentSession: Boolean) : AnalysisApiTestConfigurator() {
override val frontendKind: FrontendKind get() = FrontendKind.Fir
@@ -32,7 +32,8 @@ abstract class AnalysisApiFirSourceLikeTestConfigurator(override val analyseInDe
useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives)
usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler)
configureOptionalTestCompilerPlugin()
useConfigurators(::JvmEnvironmentConfigurator, ::ExternalAnnotationsEnvironmentConfigurator)
useConfigurators(::AnalysisApiJvmEnvironmentConfigurator)
useConfigurators(::ExternalAnnotationsEnvironmentConfigurator)
useSourcePreprocessor(::ExternalAnnotationsSourcePreprocessor)
}
}
@@ -57,6 +57,7 @@ private class KotlinStaticPsiDeclarationFromBinaryModuleProvider(
virtualFilesFromKotlinModule.ifEmpty { virtualFilesFromModule(binaryModule, fqName, isPackageName = true) }
}
}
.distinct()
.mapNotNull {
createClsJavaClassFromVirtualFile(it)
}
@@ -64,7 +64,7 @@ import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.test.util.joinToArrayString
import java.io.File
class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
open class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
companion object {
val TEST_CONFIGURATION_KIND_KEY = CompilerConfigurationKey.create<ConfigurationKind>("ConfigurationKind")
@@ -393,8 +393,8 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
val originalTarget = configuration[JVMConfigurationKeys.JVM_TARGET]
if (originalTarget == null || customDefaultTarget.majorVersion > originalTarget.majorVersion) {
// It's not safe to substitute target in general
// cause it can affect generated bytecode and original behaviour should be tested somehow.
// Original behaviour testing is perfomed by
// because it can affect generated bytecode and original behaviour should be tested somehow.
// Original behaviour testing is performed by
//
// codegenTest(target = 6, jvm = "Last", jdk = mostRecentJdk)
// codegenTest(target = 8, jvm = "Last", jdk = mostRecentJdk)
@@ -427,16 +427,15 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig
}
}
private fun List<DependencyDescription>.toFileList(): List<File> = this.flatMap { dependency ->
private fun List<DependencyDescription>.toFileList(): List<File> = this.flatMap(::convertDependencyToFileList)
protected open fun convertDependencyToFileList(dependency: DependencyDescription): List<File> {
val friendModule = testServices.dependencyProvider.getTestModule(dependency.moduleName)
listOfNotNull(
return listOfNotNull(
testServices.compiledClassesManager.getCompiledKotlinDirForModule(friendModule),
testServices.compiledClassesManager.getCompiledJavaDirForModule(friendModule)
)
}
}
// This should be used as a classpath entries when Java classes are being compiled/analyzed to become a binary/source dependencies of kt-files
@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.symbols.*
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractAnalysisApiSubstitutorsTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractBuiltInTypeTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.types.AbstractTypeByDeclarationReturnTypeTest
import org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider.AbstractPsiDeclarationProviderMultiModuleBinaryTest
import org.jetbrains.kotlin.analysis.api.standalone.fir.test.cases.components.psiDeclarationProvider.AbstractPsiDeclarationProviderSingleModuleTest
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode
import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode
@@ -109,6 +110,12 @@ internal fun AnalysisApiTestGroup.generateAnalysisApiTests() {
generateAnalysisApiNonComponentsTests()
generateResolveExtensionsTests()
}
group(
filter = testModuleKindIs(TestModuleKind.Source, TestModuleKind.ScriptSource, TestModuleKind.LibraryBinary) and
analysisApiModeIs(AnalysisApiMode.Standalone)
) {
generateAnalysisApiStandaloneTests()
}
}
private fun AnalysisApiTestGroup.generateResolveExtensionsTests() {
@@ -216,15 +223,25 @@ private fun AnalysisApiTestGroup.generateAnalysisApiNonComponentsTests() {
model(it, "typeSubstitution")
}
}
}
group("standalone", filter = analysisApiModeIs(AnalysisApiMode.Standalone)) {
test(AbstractPsiDeclarationProviderSingleModuleTest::class) {
private fun AnalysisApiTestGroup.generateAnalysisApiStandaloneTests() {
group("standalone") {
test(
AbstractPsiDeclarationProviderSingleModuleTest::class,
filter = testModuleKindIs(TestModuleKind.Source)
) {
model(it, "singleModule")
}
test(
AbstractPsiDeclarationProviderMultiModuleBinaryTest::class,
filter = testModuleKindIs(TestModuleKind.LibraryBinary)
) {
model(it, "multiModuleBinary")
}
}
}
private fun AnalysisApiTestGroup.generateAnalysisApiComponentsTests() {
component("callResolver", filter = analysisSessionModeIs(AnalysisSessionMode.Normal)) {
test(AbstractResolveCallTest::class) {