Rewrite compiler visualizer tests using new test infrastructure

This commit is contained in:
Ivan Kylchik
2021-02-04 20:23:04 +03:00
committed by TeamCityServer
parent 4c0cab4756
commit 4ac38e5f29
10 changed files with 326 additions and 213 deletions
@@ -5,44 +5,64 @@
package org.jetbrains.kotlin.visualizer
import org.jetbrains.kotlin.checkers.KotlinMultiFileTestWithJava
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.test.Directives
import org.jetbrains.kotlin.test.KotlinBaseTest
import java.io.File
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendFacade
import org.jetbrains.kotlin.test.model.FrontendKind
import org.jetbrains.kotlin.test.model.FrontendOutputHandler
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
abstract class AbstractVisualizer : KotlinMultiFileTestWithJava<KotlinBaseTest.TestModule, KotlinBaseTest.TestFile>() {
lateinit var replacement: Pair<String, String>
abstract class AbstractVisualizer : AbstractKotlinCompilerTest() {
abstract val handler: Constructor<FrontendOutputHandler<*>>
abstract val frontendKind: FrontendKind<*>
abstract val frontendFacade: Constructor<FrontendFacade<*>>
override fun createTestModule(
name: String,
dependencies: List<String>,
friends: List<String>
): TestModule? = null
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
frontend = frontendKind
targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Source
}
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator,
)
useFrontendFacades(frontendFacade)
useFrontendHandlers(handler)
override fun createTestFile(module: TestModule?, fileName: String, text: String, directives: Directives): TestFile =
TestFile(fileName, text, directives)
defaultDirectives {
+JvmEnvironmentConfigurationDirectives.WITH_STDLIB
}
forTestsMatching("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/*") {
defaultDirectives {
VisualizerDirectives.EXPECTED_FILE_PATH with "compiler/visualizer/testData/rawBuilder/declarations"
}
}
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
val environment = createEnvironment(wholeFile, files)
doVisualizerTest(wholeFile, environment)
forTestsMatching("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/*") {
defaultDirectives {
VisualizerDirectives.EXPECTED_FILE_PATH with "compiler/visualizer/testData/rawBuilder/expressions"
}
}
forTestsMatching("compiler/visualizer/testData/uncommonCases/*") {
defaultDirectives {
VisualizerDirectives.EXPECTED_FILE_PATH with "compiler/visualizer/testData/uncommonCases/resultFiles"
}
}
}
}
abstract fun doVisualizerTest(file: File, environment: KotlinCoreEnvironment)
override fun isKotlinSourceRootNeeded(): Boolean {
return true
}
fun doFirBuilderDataTest(filePath: String) {
replacement = "fir${File.separator}psi2fir" to "visualizer"
doTest(filePath)
}
fun doUncommonCasesTest(filePath: String) {
replacement = "testFiles" to "resultFiles"
doTest(filePath)
}
internal object VisualizerDirectives : SimpleDirectivesContainer() {
val EXPECTED_FILE_PATH by stringDirective(
description = "Specify the path to expected result file"
)
}
@@ -5,66 +5,47 @@
package org.jetbrains.kotlin.visualizer.fir
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.compiler.visualizer.FirVisualizer
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.createSessionForTests
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveProcessor
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirAnalysisHandler
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.defaultDirectives
import org.jetbrains.kotlin.visualizer.AbstractVisualizer
import org.jetbrains.kotlin.visualizer.VisualizerDirectives
import org.junit.Assert
import java.io.File
abstract class AbstractFirVisualizer : AbstractVisualizer() {
override fun doVisualizerTest(file: File, environment: KotlinCoreEnvironment) {
PsiElementFinder.EP.getPoint(environment.project)
.unregisterExtension(JavaElementFinder::class.java)
override val frontendKind: FrontendKind<*> = FrontendKinds.FIR
override val frontendFacade: Constructor<FrontendFacade<*>> = { FirFrontendFacade(it) }
val ktFiles = environment.getSourceFiles()
val scope = GlobalSearchScope.filesScope(environment.project, ktFiles.mapNotNull { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(environment.project))
val session = createSessionForTests(environment, scope)
override val handler: Constructor<FrontendOutputHandler<*>> = {
object : FirAnalysisHandler(it) {
override fun processModule(module: TestModule, info: FirOutputArtifact) {
val renderer = FirVisualizer(info.firFiles.values.first())
val firRenderResult = renderer.render()
val firProvider = (session.firProvider as FirProviderImpl)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider)
val fileName = info.firFiles.keys.first().name
val expectedPath = it.defaultDirectives.get(VisualizerDirectives.EXPECTED_FILE_PATH).first() + "/$fileName"
val expectedText = File(expectedPath).readLines()
if (expectedText[0].startsWith("// FIR_IGNORE")) {
Assert.assertFalse(
"Files are identical, please delete ignore directive",
expectedText.filterIndexed { index, _ -> index > 0 }.joinToString("\n") == firRenderResult
)
return
}
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firRenderResult) {
return@assertEqualsToFile it.replace("// FIR_IGNORE\n", "")
}
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
val transformer = FirTotalResolveProcessor(session)
val firFiles = ktFiles.map {
val firFile = builder.buildFirFile(it)
firProvider.recordFile(firFile)
firFile
}.also {
try {
transformer.process(it)
} catch (e: Exception) {
it.forEach { println(it.render()) }
throw e
}
}
//compare
val renderer = FirVisualizer(firFiles.first())
val psiRenderResult = renderer.render()
val expectedPath = file.absolutePath.replace(replacement.first, replacement.second)
val expectedText = File(expectedPath).readLines()
if (expectedText[0].startsWith("// FIR_IGNORE")) {
Assert.assertFalse(
"Files are identical, please delete ignore directive",
expectedText.filterIndexed { index, _ -> index > 0 }.joinToString("\n") == psiRenderResult
)
return
}
KotlinTestUtils.assertEqualsToFile(File(expectedPath), psiRenderResult) {
return@assertEqualsToFile it.replace("// FIR_IGNORE\n", "")
}
}
}
@@ -5,24 +5,38 @@
package org.jetbrains.kotlin.visualizer.psi
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.compiler.visualizer.PsiVisualizer
import org.jetbrains.kotlin.resolve.lazy.JvmResolveUtil
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicFrontendAnalysisHandler
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.defaultDirectives
import org.jetbrains.kotlin.visualizer.AbstractVisualizer
import org.jetbrains.kotlin.visualizer.VisualizerDirectives
import java.io.File
abstract class AbstractPsiVisualizer : AbstractVisualizer() {
override fun doVisualizerTest(file: File, environment: KotlinCoreEnvironment) {
val ktFiles = environment.getSourceFiles()
val analysisResult = JvmResolveUtil.analyze(ktFiles, environment)
override val frontendKind: FrontendKind<*> = FrontendKinds.ClassicFrontend
override val frontendFacade: Constructor<FrontendFacade<*>> = { ClassicFrontendFacade(it) }
val renderer = PsiVisualizer(ktFiles.first(), analysisResult)
val psiRenderResult = renderer.render()
override val handler: Constructor<FrontendOutputHandler<*>> = {
object : ClassicFrontendAnalysisHandler(it) {
override fun processModule(module: TestModule, info: ClassicFrontendOutputArtifact) {
val renderer = PsiVisualizer(info.ktFiles.values.first(), info.analysisResult)
val psiRenderResult = renderer.render()
val expectedPath = file.absolutePath.replace(replacement.first, replacement.second)
KotlinTestUtils.assertEqualsToFile(File(expectedPath), psiRenderResult) {
return@assertEqualsToFile it.replace("// FIR_IGNORE\n", "")
val fileName = info.ktFiles.keys.first().name
val expectedPath = it.defaultDirectives.get(VisualizerDirectives.EXPECTED_FILE_PATH).first() + "/$fileName"
KotlinTestUtils.assertEqualsToFile(File(expectedPath), psiRenderResult) {
return@assertEqualsToFile it.replace("// FIR_IGNORE\n", "")
}
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
}
}
}
}