diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt index 01b2bfd9f21..00eaf96ec26 100644 --- a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/test/configurators/library/AnalysisApiFirLibrarySourceTestConfigurator.kt @@ -17,10 +17,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.AnalysisApiFirT import org.jetbrains.kotlin.analysis.low.level.api.fir.test.configurators.createKtLibrarySourceModule import org.jetbrains.kotlin.analysis.test.framework.project.structure.KtModuleFactory import org.jetbrains.kotlin.analysis.test.framework.project.structure.TestModuleStructureFactory -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompiler -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompilerJar -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.compiledLibraryProvider +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.* import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestServiceRegistrar import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind @@ -44,7 +41,7 @@ object AnalysisApiFirLibrarySourceTestConfigurator : AnalysisApiTestConfigurator builder.apply { useAdditionalServices(ServiceRegistrationData(CompiledLibraryProvider::class, ::CompiledLibraryProvider)) useAdditionalService { KtLibrarySourceModuleFactory() } - useAdditionalService { TestModuleCompilerJar() } + useAdditionalService { DispatchingTestModuleCompiler() } useDirectives(SealedClassesInheritorsCaclulatorPreAnalysisHandler.Directives) usePreAnalysisHandlers(::SealedClassesInheritorsCaclulatorPreAnalysisHandler) useConfigurators(::JvmEnvironmentConfigurator) diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt index a7e122732c6..ce5795311e4 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/configurators/AnalysisApiLibraryBaseTestServiceRegistrar.kt @@ -10,7 +10,12 @@ import com.intellij.mock.MockApplication import com.intellij.openapi.extensions.LoadingOrder import com.intellij.psi.ClassFileViewProviderFactory import com.intellij.psi.FileTypeFileViewProviders +import com.intellij.psi.FileViewProviderFactory import com.intellij.psi.compiled.ClassFileDecompilers +import com.intellij.psi.impl.compiled.ClassFileStubBuilder +import com.intellij.psi.stubs.BinaryFileStubBuilders +import org.jetbrains.kotlin.analysis.decompiler.konan.K2KotlinNativeMetadataDecompiler +import org.jetbrains.kotlin.analysis.decompiler.konan.KlibMetaFileType import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinBuiltInDecompiler import org.jetbrains.kotlin.analysis.decompiler.psi.KotlinClassFileDecompiler import org.jetbrains.kotlin.analysis.test.framework.services.disposableProvider @@ -20,10 +25,21 @@ import org.jetbrains.kotlin.test.services.TestServices object AnalysisApiLibraryBaseTestServiceRegistrar : AnalysisApiTestServiceRegistrar() { override fun registerApplicationServices(application: MockApplication, testServices: TestServices) { FileTypeFileViewProviders.INSTANCE.addExplicitExtension(JavaClassFileType.INSTANCE, ClassFileViewProviderFactory()) + FileTypeFileViewProviders.INSTANCE.addExplicitExtension( + KlibMetaFileType, + FileViewProviderFactory { file, _, manager, _ -> + K2KotlinNativeMetadataDecompiler().createFileViewProvider(file, manager, physical = true) + }) + BinaryFileStubBuilders.INSTANCE.addExplicitExtension(KlibMetaFileType, ClassFileStubBuilder()) ClassFileDecompilers.getInstance().EP_NAME.point.apply { registerExtension(KotlinClassFileDecompiler(), LoadingOrder.FIRST, testServices.disposableProvider.getApplicationDisposable()) registerExtension(KotlinBuiltInDecompiler(), LoadingOrder.FIRST, testServices.disposableProvider.getApplicationDisposable()) + registerExtension( + K2KotlinNativeMetadataDecompiler(), + LoadingOrder.FIRST, + testServices.disposableProvider.getApplicationDisposable() + ) } } } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt index 0e68c960cb7..617566856fe 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/base/AbstractAnalysisApiBasedTest.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModulePr import org.jetbrains.kotlin.analysis.test.framework.services.ExpressionMarkerProvider import org.jetbrains.kotlin.analysis.test.framework.services.ExpressionMarkersSourceFilePreprocessor import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompilerExecutor +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompiler import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind import org.jetbrains.kotlin.analysis.test.framework.utils.SkipTestException @@ -117,7 +117,7 @@ abstract class AbstractAnalysisApiBasedTest : TestWithDisposable() { useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray()) useDirectives(JvmEnvironmentConfigurationDirectives) - useDirectives(CompilerExecutor.Directives) + useDirectives(TestModuleCompiler.Directives) useSourcePreprocessor(::ExpressionMarkersSourceFilePreprocessor) diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleByCompilerConfiguration.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleByCompilerConfiguration.kt index 7b5449fccfc..a0fed6ea7ed 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleByCompilerConfiguration.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/KtSourceModuleByCompilerConfiguration.kt @@ -10,6 +10,7 @@ import com.intellij.psi.PsiFile import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory import org.jetbrains.kotlin.analysis.project.structure.* +import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots @@ -17,7 +18,6 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.jvm.JvmPlatforms -import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices @@ -71,7 +71,10 @@ abstract class KtModuleByCompilerConfiguration( private fun createJdkFromConfiguration(): KtSdkModule? = configuration.get(JVMConfigurationKeys.JDK_HOME)?.let { jdkHome -> val jdkHomePaths = StandaloneProjectFactory.getDefaultJdkModulePaths(project, jdkHome.toPath()) - val scope = TestModuleStructureFactory.getScopeForLibraryByRoots(jdkHomePaths, testServices) + val scope = StandaloneProjectFactory.createSearchScopeByLibraryRoots( + jdkHomePaths, + testServices.environmentManager.getProjectEnvironment() + ) KtJdkModuleImpl( "jdk", @@ -171,7 +174,10 @@ private class LibraryByRoots( override val project: Project, testServices: TestServices, ) : KtLibraryModule { - override val contentScope: GlobalSearchScope = TestModuleStructureFactory.getScopeForLibraryByRoots(roots, testServices) + override val contentScope: GlobalSearchScope = StandaloneProjectFactory.createSearchScopeByLibraryRoots( + roots, + testServices.environmentManager.getProjectEnvironment(), + ) override val libraryName: String get() = "Test Library $roots" override val directRegularDependencies: List get() = emptyList() override val directDependsOnDependencies: List get() = emptyList() diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt index 5f063459ade..03f742e7967 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/project/structure/TestModuleStructureFactory.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.analysis.test.framework.project.structure import com.intellij.openapi.project.Project import com.intellij.psi.PsiFile import com.intellij.psi.PsiManager -import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleProjectStructure import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.KtModuleWithFiles import org.jetbrains.kotlin.analysis.api.standalone.base.project.structure.StandaloneProjectFactory @@ -20,7 +19,10 @@ import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager import org.jetbrains.kotlin.analysis.utils.errors.requireIsInstance import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot +import org.jetbrains.kotlin.platform.isCommon +import org.jetbrains.kotlin.platform.isJs import org.jetbrains.kotlin.platform.jvm.JvmPlatforms +import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.test.TestInfrastructureInternals import org.jetbrains.kotlin.test.model.DependencyRelation import org.jetbrains.kotlin.test.model.TestModule @@ -56,13 +58,7 @@ object TestModuleStructureFactory { } is KtModuleWithModifiableDependencies -> { addModuleDependencies(testModule, moduleEntriesByName, ktModule) - - buildList { - addIfNotNull(getJdkModule(testModule, project, testServices)) - addAll(getStdlibModules(testModule, project, testServices)) - addAll(getLibraryModules(testServices, testModule, project)) - addAll(createLibrariesByCompilerConfigurators(testModule, testServices, project)) - }.forEach { library -> + stdlibAndSdkDependencies(ktModule, testModule, project, testServices).forEach { library -> val cachedLibrary = binaryModulesBySourceRoots.getOrPut(library.getBinaryRoots().toSet()) { library } ktModule.directRegularDependencies.add(cachedLibrary) } @@ -74,6 +70,28 @@ object TestModuleStructureFactory { return KtModuleProjectStructure(moduleEntries, binaryModulesBySourceRoots.values) } + private fun stdlibAndSdkDependencies( + module: KtModule, + testModule: TestModule, + project: Project, + testServices: TestServices, + ): List { + return when { + module.platform.isJvm() -> jvmStdlibAndJdkDependencies(testModule, project, testServices) + module.platform.isJs() -> jsStdlibDependencies(project, testServices) + else -> error("Unsupported platform ${module.platform} in this test") + } + } + + private fun jvmStdlibAndJdkDependencies(testModule: TestModule, project: Project, testServices: TestServices): List { + return buildList { + addIfNotNull(getJdkModule(testModule, project, testServices)) + addAll(getStdlibModules(testModule, project, testServices)) + addAll(getLibraryModules(testServices, testModule, project)) + addAll(createLibrariesByCompilerConfigurators(testModule, testServices, project)) + } + } + @OptIn(TestInfrastructureInternals::class) private fun createLibrariesByCompilerConfigurators( testModule: TestModule, @@ -130,7 +148,10 @@ object TestModuleStructureFactory { return KtLibraryModuleImpl( libraryName, JvmPlatforms.defaultJvmPlatform, - getScopeForLibraryByRoots(listOf(jar), testServices), + StandaloneProjectFactory.createSearchScopeByLibraryRoots( + listOf(jar), + testServices.environmentManager.getProjectEnvironment() + ), project, listOf(jar), librarySources = null, @@ -167,16 +188,33 @@ object TestModuleStructureFactory { return KtJdkModuleImpl( "jdk", JvmPlatforms.defaultJvmPlatform, - getScopeForLibraryByRoots(jdkSourceRoots, testServices), + StandaloneProjectFactory.createSearchScopeByLibraryRoots( + jdkSourceRoots, + testServices.environmentManager.getProjectEnvironment() + ), project, jdkSourceRoots ) } - fun getScopeForLibraryByRoots(roots: Collection, testServices: TestServices): GlobalSearchScope { - return StandaloneProjectFactory.createSearchScopeByLibraryRoots( - roots, - testServices.environmentManager.getProjectEnvironment() + private fun jsStdlibDependencies(project: Project, testServices: TestServices): List { + return listOf( + jsStdlib(project, testServices), + ) + } + + private fun jsStdlib(project: Project, testServices: TestServices): KtBinaryModule { + val jar = testServices.standardLibrariesPathProvider.fullJsStdlib().toPath() + return KtLibraryModuleImpl( + PathUtil.JS_LIB_NAME, + JvmPlatforms.defaultJvmPlatform, + StandaloneProjectFactory.createSearchScopeByLibraryRoots( + listOf(jar), + testServices.environmentManager.getProjectEnvironment() + ), + project, + listOf(jar), + librarySources = null, ) } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt new file mode 100644 index 00000000000..0b9243250ba --- /dev/null +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CliTestModuleCompilers.kt @@ -0,0 +1,143 @@ +/* + * 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.test.framework.services.libraries + +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.cliArgument +import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.platform.isJs +import org.jetbrains.kotlin.platform.jvm.isJvm +import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.sourceFileProvider +import org.jetbrains.kotlin.test.services.standardLibrariesPathProvider +import org.jetbrains.kotlin.test.util.KtTestUtil +import java.io.ByteArrayInputStream +import java.nio.file.Path +import java.util.jar.Attributes +import java.util.jar.JarEntry +import java.util.jar.JarOutputStream +import java.util.jar.Manifest +import kotlin.io.path.div +import kotlin.io.path.outputStream + +abstract class CliTestModuleCompiler : TestModuleCompiler() { + internal abstract val compilerKind: CompilerExecutor.CompilerKind + + protected abstract fun buildPlatformCompilerOptions(module: TestModule, testServices: TestServices): List + + override fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path = CompilerExecutor.compileLibrary( + compilerKind, + tmpDir, + buildCompilerOptions(module, testServices), + compilationErrorExpected = Directives.COMPILATION_ERRORS in module.directives + ) + + override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { + val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath() + val librarySourcesPath = tmpDir / "library-sources.jar" + val manifest = Manifest().apply { mainAttributes[Attributes.Name.MANIFEST_VERSION] = "1.0" } + JarOutputStream(librarySourcesPath.outputStream(), manifest).use { jarOutputStream -> + for (testFile in module.files) { + val text = testServices.sourceFileProvider.getContentOfSourceFile(testFile) + addFileToJar(testFile.relativePath, text, jarOutputStream) + } + } + return librarySourcesPath + } + + private fun buildCompilerOptions(module: TestModule, testServices: TestServices): List = buildList { + addAll(buildCommonCompilerOptions(module)) + addAll(buildPlatformCompilerOptions(module, testServices)) + } + + private fun buildCommonCompilerOptions(module: TestModule): List = buildList { + module.directives[LanguageSettingsDirectives.API_VERSION].firstOrNull()?.let { apiVersion -> + addAll(listOf(CommonCompilerArguments::apiVersion.cliArgument, apiVersion.versionString)) + } + + module.directives[LanguageSettingsDirectives.LANGUAGE].firstOrNull()?.let { + add("-XXLanguage:$it") + } + + if (LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE in module.directives) { + add(CommonCompilerArguments::allowKotlinPackage.cliArgument) + } + + addAll(module.directives[Directives.COMPILER_ARGUMENTS]) + } + + private fun addFileToJar(path: String, text: String, jarOutputStream: JarOutputStream) { + jarOutputStream.putNextEntry(JarEntry(path)) + ByteArrayInputStream(text.toByteArray()).copyTo(jarOutputStream) + jarOutputStream.closeEntry() + } +} + +class JvmJarTestModuleCompiler : CliTestModuleCompiler() { + override val compilerKind = CompilerExecutor.CompilerKind.JVM + + override fun buildPlatformCompilerOptions(module: TestModule, testServices: TestServices): List = buildList { + module.directives[JvmEnvironmentConfigurationDirectives.JVM_TARGET].firstOrNull()?.let { jvmTarget -> + addAll(listOf(K2JVMCompilerArguments::jvmTarget.cliArgument, jvmTarget.description)) + + val jdkHome = when { + jvmTarget <= JvmTarget.JVM_1_8 -> KtTestUtil.getJdk8Home() + jvmTarget <= JvmTarget.JVM_11 -> KtTestUtil.getJdk11Home() + jvmTarget <= JvmTarget.JVM_17 -> KtTestUtil.getJdk17Home() + jvmTarget <= JvmTarget.JVM_21 -> KtTestUtil.getJdk21Home() + else -> error("JDK for $jvmTarget is not found") + } + + addAll(listOf(K2JVMCompilerArguments::jdkHome.cliArgument, jdkHome.toString())) + } + } +} + +class JsKlibTestModuleCompiler : CliTestModuleCompiler() { + override val compilerKind = CompilerExecutor.CompilerKind.JS + + override fun buildPlatformCompilerOptions(module: TestModule, testServices: TestServices): List { + return listOf( + K2JSCompilerArguments::libraries.cliArgument, testServices.standardLibrariesPathProvider.fullJsStdlib().absolutePath, + ) + } +} + +/** + * [DispatchingTestModuleCompiler] chooses the appropriate compiler for a module based on its platform. + * In case all tests in a suite should compile libraries for a single platform, one of the underlying [TestModuleCompiler]s + * can be registered directly. Once new test compilers are introduced, they should be added to [DispatchingTestModuleCompiler]. + */ +class DispatchingTestModuleCompiler : TestModuleCompiler() { + private val compilersByKind = mapOf( + CompilerExecutor.CompilerKind.JVM to JvmJarTestModuleCompiler(), + CompilerExecutor.CompilerKind.JS to JsKlibTestModuleCompiler(), + ) + + override fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path { + return getCompiler(module).compileTestModuleToLibrary(module, testServices) + } + + override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { + return getCompiler(module).compileTestModuleToLibrarySources(module, testServices) + } + + private fun getCompiler(module: TestModule): CliTestModuleCompiler { + val compilerKindForModule = when { + module.targetPlatform.isJvm() -> CompilerExecutor.CompilerKind.JVM + module.targetPlatform.isJs() -> CompilerExecutor.CompilerKind.JS + else -> error("DispatchingTestModuleCompiler doesn't support the platform: ${module.targetPlatform}") + } + + return compilersByKind[compilerKindForModule] + ?: error("TestModuleCompiler is not available for ${compilerKindForModule.name}") + } +} diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompilerExecutor.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompilerExecutor.kt index 0f0f5303c46..94bc5015062 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompilerExecutor.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/CompilerExecutor.kt @@ -6,83 +6,68 @@ package org.jetbrains.kotlin.analysis.test.framework.services.libraries import org.jetbrains.kotlin.analysis.test.framework.utils.SkipTestException -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.cliArgument +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments -import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.cli.common.arguments.cliArgument +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.test.MockLibraryUtil -import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives -import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives -import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer -import org.jetbrains.kotlin.test.model.TestModule -import org.jetbrains.kotlin.test.util.KtTestUtil import java.nio.file.Path -import kotlin.io.path.absolutePathString -import kotlin.io.path.div -import kotlin.io.path.exists -import kotlin.io.path.notExists +import kotlin.io.path.* -object CompilerExecutor { - fun compileLibrary(sourcesPath: Path, options: List, compilationErrorExpected: Boolean): Path { - val library = sourcesPath / "library.jar" - val sourceFiles = sourcesPath.toFile().walkBottomUp() - val commands = buildList { - sourceFiles.mapTo(this) { it.absolutePath } - addAll(options) - add("-d") - add(library.absolutePathString()) - add("-XXLanguage:-SkipStandaloneScriptsInSourceRoots") - } - try { - MockLibraryUtil.runJvmCompiler(commands) +internal object CompilerExecutor { + fun compileLibrary(compilerKind: CompilerKind, sourcesPath: Path, options: List, compilationErrorExpected: Boolean): Path { + val library = try { + compile(compilerKind, sourcesPath, options) } catch (e: Throwable) { if (!compilationErrorExpected) { throw IllegalStateException("Unexpected compilation error while compiling library", e) } + null } - if (library.exists() && compilationErrorExpected) { + if (library?.exists() == true && compilationErrorExpected) { error("Compilation error expected but, code was compiled successfully") } - if (library.notExists()) { + if (library == null || library.notExists()) { throw LibraryWasNotCompiledDueToExpectedCompilationError() } return library } - fun parseCompilerOptionsFromTestdata(module: TestModule): List = buildList { - module.directives[LanguageSettingsDirectives.API_VERSION].firstOrNull()?.let { apiVersion -> - addAll(listOf(CommonCompilerArguments::apiVersion.cliArgument, apiVersion.versionString)) + private fun compile(compilerKind: CompilerKind, sourcesPath: Path, options: List): Path { + val sourceFiles = sourcesPath.toFile().walkBottomUp() + val library = when (compilerKind) { + CompilerKind.JVM -> sourcesPath / "library.jar" + CompilerKind.JS -> sourcesPath / "library.klib" } - - module.directives[LanguageSettingsDirectives.LANGUAGE].firstOrNull()?.let { - add("-XXLanguage:$it") - } - - if (LanguageSettingsDirectives.ALLOW_KOTLIN_PACKAGE in module.directives) { - add(CommonCompilerArguments::allowKotlinPackage.cliArgument) - } - - module.directives[JvmEnvironmentConfigurationDirectives.JVM_TARGET].firstOrNull()?.let { jvmTarget -> - addAll(listOf(K2JVMCompilerArguments::jvmTarget.cliArgument, jvmTarget.description)) - - val jdkHome = when { - jvmTarget <= JvmTarget.JVM_1_8 -> KtTestUtil.getJdk8Home() - jvmTarget <= JvmTarget.JVM_11 -> KtTestUtil.getJdk11Home() - jvmTarget <= JvmTarget.JVM_17 -> KtTestUtil.getJdk17Home() - jvmTarget <= JvmTarget.JVM_21 -> KtTestUtil.getJdk21Home() - else -> error("JDK for $jvmTarget is not found") + when (compilerKind) { + CompilerKind.JVM -> { + val commands = buildList { + sourceFiles.mapTo(this) { it.absolutePath } + addAll(options) + add(K2JVMCompilerArguments::destination.cliArgument); add(library.absolutePathString()) + add("-XXLanguage:-${LanguageFeature.SkipStandaloneScriptsInSourceRoots.name}") + } + MockLibraryUtil.runJvmCompiler(commands) + } + CompilerKind.JS -> { + val commands = buildList { + add(K2JSCompilerArguments::metaInfo.cliArgument) + add(K2JSCompilerArguments::moduleName.cliArgument); add("library") + add(K2JSCompilerArguments::outputDir.cliArgument); add(library.parent.absolutePathString()) + add(K2JSCompilerArguments::irProduceKlibFile.cliArgument) + sourceFiles.mapTo(this) { it.absolutePath } + addAll(options) + } + MockLibraryUtil.runJsCompiler(commands) } - - addAll(listOf(K2JVMCompilerArguments::jdkHome.cliArgument, jdkHome.toString())) } - addAll(module.directives[Directives.COMPILER_ARGUMENTS]) + return library } - object Directives : SimpleDirectivesContainer() { - val COMPILER_ARGUMENTS by stringDirective("List of additional compiler arguments") - val COMPILATION_ERRORS by directive("Is compilation errors expected in the file") + enum class CompilerKind { + JVM, JS } } diff --git a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt index e9a4e8cdb26..e2f5074d7ce 100644 --- a/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt +++ b/analysis/analysis-test-framework/tests/org/jetbrains/kotlin/analysis/test/framework/services/libraries/TestModuleCompiler.kt @@ -5,20 +5,15 @@ package org.jetbrains.kotlin.analysis.test.framework.services.libraries +import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.TestService import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.sourceFileProvider import org.jetbrains.kotlin.test.util.KtTestUtil -import java.io.ByteArrayInputStream import java.nio.file.Path -import java.util.jar.Attributes -import java.util.jar.JarEntry -import java.util.jar.JarOutputStream -import java.util.jar.Manifest import kotlin.io.path.createFile import kotlin.io.path.div -import kotlin.io.path.outputStream import kotlin.io.path.writeText abstract class TestModuleCompiler : TestService { @@ -29,37 +24,15 @@ abstract class TestModuleCompiler : TestService { val tmpSourceFile = (tmpDir / testFile.name).createFile() tmpSourceFile.writeText(text) } - return compile(tmpDir, module) + return compile(tmpDir, module, testServices) } - abstract fun compile(tmpDir: Path, module: TestModule): Path + abstract fun compile(tmpDir: Path, module: TestModule, testServices: TestServices): Path abstract fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path? -} -class TestModuleCompilerJar : TestModuleCompiler() { - override fun compile(tmpDir: Path, module: TestModule): Path = CompilerExecutor.compileLibrary( - tmpDir, - CompilerExecutor.parseCompilerOptionsFromTestdata(module), - compilationErrorExpected = CompilerExecutor.Directives.COMPILATION_ERRORS in module.directives - ) - - override fun compileTestModuleToLibrarySources(module: TestModule, testServices: TestServices): Path { - fun addFileToJar(path: String, text: String, jarOutputStream: JarOutputStream) { - jarOutputStream.putNextEntry(JarEntry(path)) - ByteArrayInputStream(text.toByteArray()).copyTo(jarOutputStream) - jarOutputStream.closeEntry() - } - - val tmpDir = KtTestUtil.tmpDir("testSourcesToCompile").toPath() - val librarySourcesPath = tmpDir / "library-sources.jar" - val manifest = Manifest().apply { mainAttributes[Attributes.Name.MANIFEST_VERSION] = "1.0" } - JarOutputStream(librarySourcesPath.outputStream(), manifest).use { jarOutputStream -> - for (testFile in module.files) { - val text = testServices.sourceFileProvider.getContentOfSourceFile(testFile) - addFileToJar(testFile.relativePath, text, jarOutputStream) - } - } - return librarySourcesPath + object Directives : SimpleDirectivesContainer() { + val COMPILER_ARGUMENTS by stringDirective("List of additional compiler arguments") + val COMPILATION_ERRORS by directive("Is compilation errors expected in the file") } } diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.kt new file mode 100644 index 00000000000..31343cc6548 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.kt @@ -0,0 +1,6 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass + +@Y +class Cls + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.txt new file mode 100644 index 00000000000..fc4971d8dea --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.txt @@ -0,0 +1,12 @@ +KT element: KtClass +KT element text: +@Y public final class Cls public constructor() { +} +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|Y|() public final [ResolvedTo(BODY_RESOLVE)] class Cls : R|kotlin/Any| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Cls] constructor(): R|Cls| + +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.kt new file mode 100644 index 00000000000..98b71730340 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.kt @@ -0,0 +1,5 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass + +class Cls @Y constructor() + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.txt new file mode 100644 index 00000000000..4a1ce1992a0 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.txt @@ -0,0 +1,12 @@ +KT element: KtClass +KT element text: +public final class Cls @Y public constructor() { +} +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] class Cls : R|kotlin/Any| { + @R|Y|() public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Cls] constructor(): R|Cls| + +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.kt new file mode 100644 index 00000000000..5fdaf079537 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.kt @@ -0,0 +1,3 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtFunction + +public inline fun Any?.asDynamic(): dynamic = this diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.txt new file mode 100644 index 00000000000..e22c243eb79 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.txt @@ -0,0 +1,8 @@ +KT element: KtNamedFunction +KT element text: +public inline fun kotlin.Any?.asDynamic(): dynamic /* platform type */ { /* compiled code */ } +FIR element: FirSimpleFunctionImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final inline [ResolvedTo(BODY_RESOLVE)] fun R|kotlin/Any?|.asDynamic(): R|dynamic| diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.kt new file mode 100644 index 00000000000..af1aa5e2dfd --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.kt @@ -0,0 +1,7 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass + +enum class Enum { + @Y ENTRY +} + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.txt new file mode 100644 index 00000000000..e33be21e624 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.txt @@ -0,0 +1,23 @@ +KT element: KtClass +KT element text: +public final enum class Enum private constructor() : kotlin.Enum { + @Y ENTRY; +} +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] enum class Enum : R|kotlin/Enum| { + public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Enum] fun valueOf([ResolvedTo(BODY_RESOLVE)] value: R|kotlin/String|): R|Enum| { + } + + public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Enum] fun values(): R|kotlin/Array| { + } + + public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Enum] val entries: R|kotlin/enums/EnumEntries| + public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/enums/EnumEntries| + + private [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Enum] constructor(): R|Enum| + + public final static [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Enum] enum entry ENTRY: R|Enum| +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.kt new file mode 100644 index 00000000000..6c9500bd9e6 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.kt @@ -0,0 +1,5 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtFunction + +@file:JsModule("extModule") +package ext.jspackage.name +external fun foo() diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.txt new file mode 100644 index 00000000000..f580cc46a86 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.txt @@ -0,0 +1,8 @@ +KT element: KtNamedFunction +KT element text: +public external fun foo(): kotlin.Unit { /* compiled code */ } +FIR element: FirSimpleFunctionImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final external [ResolvedTo(BODY_RESOLVE)] fun foo(): R|kotlin/Unit| diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.kt new file mode 100644 index 00000000000..16fea468c89 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.kt @@ -0,0 +1,7 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtFunction + +@Y +fun fn() { +} + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.txt new file mode 100644 index 00000000000..79bf0853fb0 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.txt @@ -0,0 +1,8 @@ +KT element: KtNamedFunction +KT element text: +@Y public fun fn(): kotlin.Unit { /* compiled code */ } +FIR element: FirSimpleFunctionImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|Y|() public final [ResolvedTo(BODY_RESOLVE)] fun fn(): R|kotlin/Unit| \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.kt new file mode 100644 index 00000000000..f2c45097a55 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.kt @@ -0,0 +1,7 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass + +@JsModule("jquery") +@JsNonModule +@JsName("$") +external abstract class JQuery() { +} diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.txt new file mode 100644 index 00000000000..2d48d07f4e5 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.txt @@ -0,0 +1,12 @@ +KT element: KtClass +KT element text: +@kotlin.js.JsModule @kotlin.js.JsNonModule @kotlin.js.JsName public abstract external class JQuery public constructor() { +} +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|kotlin/js/JsModule|(import = String(jquery)) @R|kotlin/js/JsNonModule|() @R|kotlin/js/JsName|(name = String($)) public abstract external [ResolvedTo(BODY_RESOLVE)] class JQuery : R|kotlin/Any| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=JQuery] constructor(): R|JQuery| + +} diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.kt new file mode 100644 index 00000000000..aae27976d21 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.kt @@ -0,0 +1,6 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtFunction + +fun fn(@Y p: String) { +} + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.txt new file mode 100644 index 00000000000..26bc14c2e3b --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.txt @@ -0,0 +1,8 @@ +KT element: KtNamedFunction +KT element text: +public fun fn(@Y p: kotlin.String): kotlin.Unit { /* compiled code */ } +FIR element: FirSimpleFunctionImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] fun fn([ResolvedTo(BODY_RESOLVE)] @R|Y|() p: R|kotlin/String|): R|kotlin/Unit| \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.kt new file mode 100644 index 00000000000..47f5c406e0f --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.kt @@ -0,0 +1,8 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtProperty + +@Y +var prop: Int = 0 + @Y get() = field + @Y set(value) { field = value } + +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.txt new file mode 100644 index 00000000000..25affa1d95b --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.txt @@ -0,0 +1,12 @@ +KT element: KtProperty +KT element text: +@Y public var prop: kotlin.Int /* compiled code */ + public final @Y get + public final @Y set(value: kotlin.Int) {/* compiled code */ } +FIR element: FirPropertyImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +@R|Y|() public final [ResolvedTo(BODY_RESOLVE)] var prop: R|kotlin/Int| + @R|Y|() public [ResolvedTo(BODY_RESOLVE)] get(): R|kotlin/Int| + @R|Y|() public [ResolvedTo(BODY_RESOLVE)] set([ResolvedTo(BODY_RESOLVE)] value: R|kotlin/Int|): R|kotlin/Unit| \ No newline at end of file diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.kt new file mode 100644 index 00000000000..d10ed0b605e --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.kt @@ -0,0 +1,6 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtProperty + +val prop: @Y Int = 1 + +@Target(AnnotationTarget.TYPE) +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.txt new file mode 100644 index 00000000000..8e054155fe6 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.txt @@ -0,0 +1,8 @@ +KT element: KtProperty +KT element text: +public val prop: @Y kotlin.Int = COMPILED_CODE /* compiled code */ +FIR element: FirPropertyImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] val prop: R|@R|Y|() kotlin/Int| diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.kt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.kt new file mode 100644 index 00000000000..629c254495d --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.kt @@ -0,0 +1,6 @@ +// DECLARATION_TYPE: org.jetbrains.kotlin.psi.KtClass + +class Cls<@Y T> + +@Target(AnnotationTarget.TYPE_PARAMETER) +annotation class Y diff --git a/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.txt b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.txt new file mode 100644 index 00000000000..b6397cae081 --- /dev/null +++ b/analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.txt @@ -0,0 +1,12 @@ +KT element: KtClass +KT element text: +public final class Cls<@Y T> public constructor() { +} +FIR element: FirRegularClassImpl +FIR source kind: KtRealSourceElementKind + +FIR element rendered: +public final [ResolvedTo(BODY_RESOLVE)] class Cls<@R|Y|() [ResolvedTo(BODY_RESOLVE)] T> : R|kotlin/Any| { + public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Cls] constructor<@R|Y|() [ResolvedTo(BODY_RESOLVE)] T>(): R|Cls| + +} \ No newline at end of file diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt index 07754f14598..fb1f3a174cf 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/AbstractLibraryGetOrBuildFirTest.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.util.FirDeclarationForCom import org.jetbrains.kotlin.analysis.project.structure.ProjectStructureProvider import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider +import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder import org.jetbrains.kotlin.test.directives.model.SimpleDirectivesContainer @@ -23,6 +24,9 @@ import org.jetbrains.kotlin.test.services.service abstract class AbstractLibraryGetOrBuildFirTest : AbstractLowLevelApiSingleFileTest() { override val configurator = AnalysisApiFirLibraryBinaryTestConfigurator override fun configureTest(builder: TestConfigurationBuilder) { + builder.forTestsMatching("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/*") { + this.defaultsProviderBuilder.targetPlatform = JsPlatforms.defaultJsPlatform + } super.configureTest(builder) with(builder) { useDirectives(Directives) diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java index 2f80d171184..b8801be96ba 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/LibraryGetOrBuildFirTestGenerated.java @@ -84,6 +84,82 @@ public class LibraryGetOrBuildFirTestGenerated extends AbstractLibraryGetOrBuild runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/typeParameter.kt"); } + @Nested + @TestMetadata("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js") + @TestDataPath("$PROJECT_ROOT") + public class Js { + @Test + public void testAllFilesPresentInJs() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("classAnnotation.kt") + public void testClassAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/classAnnotation.kt"); + } + + @Test + @TestMetadata("constructorAnnotation.kt") + public void testConstructorAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/constructorAnnotation.kt"); + } + + @Test + @TestMetadata("dynamic.kt") + public void testDynamic() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/dynamic.kt"); + } + + @Test + @TestMetadata("enumAnnotation.kt") + public void testEnumAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/enumAnnotation.kt"); + } + + @Test + @TestMetadata("fileJsModule.kt") + public void testFileJsModule() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/fileJsModule.kt"); + } + + @Test + @TestMetadata("functionAnnotation.kt") + public void testFunctionAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/functionAnnotation.kt"); + } + + @Test + @TestMetadata("jQueryExample.kt") + public void testJQueryExample() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/jQueryExample.kt"); + } + + @Test + @TestMetadata("parameterAnnotation.kt") + public void testParameterAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/parameterAnnotation.kt"); + } + + @Test + @TestMetadata("propertyAnnotation.kt") + public void testPropertyAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/propertyAnnotation.kt"); + } + + @Test + @TestMetadata("typeAnnotation.kt") + public void testTypeAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeAnnotation.kt"); + } + + @Test + @TestMetadata("typeParameterAnnotation.kt") + public void testTypeParameterAnnotation() throws Exception { + runTest("analysis/low-level-api-fir/testData/getOrBuildFirBinary/js/typeParameterAnnotation.kt"); + } + } + @Nested @TestMetadata("analysis/low-level-api-fir/testData/getOrBuildFirBinary/publishedApi") @TestDataPath("$PROJECT_ROOT") diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt index a2319540bca..d449a761cb0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/test/configurators/AnalysisApiFirLibraryBinaryTestConfigurator.kt @@ -34,7 +34,7 @@ object AnalysisApiFirLibraryBinaryTestConfigurator : AnalysisApiTestConfigurator override fun configureTest(builder: TestConfigurationBuilder, disposable: Disposable) { builder.apply { useAdditionalService { KtLibraryBinaryModuleFactory() } - useAdditionalService { TestModuleCompilerJar() } + useAdditionalService { DispatchingTestModuleCompiler() } useAdditionalService { TestModuleDecompilerJar() } } } diff --git a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt index 5a4264b91a5..897059b2ac2 100644 --- a/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt +++ b/analysis/symbol-light-classes/tests/org/jetbrains/kotlin/light/classes/symbol/base/AbstractSymbolLightClassesTestBase.kt @@ -11,7 +11,7 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompiledLibraryProvider -import org.jetbrains.kotlin.analysis.test.framework.services.libraries.CompilerExecutor +import org.jetbrains.kotlin.analysis.test.framework.services.libraries.TestModuleCompiler import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator import org.jetbrains.kotlin.asJava.finder.JavaElementFinder import org.jetbrains.kotlin.asJava.toLightClass @@ -51,7 +51,7 @@ abstract class AbstractSymbolLightClassesTestBase( super.configureTest(builder) with(builder) { useAdditionalServices(service(::CompiledLibraryProvider)) - useDirectives(Directives, CompilerExecutor.Directives) + useDirectives(Directives, TestModuleCompiler.Directives) useAdditionalSourceProviders(::NullabilityAnnotationSourceProvider) defaultDirectives { +ConfigurationDirectives.WITH_STDLIB @@ -67,7 +67,7 @@ abstract class AbstractSymbolLightClassesTestBase( } open fun doTestByFileStructure(ktFiles: List, module: TestModule, testServices: TestServices) { - if (isTestAgainstCompiledCode && CompilerExecutor.Directives.COMPILATION_ERRORS in module.directives) { + if (isTestAgainstCompiledCode && TestModuleCompiler.Directives.COMPILATION_ERRORS in module.directives) { return } diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/test/MockLibraryUtil.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/test/MockLibraryUtil.kt index 04447be224d..489cdd57fdd 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/test/MockLibraryUtil.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/test/MockLibraryUtil.kt @@ -163,7 +163,7 @@ object MockLibraryUtil { runCompiler(compiler2JVMClass, args) } - private fun runJsCompiler(args: List) { + fun runJsCompiler(args: List) { runCompiler(compiler2JSClass, args) }