diff --git a/compiler/testData/diagnostics/wasmTests/jsInterop/jsFun.kt b/compiler/testData/diagnostics/wasmTests/jsInterop/jsFun.kt new file mode 100644 index 00000000000..7ae2cad609e --- /dev/null +++ b/compiler/testData/diagnostics/wasmTests/jsInterop/jsFun.kt @@ -0,0 +1,15 @@ +@JsFun("() => {}") +external fun topLevelExternalFun(): Unit + +external class ExternalClass { + @JsFun("() => {}") + fun memberFun(): Unit +} + +@JsFun("() => {}") +fun topLevelNonExternalFun(): Unit {} + +class NonExternalClass { + @JsFun("() => {}") + fun memberFun(): Unit {} +} 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 index 1ba7ab0bdcd..c9c02971f0e 100644 --- a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/WasmPlatformConfigurator.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmExternalDeclarationChecker import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmExternalInheritanceChecker import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmImportAnnotationChecker +import org.jetbrains.kotlin.wasm.resolve.diagnostics.WasmJsFunAnnotationChecker // TODO: Review the list of used K/JS checkers. // Refactor useful checkers into common module. @@ -30,6 +31,7 @@ object WasmPlatformConfigurator : PlatformConfiguratorBase( JsExportDeclarationChecker, WasmExternalDeclarationChecker, WasmImportAnnotationChecker, + WasmJsFunAnnotationChecker, ), additionalCallCheckers = listOf( JsModuleCallChecker, diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/DefaultErrorMessagesWasm.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/DefaultErrorMessagesWasm.kt index 4927d1ff278..9520d1a300e 100644 --- a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/DefaultErrorMessagesWasm.kt +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/DefaultErrorMessagesWasm.kt @@ -23,6 +23,8 @@ private val DIAGNOSTIC_FACTORY_TO_RENDERER by lazy { put(ErrorsWasm.WASM_IMPORT_VARARG_PARAMETER, "Vararg parameters are not supported with @WasmImport") put(ErrorsWasm.WASM_IMPORT_UNSUPPORTED_PARAMETER_TYPE, "Unsupported @WasmImport parameter type {0}", Renderers.RENDER_TYPE) put(ErrorsWasm.WASM_IMPORT_UNSUPPORTED_RETURN_TYPE, "Unsupported @WasmImport return type {0}", Renderers.RENDER_TYPE) + + put(ErrorsWasm.WRONG_JS_FUN_TARGET, "Only top-level external functions can be implemented using @JsFun") } } diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/ErrorsWasm.java b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/ErrorsWasm.java index c767fcf4f79..b5ca65acd57 100644 --- a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/ErrorsWasm.java +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/ErrorsWasm.java @@ -26,6 +26,8 @@ public interface ErrorsWasm { DiagnosticFactory1 WASM_IMPORT_UNSUPPORTED_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1 WASM_IMPORT_UNSUPPORTED_RETURN_TYPE = DiagnosticFactory1.create(ERROR); + DiagnosticFactory0 WRONG_JS_FUN_TARGET = DiagnosticFactory0.create(ERROR); + @SuppressWarnings("UnusedDeclaration") Object _initializer = new Object() { { diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmJsFunAnnotationChecker.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmJsFunAnnotationChecker.kt new file mode 100644 index 00000000000..521f350085b --- /dev/null +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmJsFunAnnotationChecker.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.wasm.resolve.diagnostics + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker +import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext +import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal +import org.jetbrains.kotlin.resolve.source.getPsi + +// TODO: Implement in K2: KT-56849 +object WasmJsFunAnnotationChecker : DeclarationChecker { + private val jsFunFqName = FqName("kotlin.JsFun") + + override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { + if (descriptor !is MemberDescriptor) return + val jsFun = descriptor.annotations.findAnnotation(jsFunFqName) ?: return + if (!descriptor.isEffectivelyExternal() || !DescriptorUtils.isTopLevelDeclaration(descriptor)) { + val jsFunPsi = jsFun.source.getPsi() ?: declaration + context.trace.report(ErrorsWasm.WRONG_JS_FUN_TARGET.on(jsFunPsi)) + } + } +} \ No newline at end of file diff --git a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/diagnostics/DiagnosticsWasmTestGenerated.java b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/diagnostics/DiagnosticsWasmTestGenerated.java index 4f999ef92a3..14cfd284daa 100644 --- a/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/diagnostics/DiagnosticsWasmTestGenerated.java +++ b/wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/diagnostics/DiagnosticsWasmTestGenerated.java @@ -56,6 +56,12 @@ public class DiagnosticsWasmTestGenerated extends AbstractDiagnosticsWasmTest { public void testJsExport() throws Exception { runTest("compiler/testData/diagnostics/wasmTests/jsInterop/jsExport.kt"); } + + @Test + @TestMetadata("jsFun.kt") + public void testJsFun() throws Exception { + runTest("compiler/testData/diagnostics/wasmTests/jsInterop/jsFun.kt"); + } } @Nested