Skip to content

Commit

Permalink
[browser] Use DynamicDependencyAttribute contructor friendly to Inter…
Browse files Browse the repository at this point in the history
…nalsVisibleTo when registering JSExports (#103402)
  • Loading branch information
maraf authored Jun 13, 2024
1 parent d2cada8 commit f1c5823
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public static class StepNames

public void Initialize(IncrementalGeneratorInitializationContext context)
{
var assemblyName = context.CompilationProvider.Select(static (c, _) => c.AssemblyName);

// Collect all methods adorned with JSExportAttribute
var attributedMethods = context.SyntaxProvider
.ForAttributeWithMetadataName(Constants.JSExportAttribute,
Expand Down Expand Up @@ -96,7 +98,8 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
.Collect();

IncrementalValueProvider<string> registration = regSyntax
.Select(static (data, ct) => GenerateRegSource(data))
.Combine(assemblyName)
.Select(static (data, ct) => GenerateRegSource(data.Left, data.Right))
.Select(static (data, ct) => data.NormalizeWhitespace().ToFullString());

IncrementalValueProvider<ImmutableArray<(string, string)>> generated = generateSingleStub
Expand Down Expand Up @@ -210,7 +213,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(
}

private static NamespaceDeclarationSyntax GenerateRegSource(
ImmutableArray<(StatementSyntax Registration, AttributeListSyntax Attribute)> methods)
ImmutableArray<(StatementSyntax Registration, AttributeListSyntax Attribute)> methods, string assemblyName)
{
const string generatedNamespace = "System.Runtime.InteropServices.JavaScript";
const string initializerClass = "__GeneratedInitializer";
Expand Down Expand Up @@ -270,8 +273,13 @@ private static NamespaceDeclarationSyntax GenerateRegSource(
IdentifierName("NonPublicMethods")))),
Token(SyntaxKind.CommaToken),
AttributeArgument(
TypeOfExpression(
IdentifierName(initializerClass)))})))}))))
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal($"{generatedNamespace}.{initializerClass}"))
),
Token(SyntaxKind.CommaToken),
AttributeArgument(
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(assemblyName))
)
})))}))))
.WithModifiers(TokenList(new[] {
Token(SyntaxKind.StaticKeyword),
Token(SyntaxKind.InternalKeyword)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.InteropServices.JavaScript;

namespace JavaScriptLibrary;

public partial class JavaScriptInterop
{
[JSExport]
public static int ExportedMethod(int a, int b) => a + b;

internal static int ValidationMethod(int a, int b) => a + b;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetPlatformIdentifier>$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)'))</TargetPlatformIdentifier>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworks>$(NetCoreAppCurrent)-browser</TargetFrameworks>
<!-- Use following lines to write the generated files to disk. -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<!-- Make debugging easier -->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<WasmNativeDebugSymbols>true</WasmNativeDebugSymbols>
<WasmNativeStrip>false</WasmNativeStrip>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)JavaScriptInterop.cs" />
<InternalsVisibleTo Include="System.Runtime.InteropServices.JavaScript.Tests" />
<ProjectReference Include="$(CoreLibProject)" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Private.Uri\src\System.Private.Uri.csproj" PrivateAssets="all" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections\src\System.Collections.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime\src\System.Runtime.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Memory\src\System.Memory.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Threading\src\System.Threading.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Threading.Thread\src\System.Threading.Thread.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime.InteropServices.JavaScript\src\System.Runtime.InteropServices.JavaScript.csproj" SkipUseReferenceAssembly="true" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
<WasmExtraFilesToDeploy Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\JavaScript\SecondRuntimeTest.js" />
<WasmExtraFilesToDeploy Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\JavaScript\timers.mjs" />
<ProjectReference Include="$(CoreLibProject)" />
<ProjectReference Include="..\JavaScriptLibrary\JavaScriptLibrary.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Private.Uri\src\System.Private.Uri.csproj" PrivateAssets="all" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections\src\System.Collections.csproj" />
<ProjectReference Include="$(LibrariesProjectRoot)System.Runtime\src\System.Runtime.csproj" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,5 +430,11 @@ public void JsExportCallback_FunctionIntIntThrow()
res = invoke(value, echoName);
Assert.Equal<T>(value, res);
}

[Fact]
public async Task InternalsVisibleToDoesntBreak()
{
Assert.Equal(JavaScriptLibrary.JavaScriptInterop.ValidationMethod(5, 6), await JavaScriptTestHelper.callJavaScriptLibrary(5, 6));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,9 @@ public static JSObject EchoIJSObject([JSMarshalAs<JSType.Object>] JSObject arg1)
{
return arg1;
}

[JSImport("callJavaScriptLibrary", "JavaScriptTestHelper")]
public static partial Task<int> callJavaScriptLibrary(int a, int b);

[JSImport("echopromise", "JavaScriptTestHelper")]
[return: JSMarshalAs<JSType.Promise<JSType.Object>>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,11 @@ export async function backbackAsync(arg1, arg2, arg3) {
return arg1(arg2, arg3);
}

export async function callJavaScriptLibrary(a, b) {
const exports = await App.runtime.getAssemblyExports("JavaScriptLibrary.dll");
return exports.JavaScriptLibrary.JavaScriptInterop.ExportedMethod(a, b);
}

export const instance = {}

globalThis.javaScriptTestHelper = instance;
Expand Down

0 comments on commit f1c5823

Please sign in to comment.