postsharp / Metalama

Metalama is a Roslyn-based meta-programming framework. Use this repo to report bugs or ask questions.
164 stars 4 forks source link

Feature: Mechanism to assign unique variable name to arbitrary IStatement #205

Open WhitWaldo opened 11 months ago

WhitWaldo commented 11 months ago

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!

PostSharpBot commented 11 months ago

Hello @WhitWaldo, thank you for submitting this issue. We will try to get back to you as soon as possible. Note to the PostSharp team, this ticket is being tracked in our dashboard under ID TP-33614.