diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoK2CompilerTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoK2CompilerTest.kt new file mode 100644 index 00000000000..194068b304d --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoK2CompilerTest.kt @@ -0,0 +1,10 @@ +/* + * 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.analysis.decompiler.stub.files + +abstract class AbstractAdditionalStubInfoK2CompilerTest : AbstractAdditionalStubInfoTest() { + override val useK2ToCompileCode = true +} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt index db3bbdc2f9a..489aee134d1 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractAdditionalStubInfoTest.kt @@ -22,7 +22,8 @@ abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() { val stub = KotlinClsStubBuilder().buildFileStub(FileContentImpl.createByFile(getClassFileToDecompile(testData, false)))!! val builder = StringBuilder() extractAdditionInfo(stub, builder, 0) - KotlinTestUtils.assertEqualsToFile(testData.expectedFile, builder.toString()) + KotlinTestUtils.assertEqualsToFile(testData.getExpectedFile(useK2ToCompileCode), builder.toString()) + testData.checkIfIdentical(useK2ToCompileCode) } private fun extractAdditionInfo(stub: StubElement<*>, builder: StringBuilder, level: Int) { diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractClsStubBuilderK2CompilerTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractClsStubBuilderK2CompilerTest.kt new file mode 100644 index 00000000000..1eb2f6d9266 --- /dev/null +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractClsStubBuilderK2CompilerTest.kt @@ -0,0 +1,10 @@ +/* + * Copyright 2010-2022 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.analysis.decompiler.stub.files + +abstract class AbstractClsStubBuilderK2CompilerTest : AbstractClsStubBuilderTest() { + override val useK2ToCompileCode: Boolean = true +} \ No newline at end of file diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractDecompiledClassTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractDecompiledClassTest.kt index 3340d39de42..012cbcdfa55 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractDecompiledClassTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractDecompiledClassTest.kt @@ -9,23 +9,29 @@ import com.intellij.core.CoreApplicationEnvironment import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem -import org.jetbrains.kotlin.analysis.decompiler.stub.file.CachedAttributeData import org.jetbrains.kotlin.analysis.decompiler.stub.file.ClsKotlinBinaryClassCache import org.jetbrains.kotlin.analysis.decompiler.stub.file.DummyFileAttributeService import org.jetbrains.kotlin.analysis.decompiler.stub.file.FileAttributeService import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment +import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.test.* +import org.jetbrains.kotlin.test.directives.FirDiagnosticsDirectives +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.utils.FirIdenticalCheckerHelper import org.jetbrains.kotlin.utils.addIfNotNull -import java.io.DataInput -import java.io.DataOutput import java.nio.file.Files import java.nio.file.Path import java.util.stream.Collectors import kotlin.io.path.absolutePathString import kotlin.io.path.name import kotlin.io.path.readText +import org.jetbrains.kotlin.test.services.JUnit5Assertions +import java.io.File +import org.jetbrains.kotlin.test.services.AssertionsService abstract class AbstractDecompiledClassTest : KotlinTestWithEnvironment() { + protected open val useK2ToCompileCode: Boolean = false + override fun createEnvironment(): KotlinCoreEnvironment { return KotlinTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations( ApplicationEnvironmentDisposer.ROOT_DISPOSABLE, @@ -55,6 +61,7 @@ abstract class AbstractDecompiledClassTest : KotlinTestWithEnvironment() { this.add("-Xuse-type-table") } this.addAll(testData.additionalCompilerOptions) + addAll(listOf("-language-version", getLanguageVersionToCompile().versionString)) } val library = CompilerTestUtil.compileJvmLibrary( src = testData.directory.toFile(), @@ -65,6 +72,16 @@ abstract class AbstractDecompiledClassTest : KotlinTestWithEnvironment() { ) } + private fun getLanguageVersionToCompile(): LanguageVersion { + return if (useK2ToCompileCode) { + val k2Version = maxOf(LanguageVersion.LATEST_STABLE, LanguageVersion.KOTLIN_2_0) + check(k2Version.usesK2) + k2Version + } else { + LanguageVersion.KOTLIN_1_9 + } + } + private fun findClassFileByName(library: Path, className: String): VirtualFile { val jarFileSystem = environment.projectEnvironment.environment.jarFileSystem as CoreJarFileSystem val root = jarFileSystem.refreshAndFindFileByPath(library.absolutePathString() + "!/")!! @@ -93,6 +110,37 @@ internal data class TestData( val jvmFileName: String, val additionalCompilerOptions: List, ) { + fun containsDirective(directive: String): Boolean { + return InTextDirectivesUtils.isDirectiveDefined(mainKotlinFile.readText(), "// $directive") + } + + fun withFirIgnoreDirective(action: () -> R): R? { + val directive = "FIR_IGNORE" + if (containsDirective(directive)) return null + return action() + } + + + fun getExpectedFile(useK2: Boolean): Path { + if (useK2) { + IdenticalCheckerHelper.getFirFileToCompare(expectedFile.toFile()).takeIf { it.exists() }?.let { return it.toPath() } + } + return expectedFile + } + + fun checkIfIdentical(useK2: Boolean) { + if (containsDirective(FirDiagnosticsDirectives.FIR_IDENTICAL.name)) { + return + } + if (useK2) { + if (IdenticalCheckerHelper.firAndClassicContentsAreEquals(expectedFile.toFile())) { + IdenticalCheckerHelper.deleteFirFile(expectedFile.toFile()) + IdenticalCheckerHelper.addDirectiveToClassicFileAndAssert(mainKotlinFile.toFile()) + } + } + } + + companion object { fun createFromDirectory(directory: Path): TestData { val allFiles = Files.list(directory).collect(Collectors.toList()) @@ -111,5 +159,23 @@ internal data class TestData( ) } } + + private object IdenticalCheckerHelper : FirIdenticalCheckerHelper( + TestServices().apply { + register(AssertionsService::class, JUnit5Assertions) + } + ) { + override fun getClassicFileToCompare(testDataFile: File): File { + val path = testDataFile.toPath() + val fileNameWithoutExtension = path.fileName.toString().removeSuffix(".k2.txt").removeSuffix(".txt") + return path.parent.resolve("$fileNameWithoutExtension.txt").toFile() + } + + override fun getFirFileToCompare(testDataFile: File): File { + val path = testDataFile.toPath() + val fileNameWithoutExtension = path.fileName.toString().removeSuffix(".k2.txt").removeSuffix(".txt") + return path.parent.resolve("$fileNameWithoutExtension.k2.txt").toFile() + } + } } diff --git a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractStubBuilderTest.kt b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractStubBuilderTest.kt index c24950e2714..30f9e1897a9 100644 --- a/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractStubBuilderTest.kt +++ b/analysis/decompiled/decompiler-to-file-stubs/tests/org/jetbrains/kotlin/analysis/decompiler/stub/files/AbstractStubBuilderTest.kt @@ -19,9 +19,10 @@ abstract class AbstractStubBuilderTest : AbstractDecompiledClassTest() { fun runTest(testDirectory: String) { val testDirectoryPath = Paths.get(testDirectory) val testData = TestData.createFromDirectory(testDirectoryPath) - - doTest(testData, useStringTable = true) - doTest(testData, useStringTable = false) + testData.withFirIgnoreDirective { + doTest(testData, useStringTable = true) + doTest(testData, useStringTable = false) + } } @@ -31,7 +32,9 @@ abstract class AbstractStubBuilderTest : AbstractDecompiledClassTest() { } private fun testClsStubsForFile(classFile: VirtualFile, testData: TestData) { - KotlinTestUtils.assertEqualsToFile(testData.expectedFile, getStubToTest(classFile).serializeToString()) + val stub = getStubToTest(classFile) + KotlinTestUtils.assertEqualsToFile(testData.getExpectedFile(useK2ToCompileCode), stub.serializeToString()) + testData.checkIfIdentical(useK2ToCompileCode) } protected abstract fun getStubToTest(classFile: VirtualFile): PsiFileStub<*> diff --git a/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/AbstractByDecompiledPsiStubBuilderK2CompilerTest.kt b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/AbstractByDecompiledPsiStubBuilderK2CompilerTest.kt new file mode 100644 index 00000000000..d9fe83ca992 --- /dev/null +++ b/analysis/decompiled/decompiler-to-psi/tests/org/jetbrains/kotlin/analysis/decompiler/psi/AbstractByDecompiledPsiStubBuilderK2CompilerTest.kt @@ -0,0 +1,10 @@ +/* + * 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.analysis.decompiler.psi + +abstract class AbstractByDecompiledPsiStubBuilderK2CompilerTest : AbstractByDecompiledPsiStubBuilderTest() { + override val useK2ToCompileCode: Boolean = true +} \ No newline at end of file diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/decompiled.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/decompiled.kt index 2ce5065bd0a..533bc7fe8ea 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/decompiled.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/decompiled.kt @@ -5,8 +5,11 @@ package org.jetbrains.kotlin.generators.tests.analysis.api +import org.jetbrains.kotlin.analysis.decompiler.psi.AbstractByDecompiledPsiStubBuilderK2CompilerTest import org.jetbrains.kotlin.analysis.decompiler.psi.AbstractByDecompiledPsiStubBuilderTest +import org.jetbrains.kotlin.analysis.decompiler.stub.files.AbstractAdditionalStubInfoK2CompilerTest import org.jetbrains.kotlin.analysis.decompiler.stub.files.AbstractAdditionalStubInfoTest +import org.jetbrains.kotlin.analysis.decompiler.stub.files.AbstractClsStubBuilderK2CompilerTest import org.jetbrains.kotlin.analysis.decompiler.stub.files.AbstractClsStubBuilderTest import org.jetbrains.kotlin.generators.TestGroupSuite @@ -18,6 +21,10 @@ internal fun TestGroupSuite.generateDecompiledTests() { testClass { model("clsFileStubBuilder", extension = null, recursive = false) } + + testClass { + model("clsFileStubBuilder", extension = null, recursive = false) + } } testGroup( @@ -27,6 +34,10 @@ internal fun TestGroupSuite.generateDecompiledTests() { testClass { model("additionalClsStubInfo", extension = null, recursive = false) } + + testClass { + model("additionalClsStubInfo", extension = null, recursive = false) + } } testGroup( @@ -36,5 +47,9 @@ internal fun TestGroupSuite.generateDecompiledTests() { testClass { model("clsFileStubBuilder", extension = null, recursive = false) } + + testClass { + model("clsFileStubBuilder", extension = null, recursive = false) + } } } \ No newline at end of file