| File: GeneratorDiagnosticsBag.cs | Web Access |
| Project: src\runtime\src\libraries\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj (Microsoft.Interop.SourceGeneration) |
// 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.Collections.Generic; using System.Collections.Immutable; using System.Resources; using Microsoft.CodeAnalysis; namespace Microsoft.Interop { /// <summary> /// A bag of diagnostics that generators can report diagnostics to. /// </summary> public class GeneratorDiagnosticsBag { private readonly IDiagnosticDescriptorProvider _descriptorProvider; private readonly ISignatureDiagnosticLocations _locations; private readonly ResourceManager _resourceManager; private readonly Type _resourceSource; private readonly List<DiagnosticInfo> _diagnostics = new(); public IEnumerable<DiagnosticInfo> Diagnostics => _diagnostics; /// <summary> /// Construct a generator diagnostics bag. /// </summary> /// <param name="descriptorProvider">A provider of specific diagnostic descriptors to use.</param> /// <param name="locations">A provider of locations for diagnostics on <see cref="TypePositionInfo"/>s.</param> /// <param name="resourceManager">A resource manager to resolve resource string parameters to diagnostics.</param> /// <param name="resourceSource">The type that represents the resource source.</param> public GeneratorDiagnosticsBag(IDiagnosticDescriptorProvider descriptorProvider, ISignatureDiagnosticLocations locations, ResourceManager resourceManager, Type resourceSource) { _descriptorProvider = descriptorProvider; _locations = locations; _resourceManager = resourceManager; _resourceSource = resourceSource; } /// <summary> /// Report a diagnostic. /// </summary> /// <param name="diagnostic">The diagnostic info.</param> public void ReportDiagnostic(DiagnosticInfo diagnostic) { _diagnostics.Add(diagnostic); } /// <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">Unsupported configuration value</param> public void ReportConfigurationNotSupported( AttributeData attributeData, string configurationName, string unsupportedValue) { ReportDiagnostic(attributeData.CreateDiagnosticInfo(_descriptorProvider.ConfigurationValueNotSupported, unsupportedValue, configurationName)); } /// <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> public void ReportConfigurationNotSupported( AttributeData attributeData, string configurationName) { ReportDiagnostic(attributeData.CreateDiagnosticInfo(_descriptorProvider.ConfigurationNotSupported, configurationName)); } /// <summary> /// Report a diagnostic for an invalid marshalling attribute. /// </summary> /// <param name="attributeData">The attribute data.</param> /// <param name="reasonResourceName">A resource name with the string describing the reason the attribute is invalid.</param> /// <param name="reasonArgs">The arguments for the localizable string.</param> public void ReportInvalidMarshallingAttributeInfo( AttributeData attributeData, string reasonResourceName, params string[] reasonArgs) { ReportDiagnostic(attributeData.CreateDiagnosticInfo(_descriptorProvider.InvalidMarshallingAttributeInfo, new LocalizableResourceString(reasonResourceName, _resourceManager, _resourceSource, reasonArgs))); } /// <summary> /// Report a diagnostic generated when resolving a generator. /// </summary> /// <param name="diagnostic">The generated diagnostic.</param> /// <exception cref="InvalidOperationException">The <see cref="IDiagnosticDescriptorProvider"/> did not provide a diagnostic for a fatal diagnostic.</exception> public void ReportGeneratorDiagnostic(GeneratorDiagnostic diagnostic) { DiagnosticDescriptor? descriptor = _descriptorProvider.GetDescriptor(diagnostic); if (descriptor is null) { if (diagnostic.IsFatal) { throw new InvalidOperationException(); } return; } _diagnostics.Add(_locations.CreateDiagnosticInfo(descriptor, diagnostic)); } /// <summary> /// Report a diagnostic generated when resolving a generator. /// </summary> /// <param name="diagnostic">The generated diagnostic.</param> /// <exception cref="InvalidOperationException">The <see cref="IDiagnosticDescriptorProvider"/> did not provide a diagnostic for a fatal diagnostic.</exception> public void ReportGeneratorDiagnostics(ImmutableArray<GeneratorDiagnostic> diagnostics) { foreach (var diagnostic in diagnostics) { ReportGeneratorDiagnostic(diagnostic); } } } /// <summary> /// Properties that are common to many interop generators' diagnostics. These properties are used by code-fixers to provide a good user experience. /// </summary> public class GeneratorDiagnosticProperties { /// <summary> /// The diagnostic can be resolved by adding the System.Runtime.CompilerServices.DisableRuntimeMarshallingAttribute to the assembly /// </summary> public const string AddDisableRuntimeMarshallingAttribute = nameof(AddDisableRuntimeMarshallingAttribute); /// <summary> /// The diagnostic can be resolved by adding the System.Runtime.InteropServices.MarshalAsAttribute to the element with one of the UnmanagedType values /// specified in the comma-separated list of values specified in the value of this property. /// </summary> public const string AddMarshalAsAttribute = nameof(AddMarshalAsAttribute); } }