From 78bd6dbdcd35072787c465d5e9297546ba4d43fc Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Thu, 10 Nov 2022 14:49:00 +0100 Subject: [PATCH] [Wasm] Allow implementing function interfaces --- .../cli/common/arguments/K2JSCompilerArguments.kt | 3 +++ compiler/testData/codegen/box/classes/kt1535.kt | 2 -- .../codegen/box/closures/closureOnTopLevel1.kt | 2 -- .../codegen/box/closures/closureOnTopLevel2.kt | 2 -- .../intersectionTypeToSubtypeConversion.kt | 2 -- .../subtypeOfFunctionalTypeToSuspendConversion.kt | 2 -- .../extensionFunctionAsSupertype.kt | 2 +- .../intersectionTypeToFunInterfaceConversion.kt | 2 -- ...subtypeOfFunctionalTypeToFunInterfaceConversion.kt | 2 -- .../codegen/box/functions/bigArity/subclass.kt | 2 -- .../testData/codegen/box/functions/invoke/kt3190.kt | 2 -- .../box/functions/invoke/kt3822invokeOnThis.kt | 2 -- .../checkers/CompilerTestLanguageVersionSettings.kt | 8 ++++++-- .../kotlin/config/LanguageVersionSettings.kt | 1 + .../js/resolve/diagnostics/JsInheritanceChecker.kt | 11 +++++++---- .../jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt | 8 ++++++-- 16 files changed, 24 insertions(+), 29 deletions(-) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt index 6d26efed96d..49de6db63a0 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/K2JSCompilerArguments.kt @@ -391,6 +391,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() { if (isIrBackendEnabled()) { this[LanguageFeature.JsAllowValueClassesInExternals] = LanguageFeature.State.ENABLED } + if (wasm) { + this[LanguageFeature.JsAllowImplementingFunctionInterface] = LanguageFeature.State.ENABLED + } } } } diff --git a/compiler/testData/codegen/box/classes/kt1535.kt b/compiler/testData/codegen/box/classes/kt1535.kt index b97b80ec3f8..de7816b4482 100644 --- a/compiler/testData/codegen/box/classes/kt1535.kt +++ b/compiler/testData/codegen/box/classes/kt1535.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: Enable when JS backend supports Java class library, since FunctionX are required for interoperation diff --git a/compiler/testData/codegen/box/closures/closureOnTopLevel1.kt b/compiler/testData/codegen/box/closures/closureOnTopLevel1.kt index cfc94f1d25f..197573699e4 100644 --- a/compiler/testData/codegen/box/closures/closureOnTopLevel1.kt +++ b/compiler/testData/codegen/box/closures/closureOnTopLevel1.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/codegen/box/closures/closureOnTopLevel2.kt b/compiler/testData/codegen/box/closures/closureOnTopLevel2.kt index 5f25ce47070..642b0693e72 100644 --- a/compiler/testData/codegen/box/closures/closureOnTopLevel2.kt +++ b/compiler/testData/codegen/box/closures/closureOnTopLevel2.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 // TODO: muted automatically, investigate should it be ran for JS or not diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt index bb6d30fadc4..261346efcef 100644 --- a/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/intersectionTypeToSubtypeConversion.kt @@ -4,8 +4,6 @@ // IGNORE_BACKEND: JVM, JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 // IGNORE_LIGHT_ANALYSIS -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt index 966652cb224..ccc996884db 100644 --- a/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt +++ b/compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt @@ -4,8 +4,6 @@ // IGNORE_BACKEND: JVM, JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 // IGNORE_LIGHT_ANALYSIS -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS import helpers.* import kotlin.coroutines.* diff --git a/compiler/testData/codegen/box/extensionFunctions/extensionFunctionAsSupertype.kt b/compiler/testData/codegen/box/extensionFunctions/extensionFunctionAsSupertype.kt index 72e5f377313..9fb4bb9fafa 100644 --- a/compiler/testData/codegen/box/extensionFunctions/extensionFunctionAsSupertype.kt +++ b/compiler/testData/codegen/box/extensionFunctions/extensionFunctionAsSupertype.kt @@ -1,5 +1,5 @@ // !LANGUAGE: +FunctionalTypeWithExtensionAsSupertype -// IGNORE_BACKEND: JS, JS_IR, WASM +// IGNORE_BACKEND: JS, JS_IR interface I: (String) -> String diff --git a/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt index ceac246720a..3d5c9551b86 100644 --- a/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt +++ b/compiler/testData/codegen/box/funInterface/intersectionTypeToFunInterfaceConversion.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS // IGNORE_BACKEND: JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 diff --git a/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt b/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt index 5084a208d40..95339eb50a0 100644 --- a/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt +++ b/compiler/testData/codegen/box/funInterface/subtypeOfFunctionalTypeToFunInterfaceConversion.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS // IGNORE_BACKEND: JS, JS_IR // IGNORE_BACKEND: JS_IR_ES6 diff --git a/compiler/testData/codegen/box/functions/bigArity/subclass.kt b/compiler/testData/codegen/box/functions/bigArity/subclass.kt index 86f7537387a..98af6b62ecd 100644 --- a/compiler/testData/codegen/box/functions/bigArity/subclass.kt +++ b/compiler/testData/codegen/box/functions/bigArity/subclass.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS // !LANGUAGE: +FunctionTypesWithBigArity // Implementing function interface is prohibited in JavaScript diff --git a/compiler/testData/codegen/box/functions/invoke/kt3190.kt b/compiler/testData/codegen/box/functions/invoke/kt3190.kt index ade38885c2e..47860503093 100644 --- a/compiler/testData/codegen/box/functions/invoke/kt3190.kt +++ b/compiler/testData/codegen/box/functions/invoke/kt3190.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IGNORED_IN_JS // IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR_ES6 //KT-3190 Compiler crash if function called 'invoke' calls a closure diff --git a/compiler/testData/codegen/box/functions/invoke/kt3822invokeOnThis.kt b/compiler/testData/codegen/box/functions/invoke/kt3822invokeOnThis.kt index b1e064bc37f..7fb2ba167fd 100644 --- a/compiler/testData/codegen/box/functions/invoke/kt3822invokeOnThis.kt +++ b/compiler/testData/codegen/box/functions/invoke/kt3822invokeOnThis.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: WASM -// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE // IGNORE_BACKEND_K1: JS_IR // IGNORE_BACKEND: JS_IR_ES6 //KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0 diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt index e6e234dde5f..c420549f6aa 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/CompilerTestLanguageVersionSettings.kt @@ -53,7 +53,11 @@ private fun specificFeaturesForTests(): Map = emptyMap() +): CompilerTestLanguageVersionSettings? { val apiVersionString = directives[API_VERSION_DIRECTIVE] val languageFeaturesString = directives[LANGUAGE_DIRECTIVE] @@ -81,7 +85,7 @@ fun parseLanguageVersionSettings(directives: Directives): CompilerTestLanguageVe val languageVersion = maxOf(LanguageVersion.LATEST_STABLE, LanguageVersion.fromVersionString(apiVersion.versionString)!!) - val languageFeatures = languageFeaturesString?.let(::collectLanguageFeatureMap).orEmpty() + val languageFeatures = languageFeaturesString?.let(::collectLanguageFeatureMap).orEmpty() + extraLanguageFeatures return CompilerTestLanguageVersionSettings(languageFeatures, apiVersion, languageVersion, mapOf(*analysisFlags.toTypedArray())) } diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index a5cfce49cfe..4877766d375 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -315,6 +315,7 @@ enum class LanguageFeature( ValueClasses(sinceVersion = null, kind = UNSTABLE_FEATURE), JavaSamConversionEqualsHashCode(sinceVersion = null, kind = UNSTABLE_FEATURE), UnitConversionsOnArbitraryExpressions(sinceVersion = null), + JsAllowImplementingFunctionInterface(sinceVersion = null, kind = UNSTABLE_FEATURE), ; init { diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsInheritanceChecker.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsInheritanceChecker.kt index 927ac3c3af1..a3e48c426f1 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsInheritanceChecker.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/resolve/diagnostics/JsInheritanceChecker.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.resolve.diagnostics import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor @@ -44,10 +45,12 @@ object JsInheritanceChecker : DeclarationChecker { } } - if (descriptor is ClassDescriptor && - descriptor.defaultType.immediateSupertypes().any { it.isBuiltinFunctionalTypeOrSubtype && !it.isSuspendFunctionTypeOrSubtype } - ) { - context.trace.report(ErrorsJs.IMPLEMENTING_FUNCTION_INTERFACE.on(declaration as KtClassOrObject)) + if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowImplementingFunctionInterface)) { + if (descriptor is ClassDescriptor && + descriptor.defaultType.immediateSupertypes().any { it.isBuiltinFunctionalTypeOrSubtype && !it.isSuspendFunctionTypeOrSubtype } + ) { + context.trace.report(ErrorsJs.IMPLEMENTING_FUNCTION_INTERFACE.on(declaration as KtClassOrObject)) + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt index 0e7ef05ede7..7c60a79cf00 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/BasicWasmBoxTest.kt @@ -45,6 +45,10 @@ abstract class BasicWasmBoxTest( private val COMMON_FILES_NAME = "_common" + private val extraLanguageFeatures = mapOf( + LanguageFeature.JsAllowImplementingFunctionInterface to LanguageFeature.State.ENABLED, + ) + fun doTest(filePath: String) = doTestWithTransformer(filePath) { it } fun doTestWithTransformer(filePath: String, transformer: java.util.function.Function) { val file = File(filePath) @@ -241,7 +245,7 @@ abstract class BasicWasmBoxTest( configuration.put(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS, true) configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, true) configuration.languageVersionSettings = languageVersionSettings - ?: LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE) + ?: LanguageVersionSettingsImpl(LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, specificFeatures = extraLanguageFeatures) return JsConfig(project, configuration, CompilerEnvironment, null, null) } @@ -256,7 +260,7 @@ abstract class BasicWasmBoxTest( } } - val languageVersionSettings = parseLanguageVersionSettings(directives) + val languageVersionSettings = parseLanguageVersionSettings(directives, extraLanguageFeatures) val temporaryFile = File(tmpDir, "WASM_TEST/$fileName") KtTestUtil.mkdirs(temporaryFile.parentFile)