From 1162d2874dea91fb494ebb836affabf1c85b6395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 15 Sep 2023 15:06:07 +0200 Subject: [PATCH 1/2] JS part --- src/mono/wasm/runtime/marshal-to-cs.ts | 7 ++++--- src/mono/wasm/runtime/marshal-to-js.ts | 18 +++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/mono/wasm/runtime/marshal-to-cs.ts b/src/mono/wasm/runtime/marshal-to-cs.ts index a0f5b58a5cd33..14d6c7e3dd747 100644 --- a/src/mono/wasm/runtime/marshal-to-cs.ts +++ b/src/mono/wasm/runtime/marshal-to-cs.ts @@ -24,6 +24,7 @@ import { TypedArray } from "./types/emscripten"; import { addUnsettledPromise, settleUnsettledPromise } from "./pthreads/shared/eventloop"; import { mono_log_warn } from "./logging"; +export const jsinteropDoc = "For more information see https://aka.ms/dotnet-wasm-jsinterop"; export function initialize_marshalers_to_cs(): void { if (js_to_cs_marshalers.size == 0) { @@ -389,7 +390,7 @@ export function marshal_js_object_to_cs(arg: JSMarshalerArgument, value: any): v } else { // if value was ManagedObject, it would be double proxied, but the C# signature requires that - mono_check(value[js_owned_gc_handle_symbol] === undefined, "JSObject proxy of ManagedObject proxy is not supported"); + mono_check(value[js_owned_gc_handle_symbol] === undefined, () => `JSObject proxy of ManagedObject proxy is not supported. ${jsinteropDoc}`); mono_check(typeof value === "function" || typeof value === "object", () => `JSObject proxy of ${typeof value} is not supported`); set_arg_type(arg, MarshalerType.JSObject); @@ -474,7 +475,7 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void { else { assert_not_disposed(value); if (value instanceof ArraySegment) { - throw new Error("NotImplementedException: ArraySegment"); + throw new Error("NotImplementedException: ArraySegment. " + jsinteropDoc); } else if (value instanceof ManagedError) { set_arg_type(arg, MarshalerType.Exception); @@ -484,7 +485,7 @@ function _marshal_cs_object_to_cs(arg: JSMarshalerArgument, value: any): void { set_arg_type(arg, MarshalerType.Object); set_gc_handle(arg, gc_handle); } else { - throw new Error("NotImplementedException " + js_type); + throw new Error("NotImplementedException " + js_type + ". " + jsinteropDoc); } } } diff --git a/src/mono/wasm/runtime/marshal-to-js.ts b/src/mono/wasm/runtime/marshal-to-js.ts index 9b5a931067fda..1ad71dbc4ae78 100644 --- a/src/mono/wasm/runtime/marshal-to-js.ts +++ b/src/mono/wasm/runtime/marshal-to-js.ts @@ -18,7 +18,7 @@ import { import { monoStringToString } from "./strings"; import { JSHandleNull, GCHandleNull, JSMarshalerArgument, JSMarshalerArguments, JSMarshalerType, MarshalerToCs, MarshalerToJs, BoundMarshalerToJs, MarshalerType } from "./types/internal"; import { TypedArray } from "./types/emscripten"; -import { get_marshaler_to_cs_by_type } from "./marshal-to-cs"; +import { get_marshaler_to_cs_by_type, jsinteropDoc } from "./marshal-to-cs"; import { localHeapViewF64, localHeapViewI32, localHeapViewU8 } from "./memory"; export function initialize_marshalers_to_js(): void { @@ -85,7 +85,7 @@ export function get_marshaler_to_js_by_type(marshaler_type: MarshalerType): Mars return undefined; } const converter = cs_to_js_marshalers.get(marshaler_type); - mono_assert(converter && typeof converter === "function", () => `ERR41: Unknown converter for type ${marshaler_type}`); + mono_assert(converter && typeof converter === "function", () => `ERR41: Unknown converter for type ${marshaler_type}. ${jsinteropDoc}`); return converter; } @@ -224,7 +224,7 @@ export function marshal_task_to_js(arg: JSMarshalerArgument, _?: MarshalerType, // when we arrived here from _marshal_cs_object_to_js res_converter = cs_to_js_marshalers.get(type); } - mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]} `); + mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}. ${jsinteropDoc}`); // this is already resolved const val = res_converter(arg); @@ -256,7 +256,7 @@ export function marshal_task_to_js(arg: JSMarshalerArgument, _?: MarshalerType, // when we arrived here from _marshal_cs_object_to_js res_converter = cs_to_js_marshalers.get(type); } - mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}`); + mono_assert(res_converter, () => `Unknown sub_converter for type ${MarshalerType[type]}. ${jsinteropDoc}`); const js_value = res_converter!(argInner); orig_resolve(js_value); @@ -291,7 +291,7 @@ export function mono_wasm_marshal_promise(args: JSMarshalerArguments): void { else if (value_type !== MarshalerType.Task) { // this is already resolved task const sub_converter = cs_to_js_marshalers.get(value_type); - mono_assert(sub_converter, () => `Unknown sub_converter for type ${MarshalerType[value_type]} `); + mono_assert(sub_converter, () => `Unknown sub_converter for type ${MarshalerType[value_type]}. ${jsinteropDoc}`); const data = sub_converter(arg_value); promise_control.resolve(data); } @@ -406,7 +406,7 @@ function _marshal_cs_object_to_js(arg: JSMarshalerArgument): any { // other types const converter = cs_to_js_marshalers.get(marshaler_type); - mono_assert(converter, () => `Unknown converter for type ${MarshalerType[marshaler_type]}`); + mono_assert(converter, () => `Unknown converter for type ${MarshalerType[marshaler_type]}. ${jsinteropDoc}`); return converter(arg); } @@ -461,7 +461,7 @@ function _marshal_array_to_js_impl(arg: JSMarshalerArgument, element_type: Marsh result = sourceView.slice();//copy } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } Module._free(buffer_ptr); return result; @@ -483,7 +483,7 @@ function _marshal_span_to_js(arg: JSMarshalerArgument, element_type?: MarshalerT result = new Span(buffer_ptr, length, MemoryViewType.Double); } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } return result; } @@ -504,7 +504,7 @@ function _marshal_array_segment_to_js(arg: JSMarshalerArgument, element_type?: M result = new ArraySegment(buffer_ptr, length, MemoryViewType.Double); } else { - throw new Error(`NotImplementedException ${MarshalerType[element_type]} `); + throw new Error(`NotImplementedException ${MarshalerType[element_type]}. ${jsinteropDoc}`); } const gc_handle = get_arg_gc_handle(arg); if (BuildConfiguration === "Debug") { From ba7db17d69ed0ea8169ea1c245d3e3580a967edf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 15 Sep 2023 15:07:10 +0200 Subject: [PATCH 2/2] C# part --- .../JSImportGenerator/Resources/Strings.resx | 26 +++++------ .../tests/JSImportGenerator.UnitTest/Fails.cs | 44 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx index b06ebce226031..1c6e47ef214f1 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Resources/Strings.resx @@ -136,7 +136,7 @@ Specified type is not supported by source-generated JavaScript interop. - {0} The generated source will not handle marshalling of the return value of method '{1}'. + {0} The generated source will not handle marshalling of the return value of method '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop {0} is a message containing additional details about what is not supported {1} is the name of the method @@ -144,21 +144,21 @@ Type is not supported by source-generated JavaScript interop. - The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter '{1}'. + The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of the return value of method '{1}'. + The type '{0}' is not supported by source-generated JavaScript interop. The generated source will not handle marshalling of the return value of method '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - {0} The generated source will not handle marshalling of parameter '{1}'. + {0} The generated source will not handle marshalling of parameter '{1}'. For more information see https://aka.ms/dotnet-wasm-jsinterop {0} is a message containing additional details about what is not supported {1} is the name of the parameter - The specified '{0}' configuration for the return value of method '{1}' is not supported by source-generated JavaScript interop. + The specified '{0}' configuration for the return value of method '{1}' is not supported by source-generated JavaScript interop. For more information see https://aka.ms/dotnet-wasm-jsinterop - The specified '{0}' configuration for parameter '{1}' is not supported by source-generated JavaScript interop. + The specified '{0}' configuration for parameter '{1}' is not supported by source-generated JavaScript interop. For more information see https://aka.ms/dotnet-wasm-jsinterop Invalid 'JSImportAttribute' usage @@ -167,10 +167,10 @@ Invalid 'JSExportAttribute' usage - Method '{0}' should be 'static', 'partial', and non-generic when marked with 'JSImportAttribute'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' should be 'static', 'partial', and non-generic when marked with 'JSImportAttribute'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop - Method '{0}' should be 'static', non-partial and non-generic when marked with 'JSExportAttribute'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' should be 'static', non-partial and non-generic when marked with 'JSExportAttribute'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop Methods marked with 'JSImportAttribute' should be 'static', 'partial', and non-generic. JavaScript interop source generation will ignore methods that are non-'static', non-'partial', or generic. @@ -179,7 +179,7 @@ Methods marked with 'JSImportAttribute' should be 'static', non-partial, and non-generic. JavaScript interop source generation will ignore methods that are non-'static', 'partial', or generic. - Method '{0}' is contained in a type '{1}' that is not marked 'partial'. JavaScript interop source generation will ignore method '{0}'. + Method '{0}' is contained in a type '{1}' that is not marked 'partial'. JavaScript interop source generation will ignore method '{0}'. For more information see https://aka.ms/dotnet-wasm-jsinterop 'JSType.Discard' could be only used with void return argument. @@ -212,18 +212,18 @@ JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. - JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. + JSImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. For more information see https://aka.ms/dotnet-wasm-jsinterop - JSImportAttribute requires unsafe code. + JSImportAttribute requires unsafe code. For more information see https://aka.ms/dotnet-wasm-jsinterop JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. - JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. + JSExportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'. For more information see https://aka.ms/dotnet-wasm-jsinterop - JSExportAttribute requires unsafe code. + JSExportAttribute requires unsafe code. For more information see https://aka.ms/dotnet-wasm-jsinterop \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs index 513af4747a4e9..f5ffe77afb794 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Fails.cs @@ -15,39 +15,39 @@ public class Fails public static IEnumerable CodeSnippetsToFail() { yield return new object?[] { CodeSnippets.DefaultReturnMarshaler(), new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Import1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Export1'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Import1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of the return value of method 'Export1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler(), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Func"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Action"), new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Import1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Export1'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Import1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of the return value of method 'Export1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Span"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.Span"), null, null }; yield return new object?[] { CodeSnippets.DefaultReturnMarshaler("System.ArraySegment"), null, null }; yield return new object?[] { CodeSnippets.AllMissing, new string[] { - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object. The generated source will not handle marshalling of parameter 'a1'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a2'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a3'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of parameter 'a4'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Func. The generated source will not handle marshalling of parameter 'a5'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Span. The generated source will not handle marshalling of parameter 'a6'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.ArraySegment. The generated source will not handle marshalling of parameter 'a7'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a8'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object[]. The generated source will not handle marshalling of parameter 'a9'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTime. The generated source will not handle marshalling of parameter 'a10'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTimeOffset. The generated source will not handle marshalling of parameter 'a11'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a12'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a13'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a14'.", - "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a15'.", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object. The generated source will not handle marshalling of parameter 'a1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a2'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of long. The generated source will not handle marshalling of parameter 'a3'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Action. The generated source will not handle marshalling of parameter 'a4'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Func. The generated source will not handle marshalling of parameter 'a5'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Span. The generated source will not handle marshalling of parameter 'a6'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.ArraySegment. The generated source will not handle marshalling of parameter 'a7'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a8'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of object[]. The generated source will not handle marshalling of parameter 'a9'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTime. The generated source will not handle marshalling of parameter 'a10'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.DateTimeOffset. The generated source will not handle marshalling of parameter 'a11'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a12'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a13'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a14'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Please annotate the argument with 'JSMarshalAsAttribute' to specify marshaling of global::System.Threading.Tasks.Task. The generated source will not handle marshalling of parameter 'a15'. For more information see https://aka.ms/dotnet-wasm-jsinterop", },null }; yield return new object?[] { CodeSnippets.InOutRef, new string[] { - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a1'.", - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a2'.", - "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a3'.", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a1'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a2'. For more information see https://aka.ms/dotnet-wasm-jsinterop", + "Parameters with 'in', 'out' and 'ref' modifiers are not supported by source-generated JavaScript interop. The generated source will not handle marshalling of parameter 'a3'. For more information see https://aka.ms/dotnet-wasm-jsinterop", }, null }; }