Skip to content

Commit

Permalink
Enhance the bound generator concept to remove duplicate parameters an…
Browse files Browse the repository at this point in the history
…d make it more pervasive throughout the system (#105597)
  • Loading branch information
jkoritzinsky authored Aug 15, 2024
1 parent bfffd58 commit 7fd8724
Show file tree
Hide file tree
Showing 56 changed files with 1,059 additions and 754 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ internal sealed class JSExportCodeGenerator : JSCodeGenerator
{
private readonly BoundGenerators _marshallers;

private readonly JSExportCodeContext _context;
private readonly StubCodeContext _context;
private readonly JSExportData _jsExportData;
private readonly JSSignatureContext _signatureContext;

public JSExportCodeGenerator(
Expand All @@ -27,30 +28,29 @@ public JSExportCodeGenerator(
IMarshallingGeneratorResolver generatorResolver)
{
_signatureContext = signatureContext;
NativeToManagedStubCodeContext innerContext = new NativeToManagedStubCodeContext(ReturnIdentifier, ReturnIdentifier)
_jsExportData = attributeData;
_context = new NativeToManagedStubCodeContext(ReturnIdentifier, ReturnIdentifier)
{
CodeEmitOptions = new(SkipInit: true)
};
_context = new JSExportCodeContext(attributeData, innerContext);

_marshallers = BoundGenerators.Create(argTypes, generatorResolver, _context, new EmptyJSGenerator(), out var bindingFailures);

diagnosticsBag.ReportGeneratorDiagnostics(bindingFailures);

if (_marshallers.ManagedReturnMarshaller.Generator.UsesNativeIdentifier(_marshallers.ManagedReturnMarshaller.TypeInfo, null))
if (_marshallers.ManagedReturnMarshaller.UsesNativeIdentifier(_context))
{
// If we need a different native return identifier, then recreate the context with the correct identifier before we generate any code.
innerContext = new NativeToManagedStubCodeContext(ReturnIdentifier, ReturnNativeIdentifier)
_context = new NativeToManagedStubCodeContext(ReturnIdentifier, ReturnNativeIdentifier)
{
CodeEmitOptions = new(SkipInit: true)
};
_context = new JSExportCodeContext(attributeData, innerContext);
}

// validate task + span mix
if (_marshallers.ManagedReturnMarshaller.TypeInfo.MarshallingAttributeInfo is JSMarshallingInfo(_, JSTaskTypeInfo))
{
BoundGenerator spanArg = _marshallers.SignatureMarshallers.FirstOrDefault(m => m.TypeInfo.MarshallingAttributeInfo is JSMarshallingInfo(_, JSSpanTypeInfo));
IBoundMarshallingGenerator spanArg = _marshallers.SignatureMarshallers.FirstOrDefault(m => m.TypeInfo.MarshallingAttributeInfo is JSMarshallingInfo(_, JSSpanTypeInfo));
if (spanArg != default)
{
diagnosticsBag.ReportGeneratorDiagnostic(new GeneratorDiagnostic.NotSupported(spanArg.TypeInfo, _context)
Expand Down Expand Up @@ -160,8 +160,9 @@ public StatementSyntax GenerateJSExportRegistration()

private ArgumentSyntax CreateSignaturesSyntax()
{
var types = ((IJSMarshallingGenerator)_marshallers.ManagedReturnMarshaller.Generator).GenerateBind(_marshallers.ManagedReturnMarshaller.TypeInfo, _context)
.Concat(_marshallers.NativeParameterMarshallers.SelectMany(p => ((IJSMarshallingGenerator)p.Generator).GenerateBind(p.TypeInfo, _context)));
IEnumerable<ExpressionSyntax> types = _marshallers.ManagedReturnMarshaller is IJSMarshallingGenerator jsGen ? jsGen.GenerateBind(_context) : [];
types = types
.Concat(_marshallers.NativeParameterMarshallers.OfType<IJSMarshallingGenerator>().SelectMany(p => p.GenerateBind(_context)));

return Argument(ArrayCreationExpression(ArrayType(IdentifierName(Constants.JSMarshalerTypeGlobal))
.WithRankSpecifiers(SingletonList(ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>(OmittedArraySizeExpression())))))
Expand All @@ -170,7 +171,7 @@ private ArgumentSyntax CreateSignaturesSyntax()

private void SetupSyntax(List<StatementSyntax> statementsToUpdate)
{
foreach (BoundGenerator marshaller in _marshallers.NativeParameterMarshallers)
foreach (IBoundMarshallingGenerator marshaller in _marshallers.NativeParameterMarshallers)
{
statementsToUpdate.Add(LocalDeclarationStatement(VariableDeclaration(marshaller.TypeInfo.ManagedType.Syntax)
.WithVariables(SingletonSeparatedList(VariableDeclarator(marshaller.TypeInfo.InstanceIdentifier)))));
Expand All @@ -195,10 +196,10 @@ private List<StatementSyntax> InvokeSyntax()
var arguments = new List<ArgumentSyntax>();

// Generate code for each parameter for the current stage
foreach (BoundGenerator marshaller in _marshallers.NativeParameterMarshallers)
foreach (IBoundMarshallingGenerator marshaller in _marshallers.NativeParameterMarshallers)
{
// convert arguments for invocation
statements.AddRange(marshaller.Generator.Generate(marshaller.TypeInfo, _context));
statements.AddRange(marshaller.Generate(_context));
arguments.Add(Argument(IdentifierName(marshaller.TypeInfo.InstanceIdentifier)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,15 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
StringBuilder source = new();
// Mark in source that the file is auto-generated.
source.AppendLine("// <auto-generated/>");
source.Append("// <auto-generated/>\r\n");
// this is the assembly level registration
source.AppendLine(generatedSources[0].Item2);
source.Append(generatedSources[0].Item2);
source.Append("\r\n");
// this is the method wrappers to be called from JS
foreach (var generated in generatedSources)
{
source.AppendLine(generated.Item1);
source.Append(generated.Item1);
source.Append("\r\n");
}
// Once https://github.com/dotnet/roslyn/issues/61326 is resolved, we can avoid the ToString() here.
Expand Down
Loading

0 comments on commit 7fd8724

Please sign in to comment.