From 54a45c49f8e874a7ff7fa7c4d77ce5d0023f2119 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Tue, 21 Feb 2023 21:53:12 +0100 Subject: [PATCH] [Wasm] Add Wasm platform and K1 FE infrastructure --- .../analysis-api-standalone/build.gradle.kts | 1 - .../project/structure/impl/KtModuleUtils.kt | 3 + build.gradle.kts | 3 + compiler/cli/build.gradle.kts | 1 + compiler/cli/cli-js/build.gradle.kts | 2 + .../jetbrains/kotlin/cli/js/K2JsIrCompiler.kt | 5 +- .../js/klib/TopDownAnalyzerFacadeForJSIR.kt | 11 ++- .../js/klib/TopDownAnalyzerFacadeForWasm.kt | 39 ++++++++ .../js/klib/prepareAnalyzedSourceModule.kt | 4 +- ...s.rendering.DefaultErrorMessages$Extension | 1 + .../jvm/compiler/EnvironmentConfigFiles.java | 1 + .../jetbrains/kotlin/ir/backend/js/klib.kt | 4 +- .../frontend/classic/ClassicFrontendFacade.kt | 44 +++++++++ .../services/CompilerConfigurationProvider.kt | 2 + .../WasmEnvironmentConfigurator.kt | 98 +++++++++++++++++++ .../jetbrains/kotlin/platform/WasmPlatform.kt | 13 +++ .../kotlin/frontend/js/di/injection.kt | 17 ++-- .../js/analyze/TopDownAnalyzerFacadeForJS.kt | 20 ++-- settings.gradle | 2 + wasm/wasm.config/build.gradle.kts | 12 +++ .../kotlin/platform/wasm/WasmPlatform.kt | 13 +++ wasm/wasm.frontend/build.gradle.kts | 16 +++ .../resolve/WasmPlatformAnalyzerServices.kt | 26 +++++ .../wasm/resolve/WasmPlatformConfigurator.kt | 54 ++++++++++ wasm/wasm.tests/build.gradle.kts | 17 +++- .../generators/tests/GenerateWasmTests.kt | 12 ++- .../kotlin/wasm/test/BasicWasmBoxTest.kt | 4 +- .../AbstractDiagnosticsWasmTest.kt | 59 +++++++++++ 28 files changed, 458 insertions(+), 26 deletions(-) create mode 100644 compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForWasm.kt create mode 100644 compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/WasmEnvironmentConfigurator.kt create mode 100644 core/compiler.common/src/org/jetbrains/kotlin/platform/WasmPlatform.kt create mode 100644 wasm/wasm.config/build.gradle.kts create mode 100644 wasm/wasm.config/src/org/jetbrains/kotlin/platform/wasm/WasmPlatform.kt create mode 100644 wasm/wasm.frontend/build.gradle.kts create mode 100644 wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformAnalyzerServices.kt create mode 100644 wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt create mode 100644 wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/diagnostics/AbstractDiagnosticsWasmTest.kt diff --git a/analysis/analysis-api-standalone/build.gradle.kts b/analysis/analysis-api-standalone/build.gradle.kts index 321cf1d56c5..45bf43a1f37 100644 --- a/analysis/analysis-api-standalone/build.gradle.kts +++ b/analysis/analysis-api-standalone/build.gradle.kts @@ -19,7 +19,6 @@ dependencies { api(project(":analysis:symbol-light-classes")) api(project(":analysis:decompiled:light-classes-for-decompiled")) api(project(":analysis:analysis-api-standalone:analysis-api-standalone-base")) - testApi(projectTests(":analysis:analysis-test-framework")) testApi(projectTests(":analysis:analysis-api-impl-base")) testApi(projectTests(":analysis:analysis-api-fir")) diff --git a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt index d6da6a54060..41938e25f1e 100644 --- a/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt +++ b/analysis/analysis-api-standalone/src/org/jetbrains/kotlin/analysis/project/structure/impl/KtModuleUtils.kt @@ -31,9 +31,11 @@ import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices +import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.isJs +import org.jetbrains.kotlin.platform.isWasm import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative @@ -49,6 +51,7 @@ internal fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServ return when { isJvm() -> JvmPlatformAnalyzerServices isJs() -> JsPlatformAnalyzerServices + isWasm() -> WasmPlatformAnalyzerServices isNative() -> NativePlatformAnalyzerServices isCommon() -> CommonPlatformAnalyzerServices else -> error("Unknown target platform: $this") diff --git a/build.gradle.kts b/build.gradle.kts index 3c6b6a48fab..c473cf769e8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -219,6 +219,8 @@ val fe10CompilerModules = arrayOf( ":js:js.dce", ":native:frontend.native", ":native:kotlin-native-utils", + ":wasm:wasm.frontend", + ":wasm:wasm.config", ":kotlin-build-common", ":compiler:backend.common.jvm", ":analysis:decompiled:light-classes-for-decompiled-fe10", @@ -667,6 +669,7 @@ tasks { register("wasmCompilerTest") { dependsOn(":wasm:wasm.tests:test") + dependsOn(":wasm:wasm.tests:diagnosticsTest") // Windows WABT release requires Visual C++ Redistributable if (!kotlinBuildProperties.isTeamcityBuild || !org.gradle.internal.os.OperatingSystem.current().isWindows) { dependsOn(":wasm:wasm.ir:test") diff --git a/compiler/cli/build.gradle.kts b/compiler/cli/build.gradle.kts index 3139a97f8cd..adc8f9d5fff 100644 --- a/compiler/cli/build.gradle.kts +++ b/compiler/cli/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { api(project(":compiler:javac-wrapper")) api(project(":js:js.translator")) api(project(":native:frontend.native")) + api(project(":wasm:wasm.frontend")) api(commonDependency("org.fusesource.jansi", "jansi")) api(project(":compiler:fir:raw-fir:psi2fir")) api(project(":compiler:fir:resolve")) diff --git a/compiler/cli/cli-js/build.gradle.kts b/compiler/cli/cli-js/build.gradle.kts index 5d3d93d7c1c..3d400d06a23 100644 --- a/compiler/cli/cli-js/build.gradle.kts +++ b/compiler/cli/cli-js/build.gradle.kts @@ -19,6 +19,8 @@ dependencies { api(project(":js:js.serializer")) api(project(":js:js.dce")) api(project(":js:js.sourcemap")) + api(project(":wasm:wasm.frontend")) + api(project(":wasm:wasm.config")) compileOnly(intellijCore()) } diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index 40492ccb093..b58252e5cd4 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -31,6 +31,8 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageUtil +import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR +import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForWasm import org.jetbrains.kotlin.cli.js.klib.generateIrForKlibSerialization import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment @@ -427,7 +429,8 @@ class K2JsIrCompiler : CLICompiler() { environmentForJS.configuration, libraries, friendLibraries, - AnalyzerWithCompilerReport(environmentForJS.configuration) + AnalyzerWithCompilerReport(environmentForJS.configuration), + analyzerFacade = if (arguments.wasm) TopDownAnalyzerFacadeForWasm else TopDownAnalyzerFacadeForJSIR ) val result = sourceModule.jsFrontEndResult.jsAnalysisResult if (result is JsAnalysisResult.RetryWithAdditionalRoots) { diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForJSIR.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForJSIR.kt index 97e5b43b0cd..1810a942055 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForJSIR.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForJSIR.kt @@ -11,11 +11,18 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider import org.jetbrains.kotlin.ir.backend.js.JsFactories -import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForJS +import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForWeb +import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices // TODO: put it in separated module `frontend.js` -object TopDownAnalyzerFacadeForJSIR : AbstractTopDownAnalyzerFacadeForJS() { +object TopDownAnalyzerFacadeForJSIR : AbstractTopDownAnalyzerFacadeForWeb() { + override val analyzerServices: PlatformDependentAnalyzerServices = JsPlatformAnalyzerServices + override val platform: TargetPlatform = JsPlatforms.defaultJsPlatform + override fun loadIncrementalCacheMetadata( incrementalData: IncrementalDataProvider, moduleContext: ModuleContext, diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForWasm.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForWasm.kt new file mode 100644 index 00000000000..7a0d37e9b30 --- /dev/null +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/TopDownAnalyzerFacadeForWasm.kt @@ -0,0 +1,39 @@ +/* + * 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.cli.js.klib + +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.context.ModuleContext +import org.jetbrains.kotlin.descriptors.PackageFragmentProvider +import org.jetbrains.kotlin.incremental.components.LookupTracker +import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider +import org.jetbrains.kotlin.ir.backend.js.JsFactories +import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForWeb +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.wasm.WasmPlatforms +import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices +import org.jetbrains.kotlin.wasm.resolve.WasmPlatformAnalyzerServices + +object TopDownAnalyzerFacadeForWasm : AbstractTopDownAnalyzerFacadeForWeb() { + override val analyzerServices: PlatformDependentAnalyzerServices = WasmPlatformAnalyzerServices + override val platform: TargetPlatform = WasmPlatforms.Default + + override fun loadIncrementalCacheMetadata( + incrementalData: IncrementalDataProvider, + moduleContext: ModuleContext, + lookupTracker: LookupTracker, + languageVersionSettings: LanguageVersionSettings + ): PackageFragmentProvider { + return JsFactories.DefaultDeserializedDescriptorFactory.createCachedPackageFragmentProvider( + incrementalData.compiledPackageParts.values.map { it.metadata }, + moduleContext.storageManager, + moduleContext.module, + CompilerDeserializationConfiguration(languageVersionSettings), + lookupTracker + ) + } +} \ No newline at end of file diff --git a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/prepareAnalyzedSourceModule.kt b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/prepareAnalyzedSourceModule.kt index b42a3c8f804..9f0061cdff9 100644 --- a/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/prepareAnalyzedSourceModule.kt +++ b/compiler/cli/cli-js/src/org/jetbrains/kotlin/cli/js/klib/prepareAnalyzedSourceModule.kt @@ -9,6 +9,7 @@ import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analyzer.AbstractAnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForWeb import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.psi.KtFile @@ -21,10 +22,11 @@ fun prepareAnalyzedSourceModule( friendDependencies: List, analyzer: AbstractAnalyzerWithCompilerReport, errorPolicy: ErrorTolerancePolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT, + analyzerFacade: AbstractTopDownAnalyzerFacadeForWeb = TopDownAnalyzerFacadeForJSIR, ): ModulesStructure { val mainModule = MainModule.SourceFiles(files) val sourceModule = ModulesStructure(project, mainModule, configuration, dependencies, friendDependencies) return sourceModule.apply { - runAnalysis(errorPolicy, analyzer, TopDownAnalyzerFacadeForJSIR) + runAnalysis(errorPolicy, analyzer, analyzerFacade) } } \ No newline at end of file diff --git a/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension b/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension index a7a0ec33d13..d9c11f9b3e4 100644 --- a/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension +++ b/compiler/cli/resources/META-INF/services/org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages$Extension @@ -2,3 +2,4 @@ org.jetbrains.kotlin.resolve.jvm.diagnostics.DefaultErrorMessagesJvm org.jetbrains.kotlin.js.resolve.diagnostics.DefaultErrorMessagesJs org.jetbrains.kotlin.resolve.konan.diagnostics.DefaultErrorMessagesNative +org.jetbrains.kotlin.wasm.resolve.diagnostics.DefaultErrorMessagesWasm diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/EnvironmentConfigFiles.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/EnvironmentConfigFiles.java index da1a2f9f74d..bfea7af9ad7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/EnvironmentConfigFiles.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/EnvironmentConfigFiles.java @@ -20,5 +20,6 @@ public enum EnvironmentConfigFiles { JVM_CONFIG_FILES, JS_CONFIG_FILES, NATIVE_CONFIG_FILES, + WASM_CONFIG_FILES, METADATA_CONFIG_FILES, } diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 6620da2b4b2..48cb5318d5d 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -42,7 +42,7 @@ import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForJS +import org.jetbrains.kotlin.js.analyze.AbstractTopDownAnalyzerFacadeForWeb import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy import org.jetbrains.kotlin.js.config.JSConfigurationKeys @@ -506,7 +506,7 @@ class ModulesStructure( fun runAnalysis( errorPolicy: ErrorTolerancePolicy, analyzer: AbstractAnalyzerWithCompilerReport, - analyzerFacade: AbstractTopDownAnalyzerFacadeForJS + analyzerFacade: AbstractTopDownAnalyzerFacadeForWeb ) { require(mainModule is MainModule.SourceFiles) val files = mainModule.files diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontendFacade.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontendFacade.kt index 5f94c49c10f..42cc467f7e5 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontendFacade.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/ClassicFrontendFacade.kt @@ -17,6 +17,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForJSIR +import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForWasm import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider import org.jetbrains.kotlin.cli.jvm.compiler.NoScopeRecordCliBindingTrace import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM @@ -51,6 +52,7 @@ import org.jetbrains.kotlin.platform.CommonPlatforms import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.isJs +import org.jetbrains.kotlin.platform.isWasm import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative @@ -65,6 +67,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProvid import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.test.directives.ConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives import org.jetbrains.kotlin.test.directives.MultiplatformDiagnosticsDirectives.ENABLE_MULTIPLATFORM_COMPOSITE_ANALYSIS_MODE import org.jetbrains.kotlin.test.model.DependencyRelation @@ -73,6 +76,7 @@ import org.jetbrains.kotlin.test.model.FrontendKinds import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.* import org.jetbrains.kotlin.test.services.configuration.JsEnvironmentConfigurator +import org.jetbrains.kotlin.test.services.configuration.WasmEnvironmentConfigurator import org.jetbrains.kotlin.test.util.KtTestUtil import org.jetbrains.kotlin.types.typeUtil.closure import org.jetbrains.kotlin.utils.addToStdlib.runIf @@ -159,6 +163,9 @@ class ClassicFrontendFacade( module, project, configuration, compilerEnvironment, files, dependencyDescriptors, friendsDescriptors ) } + targetPlatform.isWasm() -> performWasmModuleResolve( + module, project, configuration, compilerEnvironment, files, dependencyDescriptors, friendsDescriptors + ) targetPlatform.isNative() -> performNativeModuleResolve( module, project, compilerEnvironment, files, dependencyDescriptors, friendsDescriptors, dependsOnDescriptors ) @@ -331,6 +338,43 @@ class ClassicFrontendFacade( return analyzer.analysisResult } + private fun performWasmModuleResolve( + module: TestModule, + project: Project, + configuration: CompilerConfiguration, + compilerEnvironment: TargetEnvironment, + files: List, + dependencyDescriptors: List, + friendsDescriptors: List, + ): AnalysisResult { + val needsKotlinTest = ConfigurationDirectives.WITH_STDLIB in module.directives + + val runtimeKlibsNames = + listOfNotNull( + System.getProperty("kotlin.wasm.stdlib.path")!!, + System.getProperty("kotlin.wasm.kotlin.test.path")!!.takeIf { needsKotlinTest } + ).map { + File(it).absolutePath + } + + val runtimeKlibs = loadKlib(runtimeKlibsNames, configuration) + val transitiveLibraries = WasmEnvironmentConfigurator.getDependencies(module, testServices, DependencyRelation.RegularDependency) + val friendLibraries = WasmEnvironmentConfigurator.getDependencies(module, testServices, DependencyRelation.FriendDependency) + val allDependencies = runtimeKlibs + dependencyDescriptors + friendLibraries + friendsDescriptors + transitiveLibraries + + val builtInModuleDescriptor = allDependencies.firstNotNullOfOrNull { it.builtIns }?.builtInsModule + return TopDownAnalyzerFacadeForWasm.analyzeFiles( + files, + project, + configuration, + allDependencies, + friendsDescriptors + friendLibraries, + compilerEnvironment, + thisIsBuiltInsModule = builtInModuleDescriptor == null, + customBuiltInsModule = builtInModuleDescriptor + ) + } + private fun performNativeModuleResolve( module: TestModule, project: Project, diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt index 0a84f75e9b4..cb90cf28800 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.isJs +import org.jetbrains.kotlin.platform.isWasm import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative import org.jetbrains.kotlin.psi.KtFile @@ -117,6 +118,7 @@ fun TargetPlatform.platformToEnvironmentConfigFiles() = when { isJvm() -> EnvironmentConfigFiles.JVM_CONFIG_FILES isJs() -> EnvironmentConfigFiles.JS_CONFIG_FILES isNative() -> EnvironmentConfigFiles.NATIVE_CONFIG_FILES + isWasm() -> EnvironmentConfigFiles.WASM_CONFIG_FILES // TODO: is it correct? isCommon() -> EnvironmentConfigFiles.METADATA_CONFIG_FILES else -> error("Unknown platform: ${this}") diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/WasmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/WasmEnvironmentConfigurator.kt new file mode 100644 index 00000000000..2bcf8b0b6c1 --- /dev/null +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/WasmEnvironmentConfigurator.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2010-2020 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.services.configuration + +import org.jetbrains.kotlin.config.AnalysisFlag +import org.jetbrains.kotlin.config.AnalysisFlags.allowFullyQualifiedNameInKClass +import org.jetbrains.kotlin.config.AnalysisFlags.skipPrereleaseCheck +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.LanguageVersion +import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding +import org.jetbrains.kotlin.serialization.js.ModuleKind +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.EXPECT_ACTUAL_LINKER +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.GENERATE_INLINE_ANONYMOUS_FUNCTIONS +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.NO_INLINE +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.PROPERTY_LAZY_INITIALIZATION +import org.jetbrains.kotlin.test.directives.JsEnvironmentConfigurationDirectives.SOURCE_MAP_EMBED_SOURCES +import org.jetbrains.kotlin.test.directives.model.DirectivesContainer +import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives +import org.jetbrains.kotlin.test.model.ArtifactKinds +import org.jetbrains.kotlin.test.model.DependencyKind +import org.jetbrains.kotlin.test.model.DependencyRelation +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.* +import java.io.File + +class WasmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) { + override val directiveContainers: List + get() = listOf(JsEnvironmentConfigurationDirectives) + + companion object { + private fun getKlibDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List { + val visited = mutableSetOf() + fun getRecursive(module: TestModule, relation: DependencyRelation) { + val dependencies = if (relation == DependencyRelation.FriendDependency) { + module.friendDependencies + } else { + module.regularDependencies + } + dependencies + // See: `dependencyKind =` in AbstractJsBlackBoxCodegenTestBase.kt + .filter { it.kind != DependencyKind.Source } + .map { testServices.dependencyProvider.getTestModule(it.moduleName) }.forEach { + if (it !in visited) { + visited += it + getRecursive(it, relation) + } + } + } + getRecursive(module, kind) + return visited.map { testServices.dependencyProvider.getArtifact(it, ArtifactKinds.KLib).outputFile } + } + + fun getDependencies(module: TestModule, testServices: TestServices, kind: DependencyRelation): List { + return getKlibDependencies(module, testServices, kind) + .map { testServices.jsLibraryProvider.getDescriptorByPath(it.absolutePath) } + } + + } + + + override fun provideAdditionalAnalysisFlags( + directives: RegisteredDirectives, + languageVersion: LanguageVersion + ): Map, Any?> { + return super.provideAdditionalAnalysisFlags(directives, languageVersion).toMutableMap().also { + it[allowFullyQualifiedNameInKClass] = false + } + } + + override fun DirectiveToConfigurationKeyExtractor.provideConfigurationKeys() { + register(PROPERTY_LAZY_INITIALIZATION, JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION) + } + + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { + val registeredDirectives = module.directives + configuration.put(JSConfigurationKeys.MODULE_KIND, ModuleKind.ES) + + val noInline = registeredDirectives.contains(NO_INLINE) + configuration.put(CommonConfigurationKeys.DISABLE_INLINE, noInline) + configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name) + + val sourceDirs = module.files.map { it.originalFile.parent }.distinct() + configuration.put(JSConfigurationKeys.SOURCE_MAP_SOURCE_ROOTS, sourceDirs) + configuration.put(JSConfigurationKeys.SOURCE_MAP, true) + + val sourceMapSourceEmbedding = registeredDirectives[SOURCE_MAP_EMBED_SOURCES].singleOrNull() ?: SourceMapSourceEmbedding.NEVER + configuration.put(JSConfigurationKeys.SOURCE_MAP_EMBED_SOURCES, sourceMapSourceEmbedding) + + configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER, EXPECT_ACTUAL_LINKER in registeredDirectives) + } +} \ No newline at end of file diff --git a/core/compiler.common/src/org/jetbrains/kotlin/platform/WasmPlatform.kt b/core/compiler.common/src/org/jetbrains/kotlin/platform/WasmPlatform.kt new file mode 100644 index 00000000000..7ad94467169 --- /dev/null +++ b/core/compiler.common/src/org/jetbrains/kotlin/platform/WasmPlatform.kt @@ -0,0 +1,13 @@ +/* + * 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.platform + +object WasmPlatform : SimplePlatform("Wasm") { + override val oldFashionedDescription: String + get() = "Wasm " +} + +fun TargetPlatform?.isWasm(): Boolean = this?.singleOrNull() is WasmPlatform \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt index d5f6a94c84f..bddd6fb6aa8 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt @@ -33,12 +33,10 @@ import org.jetbrains.kotlin.incremental.components.InlineConstTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.platform.js.JsPlatforms -import org.jetbrains.kotlin.resolve.BindingTrace -import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer -import org.jetbrains.kotlin.resolve.TargetEnvironment -import org.jetbrains.kotlin.resolve.createContainer +import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory +import org.jetbrains.kotlin.platform.TargetPlatform fun createContainerForJS( moduleContext: ModuleContext, @@ -51,12 +49,14 @@ fun createContainerForJS( enumWhenTracker: EnumWhenTracker, additionalPackages: List, targetEnvironment: TargetEnvironment, + analyzerServices: PlatformDependentAnalyzerServices, + platform: TargetPlatform ): StorageComponentContainer { - val storageComponentContainer = createContainer("TopDownAnalyzerForJs", JsPlatformAnalyzerServices) { + val storageComponentContainer = createContainer("TopDownAnalyzerForJs", analyzerServices) { configureModule( moduleContext, - JsPlatforms.defaultJsPlatform, - JsPlatformAnalyzerServices, + platform, + analyzerServices, bindingTrace, languageVersionSettings, optimizingOptions = null, @@ -93,6 +93,7 @@ fun createTopDownAnalyzerForJs( ): LazyTopDownAnalyzer { return createContainerForJS( moduleContext, bindingTrace, declarationProviderFactory, languageVersionSettings, - lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker, additionalPackages, targetEnvironment + lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker, additionalPackages, targetEnvironment, + JsPlatformAnalyzerServices, JsPlatforms.defaultJsPlatform ).get() } diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt index 35205de0225..4bf1a0a2274 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt @@ -6,9 +6,6 @@ package org.jetbrains.kotlin.js.analyze import com.intellij.openapi.project.Project -import com.intellij.openapi.vfs.VirtualFile -import com.intellij.psi.search.DelegatingGlobalSearchScope -import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.builtins.DefaultBuiltIns import org.jetbrains.kotlin.builtins.functions.functionInterfacePackageFragmentProvider @@ -36,6 +33,7 @@ import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices import org.jetbrains.kotlin.js.resolve.MODULE_KIND import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.* @@ -45,9 +43,10 @@ import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.ModuleKind import org.jetbrains.kotlin.serialization.js.PackagesWithHeaderMetadata import org.jetbrains.kotlin.utils.JsMetadataVersion -import org.jetbrains.kotlin.utils.addToStdlib.safeAs -abstract class AbstractTopDownAnalyzerFacadeForJS { +abstract class AbstractTopDownAnalyzerFacadeForWeb { + abstract val analyzerServices: PlatformDependentAnalyzerServices + abstract val platform: TargetPlatform fun analyzeFiles( files: Collection, @@ -74,7 +73,7 @@ abstract class AbstractTopDownAnalyzerFacadeForJS { ProjectContext(project, "TopDownAnalyzer for JS"), Name.special("<$moduleName>"), builtIns, - platform = JsPlatforms.defaultJsPlatform + platform = platform ) val additionalPackages = mutableListOf() @@ -109,7 +108,7 @@ abstract class AbstractTopDownAnalyzerFacadeForJS { configuration: CompilerConfiguration, targetEnvironment: TargetEnvironment, project: Project, - additionalPackages: List = emptyList() + additionalPackages: List = emptyList(), ): JsAnalysisResult { val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing @@ -130,6 +129,8 @@ abstract class AbstractTopDownAnalyzerFacadeForJS { enumWhenTracker, additionalPackages + listOfNotNull(packageFragment), targetEnvironment, + analyzerServices, + platform ) val analysisHandlerExtensions = AnalysisHandlerExtension.getInstances(project) @@ -193,7 +194,10 @@ abstract class AbstractTopDownAnalyzerFacadeForJS { } } -object TopDownAnalyzerFacadeForJS : AbstractTopDownAnalyzerFacadeForJS() { +object TopDownAnalyzerFacadeForJS : AbstractTopDownAnalyzerFacadeForWeb() { + + override val analyzerServices: PlatformDependentAnalyzerServices = JsPlatformAnalyzerServices + override val platform: TargetPlatform = JsPlatforms.defaultJsPlatform override fun loadIncrementalCacheMetadata( incrementalData: IncrementalDataProvider, diff --git a/settings.gradle b/settings.gradle index d6146c36242..801cab3605e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -253,6 +253,8 @@ include ":kotlin-imports-dumper-compiler-plugin", ":test-instrumenter", ":wasm:wasm.ir", ":wasm:wasm.tests", + ":wasm:wasm.frontend", + ":wasm:wasm.config", ":repo:codebase-tests" include ":kotlinx-atomicfu-compiler-plugin", diff --git a/wasm/wasm.config/build.gradle.kts b/wasm/wasm.config/build.gradle.kts new file mode 100644 index 00000000000..ca15c3417e2 --- /dev/null +++ b/wasm/wasm.config/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + kotlin("jvm") + id("jps-compatible") +} + +dependencies { + api(project(":compiler:config")) +} + +sourceSets { + "main" { projectDefault() } +} diff --git a/wasm/wasm.config/src/org/jetbrains/kotlin/platform/wasm/WasmPlatform.kt b/wasm/wasm.config/src/org/jetbrains/kotlin/platform/wasm/WasmPlatform.kt new file mode 100644 index 00000000000..2c25a42a1cb --- /dev/null +++ b/wasm/wasm.config/src/org/jetbrains/kotlin/platform/wasm/WasmPlatform.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. 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.platform.wasm + +import org.jetbrains.kotlin.platform.TargetPlatform +import org.jetbrains.kotlin.platform.WasmPlatform + +object WasmPlatforms { + object Default : TargetPlatform(setOf(WasmPlatform)) +} \ No newline at end of file diff --git a/wasm/wasm.frontend/build.gradle.kts b/wasm/wasm.frontend/build.gradle.kts new file mode 100644 index 00000000000..76941e1b930 --- /dev/null +++ b/wasm/wasm.frontend/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + kotlin("jvm") + id("jps-compatible") +} + +dependencies { + api(project(":compiler:util")) + api(project(":compiler:frontend")) + api(project(":js:js.frontend")) + compileOnly(intellijCore()) +} + +sourceSets { + "main" { projectDefault() } + "test" {} +} diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformAnalyzerServices.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformAnalyzerServices.kt new file mode 100644 index 00000000000..6021d7168dd --- /dev/null +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformAnalyzerServices.kt @@ -0,0 +1,26 @@ +/* + * 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.wasm.resolve + +import org.jetbrains.kotlin.builtins.DefaultBuiltIns +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.storage.StorageManager + +object WasmPlatformAnalyzerServices : PlatformDependentAnalyzerServices() { + override fun computePlatformSpecificDefaultImports(storageManager: StorageManager, result: MutableList) { + result.add(ImportPath.fromString("kotlin.js.*")) + } + + override val platformConfigurator: PlatformConfigurator = WasmPlatformConfigurator + + val builtIns: KotlinBuiltIns + get() = DefaultBuiltIns.Instance + + override val excludedImports: List = + listOf("Promise", "Date", "Console", "Math", "RegExp", "RegExpMatch", "Json", "json").map { FqName("kotlin.js.$it") } +} diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt new file mode 100644 index 00000000000..d210379822f --- /dev/null +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt @@ -0,0 +1,54 @@ +/* + * 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.wasm.resolve + +import org.jetbrains.kotlin.container.StorageComponentContainer +import org.jetbrains.kotlin.container.useImpl +import org.jetbrains.kotlin.container.useInstance +import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor +import org.jetbrains.kotlin.js.naming.NameSuggestion +import org.jetbrains.kotlin.js.resolve.ExtensionFunctionToExternalIsInlinable +import org.jetbrains.kotlin.js.resolve.diagnostics.* +import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase +import org.jetbrains.kotlin.resolve.calls.checkers.LateinitIntrinsicApplicabilityChecker +import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker +import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmExternalInheritanceChecker + +// TODO: Review the list of used K/JS checkers. +// Refactor useful checkers into common module. +object WasmPlatformConfigurator : PlatformConfiguratorBase( + additionalDeclarationCheckers = listOf( + JsNameChecker, JsModuleChecker, JsExternalFileChecker, + JsExternalChecker, WasmExternalInheritanceChecker, + JsRuntimeAnnotationChecker, + JsExportAnnotationChecker, + JsExportDeclarationChecker, + ), + additionalCallCheckers = listOf( + JsModuleCallChecker, + JsDefinedExternallyCallChecker, + LateinitIntrinsicApplicabilityChecker(isWarningInPre19 = true) + ), +) { + override fun configureModuleComponents(container: StorageComponentContainer) { + container.useInstance(NameSuggestion()) + container.useImpl() + container.useImpl() + container.useImpl() + container.useInstance(JsModuleClassLiteralChecker) + container.useImpl() + container.useImpl() + container.useImpl() + container.useInstance(ExtensionFunctionToExternalIsInlinable) + container.useInstance(JsQualifierChecker) + container.useInstance(JsNativeDiagnosticSuppressor) + } + + override fun configureModuleDependentCheckers(container: StorageComponentContainer) { + super.configureModuleDependentCheckers(container) + container.useImpl() + } +} diff --git a/wasm/wasm.tests/build.gradle.kts b/wasm/wasm.tests/build.gradle.kts index 6c092f77bff..a10b84bdff2 100644 --- a/wasm/wasm.tests/build.gradle.kts +++ b/wasm/wasm.tests/build.gradle.kts @@ -12,6 +12,7 @@ plugins { dependencies { testApi(commonDependency("junit:junit")) testApi(projectTests(":compiler:tests-common")) + testApi(projectTests(":compiler:tests-common-new")) testApi(intellijCore()) } @@ -130,9 +131,23 @@ val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateWa projectTest(parallel = true) { workingDir = rootDir + exclude("**/diagnostics/*.class") setupV8() setupSpiderMonkey() setupWasmStdlib() setupGradlePropertiesForwarding() systemProperty("kotlin.wasm.test.root.out.dir", "$buildDir/") -} \ No newline at end of file +} + +projectTest( + taskName = "diagnosticsTest", + parallel = true, + jUnitMode = JUnitMode.JUnit5 +) { + workingDir = rootDir + include("**/diagnostics/*.class") + useJUnitPlatform() + setupWasmStdlib() + setupGradlePropertiesForwarding() + systemProperty("kotlin.wasm.test.root.out.dir", "$buildDir/") +} diff --git a/wasm/wasm.tests/test/org/jetbrains/kotlin/generators/tests/GenerateWasmTests.kt b/wasm/wasm.tests/test/org/jetbrains/kotlin/generators/tests/GenerateWasmTests.kt index 32e0c1ec163..6c2176ff126 100644 --- a/wasm/wasm.tests/test/org/jetbrains/kotlin/generators/tests/GenerateWasmTests.kt +++ b/wasm/wasm.tests/test/org/jetbrains/kotlin/generators/tests/GenerateWasmTests.kt @@ -5,9 +5,11 @@ package org.jetbrains.kotlin.generators.tests +import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5 import org.jetbrains.kotlin.generators.impl.generateTestGroupSuite import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.wasm.test.* +import org.jetbrains.kotlin.wasm.test.diagnostics.AbstractDiagnosticsWasmTest fun main(args: Array) { System.setProperty("java.awt.headless", "true") @@ -52,4 +54,12 @@ fun main(args: Array) { } } } -} + + generateTestGroupSuiteWithJUnit5(args) { + testGroup("wasm/wasm.tests/tests-gen", "compiler/testData") { + testClass { + model("diagnostics/wasmTests") + } + } + } +} \ No newline at end of file diff --git a/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/BasicWasmBoxTest.kt b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/BasicWasmBoxTest.kt index db87b6299d9..8d303668550 100644 --- a/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/BasicWasmBoxTest.kt +++ b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/BasicWasmBoxTest.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.wasm.* import org.jetbrains.kotlin.backend.wasm.dce.eliminateDeadDeclarations import org.jetbrains.kotlin.checkers.parseLanguageVersionSettings import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport +import org.jetbrains.kotlin.cli.js.klib.TopDownAnalyzerFacadeForWasm import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.config.* @@ -140,7 +141,8 @@ abstract class BasicWasmBoxTest( // TODO: Bypass the resolver fow wasm. listOf(System.getProperty("kotlin.wasm.stdlib.path")!!, System.getProperty("kotlin.wasm.kotlin.test.path")!!), emptyList(), - AnalyzerWithCompilerReport(config.configuration) + AnalyzerWithCompilerReport(config.configuration), + analyzerFacade = TopDownAnalyzerFacadeForWasm ) val (allModules, backendContext) = compileToLoweredIr( diff --git a/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/diagnostics/AbstractDiagnosticsWasmTest.kt b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/diagnostics/AbstractDiagnosticsWasmTest.kt new file mode 100644 index 00000000000..c340b583570 --- /dev/null +++ b/wasm/wasm.tests/test/org/jetbrains/kotlin/wasm/test/diagnostics/AbstractDiagnosticsWasmTest.kt @@ -0,0 +1,59 @@ +/* + * 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.wasm.test.diagnostics + +import org.jetbrains.kotlin.platform.wasm.WasmPlatforms +import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder +import org.jetbrains.kotlin.test.builders.classicFrontendHandlersStep +import org.jetbrains.kotlin.test.builders.classicFrontendStep +import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives +import org.jetbrains.kotlin.test.frontend.classic.handlers.ClassicDiagnosticsHandler +import org.jetbrains.kotlin.test.frontend.classic.handlers.DeclarationsDumpHandler +import org.jetbrains.kotlin.test.frontend.classic.handlers.OldNewInferenceMetaInfoProcessor +import org.jetbrains.kotlin.test.model.DependencyKind +import org.jetbrains.kotlin.test.model.FrontendKinds +import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest +import org.jetbrains.kotlin.test.services.JsLibraryProvider +import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator +import org.jetbrains.kotlin.test.services.configuration.WasmEnvironmentConfigurator +import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider +import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider + +abstract class AbstractDiagnosticsWasmTest : AbstractKotlinCompilerTest() { + override fun TestConfigurationBuilder.configuration() { + globalDefaults { + frontend = FrontendKinds.ClassicFrontend + targetPlatform = WasmPlatforms.Default + dependencyKind = DependencyKind.Source + } + + defaultDirectives { + +JvmEnvironmentConfigurationDirectives.USE_PSI_CLASS_FILES_READING + } + + enableMetaInfoHandler() + + useConfigurators( + ::CommonEnvironmentConfigurator, + ::WasmEnvironmentConfigurator, + ) + + useMetaInfoProcessors(::OldNewInferenceMetaInfoProcessor) + useAdditionalSourceProviders( + ::AdditionalDiagnosticsSourceFilesProvider, + ::CoroutineHelpersSourceFilesProvider, + ) + useAdditionalService(::JsLibraryProvider) + + classicFrontendStep() + classicFrontendHandlersStep { + useHandlers( + ::DeclarationsDumpHandler, + ::ClassicDiagnosticsHandler, + ) + } + } +}