From ff20ae34e53856d459e2ceb599a66dadd36c2776 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Fri, 26 Jan 2024 16:35:41 +0100 Subject: [PATCH] [Wasm/WASI] Allow external declarations only for top-level functions Fix #KT-63737 --- .../FirWasmWasiExternalDeclarationChecker.kt | 15 +++++++-------- .../diagnostics/wasmWasiTests/external.kt | 12 +++++++++--- .../WasmWasiExternalDeclarationChecker.kt | 15 ++++++++------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/compiler/fir/checkers/checkers.wasm/src/org/jetbrains/kotlin/fir/analysis/wasm/checkers/declaration/FirWasmWasiExternalDeclarationChecker.kt b/compiler/fir/checkers/checkers.wasm/src/org/jetbrains/kotlin/fir/analysis/wasm/checkers/declaration/FirWasmWasiExternalDeclarationChecker.kt index 449d57b5540..5a1a8cf77e9 100644 --- a/compiler/fir/checkers/checkers.wasm/src/org/jetbrains/kotlin/fir/analysis/wasm/checkers/declaration/FirWasmWasiExternalDeclarationChecker.kt +++ b/compiler/fir/checkers/checkers.wasm/src/org/jetbrains/kotlin/fir/analysis/wasm/checkers/declaration/FirWasmWasiExternalDeclarationChecker.kt @@ -13,23 +13,22 @@ import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclaratio import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors import org.jetbrains.kotlin.fir.declarations.FirDeclaration -import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.FirFunction import org.jetbrains.kotlin.fir.declarations.hasAnnotation import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal import org.jetbrains.kotlin.name.WasmStandardClassIds object FirWasmWasiExternalDeclarationChecker : FirBasicDeclarationChecker(MppCheckerKind.Common) { override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { + if (!context.isTopLevel) return if (!declaration.symbol.isEffectivelyExternal(context.session)) return - if (declaration is FirSimpleFunction) { - if (!context.isTopLevel) { - reporter.reportOn(declaration.source, FirWasmErrors.WASI_EXTERNAL_NOT_TOP_LEVEL_FUNCTION, context) - } else { - if (!declaration.hasAnnotation(WasmStandardClassIds.Annotations.WasmImport, context.session)) { - reporter.reportOn(declaration.source, FirWasmErrors.WASI_EXTERNAL_FUNCTION_WITHOUT_IMPORT, context) - } + if (declaration is FirFunction) { + if (!declaration.hasAnnotation(WasmStandardClassIds.Annotations.WasmImport, context.session)) { + reporter.reportOn(declaration.source, FirWasmErrors.WASI_EXTERNAL_FUNCTION_WITHOUT_IMPORT, context) } + } else { + reporter.reportOn(declaration.source, FirWasmErrors.WASI_EXTERNAL_NOT_TOP_LEVEL_FUNCTION, context) } } } diff --git a/compiler/testData/diagnostics/wasmWasiTests/external.kt b/compiler/testData/diagnostics/wasmWasiTests/external.kt index aa8218a4a72..ffa1946f604 100644 --- a/compiler/testData/diagnostics/wasmWasiTests/external.kt +++ b/compiler/testData/diagnostics/wasmWasiTests/external.kt @@ -3,9 +3,15 @@ import kotlin.wasm.WasmImport external fun foo(): Int -external interface I { - fun foo(): Int -} +external interface I { + fun foo(): Int +} + +external class X + +external val v: Int + +external object AC @WasmImport("a", "b") external fun importedFoo(): Int diff --git a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmWasiExternalDeclarationChecker.kt b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmWasiExternalDeclarationChecker.kt index beff476ee3d..6db44a2c1da 100644 --- a/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmWasiExternalDeclarationChecker.kt +++ b/wasm/wasm.frontend/src/org/jetbrains/kotlin/wasm/resolve/diagnostics/WasmWasiExternalDeclarationChecker.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.wasm.resolve.diagnostics import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.MemberDescriptor +import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtDeclaration @@ -19,18 +20,18 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal object WasmWasiExternalDeclarationChecker : DeclarationChecker { override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (descriptor !is MemberDescriptor) return + if (descriptor is PropertyAccessorDescriptor) return + if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) return if (!descriptor.isEffectivelyExternal()) return if (descriptor is FunctionDescriptor) { - if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) { + if (!descriptor.annotations.hasAnnotation(FqName("kotlin.wasm.WasmImport"))) { val reportOn = descriptor.findPsi() ?: declaration - context.trace.report(ErrorsWasm.WASI_EXTERNAL_NOT_TOP_LEVEL_FUNCTION.on(reportOn)) - } else { - if (!descriptor.annotations.hasAnnotation(FqName("kotlin.wasm.WasmImport"))) { - val reportOn = descriptor.findPsi() ?: declaration - context.trace.report(ErrorsWasm.WASI_EXTERNAL_FUNCTION_WITHOUT_IMPORT.on(reportOn)) - } + context.trace.report(ErrorsWasm.WASI_EXTERNAL_FUNCTION_WITHOUT_IMPORT.on(reportOn)) } + } else { + val reportOn = descriptor.findPsi() ?: declaration + context.trace.report(ErrorsWasm.WASI_EXTERNAL_NOT_TOP_LEVEL_FUNCTION.on(reportOn)) } } } \ No newline at end of file