[Wasm] Port WasmImport/WasmExport checker to K2 (KT-56849)
This commit is contained in:
committed by
Space Team
parent
28895a2613
commit
1c230c8f27
+16
@@ -28,4 +28,20 @@ object WASM_DIAGNOSTICS_LIST : DiagnosticList("FirWasmErrors") {
|
|||||||
parameter<ConeKotlinType>("type")
|
parameter<ConeKotlinType>("type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val WASM_INTEROP by object : DiagnosticGroup("Wasm interop") {
|
||||||
|
val NESTED_WASM_EXPORT by error<KtElement>()
|
||||||
|
val WASM_EXPORT_ON_EXTERNAL_DECLARATION by error<KtElement>()
|
||||||
|
val JS_AND_WASM_EXPORTS_ON_SAME_DECLARATION by error<KtElement>()
|
||||||
|
val NESTED_WASM_IMPORT by error<KtElement>()
|
||||||
|
val WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION by error<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE by error<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_VARARG_PARAMETER by error<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<ConeKotlinType>("type")
|
||||||
|
}
|
||||||
|
val WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE by error<KtElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||||
|
parameter<ConeKotlinType>("type")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -23,6 +23,17 @@ object FirWasmErrors {
|
|||||||
val CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION by error0<PsiElement>()
|
val CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION by error0<PsiElement>()
|
||||||
val WRONG_JS_INTEROP_TYPE by error2<KtElement, String, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
val WRONG_JS_INTEROP_TYPE by error2<KtElement, String, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
|
// Wasm interop
|
||||||
|
val NESTED_WASM_EXPORT by error0<KtElement>()
|
||||||
|
val WASM_EXPORT_ON_EXTERNAL_DECLARATION by error0<KtElement>()
|
||||||
|
val JS_AND_WASM_EXPORTS_ON_SAME_DECLARATION by error0<KtElement>()
|
||||||
|
val NESTED_WASM_IMPORT by error0<KtElement>()
|
||||||
|
val WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION by error0<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE by error0<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_VARARG_PARAMETER by error0<KtElement>()
|
||||||
|
val WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
val WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE by error1<KtElement, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
RootDiagnosticRendererFactory.registerFactory(FirWasmErrorsDefaultMessages)
|
RootDiagnosticRendererFactory.registerFactory(FirWasmErrorsDefaultMessages)
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -12,7 +12,16 @@ import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.EXTERNAL_TYPE_EXTENDS_NON_EXTERNAL_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.JS_AND_WASM_EXPORTS_ON_SAME_DECLARATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.NESTED_WASM_EXPORT
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.NESTED_WASM_IMPORT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.NON_EXTERNAL_TYPE_EXTENDS_EXTERNAL_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.NON_EXTERNAL_TYPE_EXTENDS_EXTERNAL_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_EXPORT_ON_EXTERNAL_DECLARATION
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_IMPORT_EXPORT_VARARG_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WRONG_JS_INTEROP_TYPE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors.WRONG_JS_INTEROP_TYPE
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@@ -34,5 +43,23 @@ object FirWasmErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
"Type ''{0}'' cannot be used in {1}. Only external, primitive, string and function types are supported in Kotlin/Wasm JS interop.",
|
"Type ''{0}'' cannot be used in {1}. Only external, primitive, string and function types are supported in Kotlin/Wasm JS interop.",
|
||||||
TO_STRING, FirDiagnosticRenderers.RENDER_TYPE,
|
TO_STRING, FirDiagnosticRenderers.RENDER_TYPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
map.put(NESTED_WASM_EXPORT, "Only top-level functions can be exported with '@WasmExport'.")
|
||||||
|
map.put(WASM_EXPORT_ON_EXTERNAL_DECLARATION, "Functions annotated with '@WasmExport' must not be external.")
|
||||||
|
map.put(JS_AND_WASM_EXPORTS_ON_SAME_DECLARATION, "Cannot use '@WasmExport' and '@JsExport' for same function.")
|
||||||
|
map.put(NESTED_WASM_IMPORT, "Only top-level functions can be imported with '@WasmImport'.")
|
||||||
|
map.put(WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION, "Functions annotated with '@WasmImport' must be external.")
|
||||||
|
map.put(WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE, "Default parameter values are not supported with '@WasmImport' and '@WasmExport'.")
|
||||||
|
map.put(WASM_IMPORT_EXPORT_VARARG_PARAMETER, "Vararg parameters are not supported with '@WasmImport' and '@WasmExport'.")
|
||||||
|
map.put(
|
||||||
|
WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE,
|
||||||
|
"Unsupported ''@WasmImport'' and ''@WasmExport'' parameter type ''{0}''.",
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE,
|
||||||
|
"Unsupported ''@WasmImport'' and ''@WasmExport'' return type ''{0}''.",
|
||||||
|
FirDiagnosticRenderers.RENDER_TYPE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -17,5 +17,7 @@ object WasmDeclarationCheckers : DeclarationCheckers() {
|
|||||||
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
||||||
get() = setOf(
|
get() = setOf(
|
||||||
FirWasmJsInteropTypesChecker,
|
FirWasmJsInteropTypesChecker,
|
||||||
|
FirWasmImportAnnotationChecker,
|
||||||
|
FirWasmExportAnnotationChecker,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.analysis.wasm.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.isTopLevel
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.wasm.FirWasmErrors
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.wasm.checkers.hasValidJsCodeBody
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.hasAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.name.WasmStandardClassIds
|
||||||
|
|
||||||
|
object FirWasmExportAnnotationChecker : FirBasicDeclarationChecker() {
|
||||||
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val annotation: FirAnnotation =
|
||||||
|
declaration.annotations.getAnnotationByClassId(WasmStandardClassIds.Annotations.WasmExport, context.session) ?: return
|
||||||
|
|
||||||
|
if (!context.isTopLevel) {
|
||||||
|
reporter.reportOn(annotation.source, FirWasmErrors.NESTED_WASM_EXPORT, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration.annotations.hasAnnotation(WasmStandardClassIds.Annotations.JsExport, context.session)) {
|
||||||
|
reporter.reportOn(declaration.source, FirWasmErrors.JS_AND_WASM_EXPORTS_ON_SAME_DECLARATION, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration is FirSimpleFunction) {
|
||||||
|
if (declaration.symbol.isEffectivelyExternal(context.session) || declaration.hasValidJsCodeBody()) {
|
||||||
|
reporter.reportOn(annotation.source, FirWasmErrors.WASM_EXPORT_ON_EXTERNAL_DECLARATION, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkWasmInteropSignature(declaration, context, reporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* 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.fir.analysis.wasm.checkers.declaration
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
|
||||||
|
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.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.name.WasmStandardClassIds
|
||||||
|
|
||||||
|
object FirWasmImportAnnotationChecker : FirBasicDeclarationChecker() {
|
||||||
|
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
val annotation: FirAnnotation =
|
||||||
|
declaration.annotations.getAnnotationByClassId(WasmStandardClassIds.Annotations.WasmImport, context.session) ?: return
|
||||||
|
|
||||||
|
if (!context.isTopLevel) {
|
||||||
|
reporter.reportOn(annotation.source, FirWasmErrors.NESTED_WASM_IMPORT, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!declaration.symbol.isEffectivelyExternal(context.session)) {
|
||||||
|
reporter.reportOn(annotation.source, FirWasmErrors.WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration is FirFunction) {
|
||||||
|
checkWasmInteropSignature(declaration, context, reporter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkWasmInteropSignature(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
for (parameter in declaration.valueParameters) {
|
||||||
|
val type = parameter.returnTypeRef.coneType
|
||||||
|
if (parameter.defaultValue != null) {
|
||||||
|
reporter.reportOn(parameter.source, FirWasmErrors.WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE, context)
|
||||||
|
}
|
||||||
|
if (parameter.isVararg) {
|
||||||
|
reporter.reportOn(parameter.source, FirWasmErrors.WASM_IMPORT_EXPORT_VARARG_PARAMETER, context)
|
||||||
|
}
|
||||||
|
if (!isTypeSupportedInWasmInterop(type, false, context.session)) {
|
||||||
|
reporter.reportOn(parameter.source, FirWasmErrors.WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE, type, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val returnType = declaration.returnTypeRef.coneType
|
||||||
|
if (!isTypeSupportedInWasmInterop(returnType, true, context.session)) {
|
||||||
|
reporter.reportOn(declaration.source, FirWasmErrors.WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE, returnType, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isTypeSupportedInWasmInterop(
|
||||||
|
unexpandedType: ConeKotlinType,
|
||||||
|
isInFunctionReturnPosition: Boolean,
|
||||||
|
session: FirSession,
|
||||||
|
): Boolean {
|
||||||
|
val type = unexpandedType.fullyExpandedType(session)
|
||||||
|
|
||||||
|
if (type.isUnit) {
|
||||||
|
return isInFunctionReturnPosition
|
||||||
|
}
|
||||||
|
|
||||||
|
// Primitive numbers and Boolean are supported
|
||||||
|
return type.isPrimitive && !type.isChar
|
||||||
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
import kotlin.wasm.WasmExport
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
external fun foo0(): Unit
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun foo1(): Int = js("42")
|
|
||||||
|
|
||||||
class C() {
|
|
||||||
@WasmExport("a")
|
|
||||||
fun foo2(): Int = 42
|
|
||||||
}
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun foo3(): Int = 42
|
|
||||||
|
|
||||||
@WasmExport()
|
|
||||||
fun foo4(): Int = 42
|
|
||||||
|
|
||||||
@OptIn(kotlin.js.ExperimentalJsExport::class)
|
|
||||||
@JsExport()
|
|
||||||
@WasmExport()
|
|
||||||
fun foo6(): Int = 42
|
|
||||||
|
|
||||||
val p1 = (@WasmExport("a") fun () {})
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun foo7(
|
|
||||||
p0: Unit,
|
|
||||||
p1: String,
|
|
||||||
p2: Any,
|
|
||||||
p3: Int?,
|
|
||||||
p4: Boolean?
|
|
||||||
): Unit {
|
|
||||||
p0.toString()
|
|
||||||
p1.toString()
|
|
||||||
p2.toString()
|
|
||||||
p3.toString()
|
|
||||||
p4.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun returnNullableUnit(): Unit? { return null }
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun returnNullableBoolean(): Boolean? { return null }
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun returnNullableAny(): Any? { return null }
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun <T> fooGeneric(x: T): T { return x }
|
|
||||||
|
|
||||||
@WasmExport("a")
|
|
||||||
fun fooDeafultAndVararg(
|
|
||||||
a: Int = <!CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION!>definedExternally<!>,
|
|
||||||
vararg b: Int
|
|
||||||
): Unit { b.toString() }
|
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
import kotlin.wasm.WasmExport
|
import kotlin.wasm.WasmExport
|
||||||
|
|
||||||
<!WASM_EXPORT_ON_EXTERNAL_DECLARATION!>@WasmExport("a")
|
<!WASM_EXPORT_ON_EXTERNAL_DECLARATION!>@WasmExport("a")<!>
|
||||||
external fun foo0(): Unit<!>
|
external fun foo0(): Unit
|
||||||
|
|
||||||
<!WASM_EXPORT_ON_EXTERNAL_DECLARATION!>@WasmExport("a")
|
<!WASM_EXPORT_ON_EXTERNAL_DECLARATION!>@WasmExport("a")<!>
|
||||||
fun foo1(): Int = js("42")<!>
|
fun foo1(): Int = js("42")
|
||||||
|
|
||||||
class C() {
|
class C() {
|
||||||
<!NESTED_WASM_EXPORT!>@WasmExport("a")
|
<!NESTED_WASM_EXPORT!>@WasmExport("a")<!>
|
||||||
fun foo2(): Int = 42<!>
|
fun foo2(): Int = 42
|
||||||
}
|
}
|
||||||
|
|
||||||
@WasmExport("a")
|
@WasmExport("a")
|
||||||
@@ -22,7 +24,7 @@ fun foo4(): Int = 42
|
|||||||
@WasmExport()
|
@WasmExport()
|
||||||
fun foo6(): Int = 42<!>
|
fun foo6(): Int = 42<!>
|
||||||
|
|
||||||
val p1 = (<!NESTED_WASM_EXPORT!>@WasmExport("a") fun () {}<!>)
|
val p1 = (<!NESTED_WASM_EXPORT!>@WasmExport("a")<!> fun () {})
|
||||||
|
|
||||||
@WasmExport("a")
|
@WasmExport("a")
|
||||||
fun foo7(
|
fun foo7(
|
||||||
@@ -40,19 +42,19 @@ fun foo7(
|
|||||||
}
|
}
|
||||||
|
|
||||||
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
||||||
fun returnNullableUnit(): Unit? { return null }<!>
|
fun returnNullableUnit(): Unit?<!> { return null }
|
||||||
|
|
||||||
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
||||||
fun returnNullableBoolean(): Boolean? { return null }<!>
|
fun returnNullableBoolean(): Boolean?<!> { return null }
|
||||||
|
|
||||||
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
||||||
fun returnNullableAny(): Any? { return null }<!>
|
fun returnNullableAny(): Any?<!> { return null }
|
||||||
|
|
||||||
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
<!WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE!>@WasmExport("a")
|
||||||
fun <T> fooGeneric(<!WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE!>x: T<!>): T { return x }<!>
|
fun <T> fooGeneric(<!WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE!>x: T<!>): T<!> { return x }
|
||||||
|
|
||||||
@WasmExport("a")
|
@WasmExport("a")
|
||||||
fun fooDeafultAndVararg(
|
fun fooDeafultAndVararg(
|
||||||
<!WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE!><!UNUSED_PARAMETER!>a<!>: Int = <!CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION!>definedExternally<!><!>,
|
<!WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE!>a: Int = <!CALL_TO_DEFINED_EXTERNALLY_FROM_NON_EXTERNAL_DECLARATION!>definedExternally<!><!>,
|
||||||
<!WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE, WASM_IMPORT_EXPORT_VARARG_PARAMETER!>vararg b: Int<!>
|
<!WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE, WASM_IMPORT_EXPORT_VARARG_PARAMETER!>vararg b: Int<!>
|
||||||
): Unit { b.toString() }
|
): Unit { b.toString() }
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
import kotlin.wasm.WasmImport
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun foo0(): Unit
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
fun foo1() {
|
|
||||||
}
|
|
||||||
|
|
||||||
external class C {
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
fun memberFunction()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun foo2() {
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
fun localFun() {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val p1 = (@WasmImport("a", "b") fun () {})
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun foo3(
|
|
||||||
p0: Unit,
|
|
||||||
p1: String,
|
|
||||||
p2: Any,
|
|
||||||
p3: Int?,
|
|
||||||
p4: Boolean?
|
|
||||||
): Unit
|
|
||||||
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun returnNullableUnit(): Unit?
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun returnNullableBoolean(): Boolean?
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun returnNullableAny(): Any?
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun <T> fooGeneric(x: T): T
|
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
|
||||||
external fun fooDeafultAndVararg(
|
|
||||||
a: Int = definedExternally,
|
|
||||||
vararg b: Int
|
|
||||||
): Unit
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
|
||||||
import kotlin.wasm.WasmImport
|
import kotlin.wasm.WasmImport
|
||||||
|
|
||||||
@WasmImport("a", "b")
|
@WasmImport("a", "b")
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ object WasmStandardClassIds {
|
|||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val WasmImport = "WasmImport".wasmId()
|
val WasmImport = "WasmImport".wasmId()
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val WasmExport = "WasmExport".wasmId()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Callables {
|
object Callables {
|
||||||
|
|||||||
+4
-2
@@ -30,8 +30,10 @@ public interface ErrorsWasm {
|
|||||||
DiagnosticFactory0<PsiElement> WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> WASM_IMPORT_ON_NON_EXTERNAL_DECLARATION = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> WASM_IMPORT_EXPORT_PARAMETER_DEFAULT_VALUE = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> WASM_IMPORT_EXPORT_VARARG_PARAMETER = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> WASM_IMPORT_EXPORT_VARARG_PARAMETER = DiagnosticFactory0.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, KotlinType> WASM_IMPORT_EXPORT_UNSUPPORTED_PARAMETER_TYPE =
|
||||||
DiagnosticFactory1<PsiElement, KotlinType> WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1.create(ERROR, PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory1<PsiElement, KotlinType> WASM_IMPORT_EXPORT_UNSUPPORTED_RETURN_TYPE =
|
||||||
|
DiagnosticFactory1.create(ERROR, PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
DiagnosticFactory0<PsiElement> WRONG_JS_FUN_TARGET = DiagnosticFactory0.create(ERROR);
|
DiagnosticFactory0<PsiElement> WRONG_JS_FUN_TARGET = DiagnosticFactory0.create(ERROR);
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -14,16 +14,18 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||||
|
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||||
import org.jetbrains.kotlin.wasm.util.hasValidJsCodeBody
|
import org.jetbrains.kotlin.wasm.util.hasValidJsCodeBody
|
||||||
|
|
||||||
// TODO: Implement in K2: KT-56849
|
|
||||||
abstract class WasmExportAnnotationChecker(val checkJsInterop: Boolean) : DeclarationChecker {
|
abstract class WasmExportAnnotationChecker(val checkJsInterop: Boolean) : DeclarationChecker {
|
||||||
private val wasmExportFqName = FqName("kotlin.wasm.WasmExport")
|
private val wasmExportFqName = FqName("kotlin.wasm.WasmExport")
|
||||||
private val jsExportFqName = FqName("kotlin.js.JsExport")
|
private val jsExportFqName = FqName("kotlin.js.JsExport")
|
||||||
|
|
||||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||||
if (descriptor !is FunctionDescriptor) return
|
if (descriptor !is FunctionDescriptor) return
|
||||||
if (!descriptor.annotations.hasAnnotation(wasmExportFqName)) return
|
val wasmExport = descriptor.annotations.findAnnotation(wasmExportFqName) ?: return
|
||||||
|
|
||||||
|
val wasmExportPsi = wasmExport.source.getPsi() ?: declaration
|
||||||
|
|
||||||
val trace = context.trace
|
val trace = context.trace
|
||||||
val bindingContext = trace.bindingContext
|
val bindingContext = trace.bindingContext
|
||||||
@@ -36,13 +38,11 @@ abstract class WasmExportAnnotationChecker(val checkJsInterop: Boolean) : Declar
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor.isEffectivelyExternal() || (checkJsInterop && descriptor.hasValidJsCodeBody(bindingContext))) {
|
if (descriptor.isEffectivelyExternal() || (checkJsInterop && descriptor.hasValidJsCodeBody(bindingContext))) {
|
||||||
val reportOn = descriptor.findPsi() ?: declaration
|
trace.report(ErrorsWasm.WASM_EXPORT_ON_EXTERNAL_DECLARATION.on(wasmExportPsi))
|
||||||
trace.report(ErrorsWasm.WASM_EXPORT_ON_EXTERNAL_DECLARATION.on(reportOn))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
if (!DescriptorUtils.isTopLevelDeclaration(descriptor)) {
|
||||||
val reportOn = descriptor.findPsi() ?: declaration
|
trace.report(ErrorsWasm.NESTED_WASM_EXPORT.on(wasmExportPsi))
|
||||||
trace.report(ErrorsWasm.NESTED_WASM_EXPORT.on(reportOn))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmImportAnnotationChecker.checkSignatureIsPrimitive(descriptor, trace, declaration)
|
WasmImportAnnotationChecker.checkSignatureIsPrimitive(descriptor, trace, declaration)
|
||||||
-1
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
|
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
|
|
||||||
// TODO: Implement in K2: KT-56849
|
|
||||||
object WasmImportAnnotationChecker : DeclarationChecker {
|
object WasmImportAnnotationChecker : DeclarationChecker {
|
||||||
private val wasmImportFqName = FqName("kotlin.wasm.WasmImport")
|
private val wasmImportFqName = FqName("kotlin.wasm.WasmImport")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user