Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.CodeAnalysis;

namespace Microsoft.Interop.JavaScript
{
internal sealed class DescriptorProvider : IDiagnosticDescriptorProvider
{
public DiagnosticDescriptor InvalidMarshallingAttributeInfo => GeneratorDiagnostics.MarshallingAttributeConfigurationNotSupported;

public DiagnosticDescriptor ConfigurationNotSupported => GeneratorDiagnostics.ConfigurationNotSupported;

public DiagnosticDescriptor ConfigurationValueNotSupported => GeneratorDiagnostics.ConfigurationValueNotSupported;

public DiagnosticDescriptor? GetDescriptor(GeneratorDiagnostic diagnostic)
{
return diagnostic switch
{
GeneratorDiagnostic.NotSupported { NotSupportedDetails: not null, TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.ReturnTypeNotSupportedWithDetails,
GeneratorDiagnostic.NotSupported { NotSupportedDetails: not null, TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails,
{ IsFatal: false } => null, // The JSImport and JSExport generators don't report any non-fatal diagnostics.
{ TypePositionInfo.IsManagedReturnPosition: true } => GeneratorDiagnostics.ReturnTypeNotSupported,
{ TypePositionInfo.IsManagedReturnPosition: false } => GeneratorDiagnostics.ParameterTypeNotSupported,
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.Interop
/// <summary>
/// Class for reporting diagnostics in the library import generator
/// </summary>
public class GeneratorDiagnostics : IGeneratorDiagnostics
public static class GeneratorDiagnostics
{
public class Ids
{
Expand All @@ -28,145 +28,6 @@ public class Ids
}

private const string Category = "JSImportGenerator";
private readonly List<DiagnosticInfo> _diagnostics = new List<DiagnosticInfo>();

public IEnumerable<DiagnosticInfo> Diagnostics => _diagnostics;

public void ReportInvalidMarshallingAttributeInfo(
AttributeData attributeData,
string reasonResourceName,
params string[] reasonArgs)
{
_diagnostics.Add(
attributeData.CreateDiagnosticInfo(
GeneratorDiagnostics.MarshallingAttributeConfigurationNotSupported,
new LocalizableResourceString(reasonResourceName, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.JavaScript.JSImportGenerator.SR), reasonArgs)));
}

/// <summary>
/// Report diagnostic for configuration that is not supported by the DLL import source generator
/// </summary>
/// <param name="attributeData">Attribute specifying the unsupported configuration</param>
/// <param name="configurationName">Name of the configuration</param>
/// <param name="unsupportedValue">[Optiona] Unsupported configuration value</param>
public void ReportConfigurationNotSupported(
AttributeData attributeData,
string configurationName,
string? unsupportedValue = null)
{
if (unsupportedValue == null)
{
_diagnostics.Add(
attributeData.CreateDiagnosticInfo(
GeneratorDiagnostics.ConfigurationNotSupported,
configurationName));
}
else
{
_diagnostics.Add(
attributeData.CreateDiagnosticInfo(
GeneratorDiagnostics.ConfigurationValueNotSupported,
unsupportedValue,
configurationName));
}
}

/// <summary>
/// Report diagnostic for marshalling of a parameter/return that is not supported
/// </summary>
/// <param name="diagnosticLocations">Method with the parameter/return</param>
/// <param name="info">Type info for the parameter/return</param>
/// <param name="notSupportedDetails">[Optional] Specific reason for lack of support</param>
public void ReportMarshallingNotSupported(
MethodSignatureDiagnosticLocations diagnosticLocations,
TypePositionInfo info,
string? notSupportedDetails,
ImmutableDictionary<string, string> diagnosticProperties)
{
Location diagnosticLocation = Location.None;
string elementName = string.Empty;

if (info.IsManagedReturnPosition)
{
diagnosticLocation = diagnosticLocations.FallbackLocation;
elementName = diagnosticLocations.MethodIdentifier;
}
else
{
Debug.Assert(info.ManagedIndex <= diagnosticLocations.ManagedParameterLocations.Length);
diagnosticLocation = diagnosticLocations.ManagedParameterLocations[info.ManagedIndex];
elementName = info.InstanceIdentifier;
}

if (!string.IsNullOrEmpty(notSupportedDetails))
{
// Report the specific not-supported reason.
if (info.IsManagedReturnPosition)
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ReturnTypeNotSupportedWithDetails,
diagnosticProperties,
notSupportedDetails!,
elementName));
}
else
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ParameterTypeNotSupportedWithDetails,
diagnosticProperties,
notSupportedDetails!,
elementName));
}
}
else if (info.MarshallingAttributeInfo is MarshalAsInfo)
{
// Report that the specified marshalling configuration is not supported.
// We don't forward marshalling attributes, so this is reported differently
// than when there is no attribute and the type itself is not supported.
if (info.IsManagedReturnPosition)
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ReturnConfigurationNotSupported,
diagnosticProperties,
nameof(System.Runtime.InteropServices.MarshalAsAttribute),
elementName));
}
else
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ParameterConfigurationNotSupported,
diagnosticProperties,
nameof(System.Runtime.InteropServices.MarshalAsAttribute),
elementName));
}
}
else
{
// Report that the type is not supported
if (info.IsManagedReturnPosition)
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ReturnTypeNotSupported,
diagnosticProperties,
info.ManagedType.DiagnosticFormattedName,
elementName));
}
else
{
_diagnostics.Add(
diagnosticLocation.CreateDiagnosticInfo(
GeneratorDiagnostics.ParameterTypeNotSupported,
diagnosticProperties,
info.ManagedType.DiagnosticFormattedName,
elementName));
}
}
}

public static readonly DiagnosticDescriptor ConfigurationNotSupported =
new DiagnosticDescriptor(
Expand Down Expand Up @@ -209,14 +70,14 @@ public void ReportMarshallingNotSupported(
description: GetResourceString(nameof(SR.TypeNotSupportedDescription)));

public static readonly DiagnosticDescriptor ParameterTypeNotSupported =
new DiagnosticDescriptor(
Ids.TypeNotSupported,
GetResourceString(nameof(SR.TypeNotSupportedTitle)),
GetResourceString(nameof(SR.TypeNotSupportedMessageParameter)),
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: GetResourceString(nameof(SR.TypeNotSupportedDescription)));
new DiagnosticDescriptor(
Ids.TypeNotSupported,
GetResourceString(nameof(SR.TypeNotSupportedTitle)),
GetResourceString(nameof(SR.TypeNotSupportedMessageParameter)),
Category,
DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: GetResourceString(nameof(SR.TypeNotSupportedDescription)));

public static readonly DiagnosticDescriptor ReturnTypeNotSupported =
new DiagnosticDescriptor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,16 @@ public JSExportCodeGenerator(
ImmutableArray<TypePositionInfo> argTypes,
JSExportData attributeData,
JSSignatureContext signatureContext,
Action<TypePositionInfo, MarshallingNotSupportedException> marshallingNotSupportedCallback,
GeneratorDiagnosticsBag diagnosticsBag,
IMarshallingGeneratorFactory generatorFactory)
{
Action<TypePositionInfo, string> extendedInvariantViolationsCallback = (info, details) =>
marshallingNotSupportedCallback(info, new MarshallingNotSupportedException(info, _context) { NotSupportedDetails = details });
_signatureContext = signatureContext;
NativeToManagedStubCodeContext innerContext = new NativeToManagedStubCodeContext(targetFramework, targetFrameworkVersion, ReturnIdentifier, ReturnIdentifier);
_context = new JSExportCodeContext(attributeData, innerContext);

_marshallers = BoundGenerators.Create(argTypes, generatorFactory, _context, new EmptyJSGenerator(), out var bindingFailures);
foreach (var failure in bindingFailures)
{
marshallingNotSupportedCallback(failure.Info, failure.Exception);
}

diagnosticsBag.ReportGeneratorDiagnostics(bindingFailures);

if (_marshallers.ManagedReturnMarshaller.Generator.UsesNativeIdentifier(_marshallers.ManagedReturnMarshaller.TypeInfo, null))
{
Expand All @@ -53,7 +49,7 @@ public JSExportCodeGenerator(
BoundGenerator spanArg = _marshallers.SignatureMarshallers.FirstOrDefault(m => m.TypeInfo.MarshallingAttributeInfo is JSMarshallingInfo(_, JSSpanTypeInfo));
if (spanArg != default)
{
marshallingNotSupportedCallback(spanArg.TypeInfo, new MarshallingNotSupportedException(spanArg.TypeInfo, _context)
diagnosticsBag.ReportGeneratorDiagnostic(new GeneratorDiagnostic.NotSupported(spanArg.TypeInfo, _context)
{
NotSupportedDetails = SR.SpanAndTaskNotSupported
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ private static IncrementalStubGenerationContext CalculateStubInformation(

Debug.Assert(jsExportAttr is not null);

var generatorDiagnostics = new GeneratorDiagnostics();
var locations = new MethodSignatureDiagnosticLocations(originalSyntax);
var generatorDiagnostics = new GeneratorDiagnosticsBag(new DescriptorProvider(), locations, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.JavaScript.JSImportGenerator.SR));

// Process the JSExport attribute
JSExportData? jsExportData = ProcessJSExportAttribute(jsExportAttr!);
Expand All @@ -211,7 +212,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(
signatureContext,
containingTypeContext,
methodSyntaxTemplate,
new MethodSignatureDiagnosticLocations(originalSyntax),
locations,
jsExportData,
CreateGeneratorFactory(environment, options),
new SequenceEqualImmutableArray<DiagnosticInfo>(generatorDiagnostics.Diagnostics.ToImmutableArray()));
Expand Down Expand Up @@ -289,20 +290,17 @@ private static NamespaceDeclarationSyntax GenerateRegSource(
private static (MemberDeclarationSyntax, StatementSyntax, AttributeListSyntax, ImmutableArray<DiagnosticInfo>) GenerateSource(
IncrementalStubGenerationContext incrementalContext)
{
var diagnostics = new GeneratorDiagnostics();
var diagnostics = new GeneratorDiagnosticsBag(new DescriptorProvider(), incrementalContext.DiagnosticLocation, SR.ResourceManager, typeof(FxResources.Microsoft.Interop.JavaScript.JSImportGenerator.SR));

// Generate stub code
var stubGenerator = new JSExportCodeGenerator(
incrementalContext.GeneratorFactoryKey.Key.TargetFramework,
incrementalContext.GeneratorFactoryKey.Key.TargetFrameworkVersion,
incrementalContext.SignatureContext.SignatureContext.ElementTypeInformation,
incrementalContext.JSExportData,
incrementalContext.SignatureContext,
(elementInfo, ex) =>
{
diagnostics.ReportMarshallingNotSupported(incrementalContext.DiagnosticLocation, elementInfo, ex.NotSupportedDetails, ex.DiagnosticProperties ?? ImmutableDictionary<string, string>.Empty);
},
incrementalContext.GeneratorFactoryKey.GeneratorFactory);
incrementalContext.GeneratorFactoryKey.Key.TargetFramework,
incrementalContext.GeneratorFactoryKey.Key.TargetFrameworkVersion,
incrementalContext.SignatureContext.SignatureContext.ElementTypeInformation,
incrementalContext.JSExportData,
incrementalContext.SignatureContext,
diagnostics,
incrementalContext.GeneratorFactoryKey.GeneratorFactory);

var wrapperName = "__Wrapper_" + incrementalContext.StubMethodSyntaxTemplate.Identifier + "_" + incrementalContext.SignatureContext.TypesHash;

Expand Down
Loading