Skip to content

Commit

Permalink
Merge pull request #386 from microsoft/multipleInputs
Browse files Browse the repository at this point in the history
Enable creating C# projections based on multiple input winmd's and docs
  • Loading branch information
AArnott committed Sep 7, 2021
2 parents 36aeedd + 73eef68 commit 75e3d8f
Show file tree
Hide file tree
Showing 14 changed files with 610 additions and 230 deletions.
5 changes: 3 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
<IncludeSymbols Condition=" '$(DebugType)' != 'embedded' ">true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

<MetadataVersion>10.2.163-preview</MetadataVersion>
<ApiDocsVersion>0.1.4-alpha</ApiDocsVersion>
<MetadataVersion>10.2.185-preview</MetadataVersion>
<!-- <DiaMetadataVersion>0.2.185-preview-g7e1e6a442c</DiaMetadataVersion> -->
<ApiDocsVersion>0.1.6-alpha</ApiDocsVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 3 additions & 1 deletion src/Microsoft.Windows.CsWin32/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ PInvoke001 | Functionality | Warning | SourceGenerator
PInvoke002 | Functionality | Warning | SourceGenerator
PInvoke003 | Functionality | Warning | SourceGenerator
PInvoke004 | Functionality | Warning | SourceGenerator
PInvoke005 | Functionality | Warning | SourceGenerator
PInvoke005 | Functionality | Warning | SourceGenerator
PInvoke006 | Configuration | Warning | SourceGenerator
PInvoke007 | Functionality | Error | SourceGenerator
43 changes: 40 additions & 3 deletions src/Microsoft.Windows.CsWin32/Docs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ namespace Microsoft.Windows.CsWin32
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Linq;
using MessagePack;
using Microsoft.Windows.SDK.Win32Docs;

internal class Docs
/// <summary>
/// An in-memory representation of API documentation.
/// </summary>
public class Docs
{
private static readonly Dictionary<string, Docs> DocsByPath = new Dictionary<string, Docs>(StringComparer.OrdinalIgnoreCase);

Expand All @@ -22,7 +25,12 @@ private Docs(Dictionary<string, ApiDetails> apisAndDocs)
this.apisAndDocs = apisAndDocs;
}

internal static Docs Get(string docsPath)
/// <summary>
/// Loads docs from a file.
/// </summary>
/// <param name="docsPath">The messagepack docs file to read from.</param>
/// <returns>An instance of <see cref="Docs"/> that accesses the documentation in the file specified by <paramref name="docsPath"/>.</returns>
public static Docs Get(string docsPath)
{
lock (DocsByPath)
{
Expand All @@ -48,6 +56,35 @@ internal static Docs Get(string docsPath)
}
}

/// <summary>
/// Returns a <see cref="Docs"/> instance that contains all the merged documentation from a list of docs.
/// </summary>
/// <param name="docs">The docs to be merged. When API documentation is provided by multiple docs in this list, the first one appearing in this list is taken.</param>
/// <returns>An instance that contains all the docs provided. When <paramref name="docs"/> contains exactly one element, that element is returned.</returns>
public static Docs Merge(IReadOnlyList<Docs> docs)
{
if (docs.Count == 1)
{
// Nothing to merge.
return docs[0];
}

Dictionary<string, ApiDetails> mergedDocs = new(docs.Sum(d => d.apisAndDocs.Count), StringComparer.OrdinalIgnoreCase);
foreach (Docs doc in docs)
{
foreach (KeyValuePair<string, ApiDetails> api in doc.apisAndDocs)
{
// We want a first one wins policy.
if (!mergedDocs.ContainsKey(api.Key))
{
mergedDocs.Add(api.Key, api.Value);
}
}
}

return new Docs(mergedDocs);
}

internal bool TryGetApiDocs(string apiName, [NotNullWhen(true)] out ApiDetails? docs) => this.apisAndDocs.TryGetValue(apiName, out docs);
}
}
211 changes: 165 additions & 46 deletions src/Microsoft.Windows.CsWin32/Generator.cs

Large diffs are not rendered by default.

10 changes: 0 additions & 10 deletions src/Microsoft.Windows.CsWin32/GeneratorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ public record GeneratorOptions
/// <value>The default value is "PInvoke".</value>
public string? ClassName { get; init; } = "PInvoke";

/// <summary>
/// Gets the namespace for generated code.
/// </summary>
/// <value>The default value is "Windows.Win32". Must be non-empty.</value>
public string Namespace { get; init; } = "Windows.Win32";

/// <summary>
/// Gets a value indicating whether to emit a single source file as opposed to types spread across many files.
/// </summary>
Expand Down Expand Up @@ -57,10 +51,6 @@ public record GeneratorOptions
/// <exception cref="InvalidOperationException">Thrown when some setting is invalid.</exception>
public void Validate()
{
if (string.IsNullOrWhiteSpace(this.Namespace))
{
throw new InvalidOperationException("The namespace must be set.");
}
}

/// <summary>
Expand Down
Loading

0 comments on commit 75e3d8f

Please sign in to comment.