-
Notifications
You must be signed in to change notification settings - Fork 5k
/
Copy pathGeneratedComInterfaceAttributeData.cs
88 lines (82 loc) · 4.4 KB
/
GeneratedComInterfaceAttributeData.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// 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 INamedTypeSymbol? ExceptionToUnmanagedMarshaller { get; init; }
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
};
}
if (args.TryGetValue(nameof(ExceptionToUnmanagedMarshaller), out TypedConstant exceptionToUnmanagedMarshaller))
{
if (exceptionToUnmanagedMarshaller.Value is not INamedTypeSymbol)
{
return null;
}
generatedComInterfaceAttributeData = generatedComInterfaceAttributeData with
{
ExceptionToUnmanagedMarshaller = (INamedTypeSymbol)exceptionToUnmanagedMarshaller.Value
};
}
return generatedComInterfaceAttributeData;
}
}
}