File: GeneratedComInterfaceAttributeData.cs
Web Access
Project: src\src\libraries\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj (Microsoft.Interop.ComInterfaceGenerator)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
 
namespace Microsoft.Interop
{
    /// <summary>
    /// Contains the data related to a GeneratedComInterfaceAttribute, without references to Roslyn symbols.
    /// See <seealso cref="GeneratedComInterfaceCompilationData"/> for a type with a reference to the StringMarshallingCustomType
    /// </summary>
    internal sealed record GeneratedComInterfaceData : InteropAttributeData
    {
        public ComInterfaceOptions Options { get; init; }
        public static GeneratedComInterfaceData From(GeneratedComInterfaceCompilationData generatedComInterfaceAttr)
            => new GeneratedComInterfaceData() with
            {
                IsUserDefined = generatedComInterfaceAttr.IsUserDefined,
                SetLastError = generatedComInterfaceAttr.SetLastError,
                StringMarshalling = generatedComInterfaceAttr.StringMarshalling,
                StringMarshallingCustomType = generatedComInterfaceAttr.StringMarshallingCustomType is not null
                    ? ManagedTypeInfo.CreateTypeInfoForTypeSymbol(generatedComInterfaceAttr.StringMarshallingCustomType)
                    : null,
                Options = generatedComInterfaceAttr.Options
            };
    }
 
    /// <summary>
    /// Contains the data related to a GeneratedComInterfaceAttribute, with references to Roslyn symbols.
    /// Use <seealso cref="GeneratedComInterfaceData"/> instead when using for incremental compilation state to avoid keeping a compilation alive
    /// </summary>
    internal sealed record GeneratedComInterfaceCompilationData : InteropAttributeCompilationData
    {
        public ComInterfaceOptions Options { get; init; } = ComInterfaceOptions.ManagedObjectWrapper | ComInterfaceOptions.ComObjectWrapper;
 
        public static bool TryGetGeneratedComInterfaceAttributeFromInterface(INamedTypeSymbol interfaceSymbol, [NotNullWhen(true)] out AttributeData? generatedComInterfaceAttribute)
        {
            generatedComInterfaceAttribute = null;
            foreach (var attr in interfaceSymbol.GetAttributes())
            {
                if (generatedComInterfaceAttribute is null
                    && attr.AttributeClass?.ToDisplayString() == TypeNames.GeneratedComInterfaceAttribute)
                {
                    generatedComInterfaceAttribute = attr;
                }
            }
            return generatedComInterfaceAttribute is not null;
        }
 
        public static GeneratedComInterfaceCompilationData GetAttributeDataFromInterfaceSymbol(INamedTypeSymbol interfaceSymbol)
        {
            bool found = TryGetGeneratedComInterfaceAttributeFromInterface(interfaceSymbol, out var attr);
            Debug.Assert(found);
            return GetDataFromAttribute(attr);
        }
 
        public static GeneratedComInterfaceCompilationData GetDataFromAttribute(AttributeData attr)
        {
            Debug.Assert(attr.AttributeClass.ToDisplayString() == TypeNames.GeneratedComInterfaceAttribute);
            var generatedComInterfaceAttributeData = new GeneratedComInterfaceCompilationData();
            var args = attr.NamedArguments.ToImmutableDictionary();
            generatedComInterfaceAttributeData = generatedComInterfaceAttributeData.WithValuesFromNamedArguments(args);
            if (args.TryGetValue(nameof(Options), out var options))
            {
                generatedComInterfaceAttributeData = generatedComInterfaceAttributeData with
                {
                    Options = (ComInterfaceOptions)options.Value
                };
            }
            return generatedComInterfaceAttributeData;
        }
    }
}