test: replace input and physics source freezes

This commit is contained in:
Erik 2026-08-18 15:31:57 +02:00
parent 0ad2ee1cdf
commit caa5eb8b2b
6 changed files with 313 additions and 238 deletions

View file

@ -4,6 +4,7 @@ using System.Reflection.Emit;
namespace AcDream.App.Tests.Architecture;
internal readonly record struct CompiledCall(int Offset, MethodBase Target);
internal readonly record struct CompiledInstruction(int Offset, OpCode OpCode);
/// <summary>
/// Reads compiled call/new-object edges from a method body. Architecture tests
@ -70,6 +71,70 @@ internal static class CompiledCallGraph
return literals;
}
/// <summary>
/// Reads the compiled instruction sequence without exposing operands. This
/// is sufficient for architecture tests that need to distinguish an
/// immediate return from fall-through without freezing source formatting.
/// </summary>
public static IReadOnlyList<CompiledInstruction> ReadInstructions(
MethodBase method)
{
ArgumentNullException.ThrowIfNull(method);
byte[] il = method.GetMethodBody()?.GetILAsByteArray()
?? throw new InvalidOperationException(
$"{method.DeclaringType?.FullName}.{method.Name} has no compiled body.");
var instructions = new List<CompiledInstruction>();
for (int cursor = 0; cursor < il.Length;)
{
int instructionOffset = cursor;
OpCode opCode = ReadOpCode(il, ref cursor);
instructions.Add(new CompiledInstruction(instructionOffset, opCode));
cursor += OperandSize(opCode.OperandType, il, cursor);
}
return instructions;
}
/// <summary>
/// Reads types named by compiled type operands such as casts, boxing, and
/// <c>isinst</c>. This lets tests retain an exact type boundary without
/// depending on the source expression used to spell it.
/// </summary>
public static IReadOnlyList<Type> ReadTypeReferences(MethodBase method)
{
ArgumentNullException.ThrowIfNull(method);
byte[] il = method.GetMethodBody()?.GetILAsByteArray()
?? throw new InvalidOperationException(
$"{method.DeclaringType?.FullName}.{method.Name} has no compiled body.");
Type[]? declaringArguments = method.DeclaringType?.IsGenericType == true
? method.DeclaringType.GetGenericArguments()
: null;
Type[]? methodArguments = method.IsGenericMethod
? method.GetGenericArguments()
: null;
var types = new List<Type>();
for (int cursor = 0; cursor < il.Length;)
{
OpCode opCode = ReadOpCode(il, ref cursor);
if (opCode.OperandType == OperandType.InlineType)
{
int token = BitConverter.ToInt32(il, cursor);
Type? type = method.Module.ResolveType(
token,
declaringArguments,
methodArguments);
if (type is not null)
types.Add(type);
}
cursor += OperandSize(opCode.OperandType, il, cursor);
}
return types;
}
public static int IndexOf(
IReadOnlyList<CompiledCall> calls,
Type declaringType,