-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ComInterfaceGenerator] Interface inheritance follow up (#85117)
This commit creates types to model the Com interfaces and the methods in the com interfaces. The new types with suffix "Info" are meant to be the first step of the pipeline that can be created with just an ISymbol and SyntaxNode. The types suffixed with "Context" are meant to contain all info necessary for generating the code, and they may require multiple "Info"s to be created (e.g. need info about the base interface or other methods in the interface). There is also a type that represents the Com interface and all the methods that are required to generate the code necessary for Com.
- Loading branch information
1 parent
115a475
commit ff92d4e
Showing
37 changed files
with
1,226 additions
and
406 deletions.
There are no files selected for viewing
22 changes: 22 additions & 0 deletions
22
src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/AttributeInfo.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.CSharp; | ||
|
||
namespace Microsoft.Interop | ||
{ | ||
/// <summary> | ||
/// Provides the info necessary for copying an attribute from user code to generated code. | ||
/// </summary> | ||
internal sealed record AttributeInfo(ManagedTypeInfo Type, SequenceEqualImmutableArray<string> Arguments) | ||
{ | ||
internal static AttributeInfo From(AttributeData attribute) | ||
{ | ||
var type = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(attribute.AttributeClass); | ||
var args = attribute.ConstructorArguments.Select(ca => ca.ToCSharpString()); | ||
return new(type, args.ToSequenceEqualImmutableArray()); | ||
} | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceAndMethodsContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 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.Generic; | ||
using System.Linq; | ||
using Microsoft.CodeAnalysis; | ||
|
||
namespace Microsoft.Interop | ||
{ | ||
public sealed partial class ComInterfaceGenerator | ||
{ | ||
/// <summary> | ||
/// Represents an interface and all of the methods that need to be generated for it (methods declared on the interface and methods inherited from base interfaces). | ||
/// </summary> | ||
private sealed record ComInterfaceAndMethodsContext(ComInterfaceContext Interface, SequenceEqualImmutableArray<ComMethodContext> Methods) | ||
{ | ||
// Change Calc all methods to return an ordered list of all the methods and the data in comInterfaceandMethodsContext | ||
// Have a step that runs CalculateMethodStub on each of them. | ||
// Call GroupMethodsByInterfaceForGeneration | ||
|
||
/// <summary> | ||
/// COM methods that are declared on the attributed interface declaration. | ||
/// </summary> | ||
public IEnumerable<ComMethodContext> DeclaredMethods => Methods.Where(m => !m.IsInheritedMethod); | ||
|
||
/// <summary> | ||
/// COM methods that are declared on an interface the interface inherits from. | ||
/// </summary> | ||
public IEnumerable<ComMethodContext> ShadowingMethods => Methods.Where(m => m.IsInheritedMethod); | ||
} | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
...libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceContext.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// 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.Generic; | ||
using System.Collections.Immutable; | ||
using System.Threading; | ||
|
||
namespace Microsoft.Interop | ||
{ | ||
public sealed partial class ComInterfaceGenerator | ||
{ | ||
private sealed record ComInterfaceContext(ComInterfaceInfo Info, ComInterfaceContext? Base) | ||
{ | ||
/// <summary> | ||
/// Takes a list of ComInterfaceInfo, and creates a list of ComInterfaceContext. | ||
/// </summary> | ||
public static ImmutableArray<ComInterfaceContext> GetContexts(ImmutableArray<ComInterfaceInfo> data, CancellationToken _) | ||
{ | ||
Dictionary<string, ComInterfaceInfo> symbolToInterfaceInfoMap = new(); | ||
var accumulator = ImmutableArray.CreateBuilder<ComInterfaceContext>(data.Length); | ||
foreach (var iface in data) | ||
{ | ||
symbolToInterfaceInfoMap.Add(iface.ThisInterfaceKey, iface); | ||
} | ||
Dictionary<string, ComInterfaceContext> symbolToContextMap = new(); | ||
|
||
foreach (var iface in data) | ||
{ | ||
accumulator.Add(AddContext(iface)); | ||
} | ||
return accumulator.MoveToImmutable(); | ||
|
||
ComInterfaceContext AddContext(ComInterfaceInfo iface) | ||
{ | ||
if (symbolToContextMap.TryGetValue(iface.ThisInterfaceKey, out var cachedValue)) | ||
{ | ||
return cachedValue; | ||
} | ||
|
||
if (iface.BaseInterfaceKey is null) | ||
{ | ||
var baselessCtx = new ComInterfaceContext(iface, null); | ||
symbolToContextMap[iface.ThisInterfaceKey] = baselessCtx; | ||
return baselessCtx; | ||
} | ||
|
||
if (!symbolToContextMap.TryGetValue(iface.BaseInterfaceKey, out var baseContext)) | ||
{ | ||
baseContext = AddContext(symbolToInterfaceInfoMap[iface.BaseInterfaceKey]); | ||
} | ||
var ctx = new ComInterfaceContext(iface, baseContext); | ||
symbolToContextMap[iface.ThisInterfaceKey] = ctx; | ||
return ctx; | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.