Analysis API FIR: introduce library resolve tests

This commit is contained in:
Ilya Kirillov
2022-01-25 16:46:43 +01:00
parent 96e1f1e7d4
commit caddbda01b
22 changed files with 1784 additions and 128 deletions
@@ -37,6 +37,8 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolBy
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByPsiTest
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByReferenceTest
import org.jetbrains.kotlin.generators.TestGroupSuite
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.*
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.TestModuleKind
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.component
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.group
import org.jetbrains.kotlin.generators.tests.analysis.api.dsl.test
@@ -50,6 +52,7 @@ fun TestGroupSuite.generateAnalysisApiTests() {
private fun TestGroupSuite.generateAnalysisApiNonComponentsTests() {
test(
AbstractReferenceResolveTest::class,
testModuleKinds = TestModuleKind.SOURCES_AND_LIBRARIES_SOURCES,
addFe10 = false,
) {
model("referenceResolve", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
@@ -6,8 +6,6 @@
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
import org.jetbrains.annotations.NotNull
import org.jetbrains.kotlin.analysis.api.descriptors.test.KtFe10FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.generators.MethodGenerator
import org.jetbrains.kotlin.generators.model.MethodModel
@@ -25,7 +23,7 @@ object FrontendConfiguratorTestGenerator : MethodGenerator<FrontendConfiguratorT
override fun generateBody(method: FrontendConfiguratorTestModel, p: Printer): Unit = with(p) {
print("return ")
printWithNoIndent(method.frontendConfiguratorType.configuratorClass.simpleName)
printWithNoIndent(method.frontendConfiguratorClass.simpleName)
printWithNoIndent(".INSTANCE")
printlnWithNoIndent(";")
}
@@ -33,7 +31,7 @@ object FrontendConfiguratorTestGenerator : MethodGenerator<FrontendConfiguratorT
object FrontendConfiguratorTestModelKind : MethodModel.Kind()
class FrontendConfiguratorTestModel(val frontendConfiguratorType: FrontendConfiguratorType) : MethodModel {
class FrontendConfiguratorTestModel(val frontendConfiguratorClass: KClass<out FrontendApiTestConfiguratorService>) : MethodModel {
override val kind: MethodModel.Kind get() = FrontendConfiguratorTestModelKind
override val name: String get() = "getConfigurator"
override val dataString: String? get() = null
@@ -46,12 +44,7 @@ class FrontendConfiguratorTestModel(val frontendConfiguratorType: FrontendConfig
return buildList {
add(NotNull::class.java)
add(FrontendApiTestConfiguratorService::class.java)
add(frontendConfiguratorType.configuratorClass.java)
add(frontendConfiguratorClass.java)
}
}
enum class FrontendConfiguratorType(val configuratorClass: KClass<out FrontendApiTestConfiguratorService>) {
FIR(FirFrontendApiTestConfiguratorService::class),
FE10(KtFe10FrontendApiTestConfiguratorService::class);
}
}
@@ -5,16 +5,39 @@
package org.jetbrains.kotlin.generators.tests.analysis.api.dsl
import org.jetbrains.kotlin.analysis.api.descriptors.test.KtFe10FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.binary.LibraryFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.fir.utils.libraries.source.LibrarySourceFrontendApiTestConfiguratorService
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
import org.jetbrains.kotlin.generators.TestGroup
import org.jetbrains.kotlin.generators.TestGroupSuite
import org.jetbrains.kotlin.generators.getDefaultSuiteTestClassName
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import kotlin.reflect.KClass
internal class FirAndFe10TestGroup(
val suite: TestGroupSuite,
val directory: String?
val directory: String?,
val testModuleKinds: List<TestModuleKind>,
)
internal sealed class TestModuleKind(val componentName: String) {
object SOURCE : TestModuleKind("source")
object LIBRARY : TestModuleKind("library")
object LIBRARY_SOURCE : TestModuleKind("librarySource")
companion object {
val SOURCES_ONLY = listOf(SOURCE)
val SOURCES_AND_LIBRARIES_SOURCES = listOf(SOURCE, LIBRARY_SOURCE)
}
}
internal enum class Frontend(val prefix: String) {
FIR("Fir"),
FE10("Fe10"),
}
internal fun FirAndFe10TestGroup.test(
baseClass: KClass<*>,
generateFe10: Boolean = true,
@@ -22,14 +45,14 @@ internal fun FirAndFe10TestGroup.test(
) {
analysisApiTest(
"analysis/analysis-api-fir/tests",
FrontendConfiguratorTestModel.FrontendConfiguratorType.FIR,
Frontend.FIR,
baseClass,
init
)
if (generateFe10) {
analysisApiTest(
"analysis/analysis-api-fe10/tests",
FrontendConfiguratorTestModel.FrontendConfiguratorType.FE10,
Frontend.FE10,
baseClass,
init
)
@@ -40,54 +63,95 @@ internal fun FirAndFe10TestGroup.test(
internal fun TestGroupSuite.test(
baseClass: KClass<*>,
addFe10: Boolean = true,
testModuleKinds: List<TestModuleKind> = TestModuleKind.SOURCES_ONLY,
init: TestGroup.TestClass.() -> Unit,
) {
FirAndFe10TestGroup(this, directory = null).test(baseClass, addFe10, init)
FirAndFe10TestGroup(this, directory = null, testModuleKinds).test(baseClass, addFe10, init)
}
internal fun TestGroupSuite.group(
directory: String,
testModuleKinds: List<TestModuleKind> = TestModuleKind.SOURCES_ONLY,
init: FirAndFe10TestGroup.() -> Unit,
) {
FirAndFe10TestGroup(this, directory).init()
FirAndFe10TestGroup(this, directory, testModuleKinds).init()
}
internal fun TestGroupSuite.component(
directory: String,
moduleKinds: List<TestModuleKind> = TestModuleKind.SOURCES_ONLY,
init: FirAndFe10TestGroup.() -> Unit,
) {
group("components/$directory", init)
group("components/$directory", moduleKinds, init)
}
private fun FirAndFe10TestGroup.analysisApiTest(
testRoot: String,
frontendConfiguratorType: FrontendConfiguratorTestModel.FrontendConfiguratorType,
frontend: Frontend,
testClass: KClass<*>,
init: TestGroup.TestClass.() -> Unit,
) {
with(suite) {
val fullTestPath = "analysis/analysis-api/testData" + directory?.let { "/$it" }.orEmpty()
testGroup(testRoot, fullTestPath) {
val prefix = when (frontendConfiguratorType) {
FrontendConfiguratorTestModel.FrontendConfiguratorType.FIR -> "Fir"
FrontendConfiguratorTestModel.FrontendConfiguratorType.FE10 -> "Fe10"
}
val fullPackage = getPackageName(prefix, testClass)
testClass(
testClass,
suiteTestClassName = fullPackage + prefix + getDefaultSuiteTestClassName(testClass.java.simpleName),
useJunit4 = false
) {
method(FrontendConfiguratorTestModel(frontendConfiguratorType))
init()
if (testModuleKinds.size == 1) {
analysisApiTestClass(frontend, moduleKind = TestModuleKind.SOURCE, testClass, prefixNeeded = false, init)
} else {
testModuleKinds.forEach { component ->
analysisApiTestClass(frontend, component, testClass, prefixNeeded = true, init)
}
}
}
}
}
private fun TestGroup.analysisApiTestClass(
frontend: Frontend,
moduleKind: TestModuleKind,
testClass: KClass<*>,
prefixNeeded: Boolean,
init: TestGroup.TestClass.() -> Unit
) {
val fullPackage = getPackageName(frontend.prefix, testClass)
val suiteTestClassName = fullPackage +
frontend.prefix +
moduleKind.componentName.capitalizeAsciiOnly().takeIf { prefixNeeded }.orEmpty() +
getDefaultSuiteTestClassName(testClass.java.simpleName)
getDefaultSuiteTestClassName(testClass.java.simpleName)
val configurator = createConfigurator(frontend, moduleKind)
testClass(
testClass,
suiteTestClassName = suiteTestClassName,
useJunit4 = false
) {
method(FrontendConfiguratorTestModel(configurator))
init()
}
}
private fun createConfigurator(
frontend: Frontend,
moduleKind: TestModuleKind
): KClass<out FrontendApiTestConfiguratorService> = when (frontend) {
Frontend.FIR -> when (moduleKind) {
TestModuleKind.SOURCE -> FirFrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY -> LibraryFrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY_SOURCE -> LibrarySourceFrontendApiTestConfiguratorService::class
}
Frontend.FE10 -> when (moduleKind) {
TestModuleKind.SOURCE -> KtFe10FrontendApiTestConfiguratorService::class
TestModuleKind.LIBRARY -> TODO("TestModuleKind.LIBRARY is unsupported for fe10")
TestModuleKind.LIBRARY_SOURCE -> TODO("TestModuleKind.LIBRARY_SOURCE is unsupported for fe10")
}
}
private fun getPackageName(prefix: String, testClass: KClass<*>): String {
val basePrefix = "org.jetbrains.kotlin.analysis.api.${prefix.lowercase()}"
val packagePrefix = testClass.java.name