test: replace gameplay owner source freezes

This commit is contained in:
Erik 2026-08-18 16:49:38 +02:00
parent 9b94050229
commit 84034f732c
6 changed files with 473 additions and 388 deletions

View file

@ -56,6 +56,57 @@ internal static class CompiledCallGraph
.ToArray();
}
/// <summary>
/// Reads a type's declared methods plus compiler-generated closure methods
/// nested beneath it. Composition tests use this when an owned callback or
/// acquisition factory carries the typed edge under review.
/// </summary>
public static IReadOnlyList<CompiledCall> ReadOwned(Type type)
{
ArgumentNullException.ThrowIfNull(type);
const BindingFlags flags = BindingFlags.Instance
| BindingFlags.Static
| BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.DeclaredOnly;
MethodBase[] roots = EnumerateOwnedTypes(type)
.SelectMany(owner => owner.GetMethods(flags)
.Cast<MethodBase>()
.Concat(owner.GetConstructors(flags)))
.Where(method => method.GetMethodBody() is not null)
.ToArray();
var pending = new Queue<MethodBase>(roots);
var seen = new HashSet<MethodBase>(roots);
var calls = new List<CompiledCall>();
while (pending.TryDequeue(out MethodBase? method))
{
foreach (CompiledCall call in ReadMethodReferences(method))
{
calls.Add(call);
if (call.Target.Module == type.Module
&& call.Target.Name.Contains('<', StringComparison.Ordinal)
&& call.Target.GetMethodBody() is not null
&& seen.Add(call.Target))
{
pending.Enqueue(call.Target);
}
}
}
return calls;
}
private static IEnumerable<Type> EnumerateOwnedTypes(Type root)
{
yield return root;
foreach (Type nested in root.GetNestedTypes(
BindingFlags.Public | BindingFlags.NonPublic))
{
foreach (Type owned in EnumerateOwnedTypes(nested))
yield return owned;
}
}
public static IReadOnlyList<string> ReadStringLiterals(MethodBase method)
{
ArgumentNullException.ThrowIfNull(method);