Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce a source generator for invoking methods on unmanaged vtables #68276

Merged
merged 40 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
de8d813
WIP for generating stubs for manual vtable entrypoints.
jkoritzinsky Apr 13, 2022
4e23511
Fix up some names and actually parse the right attribute.
jkoritzinsky Apr 14, 2022
6b6020a
Update ComInterfaceGenerator to not pass syntax around
jkoritzinsky Apr 14, 2022
ac354c6
Move TestUtils to a shared location and get our first test unit test …
jkoritzinsky Apr 19, 2022
2af787c
Add some tests around calling convention handling.
jkoritzinsky Apr 19, 2022
6d7327b
Add tests for the emitted native interface type shape
jkoritzinsky Apr 19, 2022
b9f3597
Add some basic marshalling tests to give some validation that we set …
jkoritzinsky Apr 19, 2022
7caa3c7
Add design doc, update API name, remove scratch pad
jkoritzinsky Apr 20, 2022
6e7e119
Fix build and run
jkoritzinsky May 13, 2022
f862f15
Fix markdownlint failures
jkoritzinsky May 13, 2022
09dc2c4
infra fixes for ComInterfaceGenerator test runs
jkoritzinsky May 13, 2022
a83b092
Add more tests
jkoritzinsky May 13, 2022
faa674e
Exclude ComInterfaceGenerator on mobile platforms
jkoritzinsky May 16, 2022
a55e337
Add basic runtime tests
jkoritzinsky May 16, 2022
7e92bd4
Remove extraneous diagnostic
jkoritzinsky May 26, 2022
f54bd51
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky May 26, 2022
d95cdac
PR feedback
jkoritzinsky Jun 7, 2022
2e2809a
Merge branch 'main' into vtable-stubs
jkoritzinsky Jun 7, 2022
8fef109
Fix build break
jkoritzinsky Jun 9, 2022
7736687
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky Jul 13, 2022
794c4cf
Get the generator up to date with our newer designs and increase the …
jkoritzinsky Jul 14, 2022
5627e53
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky Aug 24, 2022
a958552
Use static abstracts instead of partial + containing class to define …
jkoritzinsky Aug 24, 2022
7182f4b
Use MarshalDirection type in generators and update design doc
jkoritzinsky Aug 25, 2022
9ca69dd
Use static-abstracts + DIMs to remove the extra shape validation.
jkoritzinsky Aug 25, 2022
5746f8b
Fix JS generator test build
jkoritzinsky Aug 29, 2022
032ebff
Fix exclusions
jkoritzinsky Aug 31, 2022
8ac684c
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky Aug 31, 2022
fbe5edf
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky Sep 2, 2022
d964d0c
Fix exclusions of runtime tests
jkoritzinsky Sep 2, 2022
bf8485a
Disable runtime tests on Mono because Mono doesn't implement an API t…
jkoritzinsky Sep 3, 2022
7fc5e52
Fix test disable to work in the normal runtime pipeline, albeit not p…
jkoritzinsky Sep 6, 2022
2868df2
Merge branch 'main' into vtable-stubs
jkoritzinsky Sep 10, 2022
19a5b01
Merge branch 'main' of github.com:dotnet/runtime into vtable-stubs
jkoritzinsky Sep 23, 2022
3008cd5
Directly pass along target framework kind and version instead of Stub…
jkoritzinsky Sep 24, 2022
1d8bd6a
Use a wrapper struct to make using elementwise equality for immutable…
jkoritzinsky Sep 29, 2022
229f45a
Merge branch 'main' into vtable-stubs
jkoritzinsky Sep 29, 2022
4f89920
Merge branch 'main' into vtable-stubs
jkoritzinsky Oct 7, 2022
d403851
Fix build
jkoritzinsky Oct 7, 2022
1e890d4
Update the generator entry-point and the project file based on change…
jkoritzinsky Oct 10, 2022
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
399 changes: 399 additions & 0 deletions docs/design/libraries/ComInterfaceGenerator/VTableStubs.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion eng/testing/tests.props
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</ItemGroup>

<ItemGroup Condition="'$(TestRunRequiresLiveRefPack)' == 'true'">
<None Include="$(MicrosoftNetCoreAppRefPackRefDir)**/*.dll" CopyToOutputDirectory="PreserveNewest" LinkBase="live-ref-pack/" Visible="false" />
<None Include="$(MicrosoftNetCoreAppRefPackRefDir)**/*.dll" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" LinkBase="live-ref-pack/" Visible="false" />
</ItemGroup>

<!--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{D893B9AA-57C
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{E1AEBD5D-AE4E-4F61-B9ED-AEF950B0CC33}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator", "gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj", "{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator.Unit.Tests", "tests\ComInterfaceGenerator.Unit.Tests\ComInterfaceGenerator.Unit.Tests.csproj", "{1D771995-D475-429B-AC31-2B1F618AA45F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ComInterfaceGenerator.Tests", "tests\ComInterfaceGenerator.Tests\ComInterfaceGenerator.Tests.csproj", "{3741C833-C364-4269-9B1D-D442055DA7CE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Checked|Any CPU = Checked|Any CPU
Expand Down Expand Up @@ -344,6 +350,60 @@ Global
{0B5FD0C2-367D-4AD6-8001-80AD79B2441C}.Release|x64.Build.0 = Release|Any CPU
{0B5FD0C2-367D-4AD6-8001-80AD79B2441C}.Release|x86.ActiveCfg = Release|Any CPU
{0B5FD0C2-367D-4AD6-8001-80AD79B2441C}.Release|x86.Build.0 = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|Any CPU.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|x64.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|x64.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|x86.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Checked|x86.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|x64.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|x64.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|x86.ActiveCfg = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Debug|x86.Build.0 = Debug|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|Any CPU.Build.0 = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|x64.ActiveCfg = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|x64.Build.0 = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|x86.ActiveCfg = Release|Any CPU
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5}.Release|x86.Build.0 = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|Any CPU.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|x64.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|x64.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|x86.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Checked|x86.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|x64.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|x64.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|x86.ActiveCfg = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Debug|x86.Build.0 = Debug|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|Any CPU.Build.0 = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|x64.ActiveCfg = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|x64.Build.0 = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|x86.ActiveCfg = Release|Any CPU
{1D771995-D475-429B-AC31-2B1F618AA45F}.Release|x86.Build.0 = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|Any CPU.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|Any CPU.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|x64.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|x64.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|x86.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Checked|x86.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|x64.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|x64.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|x86.ActiveCfg = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Debug|x86.Build.0 = Debug|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|Any CPU.Build.0 = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|x64.ActiveCfg = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|x64.Build.0 = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|x86.ActiveCfg = Release|Any CPU
{3741C833-C364-4269-9B1D-D442055DA7CE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -365,6 +425,9 @@ Global
{866D295E-424A-4747-9417-CD7746936138} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{D3A329E3-0FEB-4136-9CB6-B38319B0FFA5} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{0B5FD0C2-367D-4AD6-8001-80AD79B2441C} = {D893B9AA-57C5-49E3-97B1-12CC62D84307}
{C3EA0A28-A597-4946-9E08-EBBBFA94BFA5} = {E1AEBD5D-AE4E-4F61-B9ED-AEF950B0CC33}
{1D771995-D475-429B-AC31-2B1F618AA45F} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
{3741C833-C364-4269-9B1D-D442055DA7CE} = {FB99AC59-1744-4F12-A4B0-0D54FCA048BF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D4031401-FEB5-4CCF-91C1-38F5646B2BFD}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<AssemblyName>Microsoft.Interop.ComInterfaceGenerator</AssemblyName>
<TargetFramework>netstandard2.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>Preview</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Microsoft.Interop</RootNamespace>
<IsRoslynComponent>true</IsRoslynComponent>
<RunAnalyzers>true</RunAnalyzers>
<!-- Disable RS2008: Enable analyzer release tracking
Diagnostics in runtime use a different mechanism (docs/project/list-of-diagnostics.md) -->
<NoWarn>RS2008;$(NoWarn)</NoWarn>

<!-- Packaging properties -->
<!-- In the future LibraryImportGenerator might ship as part of a package, but meanwhile disable packaging. -->
<IsPackable>false</IsPackable>
<IncludeBuildOutput>false</IncludeBuildOutput>
<SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
<PackageProjectUrl>https://github.com/dotnet/runtime/tree/main/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator</PackageProjectUrl>
<Description>LibraryImportGenerator</Description>
<PackageTags>LibraryImportGenerator, analyzers</PackageTags>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisVersion_4_X)" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="$(MicrosoftCodeAnalysisAnalyzersVersion)" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<None Include="$(TargetPath)" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(AssemblyName).props" Pack="true" PackagePath="build" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj" Pack="true" PackagePath="analyzers/dotnet/cs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;

namespace Microsoft.Interop
{
internal static class Comparers
{
/// <summary>
/// Comparer for an individual generated stub source as a syntax tree and the generated diagnostics for the stub.
/// </summary>
public static readonly IEqualityComparer<(MemberDeclarationSyntax Syntax, ImmutableArray<Diagnostic> Diagnostics)> GeneratedSyntax = new CustomValueTupleElementComparer<MemberDeclarationSyntax, ImmutableArray<Diagnostic>>(SyntaxEquivalentComparer.Instance, new ImmutableArraySequenceEqualComparer<Diagnostic>(EqualityComparer<Diagnostic>.Default));
}

/// <summary>
/// Generic comparer to compare two <see cref="ImmutableArray{T}"/> instances element by element.
/// </summary>
/// <typeparam name="T">The type of immutable array element.</typeparam>
internal sealed class ImmutableArraySequenceEqualComparer<T> : IEqualityComparer<ImmutableArray<T>>
{
private readonly IEqualityComparer<T> _elementComparer;

/// <summary>
/// Creates an <see cref="ImmutableArraySequenceEqualComparer{T}"/> with a custom comparer for the elements of the collection.
/// </summary>
/// <param name="elementComparer">The comparer instance for the collection elements.</param>
public ImmutableArraySequenceEqualComparer(IEqualityComparer<T> elementComparer)
{
_elementComparer = elementComparer;
}

public bool Equals(ImmutableArray<T> x, ImmutableArray<T> y)
{
return x.SequenceEqual(y, _elementComparer);
}

public int GetHashCode(ImmutableArray<T> obj)
{
throw new UnreachableException();
}
}

internal sealed class CustomValueTupleElementComparer<T, U> : IEqualityComparer<(T, U)>
{
private readonly IEqualityComparer<T> _item1Comparer;
private readonly IEqualityComparer<U> _item2Comparer;

public CustomValueTupleElementComparer(IEqualityComparer<T> item1Comparer, IEqualityComparer<U> item2Comparer)
{
_item1Comparer = item1Comparer;
_item2Comparer = item2Comparer;
}

public bool Equals((T, U) x, (T, U) y)
{
return _item1Comparer.Equals(x.Item1, y.Item1) && _item2Comparer.Equals(x.Item2, y.Item2);
}

public int GetHashCode((T, U) obj)
{
throw new UnreachableException();
}
}
}
Loading