mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
87 lines
3.1 KiB
C#
87 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Reflection.Metadata;
|
|
using System.Reflection.PortableExecutable;
|
|
using Internal.TypeSystem.Ecma;
|
|
|
|
namespace Robust.Shared.ContentPack
|
|
{
|
|
internal sealed partial class AssemblyTypeChecker
|
|
{
|
|
public static IEnumerable<(string Value, bool IsField)> DumpMetaMembers(Type type)
|
|
{
|
|
var assemblyLoc = type.Assembly.Location;
|
|
|
|
// Load assembly with System.Reflection.Metadata.
|
|
using var fs = File.OpenRead(assemblyLoc);
|
|
using var peReader = new PEReader(fs);
|
|
|
|
var metaReader = peReader.GetMetadataReader();
|
|
|
|
// Find type definition in raw assembly metadata.
|
|
// Is there a better way to do this than iterating??
|
|
TypeDefinition typeDef = default;
|
|
var found = false;
|
|
foreach (var typeDefHandle in metaReader.TypeDefinitions)
|
|
{
|
|
var tempTypeDef = metaReader.GetTypeDefinition(typeDefHandle);
|
|
var name = metaReader.GetString(tempTypeDef.Name);
|
|
var @namespace = NilNullString(metaReader, tempTypeDef.Namespace);
|
|
if (name == type.Name && @namespace == type.Namespace)
|
|
{
|
|
typeDef = tempTypeDef;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!found)
|
|
{
|
|
throw new InvalidOperationException("Type didn't exist??");
|
|
}
|
|
|
|
// Dump the list.
|
|
var provider = new TypeProvider();
|
|
|
|
foreach (var fieldHandle in typeDef.GetFields())
|
|
{
|
|
var fieldDef = metaReader.GetFieldDefinition(fieldHandle);
|
|
|
|
if ((fieldDef.Attributes & FieldAttributes.FieldAccessMask) != FieldAttributes.Public)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var fieldName = metaReader.GetString(fieldDef.Name);
|
|
var fieldType = fieldDef.DecodeSignature(provider, 0);
|
|
|
|
yield return ($"{fieldType.WhitelistToString()} {fieldName}", IsField: true);
|
|
}
|
|
|
|
foreach (var methodHandle in typeDef.GetMethods())
|
|
{
|
|
var methodDef = metaReader.GetMethodDefinition(methodHandle);
|
|
|
|
if (!methodDef.Attributes.IsPublic())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var methodName = metaReader.GetString(methodDef.Name);
|
|
var methodSig = methodDef.DecodeSignature(provider, 0);
|
|
|
|
var paramString = string.Join(", ", methodSig.ParameterTypes.Select(t => t.WhitelistToString()));
|
|
var genericCount = methodSig.GenericParameterCount;
|
|
var typeParamString = genericCount == 0
|
|
? ""
|
|
: $"<{new string(',', genericCount - 1)}>";
|
|
|
|
yield return ($"{methodSig.ReturnType.WhitelistToString()} {methodName}{typeParamString}({paramString})", IsField: false);
|
|
}
|
|
}
|
|
}
|
|
}
|