From e1eacdf0c495f857717d32355ee9df5b0e99be5a Mon Sep 17 00:00:00 2001 From: filzrev <103790468+filzrev@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:00:24 +0900 Subject: [PATCH] chore: Remove `IgnoresAccessChecksToGenerator` dependencies (#10370) chore: remove dependency to IgnoresAccessChecksToGenerator --- Directory.Build.props | 3 +- Directory.Packages.props | 1 - src/Docfx.App/Docfx.App.csproj | 5 - src/Docfx.App/Helpers/PdfPigTypeExtensions.cs | 27 +++++ src/Docfx.App/PdfBuilder.cs | 2 +- src/Docfx.Dotnet/Docfx.Dotnet.csproj | 5 - .../ExtensionMethods/ISymbolExtensions.cs | 114 ++++++++++++++++++ 7 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 src/Docfx.App/Helpers/PdfPigTypeExtensions.cs create mode 100644 src/Docfx.Dotnet/ExtensionMethods/ISymbolExtensions.cs diff --git a/Directory.Build.props b/Directory.Build.props index 9ec7dd187a7..3006e8571fe 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -19,9 +19,8 @@ warning NU1507: There are 2 package sources defined in your configuration. warning NU5104: A stable release of a package should not have a prerelease dependency. Either modify the version spec of dependency "PdfPig [0.1.9-alpha-20240510-d86c2, )" or update the version field in the nuspec. warning NU5111: The script file 'tools\.playwright\package\bin\install_media_pack.ps1' is not recognized by NuGet and hence will not be executed during installation of this package. - warning CS0436: IgnoresAccessChecksTo redefinition due to InternalsVisibleTo --> - $(NoWarn);NU1507;NU5104;NU5111;CS0436 + $(NoWarn);NU1507;NU5104;NU5111 diff --git a/Directory.Packages.props b/Directory.Packages.props index 92de3602319..7b68a0f1f54 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,6 @@ - diff --git a/src/Docfx.App/Docfx.App.csproj b/src/Docfx.App/Docfx.App.csproj index 12db285be2e..e4d0f5d7804 100644 --- a/src/Docfx.App/Docfx.App.csproj +++ b/src/Docfx.App/Docfx.App.csproj @@ -18,11 +18,6 @@ - - - - - diff --git a/src/Docfx.App/Helpers/PdfPigTypeExtensions.cs b/src/Docfx.App/Helpers/PdfPigTypeExtensions.cs new file mode 100644 index 00000000000..8b0391424c0 --- /dev/null +++ b/src/Docfx.App/Helpers/PdfPigTypeExtensions.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using UglyToad.PdfPig.Content; +using UglyToad.PdfPig.Outline.Destinations; + +#nullable enable + +namespace Docfx; + +internal static class PdfPigTypeExtensions +{ + public static NamedDestinations GetNamedDestinations(this Catalog catalog) + => GetNamedDestinationsProperty(catalog); + + public static bool TryGet(this NamedDestinations namedDestinations, string name, out ExplicitDestination dest) + => TryGetNamedDestinations(namedDestinations, name, out dest); + + // Gets property value of catalog.NamedDestination. + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_NamedDestinations")] + private static extern NamedDestinations GetNamedDestinationsProperty(Catalog value); + + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "TryGet")] + private static extern bool TryGetNamedDestinations(NamedDestinations namedDestinations, string name, out ExplicitDestination dest); +} + diff --git a/src/Docfx.App/PdfBuilder.cs b/src/Docfx.App/PdfBuilder.cs index fdb1312dc36..0eefbe13c67 100644 --- a/src/Docfx.App/PdfBuilder.cs +++ b/src/Docfx.App/PdfBuilder.cs @@ -301,7 +301,7 @@ await Parallel.ForEachAsync(pages, async (item, _) => var key = CleanUrl(url); if (!pagesByUrl.TryGetValue(key, out var dests)) pagesByUrl[key] = dests = new(); - dests.Add((node, document.Structure.Catalog.NamedDestinations)); + dests.Add((node, document.Structure.Catalog.GetNamedDestinations())); pageBytes[node] = bytes; pageNumbers[node] = numberOfPages + 1; diff --git a/src/Docfx.Dotnet/Docfx.Dotnet.csproj b/src/Docfx.Dotnet/Docfx.Dotnet.csproj index 9dbc6ec171a..d28ca0fb4ae 100644 --- a/src/Docfx.Dotnet/Docfx.Dotnet.csproj +++ b/src/Docfx.Dotnet/Docfx.Dotnet.csproj @@ -16,10 +16,6 @@ - - - - @@ -32,7 +28,6 @@ - diff --git a/src/Docfx.Dotnet/ExtensionMethods/ISymbolExtensions.cs b/src/Docfx.Dotnet/ExtensionMethods/ISymbolExtensions.cs new file mode 100644 index 00000000000..362beb83f76 --- /dev/null +++ b/src/Docfx.Dotnet/ExtensionMethods/ISymbolExtensions.cs @@ -0,0 +1,114 @@ +// 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 System.Collections.Immutable; +using System.Globalization; +using System.Reflection; +using System.Reflection.Emit; + +#nullable enable + +namespace Docfx.Dotnet; + +internal static class ISymbolExtensions +{ + public static ImmutableArray GetParameters(this ISymbol? symbol) + { + return symbol switch + { + IMethodSymbol m => m.Parameters, + IPropertySymbol nt => nt.Parameters, + _ => [], + }; + } + + public static ImmutableArray GetTypeParameters(this ISymbol? symbol) + { + return symbol switch + { + IMethodSymbol m => m.TypeParameters, + INamedTypeSymbol nt => nt.TypeParameters, + _ => [], + }; + } + + public static DocumentationComment GetDocumentationComment(this ISymbol symbol, Compilation compilation, CultureInfo? preferredCulture = null, bool expandIncludes = false, bool expandInheritdoc = false, CancellationToken cancellationToken = default) + { + // Gets FullXmlFragment by calling `symbol.DocumentationComment(...).FullXmlFragment` + string fullXmlFragment = Helpers.GetFullXmlFragment(symbol, compilation, preferredCulture, expandIncludes, expandInheritdoc, cancellationToken); + + return new DocumentationComment + { + FullXmlFragment = fullXmlFragment, + }; + } + + internal class DocumentationComment + { + public required string FullXmlFragment { get; init; } + } + + private static class Helpers + { + /// + /// Gets result of `symbol.GetDocumentationComment(args).FullXmlFragment` + /// + public static string GetFullXmlFragment(ISymbol symbol, Compilation compilation, CultureInfo? preferredCulture = null, bool expandIncludes = false, bool expandInheritdoc = false, CancellationToken cancellationToken = default) + => CachedDelegate(symbol, compilation, preferredCulture, expandIncludes, expandInheritdoc, cancellationToken); + + static Helpers() + { + CachedDelegate = GetDelegate(); + } + + private delegate string GetFullXmlFragmentDelegate(ISymbol symbol, Compilation compilation, CultureInfo? preferredCulture, bool expandIncludes, bool expandInheritdoc, CancellationToken cancellationToken); + private static readonly GetFullXmlFragmentDelegate CachedDelegate; + + private static GetFullXmlFragmentDelegate GetDelegate() + { + // Gets Microsoft.CodeAnalysis.Workspaces assembly + var workspaceAssembly = typeof(Workspace).Assembly; + + // Gets MethodInfo for GetDocumentationComment + var type = workspaceAssembly.GetType("Microsoft.CodeAnalysis.Shared.Extensions.ISymbolExtensions", throwOnError: true)!; + var methodInfo = type.GetMethod("GetDocumentationComment", BindingFlags.Public | BindingFlags.Static); + + // Gets PropertyInfo for DocumentationComment. + var docCommentType = workspaceAssembly.GetType("Microsoft.CodeAnalysis.Shared.Utilities.DocumentationComment", throwOnError: true)!; + var propertyInfo = docCommentType.GetProperty("FullXmlFragment", BindingFlags.Instance | BindingFlags.Public)!; + + // Reflection may fail when updating the Microsoft.CodeAnalysis.Workspaces.Common package.. + if (methodInfo == null || propertyInfo == null) + throw new InvalidOperationException("Failed to get required MethodInfo/PropertyInfo via reflection."); + + var dm = new DynamicMethod(string.Empty, returnType: typeof(string), parameterTypes: [ + typeof(ISymbol), + typeof(Compilation), + typeof(CultureInfo), // preferredCulture + typeof(bool), // expandIncludes + typeof(bool), // expandInheritdoc + typeof(CancellationToken), + ]); + + ILGenerator il = dm.GetILGenerator(); + + // call Microsoft.CodeAnalysis.Shared.Extensions.ISymbolExtensions::GetDocumentationComment(args) + il.Emit(OpCodes.Ldarg_0); // symbol + il.Emit(OpCodes.Ldarg_1); // compilation + il.Emit(OpCodes.Ldarg_2); // preferredCulture + il.Emit(OpCodes.Ldarg_3); // expandIncludes + il.Emit(OpCodes.Ldarg_S, 4); // expandInheritdoc + il.Emit(OpCodes.Ldarg_S, 5); // cancellationToken + il.EmitCall(OpCodes.Call, methodInfo, null); + + // callvirt DocumentationComment::get_FullXmlFragment() + il.EmitCall(OpCodes.Callvirt, propertyInfo.GetMethod!, null); + + // return FullXmlFragment + il.Emit(OpCodes.Ret); + + return dm.CreateDelegate(); + } + } +}