Test infra: adapt blackbox test runner to work with non-psi sources
This commit is contained in:
+1
-1
@@ -327,7 +327,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
||||
generationState.beforeCompile()
|
||||
generationState.oldBEInitTrace(ktFiles)
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, ktFiles, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
|
||||
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
|
||||
) {
|
||||
performanceManager?.notifyIRLoweringFinished()
|
||||
performanceManager?.notifyIRGenerationStarted()
|
||||
|
||||
@@ -241,7 +241,7 @@ fun generateCodeFromIr(
|
||||
|
||||
generationState.beforeCompile()
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, emptyList() /* !! */, input.irModuleFragment, input.symbolTable, input.extensions,
|
||||
generationState, input.irModuleFragment, input.symbolTable, input.extensions,
|
||||
FirJvmBackendExtension(input.firSession, input.components)
|
||||
) {
|
||||
performanceManager?.notifyIRLoweringFinished()
|
||||
|
||||
+6
-9
@@ -8,7 +8,10 @@ package org.jetbrains.kotlin.backend.jvm
|
||||
import org.jetbrains.kotlin.analyzer.hasJdkCapability
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.backend.common.phaser.then
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
|
||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.IrIntrinsicMethods
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.getIoFile
|
||||
@@ -59,7 +62,6 @@ open class JvmIrCodegenFactory(
|
||||
) : CodegenFactory {
|
||||
data class JvmIrBackendInput(
|
||||
val irModuleFragment: IrModuleFragment,
|
||||
val ktFiles: List<KtFile>,
|
||||
val symbolTable: SymbolTable,
|
||||
val phaseConfig: PhaseConfig?,
|
||||
val irProviders: List<IrProvider>,
|
||||
@@ -215,7 +217,6 @@ open class JvmIrCodegenFactory(
|
||||
}
|
||||
return JvmIrBackendInput(
|
||||
irModuleFragment,
|
||||
input.files.toList(),
|
||||
symbolTable,
|
||||
phaseConfig,
|
||||
irProviders,
|
||||
@@ -250,7 +251,7 @@ open class JvmIrCodegenFactory(
|
||||
}
|
||||
|
||||
override fun invokeLowerings(state: GenerationState, input: CodegenFactory.BackendInput): CodegenFactory.CodegenInput {
|
||||
val (irModuleFragment, _, symbolTable, customPhaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) =
|
||||
val (irModuleFragment, symbolTable, customPhaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) =
|
||||
input as JvmIrBackendInput
|
||||
val irSerializer = if (
|
||||
state.configuration.get(JVMConfigurationKeys.SERIALIZE_IR, JvmSerializeIrMode.NONE) != JvmSerializeIrMode.NONE
|
||||
@@ -289,7 +290,6 @@ open class JvmIrCodegenFactory(
|
||||
|
||||
fun generateModuleInFrontendIRMode(
|
||||
state: GenerationState,
|
||||
ktFiles: List<KtFile>,
|
||||
irModuleFragment: IrModuleFragment,
|
||||
symbolTable: SymbolTable,
|
||||
extensions: JvmGeneratorExtensionsImpl,
|
||||
@@ -299,10 +299,7 @@ open class JvmIrCodegenFactory(
|
||||
val irProviders = configureBuiltInsAndGenerateIrProvidersInFrontendIRMode(irModuleFragment, symbolTable, extensions)
|
||||
generateModule(
|
||||
state,
|
||||
JvmIrBackendInput(
|
||||
irModuleFragment, ktFiles, symbolTable, phaseConfig, irProviders, extensions, backendExtension,
|
||||
notifyCodegenStart
|
||||
)
|
||||
JvmIrBackendInput(irModuleFragment, symbolTable, phaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ dependencies {
|
||||
testApi(project(":compiler:cli"))
|
||||
testImplementation(project(":compiler:ir.tree.impl"))
|
||||
testImplementation(project(":compiler:backend.jvm.entrypoint"))
|
||||
testImplementation(project(":compiler:backend.jvm.lower"))
|
||||
testImplementation(intellijCore())
|
||||
|
||||
testCompileOnly(project(":kotlin-reflect-api"))
|
||||
|
||||
+6
-1
@@ -9,10 +9,12 @@ import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.DefaultCodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.ArtifactKinds
|
||||
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||
import org.jetbrains.kotlin.test.model.SourceFileInfo
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
@@ -42,6 +44,9 @@ class ClassicJvmBackendFacade(
|
||||
|
||||
KotlinCodegenFacade.compileCorrectFiles(psiFiles, generationState, DefaultCodegenFactory)
|
||||
javaCompilerFacade.compileJavaFiles(module, configuration, generationState.factory)
|
||||
return BinaryArtifacts.Jvm(generationState.factory, psiFiles)
|
||||
return BinaryArtifacts.Jvm(
|
||||
generationState.factory,
|
||||
psiFiles.map { SourceFileInfo(it, JvmFileClassUtil.getFileClassInfoNoResolve(it)) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -9,6 +9,7 @@ import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil.getMemberDeclarationsToGenerate
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil.getFileClassInfoNoResolve
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
@@ -31,7 +32,7 @@ import org.jetbrains.kotlin.test.services.jvm.compiledClassesManager
|
||||
import org.jetbrains.kotlin.test.services.jvm.jvmBoxMainClassProvider
|
||||
import org.jetbrains.kotlin.test.services.runtimeClasspathProviders
|
||||
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider
|
||||
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider.Companion.containsBoxMethod
|
||||
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider.Companion.fileContainsBoxMethod
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
@@ -55,15 +56,15 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
}
|
||||
|
||||
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
|
||||
val ktFiles = info.ktFiles.ifEmpty { return }
|
||||
val fileInfos = info.fileInfos.ifEmpty { return }
|
||||
val reportProblems = !testServices.codegenSuppressionChecker.failuresInModuleAreIgnored(module)
|
||||
val classLoader = createAndVerifyClassLoader(module, info.classFileFactory, reportProblems)
|
||||
try {
|
||||
for (ktFile in ktFiles) {
|
||||
if (containsBoxMethod(ktFile.text)) {
|
||||
for (fileInfo in fileInfos) {
|
||||
if (fileContainsBoxMethod(fileInfo.file)) {
|
||||
boxMethodFound = true
|
||||
callBoxMethodAndCheckResultWithCleanup(
|
||||
ktFile,
|
||||
fileInfo.info,
|
||||
module,
|
||||
info.classFileFactory,
|
||||
classLoader,
|
||||
@@ -79,7 +80,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
}
|
||||
|
||||
private fun callBoxMethodAndCheckResultWithCleanup(
|
||||
ktFile: KtFile,
|
||||
fileInfo: JvmFileClassInfo,
|
||||
module: TestModule,
|
||||
classFileFactory: ClassFileFactory,
|
||||
classLoader: URLClassLoader,
|
||||
@@ -87,7 +88,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
reportProblems: Boolean
|
||||
) {
|
||||
try {
|
||||
callBoxMethodAndCheckResult(ktFile, module, classFileFactory, classLoader, unexpectedBehaviour)
|
||||
callBoxMethodAndCheckResult(fileInfo, module, classFileFactory, classLoader, unexpectedBehaviour)
|
||||
} catch (e: Throwable) {
|
||||
if (reportProblems) {
|
||||
try {
|
||||
@@ -106,11 +107,11 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
}
|
||||
|
||||
private fun findClassAndMethodToExecute(
|
||||
ktFile: KtFile,
|
||||
fileInfo: JvmFileClassInfo,
|
||||
classLoader: URLClassLoader,
|
||||
classFileFactory: ClassFileFactory
|
||||
): Pair<Class<*>, Method> {
|
||||
val className = ktFile.getFacadeFqName() ?: error("Class<*> for ${ktFile.name} not found")
|
||||
val className = fileInfo.facadeClassFqName.asString()
|
||||
val clazz = try {
|
||||
classLoader.getGeneratedClass(className)
|
||||
} catch (e: LinkageError) {
|
||||
@@ -121,7 +122,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
}
|
||||
|
||||
private fun callBoxMethodAndCheckResult(
|
||||
ktFile: KtFile,
|
||||
fileInfo: JvmFileClassInfo,
|
||||
module: TestModule,
|
||||
classFileFactory: ClassFileFactory,
|
||||
classLoader: URLClassLoader,
|
||||
@@ -132,7 +133,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
module,
|
||||
classFileFactory,
|
||||
classLoader,
|
||||
findClassAndMethodToExecute(ktFile, classLoader, classFileFactory).first
|
||||
findClassAndMethodToExecute(fileInfo, classLoader, classFileFactory).first
|
||||
)
|
||||
} else {
|
||||
val jdkKind = module.directives.singleOrZeroValue(JDK_KIND)
|
||||
@@ -141,7 +142,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
|
||||
} else {
|
||||
runBoxInCurrentProcess(
|
||||
classLoader,
|
||||
findClassAndMethodToExecute(ktFile, classLoader, classFileFactory).second
|
||||
findClassAndMethodToExecute(fileInfo, classLoader, classFileFactory).second
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+33
-1
@@ -6,13 +6,22 @@
|
||||
package org.jetbrains.kotlin.test.backend.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendException
|
||||
import org.jetbrains.kotlin.backend.jvm.MultifileFacadeFileEntry
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.getFileClassInfoFromIrFile
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.util.NaiveSourceBasedFileEntryImpl
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.backend.classic.JavaCompilerFacade
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||
import org.jetbrains.kotlin.test.model.ArtifactKinds
|
||||
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||
import org.jetbrains.kotlin.test.model.SourceFileInfo
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.compilerConfigurationProvider
|
||||
import java.io.File
|
||||
|
||||
class JvmIrBackendFacade(
|
||||
testServices: TestServices
|
||||
@@ -39,6 +48,29 @@ class JvmIrBackendFacade(
|
||||
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
|
||||
javaCompilerFacade.compileJavaFiles(module, configuration, state.factory)
|
||||
|
||||
return BinaryArtifacts.Jvm(state.factory, inputArtifact.backendInput.ktFiles)
|
||||
fun sourceFileInfos(irFile: IrFile, allowNestedMultifileFacades: Boolean): List<SourceFileInfo<*>> =
|
||||
when (val fileEntry = irFile.fileEntry) {
|
||||
is PsiIrFileEntry -> {
|
||||
listOf(SourceFileInfo(fileEntry.psiFile, JvmFileClassUtil.getFileClassInfoNoResolve(fileEntry.psiFile as KtFile)))
|
||||
}
|
||||
is NaiveSourceBasedFileEntryImpl -> {
|
||||
val file = File(fileEntry.name)
|
||||
listOf(SourceFileInfo(file, getFileClassInfoFromIrFile(irFile, file.name)))
|
||||
}
|
||||
is MultifileFacadeFileEntry -> {
|
||||
if (!allowNestedMultifileFacades) error("nested multi-file facades are not allowed")
|
||||
else fileEntry.partFiles.flatMap { sourceFileInfos(it, allowNestedMultifileFacades = false) }
|
||||
}
|
||||
else -> {
|
||||
error("unknown kind of file entry: $fileEntry")
|
||||
}
|
||||
}
|
||||
|
||||
return BinaryArtifacts.Jvm(
|
||||
state.factory,
|
||||
inputArtifact.backendInput.irModuleFragment.files.flatMap {
|
||||
sourceFileInfos(it, allowNestedMultifileFacades = true)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -76,7 +76,6 @@ class Fir2IrResultsConverter(
|
||||
codegenFactory,
|
||||
JvmIrCodegenFactory.JvmIrBackendInput(
|
||||
irModuleFragment,
|
||||
ktFiles,
|
||||
symbolTable,
|
||||
phaseConfig,
|
||||
irProviders,
|
||||
|
||||
+7
-7
@@ -6,18 +6,18 @@
|
||||
package org.jetbrains.kotlin.test.model
|
||||
|
||||
import org.jetbrains.kotlin.codegen.ClassFileFactory
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo
|
||||
import org.jetbrains.kotlin.ir.backend.js.CompilerResult
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsProgram
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.ir.backend.js.LoweredIr
|
||||
import org.jetbrains.kotlin.js.facade.TranslationResult
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.io.File
|
||||
|
||||
class SourceFileInfo<F>(
|
||||
val file: F,
|
||||
val info: JvmFileClassInfo
|
||||
)
|
||||
|
||||
object BinaryArtifacts {
|
||||
class Jvm(val classFileFactory: ClassFileFactory, val ktFiles: Collection<KtFile>) : ResultingArtifact.Binary<Jvm>() {
|
||||
class Jvm(val classFileFactory: ClassFileFactory, val fileInfos: Collection<SourceFileInfo<*>>) : ResultingArtifact.Binary<Jvm>() {
|
||||
override val kind: BinaryKind<Jvm>
|
||||
get() = ArtifactKinds.Jvm
|
||||
}
|
||||
|
||||
+9
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.services.sourceProviders
|
||||
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.REQUIRES_SEPARATE_PROCESS
|
||||
import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JDK_KIND
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.AdditionalSourceProvider
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.temporaryDirectoryManager
|
||||
import java.io.File
|
||||
|
||||
open class MainFunctionForBlackBoxTestsSourceProvider(testServices: TestServices) : AdditionalSourceProvider(testServices) {
|
||||
companion object {
|
||||
@@ -37,6 +39,13 @@ open class MainFunctionForBlackBoxTestsSourceProvider(testServices: TestServices
|
||||
return containsBoxMethod(file.originalContent)
|
||||
}
|
||||
|
||||
fun <T> fileContainsBoxMethod(file: T): Boolean =
|
||||
when (file) {
|
||||
is PsiFile -> containsBoxMethod(file.text)
|
||||
is File -> containsBoxMethod(file.readText())
|
||||
else -> error("Unknown file type: $file")
|
||||
}
|
||||
|
||||
fun containsBoxMethod(fileContent: String): Boolean {
|
||||
return START_BOX_METHOD_REGEX.containsMatchIn(fileContent) ||
|
||||
MIDDLE_BOX_METHOD_REGEX.containsMatchIn(fileContent) ||
|
||||
|
||||
@@ -134,7 +134,7 @@ object GenerationUtils {
|
||||
generationState.beforeCompile()
|
||||
generationState.oldBEInitTrace(files)
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, files, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components),
|
||||
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components),
|
||||
) {}
|
||||
|
||||
generationState.factory.done()
|
||||
|
||||
Reference in New Issue
Block a user