Skip to content

Commit

Permalink
Merge pull request #1037 from microsoft/fix953
Browse files Browse the repository at this point in the history
Fix CsWin32 api doc reading in newer C# compiler versions
  • Loading branch information
AArnott committed Sep 18, 2023
2 parents 93af057 + b3d8d8d commit c11feb0
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 5 deletions.
4 changes: 4 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,9 @@ dotnet_diagnostic.DOC202.severity = warning
# CA1062: Validate arguments of public methods
dotnet_diagnostic.CA1062.severity = suggestion

# MessagePack analyzer diagnostics
dotnet_diagnostic.MsgPack001.severity = error
dotnet_diagnostic.MsgPack002.severity = error

[*.sln]
indent_style = tab
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>

<MetadataVersion>54.0.44-preview</MetadataVersion>
<WDKMetadataVersion>0.7.3-experimental</WDKMetadataVersion>
<!-- <DiaMetadataVersion>0.2.185-preview-g7e1e6a442c</DiaMetadataVersion> -->
<ApiDocsVersion>0.1.42-alpha</ApiDocsVersion>

<CodeAnalysisVersion>4.6.0</CodeAnalysisVersion>
<CodeAnalysisVersion Condition="'$(IsTestProject)'!='true'">3.11.0</CodeAnalysisVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
<PackageVersion Include="MessagePack" Version="2.2.85" />
<PackageVersion Include="MessagePackAnalyzer" Version="2.5.108" />
<PackageVersion Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" />
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="$(CodeAnalysisVersion)" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing.XUnit" Version="1.1.2-beta1.23323.1" />
Expand Down Expand Up @@ -54,4 +53,4 @@
<ItemGroup>
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
</ItemGroup>
</Project>
</Project>
71 changes: 70 additions & 1 deletion src/Microsoft.Windows.CsWin32/Docs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using MessagePack;
using MessagePack.Formatters;
using MessagePack.Resolvers;

namespace Microsoft.Windows.CsWin32;

Expand All @@ -11,6 +13,10 @@ namespace Microsoft.Windows.CsWin32;
public class Docs
{
private static readonly Dictionary<string, Docs> DocsByPath = new Dictionary<string, Docs>(StringComparer.OrdinalIgnoreCase);
private static readonly MessagePackSerializerOptions MsgPackOptions = MessagePackSerializerOptions.Standard.WithResolver(
CompositeResolver.Create(
new IMessagePackFormatter[] { new ApiDetailsFormatter() },
new IFormatterResolver[] { StandardResolver.Instance }));

private readonly Dictionary<string, ApiDetails> apisAndDocs;

Expand All @@ -35,7 +41,7 @@ public static Docs Get(string docsPath)
}

using FileStream docsStream = File.OpenRead(docsPath);
Dictionary<string, ApiDetails>? data = MessagePackSerializer.Deserialize<Dictionary<string, ApiDetails>>(docsStream);
Dictionary<string, ApiDetails>? data = MessagePackSerializer.Deserialize<Dictionary<string, ApiDetails>>(docsStream, MsgPackOptions);
var docs = new Docs(data);

lock (DocsByPath)
Expand Down Expand Up @@ -85,4 +91,67 @@ public static Docs Merge(IReadOnlyList<Docs> docs)
}

internal bool TryGetApiDocs(string apiName, [NotNullWhen(true)] out ApiDetails? docs) => this.apisAndDocs.TryGetValue(apiName, out docs);

/// <summary>
/// Formatter for <see cref="ApiDetails"/>.
/// </summary>
/// <remarks>
/// We have to manually write this to avoid using the <see cref="DynamicObjectResolver"/> since newer C# compiler versions fail
/// when that dynamic type creator creates a non-collectible assembly that our own evidently collectible assembly references.
/// </remarks>
private class ApiDetailsFormatter : IMessagePackFormatter<ApiDetails>
{
public ApiDetails Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
string? helpLink = null;
string? description = null;
string? remarks = null;
Dictionary<string, string>? parameters = null;
Dictionary<string, string>? fields = null;
string? returnValue = null;
int count = reader.ReadArrayHeader();
for (int i = 0; i < count; i++)
{
switch (i)
{
case 0:
helpLink = reader.ReadString();
break;
case 1:
description = reader.ReadString();
break;
case 2:
remarks = reader.ReadString();
break;
case 3:
parameters = options.Resolver.GetFormatterWithVerify<Dictionary<string, string>>().Deserialize(ref reader, options);
break;
case 4:
fields = options.Resolver.GetFormatterWithVerify<Dictionary<string, string>>().Deserialize(ref reader, options);
break;
case 5:
returnValue = reader.ReadString();
break;
default:
reader.Skip();
break;
}
}

return new ApiDetails
{
HelpLink = helpLink is null ? null : new Uri(helpLink),
Description = description,
Remarks = remarks,
Parameters = parameters ?? new Dictionary<string, string>(),
Fields = fields ?? new Dictionary<string, string>(),
ReturnValue = returnValue,
};
}

public void Serialize(ref MessagePackWriter writer, ApiDetails value, MessagePackSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<ItemGroup>
<PackageReference Include="IsExternalInit" PrivateAssets="all" />
<PackageReference Include="MessagePack" />
<PackageReference Include="MessagePackAnalyzer" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Microsoft.Windows.SDK.Win32Metadata" GeneratePathProperty="true" PrivateAssets="none" />
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Windows.CsWin32/SourceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ private static IReadOnlyList<string> CollectMetadataPaths(GeneratorExecutionCont
}
catch (Exception e)
{
context.ReportDiagnostic(Diagnostic.Create(DocParsingError, null, path, e.Message));
context.ReportDiagnostic(Diagnostic.Create(DocParsingError, null, path, e));
}
}

Expand Down

0 comments on commit c11feb0

Please sign in to comment.