Files
InterfaceGenerator/Speckle.InterfaceGenerator/SymbolExtensions.cs
T
2024-09-03 09:19:40 +01:00

86 lines
2.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
namespace Speckle.InterfaceGenerator;
internal static class SymbolExtensions
{
public static string GetNamespaceAndType(this ITypeSymbol typeSymbol)
{
if (typeSymbol is ITypeParameterSymbol t)
{
return t.Name;
}
return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
}
public static bool TryGetAttribute(
this ISymbol symbol,
INamedTypeSymbol attributeType,
out IEnumerable<AttributeData> attributes
)
{
attributes = symbol
.GetAttributes()
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
return attributes.Any();
}
public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType)
{
return symbol
.GetAttributes()
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
}
//Ref: https://stackoverflow.com/questions/27105909/get-fully-qualified-metadata-name-in-roslyn
public static string GetFullMetadataName(this ISymbol symbol, bool useNameWhenNotFound = false)
{
if (IsRootNamespace(symbol))
{
return useNameWhenNotFound ? symbol.Name : string.Empty;
}
var stringBuilder = new StringBuilder(symbol.MetadataName);
var last = symbol;
symbol = symbol.ContainingSymbol;
while (!IsRootNamespace(symbol))
{
if (symbol is ITypeSymbol && last is ITypeSymbol)
{
stringBuilder.Insert(0, '+');
}
else
{
stringBuilder.Insert(0, '.');
}
stringBuilder.Insert(
0,
symbol.OriginalDefinition.ToDisplayString(
SymbolDisplayFormat.MinimallyQualifiedFormat
)
);
symbol = symbol.ContainingSymbol;
}
var retVal = stringBuilder.ToString();
if (string.IsNullOrWhiteSpace(retVal) && useNameWhenNotFound)
{
return symbol.Name;
}
return retVal;
}
private static bool IsRootNamespace(ISymbol symbol)
{
return symbol is INamespaceSymbol { IsGlobalNamespace: true };
}
}