-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and motivation
For adding AssemblyBuilder.Save() equivalent in .NET Core we have abstracted most of the System.Refleciton.Emit types and adding new implementations for them. This abstraction did not cover Label and LocalBuilder types and its constructors are internal, so I could not create an instance from the new ILGenerator implementation.
API Proposal
-
For
LocalBuilderwe need to unseal theLocalBuilderclass and make it abstract, make theinternalconstructorprotected, also add a public getter that exposes themethodthe local belongs to.namespace System.Reflection.Emit; -public sealed class LocalBuilder : System.Reflection.LocalVariableInfo +public abstract class LocalBuilder : System.Reflection.LocalVariableInfo { - internal LocalBuilder(int localIndex, Type localType, MethodInfo method, bool isPinned) { } + protected LocalBuilder() { } + public abstract MethodInfo LocalMethod { get; } }
Abstract
LocalMethodproperty can be used for validation. ParentLocalVariableInfohas public virtual properties likeLocalType,LocalIndex,IsPinned. -
For
Labelstruct we need a protected factory method in the abstractILGeneratortype so that we can create an instance from derived types.namespace System.Reflection.Emit; public abstract class ILGenerator { protected ILGenerator() { } ... public abstract Label DefineLabel(); + protected static Label CreateLabel(int id) { throw null; } } public readonly partial struct Label : System.IEquatable<System.Reflection.Emit.Label> { ... + public int Id { get; } }
API Usage
internal sealed class ILGeneratorImpl : ILGenerator
{
public override Label DefineLabel()
{
LabelHandle metadataLabel = _il.DefineLabel();
Label emitLabel = CreateLabel(metadataLabel.Id);
_labelTable.Add(emitLabel, metadataLabel);
return emitLabel;
}
}Related to #92975
CC @steveharter