FIR JS: enable full JS box tests with FIR

This commit is contained in:
Ilya Chernikov
2022-07-06 13:01:03 +02:00
parent 30df65c321
commit fa0cda6236
17 changed files with 343 additions and 69 deletions
@@ -10,14 +10,12 @@ import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.test.Constructor
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep
import org.jetbrains.kotlin.test.builders.irHandlersStep
import org.jetbrains.kotlin.test.builders.jsArtifactsHandlersStep
import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives
import org.jetbrains.kotlin.test.directives.DiagnosticsDirectives.DIAGNOSTICS
import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives
import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.runners.codegen.commonClassicFrontendHandlersForCodegenTest
@@ -105,6 +103,10 @@ abstract class AbstractJsBlackBoxCodegenTestBase<R : ResultingArtifact.FrontendO
useHandlers(::ClassicDiagnosticsHandler)
}
firHandlersStep {
useHandlers(::FirDiagnosticsHandler)
}
facadeStep(frontendToBackendConverter)
irHandlersStep()
@@ -0,0 +1,105 @@
/*
* 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.js.test.converters
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.util.IrMessageLogger
import org.jetbrains.kotlin.js.test.utils.JsIrIncrementalDataProvider
import org.jetbrains.kotlin.js.test.utils.jsIrIncrementalDataProvider
import org.jetbrains.kotlin.library.KotlinAbiVersion
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.test.backend.ir.IrBackendFacade
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
import org.jetbrains.kotlin.test.frontend.classic.ModuleDescriptorProvider
import org.jetbrains.kotlin.test.frontend.classic.moduleDescriptorProvider
import org.jetbrains.kotlin.test.frontend.fir.getAllJsDependenciesPaths
import org.jetbrains.kotlin.test.frontend.fir.resolveJsLibraries
import org.jetbrains.kotlin.test.model.ArtifactKinds
import org.jetbrains.kotlin.test.model.BinaryArtifacts
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.*
import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.io.File
class FirJsKlibBackendFacade(
testServices: TestServices,
private val firstTimeCompilation: Boolean
) : IrBackendFacade<BinaryArtifacts.KLib>(testServices, ArtifactKinds.KLib) {
override val additionalServices: List<ServiceRegistrationData>
get() = listOf(service(::JsIrIncrementalDataProvider), service(::ModuleDescriptorProvider))
constructor(testServices: TestServices): this(testServices, firstTimeCompilation = true)
override fun shouldRunAnalysis(module: TestModule): Boolean {
return module.backendKind == inputKind
}
override fun transform(module: TestModule, inputArtifact: IrBackendInput): BinaryArtifacts.KLib {
require(inputArtifact is IrBackendInput.JsIrBackendInput) {
"JsKlibBackendFacade expects IrBackendInput.JsIrBackendInput as input"
}
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val outputFile = JsEnvironmentConfigurator.getJsKlibArtifactPath(testServices, module.name)
// TODO: consider avoiding repeated libraries resolution
val libraries = resolveJsLibraries(module, testServices, configuration)
if (firstTimeCompilation) {
serializeModuleIntoKlib(
configuration[CommonConfigurationKeys.MODULE_NAME]!!,
configuration,
configuration.get(IrMessageLogger.IR_MESSAGE_LOGGER) ?: IrMessageLogger.None,
inputArtifact.sourceFiles,
klibPath = outputFile,
libraries.map { it.library },
inputArtifact.irModuleFragment,
inputArtifact.expectDescriptorToSymbol,
cleanFiles = inputArtifact.icData,
nopack = true,
perFile = false,
containsErrorCode = inputArtifact.hasErrors,
abiVersion = KotlinAbiVersion.CURRENT, // TODO get from test file data
jsOutputName = null,
inputArtifact.serializeSingleFile
)
}
// TODO: consider avoiding repeated libraries resolution
val lib = jsResolveLibraries(
getAllJsDependenciesPaths(module, testServices) + listOf(outputFile),
emptyList(),
configuration.resolverLogger
).getFullResolvedList().last().library
val moduleDescriptor = JsFactories.DefaultDeserializedDescriptorFactory.createDescriptorOptionalBuiltIns(
lib,
configuration.languageVersionSettings,
LockBasedStorageManager("ModulesStructure"),
inputArtifact.irModuleFragment.descriptor.builtIns,
packageAccessHandler = null,
lookupTracker = LookupTracker.DO_NOTHING
)
// TODO: find out why it must be so weird
moduleDescriptor.safeAs<ModuleDescriptorImpl>()?.let {
it.setDependencies(inputArtifact.irModuleFragment.descriptor.allDependencyModules.filterIsInstance<ModuleDescriptorImpl>() + it)
}
testServices.moduleDescriptorProvider.replaceModuleDescriptorForModule(module, moduleDescriptor)
if (JsEnvironmentConfigurator.incrementalEnabled(testServices)) {
testServices.jsIrIncrementalDataProvider.recordIncrementalData(module, lib)
}
testServices.jsLibraryProvider.setDescriptorAndLibraryByName(outputFile, moduleDescriptor, lib)
return BinaryArtifacts.KLib(File(outputFile))
}
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.js.test.ir
import org.jetbrains.kotlin.js.test.AbstractJsBlackBoxCodegenTestBase
import org.jetbrains.kotlin.js.test.converters.FirJsKlibBackendFacade
import org.jetbrains.kotlin.js.test.JsSteppingTestAdditionalSourceProvider
import org.jetbrains.kotlin.js.test.converters.JsIrBackendFacade
import org.jetbrains.kotlin.js.test.converters.JsKlibBackendFacade
@@ -20,6 +21,7 @@ import org.jetbrains.kotlin.test.directives.*
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontend2IrConverter
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendFacade
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrJsResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
@@ -186,7 +188,7 @@ private class SkipMultiModuleTestsMetaConfigurator(testServices: TestServices) :
}
}
abstract class AbstractFirJsTest(
open class AbstractFirJsTest(
pathToTestDir: String = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/box/",
testGroupOutputDirPrefix: String = "box/",
) : AbstractJsBlackBoxCodegenTestBase<FirOutputArtifact, IrBackendInput, BinaryArtifacts.KLib>(
@@ -196,10 +198,10 @@ abstract class AbstractFirJsTest(
get() = ::FirFrontendFacade
override val frontendToBackendConverter: Constructor<Frontend2BackendConverter<FirOutputArtifact, IrBackendInput>>
get() = ::Fir2IrResultsConverter
get() = ::Fir2IrJsResultsConverter
override val backendFacade: Constructor<BackendFacade<IrBackendInput, BinaryArtifacts.KLib>>
get() = ::JsKlibBackendFacade
get() = ::FirJsKlibBackendFacade
override val afterBackendFacade: Constructor<AbstractTestFacade<BinaryArtifacts.KLib, BinaryArtifacts.Js>>?
get() = ::JsIrBackendFacade
@@ -213,8 +215,6 @@ abstract class AbstractFirJsTest(
super.configure(builder)
with (builder) {
defaultDirectives {
+ConfigurationDirectives.WITH_STDLIB
+LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE
val runIc = getBoolean("kotlin.js.ir.icMode")
if (runIc) +JsEnvironmentConfigurationDirectives.RUN_IC
if (getBoolean("kotlin.js.ir.klibMainModule")) +JsEnvironmentConfigurationDirectives.KLIB_MAIN_MODULE