diff --git a/src/Components/Web.JS/src/Boot.WebAssembly.Common.ts b/src/Components/Web.JS/src/Boot.WebAssembly.Common.ts index 6740dd9a84e9..7efd32e495f4 100644 --- a/src/Components/Web.JS/src/Boot.WebAssembly.Common.ts +++ b/src/Components/Web.JS/src/Boot.WebAssembly.Common.ts @@ -2,13 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. /* eslint-disable array-element-newline */ -import { DotNet } from '@microsoft/dotnet-js-interop'; +/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { Blazor } from './GlobalExports'; import * as Environment from './Environment'; -import { BINDING, monoPlatform, dispatcher, getInitializer } from './Platform/Mono/MonoPlatform'; +import { monoPlatform, dispatcher, getInitializer } from './Platform/Mono/MonoPlatform'; import { renderBatch, getRendererer, attachRootComponentToElement, attachRootComponentToLogicalElement } from './Rendering/Renderer'; import { SharedMemoryRenderBatch } from './Rendering/RenderBatch/SharedMemoryRenderBatch'; -import { PlatformApi, Pointer } from './Platform/Platform'; +import { Pointer } from './Platform/Platform'; import { WebAssemblyStartOptions } from './Platform/WebAssemblyStartOptions'; import { addDispatchEventMiddleware } from './Rendering/WebRendererInteropMethods'; import { WebAssemblyComponentDescriptor, discoverWebAssemblyPersistedState } from './Services/ComponentDescriptorDiscovery'; @@ -19,7 +19,6 @@ import { RootComponentManager } from './Services/RootComponentManager'; import { WebRendererId } from './Rendering/WebRendererId'; let options: Partial | undefined; -let initializersPromise: Promise; let platformLoadPromise: Promise | undefined; let loadedWebAssemblyPlatform = false; let started = false; @@ -43,7 +42,7 @@ export function resolveInitialUpdate(value: string): void { } let resolveInitializersPromise: (value: void) => void; -initializersPromise = new Promise(resolve => { +const initializersPromise = new Promise(resolve => { resolveInitializersPromise = resolve; }); @@ -105,7 +104,6 @@ async function startCore(components: RootComponentManager dispatcher.invokeDotNetStaticMethod('Microsoft.AspNetCore.Components.WebAssembly', 'GetApplyUpdateCapabilities'); // Configure JS interop - Blazor._internal.invokeJSFromDotNet = invokeJSFromDotNet; Blazor._internal.invokeJSJson = invokeJSJson; Blazor._internal.endInvokeDotNetFromJS = endInvokeDotNetFromJS; Blazor._internal.receiveWebAssemblyDotNetDataStream = receiveWebAssemblyDotNetDataStream; @@ -169,7 +167,7 @@ async function startCore(components: RootComponentManager components.onAfterUpdateRootComponents?.(batchId); - Blazor._internal.attachRootComponentToElement = (selector, componentId, rendererId: any) => { + Blazor._internal.attachRootComponentToElement = (selector, componentId, rendererId) => { const element = componentAttacher.resolveRegisteredElement(selector); if (!element) { attachRootComponentToElement(selector, componentId, rendererId); @@ -178,17 +176,16 @@ async function startCore(components: RootComponentManager { - if (typeof Module !== 'undefined' && Module.err) { - // Logs it, and causes the error UI to appear - Module.err(error); - } else { - // The error must have happened so early we didn't yet set up the error UI, so just log to console - console.error(error); - } - }); + boot().catch(printErr); } diff --git a/src/Components/Web.JS/src/GlobalExports.ts b/src/Components/Web.JS/src/GlobalExports.ts index 52c3dec4d0e6..fad0d11cc42e 100644 --- a/src/Components/Web.JS/src/GlobalExports.ts +++ b/src/Components/Web.JS/src/GlobalExports.ts @@ -52,7 +52,6 @@ export interface IBlazor { forceCloseConnection?: () => Promise; InputFile?: typeof InputFile; NavigationLock: typeof NavigationLock; - invokeJSFromDotNet?: (callInfo: Pointer, arg0: any, arg1: any, arg2: any) => any; invokeJSJson?: (identifier: string, targetInstanceId: number, resultType: number, argsJson: string, asyncHandle: number) => string | null; endInvokeDotNetFromJS?: (callId: string, success: boolean, resultJsonOrErrorMessage: string) => void; receiveByteArray?: (id: number, data: Uint8Array) => void; diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts index 31c0cba1b6e7..8b31c404b74b 100644 --- a/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts +++ b/src/Components/Web.JS/src/Platform/Mono/MonoPlatform.ts @@ -10,55 +10,22 @@ import { showErrorNotification } from '../../BootErrors'; import { Platform, System_Array, Pointer, System_Object, System_String, HeapLock, PlatformApi } from '../Platform'; import { WebAssemblyBootResourceType, WebAssemblyStartOptions } from '../WebAssemblyStartOptions'; import { Blazor } from '../../GlobalExports'; -import { DotnetModuleConfig, EmscriptenModule, MonoConfig, ModuleAPI, RuntimeAPI, GlobalizationMode } from 'dotnet-runtime'; -import { BINDINGType, MONOType } from 'dotnet-runtime/dotnet-legacy'; +import { DotnetModuleConfig, MonoConfig, ModuleAPI, RuntimeAPI, GlobalizationMode } from 'dotnet-runtime'; import { fetchAndInvokeInitializers } from '../../JSInitializers/JSInitializers.WebAssembly'; import { JSInitializer } from '../../JSInitializers/JSInitializers'; -import { WebRendererId } from '../../Rendering/WebRendererId'; // initially undefined and only fully initialized after createEmscriptenModuleInstance() -export let BINDING: BINDINGType = undefined as any; -export let MONO: MONOType = undefined as any; -export let Module: DotnetModuleConfig & EmscriptenModule = undefined as any; export let dispatcher: DotNet.ICallDispatcher = undefined as any; let MONO_INTERNAL: any = undefined as any; let runtime: RuntimeAPI = undefined as any; let jsInitializer: JSInitializer; -const uint64HighOrderShift = Math.pow(2, 32); -const maxSafeNumberHighPart = Math.pow(2, 21) - 1; // The high-order int32 from Number.MAX_SAFE_INTEGER - let currentHeapLock: MonoHeapLock | null = null; -// Memory access helpers -// The implementations are exactly equivalent to what the global getValue(addr, type) function does, -// except without having to parse the 'type' parameter, and with less risk of mistakes at the call site -function getValueI16(ptr: number) { - return MONO.getI16(ptr); -} -function getValueI32(ptr: number) { - return MONO.getI32(ptr); -} -function getValueFloat(ptr: number) { - return MONO.getF32(ptr); -} - export function getInitializer() { return jsInitializer; } -function getValueU64(ptr: number) { - // There is no Module.HEAPU64, and Module.getValue(..., 'i64') doesn't work because the implementation - // treats 'i64' as being the same as 'i32'. Also we must take care to read both halves as unsigned. - const heapU32Index = ptr >> 2; - const highPart = Module.HEAPU32[heapU32Index + 1]; - if (highPart > maxSafeNumberHighPart) { - throw new Error(`Cannot read uint64 with high order part ${highPart}, because the result would exceed Number.MAX_SAFE_INTEGER.`); - } - - return (highPart * uint64HighOrderShift) + Module.HEAPU32[heapU32Index]; -} - export const monoPlatform: Platform = { load: function load(options: Partial, onConfigLoaded?: (loadedConfig: MonoConfig) => void) { return createRuntimeInstance(options, onConfigLoaded); @@ -77,18 +44,6 @@ export const monoPlatform: Platform = { } }, - toUint8Array: function toUint8Array(array: System_Array): Uint8Array { - const dataPtr = getArrayDataPointer(array); - const length = getValueI32(dataPtr); - const uint8Array = new Uint8Array(length); - uint8Array.set(Module.HEAPU8.subarray(dataPtr + 4, dataPtr + 4 + length)); - return uint8Array; - }, - - getArrayLength: function getArrayLength(array: System_Array): number { - return getValueI32(getArrayDataPointer(array)); - }, - getArrayEntryPtr: function getArrayEntryPtr(array: System_Array, index: number, itemSize: number): TPtr { // First byte is array length, followed by entries const address = getArrayDataPointer(array) + 4 + index * itemSize; @@ -97,31 +52,27 @@ export const monoPlatform: Platform = { getObjectFieldsBaseAddress: function getObjectFieldsBaseAddress(referenceTypedObject: System_Object): Pointer { // The first two int32 values are internal Mono data - return (referenceTypedObject as any as number + 8) as any as Pointer; + return (referenceTypedObject as any + 8) as any as Pointer; }, readInt16Field: function readHeapInt16(baseAddress: Pointer, fieldOffset?: number): number { - return getValueI16((baseAddress as any as number) + (fieldOffset || 0)); + return runtime.getHeapI16((baseAddress as any) + (fieldOffset || 0)); }, readInt32Field: function readHeapInt32(baseAddress: Pointer, fieldOffset?: number): number { - return getValueI32((baseAddress as unknown as number) + (fieldOffset || 0)); + return runtime.getHeapI32((baseAddress as any) + (fieldOffset || 0)); }, readUint64Field: function readHeapUint64(baseAddress: Pointer, fieldOffset?: number): number { - return getValueU64((baseAddress as unknown as number) + (fieldOffset || 0)); - }, - - readFloatField: function readHeapFloat(baseAddress: Pointer, fieldOffset?: number): number { - return getValueFloat((baseAddress as unknown as number) + (fieldOffset || 0)); + return runtime.getHeapU52((baseAddress as any) + (fieldOffset || 0)); }, - readObjectField: function readHeapObject(baseAddress: Pointer, fieldOffset?: number): T { - return getValueI32((baseAddress as unknown as number) + (fieldOffset || 0)) as any as T; + readObjectField: function readObjectField(baseAddress: Pointer, fieldOffset?: number): T { + return runtime.getHeapU32((baseAddress as any) + (fieldOffset || 0)) as any as T; }, - readStringField: function readHeapObject(baseAddress: Pointer, fieldOffset?: number, readBoolValueAsString?: boolean): string | null { - const fieldValue = getValueI32((baseAddress as unknown as number) + (fieldOffset || 0)); + readStringField: function readStringField(baseAddress: Pointer, fieldOffset?: number, readBoolValueAsString?: boolean): string | null { + const fieldValue = runtime.getHeapU32((baseAddress as any) + (fieldOffset || 0)); if (fieldValue === 0) { return null; } @@ -129,14 +80,14 @@ export const monoPlatform: Platform = { if (readBoolValueAsString) { // Some fields are stored as a union of bool | string | null values, but need to read as a string. // If the stored value is a bool, the behavior we want is empty string ('') for true, or null for false. - const unboxedValue = BINDING.unbox_mono_obj(fieldValue as any as System_Object); + + const unboxedValue = MONO_INTERNAL.monoObjectAsBoolOrNullUnsafe(fieldValue as any as System_Object); if (typeof (unboxedValue) === 'boolean') { return unboxedValue ? '' : null; } - return unboxedValue; } - return BINDING.conv_string(fieldValue as any as System_String); + return MONO_INTERNAL.monoStringToStringUnsafe(fieldValue as any as System_String); }, readStructField: function readStructField(baseAddress: Pointer, fieldOffset?: number): T { @@ -206,13 +157,12 @@ function prepareRuntimeConfig(options: Partial, onConfi jsInitializer = await fetchAndInvokeInitializers(options, loadedConfig); }; - const moduleConfig = (window['Module'] || {}) as typeof Module; + const moduleConfig = (window['Module'] || {}) as any; const dotnetModuleConfig: DotnetModuleConfig = { ...moduleConfig, onConfigLoaded: (onConfigLoaded as (config: MonoConfig) => void | Promise), onDownloadResourceProgress: setProgress, config, - disableDotnet6Compatibility: false, out: print, err: printErr, }; @@ -251,10 +201,7 @@ async function configureRuntimeInstance(): Promise { throw new Error('The runtime must be loaded it gets configured.'); } - const { MONO: mono, BINDING: binding, Module: module, setModuleImports, INTERNAL: mono_internal, getConfig, invokeLibraryInitializers } = runtime; - Module = module; - BINDING = binding; - MONO = mono; + const { setModuleImports, INTERNAL: mono_internal, getConfig, invokeLibraryInitializers } = runtime; MONO_INTERNAL = mono_internal; attachDebuggerHotkey(getConfig()); @@ -285,7 +232,7 @@ function setProgress(resourcesLoaded, totalResources) { const suppressMessages = ['DEBUGGING ENABLED']; const print = line => (suppressMessages.indexOf(line) < 0 && console.log(line)); -const printErr = line => { +export const printErr = line => { // If anything writes to stderr, treat it as a critical exception. The underlying runtime writes // to stderr if a truly critical problem occurs outside .NET code. Note that .NET unhandled // exceptions also reach this, but via a different code path - see dotNetCriticalError below. diff --git a/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts b/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts deleted file mode 100644 index e7bf0e2e11ef..000000000000 --- a/src/Components/Web.JS/src/Platform/Mono/MonoTypes.ts +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -import { Pointer, System_String, System_Array, System_Object } from '../Platform'; - -// Mono uses this global to hang various debugging-related items on - -declare interface MONO { - loaded_files: string[]; - mono_wasm_runtime_ready (): void; - mono_wasm_setenv (name: string, value: string): void; - mono_wasm_load_data_archive(data: Uint8Array, prefix: string): void; - mono_wasm_load_bytes_into_heap (data: Uint8Array): Pointer; - mono_wasm_load_icu_data(heapAddress: Pointer): boolean; -} - -// Mono uses this global to hold low-level interop APIs -declare interface BINDING { - mono_obj_array_new(length: number): System_Array; - mono_obj_array_set(array: System_Array, index: number, value: System_Object): void; - js_string_to_mono_string(jsString: string): System_String; - js_typed_array_to_array(array: Uint8Array): System_Object; - js_to_mono_obj(jsObject: unknown) : System_Object; - mono_array_to_js_array(array: System_Array) : Array; - conv_string(dotnetString: System_String | null): string | null; - bind_static_method(fqn: string, signature?: string): Function; - call_assembly_entry_point(assemblyName: string, args: unknown[], signature: unknown): Promise; - unbox_mono_obj(object: System_Object): unknown; -} - -declare global { - let MONO: MONO; - let BINDING: BINDING; -} diff --git a/src/Components/Web.JS/src/Platform/Platform.ts b/src/Components/Web.JS/src/Platform/Platform.ts index cb5de4c8c731..728bd330b33d 100644 --- a/src/Components/Web.JS/src/Platform/Platform.ts +++ b/src/Components/Web.JS/src/Platform/Platform.ts @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-unused-vars */ import { MonoObject, MonoString, MonoArray } from 'dotnet-runtime/dotnet-legacy'; import { WebAssemblyStartOptions } from './WebAssemblyStartOptions'; import { MonoConfig } from 'dotnet-runtime'; @@ -11,16 +13,12 @@ export interface Platform { callEntryPoint(): Promise; - toUint8Array(array: System_Array): Uint8Array; - - getArrayLength(array: System_Array): number; getArrayEntryPtr(array: System_Array, index: number, itemSize: number): TPtr; getObjectFieldsBaseAddress(referenceTypedObject: System_Object): Pointer; readInt16Field(baseAddress: Pointer, fieldOffset?: number): number; readInt32Field(baseAddress: Pointer, fieldOffset?: number): number; readUint64Field(baseAddress: Pointer, fieldOffset?: number): number; - readFloatField(baseAddress: Pointer, fieldOffset?: number): number; readObjectField(baseAddress: Pointer, fieldOffset?: number): T; readStringField(baseAddress: Pointer, fieldOffset?: number, readBoolValueAsString?: boolean): string | null; readStructField(baseAddress: Pointer, fieldOffset?: number): T; diff --git a/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt b/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..9f03b1a9685f 100644 --- a/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt +++ b/src/Components/WebAssembly/JSInterop/src/PublicAPI.Unshipped.txt @@ -1 +1,9 @@ #nullable enable +*REMOVED*~Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) -> TResult +*REMOVED*~Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) -> TResult +*REMOVED*~Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string identifier, T0 arg0) -> TResult +*REMOVED*~Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string identifier) -> TResult +*REMOVED*Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1, T2 arg2) -> TResult +*REMOVED*Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1) -> TResult +*REMOVED*Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier, T0 arg0) -> TResult +*REMOVED*Microsoft.JSInterop.WebAssembly.WebAssemblyJSRuntime.InvokeUnmarshalled(string! identifier) -> TResult diff --git a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReference.cs b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReference.cs index 1535be93b970..20027bd52474 100644 --- a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReference.cs +++ b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReference.cs @@ -5,7 +5,7 @@ namespace Microsoft.JSInterop.WebAssembly; -internal sealed class WebAssemblyJSObjectReference : JSInProcessObjectReference, IJSUnmarshalledObjectReference +internal sealed class WebAssemblyJSObjectReference : JSInProcessObjectReference { private readonly WebAssemblyJSRuntime _jsRuntime; @@ -14,38 +14,4 @@ public WebAssemblyJSObjectReference(WebAssemblyJSRuntime jsRuntime, long id) { _jsRuntime = jsRuntime; } - -#pragma warning disable CS0612 // Type or member is obsolete - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier) - { - ThrowIfDisposed(); - - return _jsRuntime.InvokeUnmarshalled(identifier, null, null, null, Id); - } - - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0) - { - ThrowIfDisposed(); - - return _jsRuntime.InvokeUnmarshalled(identifier, arg0, null, null, Id); - } - - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) - { - ThrowIfDisposed(); - - return _jsRuntime.InvokeUnmarshalled(identifier, arg0, arg1, null, Id); - } - - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) - { - ThrowIfDisposed(); - - return _jsRuntime.InvokeUnmarshalled(identifier, arg0, arg1, arg2, Id); - } -#pragma warning restore CS0612 // Type or member is obsolete } diff --git a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReferenceJsonConverter.cs b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReferenceJsonConverter.cs index 32ae814a7efe..ff294cef2648 100644 --- a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReferenceJsonConverter.cs +++ b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSObjectReferenceJsonConverter.cs @@ -20,8 +20,7 @@ public override bool CanConvert(Type typeToConvert) { return typeToConvert == typeof(WebAssemblyJSObjectReference) || typeToConvert == typeof(IJSObjectReference) || - typeToConvert == typeof(IJSInProcessObjectReference) || - typeToConvert == typeof(IJSUnmarshalledObjectReference); + typeToConvert == typeof(IJSInProcessObjectReference); } public override IJSObjectReference? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) diff --git a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs index 7edc56420263..21f62b89f369 100644 --- a/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs +++ b/src/Components/WebAssembly/JSInterop/src/WebAssemblyJSRuntime.cs @@ -12,7 +12,7 @@ namespace Microsoft.JSInterop.WebAssembly; /// Provides methods for invoking JavaScript functions for applications running /// on the Mono WebAssembly runtime. /// -public abstract class WebAssemblyJSRuntime : JSInProcessRuntime, IJSUnmarshalledRuntime +public abstract class WebAssemblyJSRuntime : JSInProcessRuntime { /// /// Initializes a new instance of . @@ -56,73 +56,4 @@ protected override void SendByteArray(int id, byte[] data) { InternalCalls.ReceiveByteArray(id, data); } - - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - internal TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2, long targetInstanceId) - { - var resultType = JSCallResultTypeHelper.FromGeneric(); - - var callInfo = new JSCallInfo - { - FunctionIdentifier = identifier, - TargetInstanceId = targetInstanceId, - ResultType = resultType, - }; - - string exception; - - switch (resultType) - { - case JSCallResultType.Default: - case JSCallResultType.JSVoidResult: - var result = InternalCalls.InvokeJS(out exception, ref callInfo, arg0, arg1, arg2); - return exception != null - ? throw new JSException(exception) - : result; - case JSCallResultType.JSObjectReference: - var id = InternalCalls.InvokeJS(out exception, ref callInfo, arg0, arg1, arg2); - return exception != null - ? throw new JSException(exception) - : (TResult)(object)new WebAssemblyJSObjectReference(this, id); - case JSCallResultType.JSStreamReference: - var serializedStreamReference = InternalCalls.InvokeJS(out exception, ref callInfo, arg0, arg1, arg2); - return exception != null - ? throw new JSException(exception) - : (TResult)(object)DeserializeJSStreamReference(serializedStreamReference); - default: - throw new InvalidOperationException($"Invalid result type '{resultType}'."); - } - } - - [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "IJSStreamReference is referenced in Microsoft.JSInterop.Infrastructure.JSStreamReferenceJsonConverter")] - private IJSStreamReference DeserializeJSStreamReference(string serializedStreamReference) - { - var jsStreamReference = JsonSerializer.Deserialize(serializedStreamReference, JsonSerializerOptions); - if (jsStreamReference is null) - { - throw new ArgumentException($"Failed to parse as {nameof(IJSStreamReference)}.", nameof(serializedStreamReference)); - } - - return jsStreamReference; - } - - /// - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier) - => InvokeUnmarshalled(identifier, null, null, null, 0); - - /// - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0) - => InvokeUnmarshalled(identifier, arg0, null, null, 0); - - /// - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) - => InvokeUnmarshalled(identifier, arg0, arg1, null, 0); - - /// - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) - => InvokeUnmarshalled(identifier, arg0, arg1, arg2, 0); } diff --git a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.WarningSuppressions.xml b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.WarningSuppressions.xml index b394263f6173..86af354e396a 100644 --- a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.WarningSuppressions.xml +++ b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.WarningSuppressions.xml @@ -13,12 +13,6 @@ member M:Microsoft.AspNetCore.Components.RootComponentTypeCache.ResolveType(Microsoft.AspNetCore.Components.RootComponentTypeCache.Key,System.Reflection.Assembly[]) - - ILLink - IL2026 - member - M:Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder.InitializeRegisteredRootComponents(Microsoft.JSInterop.IJSUnmarshalledRuntime) - ILLink IL2026 @@ -43,11 +37,5 @@ member M:Microsoft.Extensions.HotReload.HotReloadAgent.<GetHandlerActions>g__GetUpdateMethod|9_1(System.Type,System.String) - - ILLink - IL2072 - member - M:Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder.InitializeRegisteredRootComponents(Microsoft.JSInterop.IJSUnmarshalledRuntime) - \ No newline at end of file diff --git a/src/Components/WebAssembly/WebAssembly/test/JSObjectReferenceJsonConverterTest.cs b/src/Components/WebAssembly/WebAssembly/test/JSObjectReferenceJsonConverterTest.cs index ca2e50bd9608..65aeb2acf662 100644 --- a/src/Components/WebAssembly/WebAssembly/test/JSObjectReferenceJsonConverterTest.cs +++ b/src/Components/WebAssembly/WebAssembly/test/JSObjectReferenceJsonConverterTest.cs @@ -44,18 +44,4 @@ public void Read_ReadsJson_IJSInProcessObjectReference() // Assert Assert.Equal(expectedId, deserialized?.Id); } - - [Fact] - public void Read_ReadsJson_IJSUnmarshalledObjectReference() - { - // Arrange - var expectedId = 3; - var json = $"{{\"__jsObjectId\":{expectedId}}}"; - - // Act - var deserialized = (WebAssemblyJSObjectReference)JsonSerializer.Deserialize(json, JsonSerializerOptions)!; - - // Assert - Assert.Equal(expectedId, deserialized?.Id); - } } diff --git a/src/Components/test/E2ETest/Tests/InteropTest.cs b/src/Components/test/E2ETest/Tests/InteropTest.cs index bd233b4ffd5f..af5f69580065 100644 --- a/src/Components/test/E2ETest/Tests/InteropTest.cs +++ b/src/Components/test/E2ETest/Tests/InteropTest.cs @@ -133,9 +133,6 @@ public void CanInvokeDotNetMethods() ["invokeThrowsSerializingCircularStructure"] = "Success", ["invokeThrowsUndefinedJSObjectReference"] = "Success", ["invokeThrowsNullJSObjectReference"] = "Success", - ["jsUnmarshalledObjectReference.unmarshalledFunction"] = "True", - ["jsToDotNetStreamReturnValueUnmarshalled"] = "Success", - ["jsCastedUnmarshalledObjectReference.unmarshalledFunction"] = "False", ["stringValueUpperSync"] = "MY STRING", ["testDtoNonSerializedValueSync"] = "99999", ["testDtoSync"] = "Same", @@ -144,7 +141,6 @@ public void CanInvokeDotNetMethods() ["genericInstanceMethod"] = @"""Updated value 2""", ["requestDotNetStreamReference"] = @"""Success""", ["requestDotNetStreamWrapperReference"] = @"""Success""", - ["disposeJSInProcessObjectReference"] = "Success", }; // Include the sync assertions only when running under WebAssembly diff --git a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor index 31d28fd23ffd..6310b0e745be 100644 --- a/src/Components/test/testassets/BasicTestApp/InteropComponent.razor +++ b/src/Components/test/testassets/BasicTestApp/InteropComponent.razor @@ -236,7 +236,7 @@ if (shouldSupportSyncInterop) { - await InvokeInProcessJSInterop(); + InvokeInProcessJSInterop(); } var byteArray = new byte[] { 1, 5, 7, 15, 35, 200 }; @@ -334,7 +334,7 @@ ReceiveDotNetObjectByRefResult["testDto"] = result.TestDto.Value == passDotNetObjectByRef ? "Same" : "Different"; } - public async Task InvokeInProcessJSInterop() + public void InvokeInProcessJSInterop() { var inProcRuntime = ((IJSInProcessRuntime)JSRuntime); @@ -408,39 +408,6 @@ { ReturnValues["invokeVoidReturnsWithoutSerializingInIJSInProcessObjectReference"] = $"Failure: {ex.Message}"; } - - // we should be able to downcast a IJSInProcessObjectReference as a IJSUnmarshalledObjectReference - var unmarshalledCast = (IJSUnmarshalledObjectReference)jsInProcObjectReference; -#pragma warning disable CS0618 // Type or member is obsolete - ReturnValues["jsCastedUnmarshalledObjectReference.unmarshalledFunction"] = unmarshalledCast.InvokeUnmarshalled("unmarshalledFunction", new InteropStruct - { - Message = "Sent from .NET", - NumberField = 41, - }).ToString(); - - try - { - jsInProcObjectReference.Dispose(); - ReturnValues["disposeJSInProcessObjectReference"] = "Success"; - } - catch (Exception ex) - { - ReturnValues["disposeJSInProcessObjectReference"] = $"Failure: {ex.Message}"; - } - - var unmarshalledRuntime = (IJSUnmarshalledRuntime)JSRuntime; - var jsUnmarshalledReference = unmarshalledRuntime.InvokeUnmarshalled("returnJSObjectReference"); - ReturnValues["jsUnmarshalledObjectReference.unmarshalledFunction"] = jsUnmarshalledReference.InvokeUnmarshalled("unmarshalledFunction", new InteropStruct - { - Message = "Sent from .NET", - NumberField = 42, - }).ToString(); - - - var dataReference = unmarshalledRuntime.InvokeUnmarshalled("jsToDotNetStreamReturnValue"); -#pragma warning restore CS0618 // Type or member is obsolete - using var dataReferenceStream = await dataReference.OpenReadStreamAsync(); - await ValidateStreamValuesAsync("jsToDotNetStreamReturnValueUnmarshalled", dataReferenceStream); } public class PassDotNetObjectByRefArgs diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js index 8e344b4141b0..dac70d67e6ec 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/js/jsinteroptests.js @@ -346,11 +346,6 @@ function returnJSObjectReference() { dispose: function () { DotNet.disposeJSObjectReference(this); }, - unmarshalledFunction: function (fields) { - const message = Blazor.platform.readStringField(fields, 0); - const numberField = Blazor.platform.readInt32Field(fields, 8); - return message === "Sent from .NET" && numberField === 42; - } }; } diff --git a/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledObjectReference.cs b/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledObjectReference.cs deleted file mode 100644 index e906556b0013..000000000000 --- a/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledObjectReference.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.JSInterop; - -/// -/// Represents a reference to a JavaScript object whose functions can be invoked synchronously without JSON marshalling. -/// -public interface IJSUnmarshalledObjectReference : IJSInProcessObjectReference -{ - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The type of the third argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The third argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2); -} diff --git a/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledRuntime.cs b/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledRuntime.cs deleted file mode 100644 index d5241f139258..000000000000 --- a/src/JSInterop/Microsoft.JSInterop/src/IJSUnmarshalledRuntime.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace Microsoft.JSInterop; - -/// -/// Represents an instance of a JavaScript runtime to which calls may be dispatched without JSON marshalling. -/// Not all JavaScript runtimes support this capability. Currently it is only supported on WebAssembly and for -/// security reasons, will never be supported for .NET code that runs on the server. -/// This is an advanced mechanism that should only be used in performance-critical scenarios. -/// -public interface IJSUnmarshalledRuntime -{ - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1); - - /// - /// Invokes the JavaScript function registered with the specified identifier. - /// - /// The type of the first argument. - /// The type of the second argument. - /// The type of the third argument. - /// The .NET type corresponding to the function's return value type. - /// The identifier used when registering the target function. - /// The first argument. - /// The second argument. - /// The third argument. - /// The result of the function invocation. - [Obsolete("This method is obsolete. Use JSImportAttribute instead.")] - TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2); -} diff --git a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..d7a3755ff3c5 100644 --- a/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt +++ b/src/JSInterop/Microsoft.JSInterop/src/PublicAPI.Unshipped.txt @@ -1 +1,11 @@ #nullable enable +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledObjectReference +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledObjectReference.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1, T2 arg2) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledObjectReference.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledObjectReference.InvokeUnmarshalled(string! identifier, T0 arg0) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledObjectReference.InvokeUnmarshalled(string! identifier) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledRuntime +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1, T2 arg2) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledRuntime.InvokeUnmarshalled(string! identifier, T0 arg0, T1 arg1) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledRuntime.InvokeUnmarshalled(string! identifier, T0 arg0) -> TResult +*REMOVED*Microsoft.JSInterop.IJSUnmarshalledRuntime.InvokeUnmarshalled(string! identifier) -> TResult \ No newline at end of file diff --git a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/JSObjectReferenceJsonConverterTest.cs b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/JSObjectReferenceJsonConverterTest.cs index ea82e11f0090..63b5a889782a 100644 --- a/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/JSObjectReferenceJsonConverterTest.cs +++ b/src/JSInterop/Microsoft.JSInterop/test/Infrastructure/JSObjectReferenceJsonConverterTest.cs @@ -87,31 +87,4 @@ public void Write_WritesValidJson() // Assert Assert.Equal($"{{\"__jsObjectId\":{jsObjectRef.Id}}}", json); } - - private class TestJSUnmarshalledObjectReference : JSInProcessObjectReference, IJSUnmarshalledObjectReference - { - public TestJSUnmarshalledObjectReference(long id) : base(default!, id) - { - } - - public TResult InvokeUnmarshalled(string identifier) - { - throw new NotImplementedException(); - } - - public TResult InvokeUnmarshalled(string identifier, T0 arg0) - { - throw new NotImplementedException(); - } - - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1) - { - throw new NotImplementedException(); - } - - public TResult InvokeUnmarshalled(string identifier, T0 arg0, T1 arg1, T2 arg2) - { - throw new NotImplementedException(); - } - } } diff --git a/src/Shared/JSInterop/JSCallResultTypeHelper.cs b/src/Shared/JSInterop/JSCallResultTypeHelper.cs index 789f432de504..69e90b8943c2 100644 --- a/src/Shared/JSInterop/JSCallResultTypeHelper.cs +++ b/src/Shared/JSInterop/JSCallResultTypeHelper.cs @@ -16,8 +16,7 @@ public static JSCallResultType FromGeneric() if (typeof(TResult).Assembly == _currentAssembly) { if (typeof(TResult) == typeof(IJSObjectReference) || - typeof(TResult) == typeof(IJSInProcessObjectReference) || - typeof(TResult) == typeof(IJSUnmarshalledObjectReference)) + typeof(TResult) == typeof(IJSInProcessObjectReference)) { return JSCallResultType.JSObjectReference; }