Metalama icon indicating copy to clipboard operation
Metalama copied to clipboard

Feature: Mechanism to assign unique variable name to arbitrary IStatement

Open WhitWaldo opened this issue 11 months ago • 1 comments

Today, one might write a statement along the lines of (contrived):

var sampleBuilder = new StatementBuilder();
sampleBuilder.AppendVerbatim("var abc = ");
sampleBuilder.AppendLiteral(123);
sampleBuilder.AppendVerbatim(";");
meta.InsertStatement(sampleBuilder.ToStatement());

This is fine as it'll put var abc = 123; in your run-time code and it works. However, I keep running into a need to reference abc later on in my templates. As it is, I have to access it with:

var abc = ExpressionFactory.Parse("abc").Value;

That's fine except now my output looks like:

var abc = 123;
var abc = abc;

I might put a compile-time loop around this and use meta.CompileTime to make the variable name unique, but I still wind up with that second declaration each time + I had to manage the meta.CompileTime bit myself.

If I had an expression, I could simply create a new instance of ExpressionBuilder, build it out and assign its Value property to a local variable and use it wherever I wanted (yielding something like the second line above). I'd like to request something similar for a StatementBuilder.

Now, I'm not sure how exactly this would look given that a statement usually also contains an assignment already and we're trying to avoid that here. Just spitballing, but maybe this can look something like this:

var sampleBuilder = new StatementBuilder();
sampleBuilder.AppendVerbatim("var abc = ");
sampleBuilder.AppendLiteral(123);
sampleBuilder.AppendVerbatim(";");
meta.InsertExpression(sampleBuilder.Value);

That last line would then do something in the Metalama compiler specific to the IStatement overload on meta.InsertExpression. Today, we'd take a look at the the earlier examples and get:

var abc = 123;
var abc = abc;

Rather, since we're passing the IStatement in here and indicating we want to insert an expression, it would flatten this and develop the unique name in the second line and then assigns it the expression value in the first line. This way, it doesn't really matter what the original variable name is as it's completely ignored in the output. Even better, this also handles if the statement doesn't include a variable assignment - same thing, except there's no variable to ignore in the first step and it just proceeds to flatten the two in the output.

var abc = 123;

Of course, I'm sure I'll be quite pleased with whatever API shape you come up with in the alternative, but this would save be a lot of duplicate code in my generated files, so I appreciate you taking the time to consider the request. Thanks!

WhitWaldo avatar Aug 03 '23 11:08 WhitWaldo