mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-15 06:42:25 +02:00
* Add source generator for DataDefinition validation * Add source generator for reading * Add source generator for writing * Include prototypes and other meansdatadefinition types * Target ISerializationGenerated in data definitions * Murder * Use array, struct, enum methods * Source generate get field definitions * serv5 * Fix and pray * Fix release compile * Tayrtahn review * a * Generator bugfix --------- Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
114 lines
3.5 KiB
C#
114 lines
3.5 KiB
C#
using Microsoft.CodeAnalysis;
|
|
|
|
namespace Robust.Roslyn.Shared;
|
|
|
|
#nullable enable
|
|
|
|
public static class TypeSymbolHelper
|
|
{
|
|
public static bool ShittyTypeMatch(ITypeSymbol type, string attributeMetadataName)
|
|
{
|
|
// Doing it like this only allocates when the type actually matches, which is good enough for me right now.
|
|
if (!attributeMetadataName.EndsWith(type.Name))
|
|
return false;
|
|
|
|
return type.ToDisplayString() == attributeMetadataName;
|
|
}
|
|
|
|
public static bool ImplementsInterface(ITypeSymbol type, string interfaceTypeName)
|
|
{
|
|
foreach (var interfaceType in type.AllInterfaces)
|
|
{
|
|
if (ShittyTypeMatch(interfaceType, interfaceTypeName))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool ImplementsInterface(ITypeSymbol type, INamedTypeSymbol interfaceType)
|
|
{
|
|
foreach (var @interface in type.AllInterfaces)
|
|
{
|
|
if (SymbolEqualityComparer.Default.Equals(@interface, interfaceType))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all Members of a symbol, including those that are inherited.
|
|
/// We need this because sometimes Components have abstract parents with autonetworked datafields.
|
|
/// </summary>
|
|
public static IEnumerable<ISymbol> GetAllMembersIncludingInherited(INamedTypeSymbol type)
|
|
{
|
|
var current = type;
|
|
while (current != null)
|
|
{
|
|
foreach (var member in current.GetMembers())
|
|
{
|
|
yield return member;
|
|
}
|
|
|
|
current = current.BaseType;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// If <paramref name="type"/> is a Nullable{T}, returns the <see cref="ITypeSymbol"/> of the underlying type.
|
|
/// Otherwise, returns <paramref name="type"/>.
|
|
/// </summary>
|
|
// Modified from https://www.meziantou.net/working-with-types-in-a-roslyn-analyzer.htm
|
|
public static ITypeSymbol GetNullableUnderlyingTypeOrSelf(ITypeSymbol type)
|
|
{
|
|
if (type is INamedTypeSymbol namedType && namedType.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T)
|
|
{
|
|
return namedType.TypeArguments[0];
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enumerates all base types of the given <paramref name="type"/>.
|
|
/// </summary>
|
|
public static IEnumerable<ITypeSymbol> GetBaseTypes(ITypeSymbol type)
|
|
{
|
|
var baseType = type.BaseType;
|
|
while (baseType != null)
|
|
{
|
|
yield return baseType;
|
|
baseType = baseType.BaseType;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the given <paramref name="type"/> inherits from <paramref name="other"/>.
|
|
/// </summary>
|
|
/// <returns>True if <paramref name="type"/> inherits from <paramref name="other"/>, otherwise false.</returns>
|
|
public static bool Inherits(ITypeSymbol type, ITypeSymbol other)
|
|
{
|
|
foreach (var baseType in GetBaseTypes(type))
|
|
{
|
|
if (SymbolEqualityComparer.Default.Equals(baseType, other))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the given <paramref name="type"/> inherits from a type with the given metadata name.
|
|
/// </summary>
|
|
public static bool Inherits(ITypeSymbol type, string otherTypeName)
|
|
{
|
|
foreach (var baseType in GetBaseTypes(type))
|
|
{
|
|
if (ShittyTypeMatch(baseType, otherTypeName))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|