Create an anonymous type programmatically
ReinisV opened this issue · comments
Reinis Vesers commented
I want to build an RtArgument
whose type is anonymous object whose shape is decided at runtime.
The C# code should be something like:
internal class BuildResultCodeGenerator : ClassCodeGenerator
{
public override RtClass GenerateNode(Type element, RtClass result, TypeResolver resolver)
{
// First of all, we fetch original AST node that is being generated by default
result = base.GenerateNode(element, result, resolver);
if (result == null) return null;
var constructor = new RtConstructor
{
Arguments = new List<RtArgument>
{
new()
{
Type = new RtAnonymousObjectType
{
Members = new Dictionary<RtIdentifier, RtTypeName>
{
{new RtIdentifier("stringField"), resolver.ResolveTypeName(typeof(String))},
{new RtIdentifier("numberField"), resolver.ResolveTypeName(typeof(Int32))},
}
},
Identifier = new RtIdentifier("something")
}
},
Body = new RtRaw(""),
};
result.Members.Add(constructor);
}
}
public sealed class RtAnonymousObjectType : RtTypeName
{
/// <summary>Type for dictionary key</summary>
public Dictionary<RtIdentifier, RtTypeName> Members { get; set; }
/// <inheritdoc />
public override IEnumerable<RtNode> Children
{
get
{
foreach (var identifierTypePair in this.Members.ToList())
{
yield return (RtNode)identifierTypePair.Value;
}
}
}
/// <inheritdoc />
public override void Accept(IRtVisitor visitor) => visitor.Visit(this);
/// <inheritdoc />
public override void Accept<T>(IRtVisitor<T> visitor) => visitor.Visit(this);
/// <inheritdoc />
public override string ToString() => $"{{ {String.Join(",\n", this.Members.ToList().Select(identifierTypePair => $"{identifierTypePair.Key}: {identifierTypePair.Value}"))} }}";
}
The result should be something like:
export class BuildResult
{
constructor (something: {stringField: string, numberField: number}) { }
}
Obviously, this C# code doesnt work, I get an "unknown node passed" error from here, but I can't find any Rt
structures that would work. The closest seems to be RtDictionaryType
, but that does not allow to set specific field names.
What am I missing?