[Wasm] Allow implementing function interfaces

This commit is contained in:
Svyatoslav Kuzmich
2022-11-10 14:49:00 +01:00
parent edc54524aa
commit 78bd6dbdcd
16 changed files with 24 additions and 29 deletions
@@ -391,6 +391,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
if (isIrBackendEnabled()) { if (isIrBackendEnabled()) {
this[LanguageFeature.JsAllowValueClassesInExternals] = LanguageFeature.State.ENABLED this[LanguageFeature.JsAllowValueClassesInExternals] = LanguageFeature.State.ENABLED
} }
if (wasm) {
this[LanguageFeature.JsAllowImplementingFunctionInterface] = LanguageFeature.State.ENABLED
}
} }
} }
} }
-2
View File
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
// TODO: Enable when JS backend supports Java class library, since FunctionX are required for interoperation // TODO: Enable when JS backend supports Java class library, since FunctionX are required for interoperation
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
// TODO: muted automatically, investigate should it be ran for JS or not // TODO: muted automatically, investigate should it be ran for JS or not
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
// TODO: muted automatically, investigate should it be ran for JS or not // TODO: muted automatically, investigate should it be ran for JS or not
@@ -4,8 +4,6 @@
// IGNORE_BACKEND: JVM, JS, JS_IR // IGNORE_BACKEND: JVM, JS, JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
// IGNORE_LIGHT_ANALYSIS // IGNORE_LIGHT_ANALYSIS
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
import helpers.* import helpers.*
import kotlin.coroutines.* import kotlin.coroutines.*
@@ -4,8 +4,6 @@
// IGNORE_BACKEND: JVM, JS, JS_IR // IGNORE_BACKEND: JVM, JS, JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
// IGNORE_LIGHT_ANALYSIS // IGNORE_LIGHT_ANALYSIS
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
import helpers.* import helpers.*
import kotlin.coroutines.* import kotlin.coroutines.*
@@ -1,5 +1,5 @@
// !LANGUAGE: +FunctionalTypeWithExtensionAsSupertype // !LANGUAGE: +FunctionalTypeWithExtensionAsSupertype
// IGNORE_BACKEND: JS, JS_IR, WASM // IGNORE_BACKEND: JS, JS_IR
interface I: (String) -> String interface I: (String) -> String
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS, JS_IR // IGNORE_BACKEND: JS, JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS, JS_IR // IGNORE_BACKEND: JS, JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// !LANGUAGE: +FunctionTypesWithBigArity // !LANGUAGE: +FunctionTypesWithBigArity
// Implementing function interface is prohibited in JavaScript // Implementing function interface is prohibited in JavaScript
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IGNORED_IN_JS
// IGNORE_BACKEND: JS_IR // IGNORE_BACKEND: JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
//KT-3190 Compiler crash if function called 'invoke' calls a closure //KT-3190 Compiler crash if function called 'invoke' calls a closure
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: WASM
// WASM_MUTE_REASON: IMPLEMENTING_FUNCTION_INTERFACE
// IGNORE_BACKEND_K1: JS_IR // IGNORE_BACKEND_K1: JS_IR
// IGNORE_BACKEND: JS_IR_ES6 // IGNORE_BACKEND: JS_IR_ES6
//KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T> //KT-3822 Compiler crashes when use invoke convention with `this` in class which extends Function0<T>
@@ -53,7 +53,11 @@ private fun specificFeaturesForTests(): Map<LanguageFeature, LanguageFeature.Sta
fun parseLanguageVersionSettingsOrDefault(directiveMap: Directives): CompilerTestLanguageVersionSettings = fun parseLanguageVersionSettingsOrDefault(directiveMap: Directives): CompilerTestLanguageVersionSettings =
parseLanguageVersionSettings(directiveMap) ?: defaultLanguageVersionSettings() parseLanguageVersionSettings(directiveMap) ?: defaultLanguageVersionSettings()
fun parseLanguageVersionSettings(directives: Directives): CompilerTestLanguageVersionSettings? { @JvmOverloads
fun parseLanguageVersionSettings(
directives: Directives,
extraLanguageFeatures: Map<LanguageFeature, LanguageFeature.State> = emptyMap()
): CompilerTestLanguageVersionSettings? {
val apiVersionString = directives[API_VERSION_DIRECTIVE] val apiVersionString = directives[API_VERSION_DIRECTIVE]
val languageFeaturesString = directives[LANGUAGE_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 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())) return CompilerTestLanguageVersionSettings(languageFeatures, apiVersion, languageVersion, mapOf(*analysisFlags.toTypedArray()))
} }
@@ -315,6 +315,7 @@ enum class LanguageFeature(
ValueClasses(sinceVersion = null, kind = UNSTABLE_FEATURE), ValueClasses(sinceVersion = null, kind = UNSTABLE_FEATURE),
JavaSamConversionEqualsHashCode(sinceVersion = null, kind = UNSTABLE_FEATURE), JavaSamConversionEqualsHashCode(sinceVersion = null, kind = UNSTABLE_FEATURE),
UnitConversionsOnArbitraryExpressions(sinceVersion = null), UnitConversionsOnArbitraryExpressions(sinceVersion = null),
JsAllowImplementingFunctionInterface(sinceVersion = null, kind = UNSTABLE_FEATURE),
; ;
init { init {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.js.resolve.diagnostics
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -44,10 +45,12 @@ object JsInheritanceChecker : DeclarationChecker {
} }
} }
if (descriptor is ClassDescriptor && if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JsAllowImplementingFunctionInterface)) {
descriptor.defaultType.immediateSupertypes().any { it.isBuiltinFunctionalTypeOrSubtype && !it.isSuspendFunctionTypeOrSubtype } if (descriptor is ClassDescriptor &&
) { descriptor.defaultType.immediateSupertypes().any { it.isBuiltinFunctionalTypeOrSubtype && !it.isSuspendFunctionTypeOrSubtype }
context.trace.report(ErrorsJs.IMPLEMENTING_FUNCTION_INTERFACE.on(declaration as KtClassOrObject)) ) {
context.trace.report(ErrorsJs.IMPLEMENTING_FUNCTION_INTERFACE.on(declaration as KtClassOrObject))
}
} }
} }
@@ -45,6 +45,10 @@ abstract class BasicWasmBoxTest(
private val COMMON_FILES_NAME = "_common" private val COMMON_FILES_NAME = "_common"
private val extraLanguageFeatures = mapOf(
LanguageFeature.JsAllowImplementingFunctionInterface to LanguageFeature.State.ENABLED,
)
fun doTest(filePath: String) = doTestWithTransformer(filePath) { it } fun doTest(filePath: String) = doTestWithTransformer(filePath) { it }
fun doTestWithTransformer(filePath: String, transformer: java.util.function.Function<String, String>) { fun doTestWithTransformer(filePath: String, transformer: java.util.function.Function<String, String>) {
val file = File(filePath) 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_ARRAY_RANGE_CHECKS, true)
configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, true) configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, true)
configuration.languageVersionSettings = languageVersionSettings 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) 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") val temporaryFile = File(tmpDir, "WASM_TEST/$fileName")
KtTestUtil.mkdirs(temporaryFile.parentFile) KtTestUtil.mkdirs(temporaryFile.parentFile)