diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 7178b76e48a..b16d8fff6e9 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -19294,6 +19294,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt"); } + @Test + @TestMetadata("boxResultInlineClassOfConstructorCall.kt") + public void testBoxResultInlineClassOfConstructorCallWithoutJvmInlineAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt", s -> s.replaceAll("@(kotlin.jvm.)?JvmInline", "")); + } + @Test @TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt") public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception { diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt index 202fbbabe6f..c2293b2684a 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/TestRunner.kt @@ -24,9 +24,13 @@ class TestRunner(private val testConfiguration: TestConfiguration) { private val allFailedExceptions = mutableListOf() private val allRanHandlers = mutableSetOf>() - fun runTest(@TestDataFile testDataFileName: String, beforeDispose: (TestConfiguration) -> Unit = {}) { + fun runTest( + @TestDataFile testDataFileName: String, + beforeDispose: (TestConfiguration) -> Unit = {}, + expectedFileTransformer: ((String) -> String)? = null + ) { try { - runTestImpl(testDataFileName) + runTestImpl(testDataFileName, expectedFileTransformer) } finally { try { testConfiguration.testServices.temporaryDirectoryManager.cleanupTemporaryDirectories() @@ -38,7 +42,7 @@ class TestRunner(private val testConfiguration: TestConfiguration) { } } - private fun runTestImpl(@TestDataFile testDataFileName: String) { + private fun runTestImpl(@TestDataFile testDataFileName: String, expectedFileTransformer: ((String) -> String)?) { val services = testConfiguration.testServices @Suppress("NAME_SHADOWING") @@ -66,12 +70,13 @@ class TestRunner(private val testConfiguration: TestConfiguration) { if (it.shouldSkipTest()) return } - runTestPipeline(moduleStructure, services) + runTestPipeline(moduleStructure, services, expectedFileTransformer) } fun runTestPipeline( moduleStructure: TestModuleStructure, - services: TestServices + services: TestServices, + expectedFileTransformer: ((String) -> String)?, ) { val globalMetadataInfoHandler = testConfiguration.testServices.globalMetadataInfoHandler globalMetadataInfoHandler.parseExistingMetadataInfosFromAllSources() @@ -100,7 +105,7 @@ class TestRunner(private val testConfiguration: TestConfiguration) { } if (testConfiguration.metaInfoHandlerEnabled) { withAssertionCatching(WrappedException::FromMetaInfoHandler) { - globalMetadataInfoHandler.compareAllMetaDataInfos() + globalMetadataInfoHandler.compareAllMetaDataInfos(expectedFileTransformer) } } diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/GlobalMetadataInfoHandler.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/GlobalMetadataInfoHandler.kt index f3b38b30367..85f4da53413 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/GlobalMetadataInfoHandler.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/GlobalMetadataInfoHandler.kt @@ -51,7 +51,7 @@ class GlobalMetadataInfoHandler( infos += codeMetaInfos } - fun compareAllMetaDataInfos() { + fun compareAllMetaDataInfos(expectedTransformer: ((String) -> String)?) { // TODO: adapt to multiple testdata files val moduleStructure = testServices.moduleStructure val builder = StringBuilder() @@ -70,7 +70,14 @@ class GlobalMetadataInfoHandler( } } val actualText = builder.toString() - testServices.assertions.assertEqualsToFile(moduleStructure.originalTestDataFiles.single(), actualText) + val expectedFile = moduleStructure.originalTestDataFiles.single() + if (expectedTransformer != null) { + val expectedContent = expectedFile.readText().let(expectedTransformer) + val message = "Actual data differs from transformed content of file $expectedFile" + testServices.assertions.assertEquals(expectedContent, actualText) { message } + } else { + testServices.assertions.assertEqualsToFile(expectedFile, actualText) + } } private fun StringBuilder.stripAdditionalEmptyLines(file: TestFile): CharSequence { diff --git a/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt b/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt index ae11364c673..39e9d9baff2 100644 --- a/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt +++ b/compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt @@ -1,4 +1,5 @@ // WITH_STDLIB +// WORKS_WITHOUT_JVM_INLINE @Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") @kotlin.jvm.JvmInline diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 6ebb4c114ad..4430fc57c20 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -19294,6 +19294,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt"); } + @Test + @TestMetadata("boxResultInlineClassOfConstructorCall.kt") + public void testBoxResultInlineClassOfConstructorCallWithoutJvmInlineAnnotation() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/boxResultInlineClassOfConstructorCall.kt", s -> s.replaceAll("@(kotlin.jvm.)?JvmInline", "")); + } + @Test @TestMetadata("boxUnboxInlineClassesWithOperatorsGetSet.kt") public void testBoxUnboxInlineClassesWithOperatorsGetSet() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt index 045b197685f..9caa9ec2d4e 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/runners/AbstractKotlinCompilerTest.kt @@ -12,11 +12,9 @@ import org.jetbrains.kotlin.test.builders.testRunner import org.jetbrains.kotlin.test.directives.ConfigurationDirectives import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives import org.jetbrains.kotlin.test.model.ResultingArtifact +import org.jetbrains.kotlin.test.model.TestFile import org.jetbrains.kotlin.test.preprocessors.MetaInfosCleanupPreprocessor -import org.jetbrains.kotlin.test.services.JUnit5Assertions -import org.jetbrains.kotlin.test.services.KotlinTestInfo -import org.jetbrains.kotlin.test.services.SourceFilePreprocessor -import org.jetbrains.kotlin.test.services.TemporaryDirectoryManager +import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.FlexibleTypeImpl @@ -82,4 +80,19 @@ abstract class AbstractKotlinCompilerTest { open fun runTest(@TestDataFile filePath: String) { testRunner(filePath, configuration).runTest(filePath) } + + @JvmOverloads + open fun runTest( + @TestDataFile filePath: String, + actualContentModifier: (String) -> String, + expectedContentModifier: ((String) -> String)? = actualContentModifier + ) { + class SourceTransformer(testServices: TestServices) : SourceFilePreprocessor(testServices) { + override fun process(file: TestFile, content: String): String = content.let(actualContentModifier) + } + testRunner(filePath) { + configuration.let { it() } // property configuration, not method + useSourcePreprocessor({ SourceTransformer(it) }) + }.runTest(filePath, expectedFileTransformer = expectedContentModifier) + } } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/generators/impl/TestGeneratorImpl.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/generators/impl/TestGeneratorImpl.kt index 27939dd969f..5bb74fab009 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/generators/impl/TestGeneratorImpl.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/generators/impl/TestGeneratorImpl.kt @@ -20,13 +20,13 @@ import org.junit.runner.RunWith import org.junit.runners.BlockJUnit4ClassRunner import java.io.File import java.io.IOException -import java.util.* private val METHOD_GENERATORS = listOf( RunTestMethodGenerator, SimpleTestClassModelTestAllFilesPresentMethodGenerator, SimpleTestMethodGenerator, - SingleClassTestModelAllFilesPresentedMethodGenerator + SingleClassTestModelAllFilesPresentedMethodGenerator, + WithoutJvmInlineTestMethodGenerator, ) object TestGeneratorImpl : TestGenerator(METHOD_GENERATORS) { diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/NewTestGeneratorImpl.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/NewTestGeneratorImpl.kt index f80bab966ec..e813eecdea8 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/NewTestGeneratorImpl.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/NewTestGeneratorImpl.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.generators import org.jetbrains.kotlin.generators.impl.SimpleTestClassModelTestAllFilesPresentMethodGenerator import org.jetbrains.kotlin.generators.impl.SimpleTestMethodGenerator import org.jetbrains.kotlin.generators.impl.SingleClassTestModelAllFilesPresentedMethodGenerator +import org.jetbrains.kotlin.generators.impl.WithoutJvmInlineTestMethodGenerator import org.jetbrains.kotlin.generators.model.* import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil import org.jetbrains.kotlin.test.TestMetadata @@ -18,14 +19,14 @@ import org.junit.jupiter.api.Tag import org.junit.jupiter.api.Test import java.io.File import java.io.IOException -import java.util.* private const val TEST_GENERATOR_NAME = "GenerateNewCompilerTests.kt" private val METHOD_GENERATORS = listOf( SimpleTestClassModelTestAllFilesPresentMethodGenerator, SimpleTestMethodGenerator, - SingleClassTestModelAllFilesPresentedMethodGenerator + SingleClassTestModelAllFilesPresentedMethodGenerator, + WithoutJvmInlineTestMethodGenerator, ) object NewTestGeneratorImpl : TestGenerator(METHOD_GENERATORS) { diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/impl/WithoutJvmInlineTestMethodGenerator.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/impl/WithoutJvmInlineTestMethodGenerator.kt new file mode 100644 index 00000000000..26f3ea0ff9b --- /dev/null +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/impl/WithoutJvmInlineTestMethodGenerator.kt @@ -0,0 +1,30 @@ +/* + * 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.generators.impl + +import org.jetbrains.kotlin.generators.MethodGenerator +import org.jetbrains.kotlin.generators.model.MethodModel +import org.jetbrains.kotlin.generators.model.RunTestMethodModel +import org.jetbrains.kotlin.generators.model.WithoutJvmInlineTestMethodModel +import org.jetbrains.kotlin.test.util.KtTestUtil +import org.jetbrains.kotlin.utils.Printer + +object WithoutJvmInlineTestMethodGenerator : MethodGenerator() { + + override val kind: MethodModel.Kind + get() = WithoutJvmInlineTestMethodModel.Kind + + override fun generateSignature(method: WithoutJvmInlineTestMethodModel, p: Printer) { + generateDefaultSignature(method, p) + } + + override fun generateBody(method: WithoutJvmInlineTestMethodModel, p: Printer) { + with(method) { + val filePath = KtTestUtil.getFilePath(source.file) + if (source.file.isDirectory) "/" else "" + p.println("${RunTestMethodModel.METHOD_NAME}(\"$filePath\", s -> s.replaceAll(\"@(kotlin.jvm.)?JvmInline\", \"\"));") + } + } +} diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SimpleTestClassModel.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SimpleTestClassModel.kt index 2699a1d5337..1cae3199540 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SimpleTestClassModel.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SimpleTestClassModel.kt @@ -8,10 +8,10 @@ import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.generators.util.TestGeneratorUtil.fileNameToJavaIdentifier import org.jetbrains.kotlin.generators.util.extractTagsFromDirectory import org.jetbrains.kotlin.generators.util.extractTagsFromTestFile +import org.jetbrains.kotlin.generators.util.methodModelLocator import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.util.KtTestUtil import java.io.File -import java.util.* import java.util.regex.Pattern class SimpleTestClassModel( @@ -87,16 +87,14 @@ class SimpleTestClassModel( override val methods: Collection by lazy { if (!rootFile.isDirectory) { - return@lazy listOf( - SimpleTestMethodModel( - rootFile, - rootFile, - filenamePattern, - checkFilenameStartsLowerCase, - targetBackend, - skipIgnored, - extractTagsFromTestFile(rootFile) - ) + return@lazy methodModelLocator( + rootFile, + rootFile, + filenamePattern, + checkFilenameStartsLowerCase, + targetBackend, + skipIgnored, + extractTagsFromTestFile(rootFile) ) } val result = mutableListOf() @@ -110,8 +108,8 @@ class SimpleTestClassModel( if (file.isDirectory && excludeParentDirs && dirHasSubDirs(file)) { continue } - result.add( - SimpleTestMethodModel( + result.addAll( + methodModelLocator( rootFile, file, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored, extractTagsFromTestFile(file) ) diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SingleClassTestModel.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SingleClassTestModel.kt index 3b3d2b95542..cd005e6be25 100644 --- a/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SingleClassTestModel.kt +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/SingleClassTestModel.kt @@ -5,10 +5,10 @@ package org.jetbrains.kotlin.generators.model import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.generators.util.methodModelLocator import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.util.KtTestUtil import java.io.File -import java.util.* import java.util.regex.Pattern class SingleClassTestModel( @@ -45,10 +45,8 @@ class SingleClassTestModel( get() = emptyList() private fun getTestMethodsFromFile(file: File): Collection { - return listOf( - SimpleTestMethodModel( - rootFile, file, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored, tags = emptyList() - ) + return methodModelLocator( + rootFile, file, filenamePattern, checkFilenameStartsLowerCase, targetBackend, skipIgnored, tags = emptyList() ) } diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/WithoutJvmInlineTestMethodModel.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/WithoutJvmInlineTestMethodModel.kt new file mode 100644 index 00000000000..693b2ae633c --- /dev/null +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/model/WithoutJvmInlineTestMethodModel.kt @@ -0,0 +1,21 @@ +/* + * 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.generators.model + +class WithoutJvmInlineTestMethodModel( + val source: SimpleTestMethodModel +) : MethodModel { + object Kind : MethodModel.Kind() + + override val kind: MethodModel.Kind + get() = Kind + override val name: String + get() = "${source.name}WithoutJvmInlineAnnotation" + override val dataString: String + get() = source.dataString + override val tags: List + get() = source.tags +} \ No newline at end of file diff --git a/generators/test-generator/tests/org/jetbrains/kotlin/generators/util/MethodModelLocator.kt b/generators/test-generator/tests/org/jetbrains/kotlin/generators/util/MethodModelLocator.kt new file mode 100644 index 00000000000..6a524b00f64 --- /dev/null +++ b/generators/test-generator/tests/org/jetbrains/kotlin/generators/util/MethodModelLocator.kt @@ -0,0 +1,37 @@ +/* + * 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.generators.util + +import org.jetbrains.kotlin.generators.model.* +import org.jetbrains.kotlin.test.TargetBackend +import java.io.File +import java.util.regex.Pattern + +fun TestEntityModel.containsWithoutJvmInline(backend: TargetBackend): Boolean = backend == TargetBackend.JVM_IR && when (this) { + is ClassModel -> methods.any { it.containsWithoutJvmInline(backend) } || innerTestClasses.any { it.containsWithoutJvmInline(backend) } + is SimpleTestMethodModel -> file.readLines().any { Regex("^\\s*//\\s*WORKS_WITHOUT_JVM_INLINE\\s*$").matches(it) } + else -> false +} + +fun methodModelLocator( + rootDir: File, + file: File, + filenamePattern: Pattern, + checkFilenameStartsLowerCase: Boolean?, + targetBackend: TargetBackend, + skipIgnored: Boolean, + tags: List +): List = SimpleTestMethodModel( + rootDir, + file, + filenamePattern, + checkFilenameStartsLowerCase, + targetBackend, + skipIgnored, + tags +).let { methodModel -> + listOf(methodModel) + if (methodModel.containsWithoutJvmInline(targetBackend)) listOf(WithoutJvmInlineTestMethodModel(methodModel)) else emptyList() +} \ No newline at end of file