Created
March 1, 2023 07:58
-
-
Save Youssef1313/701066a90b7a0dde3193c5acf9e372d1 to your computer and use it in GitHub Desktop.
This file contains 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
public class Visitor : SymbolVisitor | |
{ | |
// TODO: Pooling | |
internal StringBuilder Builder { get; } = new(); | |
private readonly bool _includeGlobalNamespace; | |
private void AppendName(string text) | |
{ | |
if (SyntaxFacts.GetKeywordKind(text) != SyntaxKind.None) | |
{ | |
Builder.Append('@'); | |
} | |
Builder.Append(text); | |
} | |
public override void VisitArrayType(IArrayTypeSymbol symbol) | |
{ | |
Visit(symbol.ElementType); | |
Builder.Append("[]"); | |
} | |
public override void VisitDynamicType(IDynamicTypeSymbol symbol) | |
{ | |
Builder.Append("dynamic"); | |
} | |
public override void VisitNamedType(INamedTypeSymbol symbol) | |
{ | |
if (GetSpecialTypeName(symbol) is string specialName) | |
{ | |
Builder.Append(specialName); | |
return; | |
} | |
if (symbol.IsGenericType && symbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) | |
{ | |
Visit(symbol.TypeArguments[0]); | |
Builder.Append('?'); | |
return; | |
} | |
Visit(symbol.ContainingSymbol); | |
if (symbol.ContainingSymbol is INamespaceSymbol { IsGlobalNamespace: true }) | |
{ | |
if (_includeGlobalNamespace) | |
{ | |
Builder.Append("global::"); | |
} | |
} | |
else | |
{ | |
Builder.Append('.'); | |
} | |
AppendName(symbol.Name); | |
if (symbol.IsGenericType) | |
{ | |
Builder.Append('<'); | |
for (int i = 0; i < symbol.TypeArguments.Length; i++) | |
{ | |
Visit(symbol.TypeArguments[i]); | |
if (i < symbol.TypeArguments.Length - 1) | |
{ | |
Builder.Append(", "); | |
} | |
} | |
Builder.Append('>'); | |
} | |
} | |
private static string? GetSpecialTypeName(INamedTypeSymbol symbol) | |
{ | |
return symbol.SpecialType switch | |
{ | |
SpecialType.System_SByte => "sbyte", | |
SpecialType.System_Int16 => "short", | |
SpecialType.System_Int32 => "int", | |
SpecialType.System_Int64 => "long", | |
SpecialType.System_Byte => "byte", | |
SpecialType.System_UInt16 => "ushort", | |
SpecialType.System_UInt32 => "uint", | |
SpecialType.System_UInt64 => "ulong", | |
SpecialType.System_Single => "float", | |
SpecialType.System_Double => "double", | |
SpecialType.System_Decimal => "decimal", | |
SpecialType.System_Char => "char", | |
SpecialType.System_Boolean => "bool", | |
SpecialType.System_String => "string", | |
SpecialType.System_Object => "object", | |
_ => null, | |
}; | |
} | |
public override void VisitNamespace(INamespaceSymbol symbol) | |
{ | |
Visit(symbol.ContainingSymbol); | |
if (symbol.IsGlobalNamespace) | |
{ | |
return; | |
} | |
if (symbol.ContainingNamespace?.IsGlobalNamespace == true) | |
{ | |
if (_includeGlobalNamespace) | |
{ | |
Builder.Append("global::"); | |
} | |
} | |
else | |
{ | |
Builder.Append('.'); | |
} | |
AppendName(symbol.Name); | |
} | |
public override void VisitTypeParameter(ITypeParameterSymbol symbol) | |
{ | |
AppendName(symbol.Name); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment