K2 Scripting: add Fir script codegen tests

27 failing tests are muted
This commit is contained in:
Ilya Chernikov
2023-06-02 16:21:49 +02:00
committed by Space Team
parent 83d0dbe436
commit 5824b9c59c
35 changed files with 631 additions and 42 deletions
@@ -48,6 +48,8 @@ abstract class CLICompiler<A : CommonCompilerArguments> : CLITool<A>() {
const val SCRIPT_PLUGIN_REGISTRAR_NAME =
"org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar"
const val SCRIPT_PLUGIN_COMMANDLINE_PROCESSOR_NAME = "org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCommandLineProcessor"
const val SCRIPT_PLUGIN_K2_REGISTRAR_NAME =
"org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingK2CompilerPluginRegistrar"
}
abstract val defaultPerformanceManager: CommonCompilerPerformanceManager
@@ -0,0 +1,349 @@
/*
* 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.test.runners.codegen;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
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.test.generators.GenerateCompilerTestsKt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/script")
@TestDataPath("$PROJECT_ROOT")
public class FirScriptCodegenTestGenerated extends AbstractFirScriptCodegenTest {
@Test
@TestMetadata("adder.kts")
public void testAdder() throws Exception {
runTest("compiler/testData/codegen/script/adder.kts");
}
@Test
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("classLiteralInsideFunction.kts")
public void testClassLiteralInsideFunction() throws Exception {
runTest("compiler/testData/codegen/script/classLiteralInsideFunction.kts");
}
@Test
@TestMetadata("destructuringDeclaration.kts")
public void testDestructuringDeclaration() throws Exception {
runTest("compiler/testData/codegen/script/destructuringDeclaration.kts");
}
@Test
@TestMetadata("destructuringDeclarationUnderscore.kts")
public void testDestructuringDeclarationUnderscore() throws Exception {
runTest("compiler/testData/codegen/script/destructuringDeclarationUnderscore.kts");
}
@Test
@TestMetadata("empty.kts")
public void testEmpty() throws Exception {
runTest("compiler/testData/codegen/script/empty.kts");
}
@Test
@TestMetadata("helloWorld.kts")
public void testHelloWorld() throws Exception {
runTest("compiler/testData/codegen/script/helloWorld.kts");
}
@Test
@TestMetadata("inline.kts")
public void testInline() throws Exception {
runTest("compiler/testData/codegen/script/inline.kts");
}
@Test
@TestMetadata("innerClass.kts")
public void testInnerClass() throws Exception {
runTest("compiler/testData/codegen/script/innerClass.kts");
}
@Test
@TestMetadata("kt20707.kts")
public void testKt20707() throws Exception {
runTest("compiler/testData/codegen/script/kt20707.kts");
}
@Test
@TestMetadata("kt22029.kts")
public void testKt22029() throws Exception {
runTest("compiler/testData/codegen/script/kt22029.kts");
}
@Test
@TestMetadata("kt48025.kts")
public void testKt48025() throws Exception {
runTest("compiler/testData/codegen/script/kt48025.kts");
}
@Test
@TestMetadata("localDelegatedProperty.kts")
public void testLocalDelegatedProperty() throws Exception {
runTest("compiler/testData/codegen/script/localDelegatedProperty.kts");
}
@Test
@TestMetadata("localDelegatedPropertyInLambda.kts")
public void testLocalDelegatedPropertyInLambda() throws Exception {
runTest("compiler/testData/codegen/script/localDelegatedPropertyInLambda.kts");
}
@Test
@TestMetadata("localDelegatedPropertyNoExplicitType.kts")
public void testLocalDelegatedPropertyNoExplicitType() throws Exception {
runTest("compiler/testData/codegen/script/localDelegatedPropertyNoExplicitType.kts");
}
@Test
@TestMetadata("localFunction.kts")
public void testLocalFunction() throws Exception {
runTest("compiler/testData/codegen/script/localFunction.kts");
}
@Test
@TestMetadata("outerCapture.kts")
public void testOuterCapture() throws Exception {
runTest("compiler/testData/codegen/script/outerCapture.kts");
}
@Test
@TestMetadata("parameter.kts")
public void testParameter() throws Exception {
runTest("compiler/testData/codegen/script/parameter.kts");
}
@Test
@TestMetadata("parameterArray.kts")
public void testParameterArray() throws Exception {
runTest("compiler/testData/codegen/script/parameterArray.kts");
}
@Test
@TestMetadata("parameterClosure.kts")
public void testParameterClosure() throws Exception {
runTest("compiler/testData/codegen/script/parameterClosure.kts");
}
@Test
@TestMetadata("parameterLong.kts")
public void testParameterLong() throws Exception {
runTest("compiler/testData/codegen/script/parameterLong.kts");
}
@Test
@TestMetadata("secondLevelFunction.kts")
public void testSecondLevelFunction() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelFunction.kts");
}
@Test
@TestMetadata("secondLevelFunctionClosure.kts")
public void testSecondLevelFunctionClosure() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelFunctionClosure.kts");
}
@Test
@TestMetadata("secondLevelVal.kts")
public void testSecondLevelVal() throws Exception {
runTest("compiler/testData/codegen/script/secondLevelVal.kts");
}
@Test
@TestMetadata("simpleClass.kts")
public void testSimpleClass() throws Exception {
runTest("compiler/testData/codegen/script/simpleClass.kts");
}
@Test
@TestMetadata("string.kts")
public void testString() throws Exception {
runTest("compiler/testData/codegen/script/string.kts");
}
@Test
@TestMetadata("topLevelFunction.kts")
public void testTopLevelFunction() throws Exception {
runTest("compiler/testData/codegen/script/topLevelFunction.kts");
}
@Test
@TestMetadata("topLevelFunctionClosure.kts")
public void testTopLevelFunctionClosure() throws Exception {
runTest("compiler/testData/codegen/script/topLevelFunctionClosure.kts");
}
@Test
@TestMetadata("topLevelLocalDelegatedProperty.kts")
public void testTopLevelLocalDelegatedProperty() throws Exception {
runTest("compiler/testData/codegen/script/topLevelLocalDelegatedProperty.kts");
}
@Test
@TestMetadata("topLevelPropertiesWithGetSet.kts")
public void testTopLevelPropertiesWithGetSet() throws Exception {
runTest("compiler/testData/codegen/script/topLevelPropertiesWithGetSet.kts");
}
@Test
@TestMetadata("topLevelProperty.kts")
public void testTopLevelProperty() throws Exception {
runTest("compiler/testData/codegen/script/topLevelProperty.kts");
}
@Test
@TestMetadata("topLevelPropertyWithProvideDelegate.kts")
public void testTopLevelPropertyWithProvideDelegate() throws Exception {
runTest("compiler/testData/codegen/script/topLevelPropertyWithProvideDelegate.kts");
}
@Test
@TestMetadata("topLevelTypealias.kts")
public void testTopLevelTypealias() throws Exception {
runTest("compiler/testData/codegen/script/topLevelTypealias.kts");
}
@Nested
@TestMetadata("compiler/testData/codegen/script/scriptInstanceCapturing")
@TestDataPath("$PROJECT_ROOT")
public class ScriptInstanceCapturing {
@Test
public void testAllFilesPresentInScriptInstanceCapturing() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("anonymousObjectCapturesProperty.kts")
public void testAnonymousObjectCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/anonymousObjectCapturesProperty.kts");
}
@Test
@TestMetadata("classCapturesExtensionIndirect.kts")
public void testClassCapturesExtensionIndirect() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect.kts");
}
@Test
@TestMetadata("classCapturesExtensionIndirect2x.kts")
public void testClassCapturesExtensionIndirect2x() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesExtensionIndirect2x.kts");
}
@Test
@TestMetadata("classCapturesFunction.kts")
public void testClassCapturesFunction() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesFunction.kts");
}
@Test
@TestMetadata("classCapturesProperty.kts")
public void testClassCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesProperty.kts");
}
@Test
@TestMetadata("classCapturesPropertyInStringTemplate.kts")
public void testClassCapturesPropertyInStringTemplate() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyInStringTemplate.kts");
}
@Test
@TestMetadata("classCapturesPropertyIndirect.kts")
public void testClassCapturesPropertyIndirect() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect.kts");
}
@Test
@TestMetadata("classCapturesPropertyIndirect2x.kts")
public void testClassCapturesPropertyIndirect2x() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/classCapturesPropertyIndirect2x.kts");
}
@Test
@TestMetadata("companionCapturesProperty.kts")
public void testCompanionCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/companionCapturesProperty.kts");
}
@Test
@TestMetadata("enumCapturesProperty.kts")
public void testEnumCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumCapturesProperty.kts");
}
@Test
@TestMetadata("enumEntryCapturesProperty.kts")
public void testEnumEntryCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/enumEntryCapturesProperty.kts");
}
@Test
@TestMetadata("innerClassesHierarchyCaptureProperty.kts")
public void testInnerClassesHierarchyCaptureProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/innerClassesHierarchyCaptureProperty.kts");
}
@Test
@TestMetadata("interfaceCapturesProperty.kts")
public void testInterfaceCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/interfaceCapturesProperty.kts");
}
@Test
@TestMetadata("nestedAndOuterClassesCaptureProperty.kts")
public void testNestedAndOuterClassesCaptureProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/nestedAndOuterClassesCaptureProperty.kts");
}
@Test
@TestMetadata("nestedClassCapturesProperty.kts")
public void testNestedClassCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/nestedClassCapturesProperty.kts");
}
@Test
@TestMetadata("nestedInnerClassCapturesProperty.kts")
public void testNestedInnerClassCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/nestedInnerClassCapturesProperty.kts");
}
@Test
@TestMetadata("nestedToObjectClassCapturesProperty.kts")
public void testNestedToObjectClassCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/nestedToObjectClassCapturesProperty.kts");
}
@Test
@TestMetadata("objectCapturesProperty.kts")
public void testObjectCapturesProperty() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesProperty.kts");
}
@Test
@TestMetadata("objectCapturesPropertyIndirect.kts")
public void testObjectCapturesPropertyIndirect() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyIndirect.kts");
}
@Test
@TestMetadata("objectCapturesPropertyViaExtension.kts")
public void testObjectCapturesPropertyViaExtension() throws Exception {
runTest("compiler/testData/codegen/script/scriptInstanceCapturing/objectCapturesPropertyViaExtension.kts");
}
}
}
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
package script.long.name.inside.packag
interface I {
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
val (abc, def) = A()
val rv = abc + def
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
val (_, b, _) = A()
class A {
+2
View File
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 2
inline fun foo(l: (Int) -> Int ): Int {
return l(1)
+1
View File
@@ -1,3 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
val b = "K"
+2
View File
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
enum class Build { Debug, Release }
fun applySomething(build: Build) = when (build) {
+1
View File
@@ -1,3 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
data class Pair(val first: Int, val second: Int)
+1
View File
@@ -1,3 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
val p = 0
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
import kotlin.reflect.KProperty
class Delegate {
@@ -1,3 +1,4 @@
// IGNORE_BACKEND_K2: JVM_IR
// WITH_REFLECT
import kotlin.reflect.KProperty
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
import kotlin.reflect.KProperty
class Delegate {
+2
View File
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
// param: 10
fun addX(y: Int) = java.lang.Integer.parseInt(args[0]) + y
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 42
@@ -1,5 +1,6 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: kotlin.Unit
@@ -1,5 +1,6 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: kotlin.Unit
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 42
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: abc
@@ -1,5 +1,6 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 42
@@ -1,5 +1,6 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 42
@@ -1,5 +1,6 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND: JVM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: 42
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: abcabc
@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JS, JS_IR, JS_IR_ES6, NATIVE, WASM
// IGNORE_BACKEND_K2: JVM_IR
// expected: rv: abc!
+2
View File
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
class SimpleClass(val s: String) {
fun foo() = s
}
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
import kotlin.reflect.KProperty
class Delegate {
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
var log = "begin"
fun append(msg: String) {
log = "$log;$msg"
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
import kotlin.reflect.KProperty
class Delegate {
@@ -1,3 +1,5 @@
// IGNORE_BACKEND_K2: JVM_IR
class SimpleClass(val s: String) {
fun foo() = s
}
@@ -282,7 +282,7 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
classFileFactory: ClassFileFactory,
reportProblems: Boolean
): GeneratedClassLoader {
val classLoader = createClassLoader(module, classFileFactory)
val classLoader = generatedTestClassLoader(testServices, module, classFileFactory)
if (REQUIRES_SEPARATE_PROCESS !in module.directives && module.directives.singleOrZeroValue(JDK_KIND)?.requiresSeparateProcess != true) {
val verificationSucceeded = CodegenTestUtil.verifyAllFilesWithAsm(classFileFactory, classLoader, reportProblems)
if (!verificationSucceeded) {
@@ -292,41 +292,6 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
return classLoader
}
private fun createClassLoader(module: TestModule, classFileFactory: ClassFileFactory): GeneratedClassLoader {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val parentClassLoader = if (configuration[TEST_CONFIGURATION_KIND_KEY]?.withReflection == true) {
testServices.standardLibrariesPathProvider.getRuntimeAndReflectJarClassLoader()
} else {
testServices.standardLibrariesPathProvider.getRuntimeJarClassLoader()
}
val classpath = computeRuntimeClasspath(module)
return GeneratedClassLoader(classFileFactory, parentClassLoader, *classpath.map { it.toURI().toURL() }.toTypedArray())
}
private fun computeRuntimeClasspath(rootModule: TestModule): List<File> {
val visited = mutableSetOf<TestModule>()
val result = mutableListOf<File>()
fun computeClasspath(module: TestModule, isRoot: Boolean) {
if (!visited.add(module)) return
if (!isRoot) {
result.add(testServices.compiledClassesManager.getCompiledKotlinDirForModule(module))
}
result.addIfNotNull(testServices.compiledClassesManager.getCompiledJavaDirForModule(module))
for (dependency in module.allDependencies) {
if (dependency.kind == DependencyKind.Binary) {
computeClasspath(testServices.dependencyProvider.getTestModule(dependency.moduleName), false)
}
}
}
computeClasspath(rootModule, true)
testServices.runtimeClasspathProviders.flatMapTo(result) { it.runtimeClassPaths(rootModule) }
return result
}
private fun KtFile.getFacadeFqName(): String? {
return runIf(getMemberDeclarationsToGenerate(this).isNotEmpty()) {
getFileClassInfoNoResolve(this).facadeClassFqName.asString()
@@ -349,3 +314,42 @@ open class JvmBoxRunner(testServices: TestServices) : JvmBinaryArtifactHandler(t
}
}
}
internal fun generatedTestClassLoader(
testServices: TestServices,
module: TestModule,
classFileFactory: ClassFileFactory,
): GeneratedClassLoader {
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(module)
val parentClassLoader = if (configuration[TEST_CONFIGURATION_KIND_KEY]?.withReflection == true) {
testServices.standardLibrariesPathProvider.getRuntimeAndReflectJarClassLoader()
} else {
testServices.standardLibrariesPathProvider.getRuntimeJarClassLoader()
}
val classpath = computeTestRuntimeClasspath(testServices, module)
return GeneratedClassLoader(classFileFactory, parentClassLoader, *classpath.map { it.toURI().toURL() }.toTypedArray())
}
private fun computeTestRuntimeClasspath(testServices: TestServices, rootModule: TestModule): MutableList<File> {
val visited = mutableSetOf<TestModule>()
val result = mutableListOf<File>()
fun computeClasspath(module: TestModule, isRoot: Boolean) {
if (!visited.add(module)) return
if (!isRoot) {
result.add(testServices.compiledClassesManager.getCompiledKotlinDirForModule(module))
}
result.addIfNotNull(testServices.compiledClassesManager.getCompiledJavaDirForModule(module))
for (dependency in module.allDependencies) {
if (dependency.kind == DependencyKind.Binary) {
computeClasspath(testServices.dependencyProvider.getTestModule(dependency.moduleName), false)
}
}
}
computeClasspath(rootModule, true)
testServices.runtimeClasspathProviders.flatMapTo(result) { it.runtimeClassPaths(rootModule) }
return result
}
@@ -0,0 +1,187 @@
/*
* 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.test.runners.codegen
import org.jetbrains.kotlin.KtPsiSourceFile
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.codegen.GeneratedClassLoader
import org.jetbrains.kotlin.compiler.plugin.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.FirParser
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.backend.BlackBoxCodegenSuppressor
import org.jetbrains.kotlin.test.backend.handlers.*
import org.jetbrains.kotlin.test.backend.handlers.generatedTestClassLoader
import org.jetbrains.kotlin.test.backend.ir.JvmIrBackendFacade
import org.jetbrains.kotlin.test.builders.*
import org.jetbrains.kotlin.test.directives.configureFirParser
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
import org.jetbrains.kotlin.test.frontend.fir.FirFailingTestSuppressor
import org.jetbrains.kotlin.test.frontend.fir.FirFrontendFacade
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirDiagnosticsHandler
import org.jetbrains.kotlin.test.frontend.fir.handlers.FirIdenticalChecker
import org.jetbrains.kotlin.test.model.BinaryArtifacts
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
import org.jetbrains.kotlin.test.services.EnvironmentConfigurator
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.fir.FirOldFrontendMetaConfigurator
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.net.URLClassLoader
open class AbstractFirScriptCodegenTest : AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR) {
override fun TestConfigurationBuilder.configuration() {
globalDefaults {
frontend = FrontendKinds.FIR
targetPlatform = JvmPlatforms.defaultJvmPlatform
dependencyKind = DependencyKind.Source
}
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator,
::ScriptingPluginEnvironmentConfigurator
)
facadeStep(::FirFrontendFacade)
firHandlersStep()
facadeStep(::Fir2IrResultsConverter)
irHandlersStep {
useHandlers(
::IrTextDumpHandler,
::IrPrettyKotlinDumpHandler,
)
}
facadeStep(::JvmIrBackendFacade)
jvmArtifactsHandlersStep(init = {})
configureFirHandlersStep {
useHandlers(
::FirDiagnosticsHandler
)
commonFirHandlersForCodegenTest()
}
configureJvmArtifactsHandlersStep {
commonBackendHandlersForCodegenTest()
useHandlers(
::BytecodeListingHandler,
::FirJvmScriptRunChecker
)
}
enableMetaInfoHandler()
useAfterAnalysisCheckers(
::FirFailingTestSuppressor,
::BlackBoxCodegenSuppressor
)
}
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
configureFirParser(FirParser.Psi)
}
}
}
class FirJvmScriptRunChecker(testServices: TestServices) : JvmBinaryArtifactHandler(testServices) {
private var scriptProcessed = false
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
val fileInfos = info.fileInfos.ifEmpty { return }
val classLoader = generatedTestClassLoader(testServices, module, info.classFileFactory)
try {
for (fileInfo in fileInfos) {
when (val sourceFile = fileInfo.sourceFile) {
is KtPsiSourceFile -> (sourceFile.psiFile as? KtFile)?.let { ktFile ->
ktFile.script?.fqName?.let { scriptFqName ->
runAndCheckScript(ktFile, scriptFqName, classLoader)
scriptProcessed = true
}
}
else -> {
assertions.fail { "Only PSI scripts are supported so far" }
}
}
}
} finally {
classLoader.dispose()
}
}
private fun runAndCheckScript(
ktFile: KtFile,
scriptFqName: FqName,
classLoader: GeneratedClassLoader,
) {
val expected = Regex("// expected: (\\S+): (.*)").findAll(ktFile.text).map {
it.groups[1]!!.value to it.groups[2]!!.value
}
val scriptClass = classLoader.loadClass(scriptFqName.asString())
val ctor = scriptClass.constructors.single()
val args: Array<String> =
Regex("param: (\\S.*)").find(ktFile.text)?.let { it.groups[1]?.value?.split(" ") }
.orEmpty().toTypedArray()
val scriptInstance = ctor.newInstance(args)
var anyExpectationFound = false
for ((fieldName, expectedValue) in expected) {
anyExpectationFound = true
if (expectedValue == "<nofield>") {
try {
scriptClass.getDeclaredField(fieldName)
assertions.fail { "must have no field $fieldName" }
} catch (e: NoSuchFieldException) {
continue
}
}
val field = scriptClass.getDeclaredField(fieldName)
field.isAccessible = true
val result = field[scriptInstance]
val resultString = result?.toString() ?: "null"
assertions.assertEquals(expectedValue, resultString) { "comparing field $fieldName" }
}
assertions.assertTrue(anyExpectationFound) { "expecting at least one expectation" }
}
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
if (!scriptProcessed) {
assertions.fail { "Can't find script to test" }
}
}
}
class ScriptingPluginEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) {
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
val libPath = PathUtil.kotlinPathsForCompiler.libPath
val pluginClasspath = PathUtil.KOTLIN_SCRIPTING_PLUGIN_CLASSPATH_JARS.map { File(libPath, it) }
val pluginClassLoader = URLClassLoader(pluginClasspath.map { it.toURI().toURL() }.toTypedArray(), this::class.java.classLoader)
val pluginRegistrarClass = pluginClassLoader.loadClass(CLICompiler.SCRIPT_PLUGIN_REGISTRAR_NAME)
@Suppress("DEPRECATION")
(pluginRegistrarClass.getDeclaredConstructor().newInstance() as? ComponentRegistrar)?.also {
configuration.add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, it)
}
val pluginK2RegistrarClass = pluginClassLoader.loadClass(CLICompiler.SCRIPT_PLUGIN_K2_REGISTRAR_NAME)
(pluginK2RegistrarClass.getDeclaredConstructor().newInstance() as? CompilerPluginRegistrar)?.also {
configuration.add(CompilerPluginRegistrar.COMPILER_PLUGIN_REGISTRARS, it)
}
}
}
@@ -46,9 +46,12 @@ import org.jetbrains.kotlin.resolve.AbstractResolveTest
import org.jetbrains.kotlin.resolve.calls.AbstractResolvedCallsTest
import org.jetbrains.kotlin.resolve.calls.AbstractResolvedConstructorDelegationCallsTests
import org.jetbrains.kotlin.test.TargetBackend
import org.jetbrains.kotlin.test.utils.CUSTOM_TEST_DATA_EXTENSION_PATTERN
import org.jetbrains.kotlin.types.AbstractTypeBindingTest
fun generateJUnit3CompilerTests(args: Array<String>) {
val excludedCustomTestdataPattern = CUSTOM_TEST_DATA_EXTENSION_PATTERN
generateTestGroupSuite(args) {
testGroup("compiler/tests-gen", "compiler/testData") {
testClass<AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation> {
@@ -103,7 +106,7 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
}
testClass<AbstractScriptCodegenTest> {
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM)
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM, excludedPattern = excludedCustomTestdataPattern)
}
testClass<AbstractCustomScriptCodegenTest> {
@@ -379,7 +382,7 @@ fun generateJUnit3CompilerTests(args: Array<String>) {
}
testClass<AbstractIrScriptCodegenTest> {
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM_IR)
model("codegen/script", extension = "kts", targetBackend = TargetBackend.JVM_IR, excludedPattern = excludedCustomTestdataPattern)
}
}
@@ -348,6 +348,10 @@ fun generateJUnit5CompilerTests(args: Array<String>) {
testClass<AbstractFirLightTreeBytecodeListingTest> {
model("codegen/bytecodeListing")
}
testClass<AbstractFirScriptCodegenTest> {
model("codegen/script", pattern = "^(.*)\\.kts?$", excludedPattern = excludedCustomTestdataPattern)
}
}
testGroup("compiler/fir/analysis-tests/tests-gen", "compiler/fir/analysis-tests/testData") {
@@ -32,7 +32,7 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM, true);
}
@TestMetadata("classLiteralInsideFunction.kts")
@@ -199,7 +199,7 @@ public class ScriptCodegenTestGenerated extends AbstractScriptCodegenTest {
}
public void testAllFilesPresentInScriptInstanceCapturing() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM, true);
}
@TestMetadata("anonymousObjectCapturesProperty.kts")
@@ -32,7 +32,7 @@ public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script"), Pattern.compile("^(.+)\\.kts$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@TestMetadata("classLiteralInsideFunction.kts")
@@ -199,7 +199,7 @@ public class IrScriptCodegenTestGenerated extends AbstractIrScriptCodegenTest {
}
public void testAllFilesPresentInScriptInstanceCapturing() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), null, TargetBackend.JVM_IR, true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/script/scriptInstanceCapturing"), Pattern.compile("^(.+)\\.kts$"), Pattern.compile("^(.+)\\.(reversed|fir|ll)\\.kts?$"), TargetBackend.JVM_IR, true);
}
@TestMetadata("anonymousObjectCapturesProperty.kts")