Created
July 13, 2024 21:42
-
-
Save rodion-m/f116db6b7f745c0f535b1ed615c4b8f0 to your computer and use it in GitHub Desktop.
A factory for creating instances of the internal SymbolDisplayFormat class from the Roslyn library.
This file contains hidden or 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
using System.Reflection; | |
using Microsoft.CodeAnalysis; | |
namespace Gend.Domain; | |
/// <summary> | |
/// Provides a factory for creating instances of the internal SymbolDisplayFormat class from the Roslyn library. | |
/// </summary> | |
public static class SymbolDisplayFormatFactory | |
{ | |
private static readonly ConstructorInfo ConstructorInfo; | |
private static readonly Type SymbolDisplayCompilerInternalOptionsType; | |
/// <summary> | |
/// Static constructor to initialize reflection-based access to internal Roslyn types. | |
/// </summary> | |
static SymbolDisplayFormatFactory() | |
{ | |
try | |
{ | |
Assembly assembly = typeof(SymbolDisplayFormat).Assembly; | |
Type symbolDisplayFormatType = typeof(SymbolDisplayFormat); | |
string enumTypeName = "Microsoft.CodeAnalysis.SymbolDisplayCompilerInternalOptions"; | |
SymbolDisplayCompilerInternalOptionsType = assembly.GetType(enumTypeName) | |
?? throw new InvalidOperationException($"Type '{enumTypeName}' not found."); | |
ConstructorInfo? constructorInfo = symbolDisplayFormatType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance) | |
.FirstOrDefault(c => c.GetParameters().Length == 12); | |
ConstructorInfo = constructorInfo | |
?? throw new InvalidOperationException("Constructor with 12 parameters not found."); | |
} | |
catch (Exception ex) | |
{ | |
throw new InvalidOperationException( | |
"Failed to initialize SymbolDisplayFormatFactory. " + | |
"Please check the version of the 'Microsoft.CodeAnalysis' package (it surely works with 4.10).", ex); | |
} | |
} | |
/// <summary> | |
/// Creates an instance of the internal SymbolDisplayFormat class using reflection. | |
/// </summary> | |
public static SymbolDisplayFormat CreateSymbolDisplayFormat( | |
SymbolDisplayCompilerInternalOptions compilerInternalOptions, | |
SymbolDisplayGlobalNamespaceStyle globalNamespaceStyle = default, | |
SymbolDisplayTypeQualificationStyle typeQualificationStyle = default, | |
SymbolDisplayGenericsOptions genericsOptions = default, | |
SymbolDisplayMemberOptions memberOptions = default, | |
SymbolDisplayParameterOptions parameterOptions = default, | |
SymbolDisplayDelegateStyle delegateStyle = default, | |
SymbolDisplayExtensionMethodStyle extensionMethodStyle = default, | |
SymbolDisplayPropertyStyle propertyStyle = default, | |
SymbolDisplayLocalOptions localOptions = default, | |
SymbolDisplayKindOptions kindOptions = default, | |
SymbolDisplayMiscellaneousOptions miscellaneousOptions = default) | |
{ | |
object internalCompilerOptions = Enum.ToObject( | |
SymbolDisplayCompilerInternalOptionsType, | |
(int)compilerInternalOptions); | |
return (SymbolDisplayFormat)ConstructorInfo.Invoke(new[] | |
{ | |
internalCompilerOptions, | |
globalNamespaceStyle, | |
typeQualificationStyle, | |
genericsOptions, | |
memberOptions, | |
parameterOptions, | |
delegateStyle, | |
extensionMethodStyle, | |
propertyStyle, | |
localOptions, | |
kindOptions, | |
miscellaneousOptions | |
}); | |
} | |
/// <summary> | |
/// Represents compiler internal options for symbol display in Roslyn. | |
/// This enum mirrors the internal SymbolDisplayCompilerInternalOptions enum in the Roslyn library. | |
/// </summary> | |
[Flags] | |
public enum SymbolDisplayCompilerInternalOptions | |
{ | |
/// <summary> | |
/// No special options. | |
/// </summary> | |
None = 0, | |
/// <summary> | |
/// Use metadata method names (e.g., ".ctor" instead of "Goo"). | |
/// </summary> | |
UseMetadataMethodNames = 1 << 0, | |
/// <summary> | |
/// Use arity for generic types (e.g., "List`1" instead of "List<T>"). | |
/// Overrides GenericsOptions on types. | |
/// </summary> | |
UseArityForGenericTypes = 1 << 1, | |
/// <summary> | |
/// Append "[Missing]" to missing Metadata types (for testing). | |
/// </summary> | |
FlagMissingMetadataTypes = 1 << 2, | |
/// <summary> | |
/// Include the Script type when qualifying type names. | |
/// </summary> | |
IncludeScriptType = 1 << 3, | |
/// <summary> | |
/// Include custom modifiers (e.g., modopt([mscorlib]System.Runtime.CompilerServices.IsConst)) on | |
/// the member (return) type and parameters. | |
/// </summary> | |
IncludeCustomModifiers = 1 << 4, | |
/// <summary> | |
/// Reverse array rank specifiers (e.g., "int[,][]" instead of "int[][,]"). | |
/// </summary> | |
ReverseArrayRankSpecifiers = 1 << 5, | |
/// <summary> | |
/// Display `System.[U]IntPtr` instead of `n[u]int`. | |
/// </summary> | |
UseNativeIntegerUnderlyingType = 1 << 6, | |
/// <summary> | |
/// Separate nested types from containing types using '+' instead of '.' (dot). | |
/// </summary> | |
UsePlusForNestedTypes = 1 << 7, | |
/// <summary> | |
/// Display `[email protected]` instead of `MyType`. | |
/// </summary> | |
IncludeContainingFileForFileTypes = 1 << 8, | |
/// <summary> | |
/// Does not include parameter name if the parameter is displayed on its own | |
/// (i.e., not as part of a method, delegate, or indexer). | |
/// </summary> | |
ExcludeParameterNameIfStandalone = 1 << 9, | |
/// <summary> | |
/// Display `<File>F<sha256-hex-string>_MyType` instead of `MyType`. | |
/// Differs from IncludeContainingFileForFileTypes because it guarantees that | |
/// the prefix will be unique for all files which are permitted to declare file-local types. | |
/// </summary> | |
IncludeFileLocalTypesPrefix = 1 << 10 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment