Using Roslyn, I'm generating C# code based on a method symbol parsed from code outside of my control. Therefore, the method could have any number of arguments. The code I generate includes a lambda expression that takes a single argument, such as:
// I'm generating code like this
public void SomeMethod()
{
DoSomething(x => x.Foo());
}
A potential problem with this code is if the containing method includes a parameter called x
:
// my code generator might produce this
public void SomeMethod(int x)
{
DoSomething(x => x.Foo());
}
This code results in an error:
A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Fair enough.
To get around this, I was thinking I could start with the identifier name x
, use SemanticModel.LookupSymbols
to see whether it's already defined. If so, prepend _
(to get _x
) and repeat.
But is this the best way? And if so, how do I use LookupSymbols
when all I have is a method symbol?
Another option I thought of was to just use the Parameters
collection in the method symbol. I could perform the same name selection algorithm against them instead. But would this suffice? For example:
private static string GetIdentifierName(IMethodSymbol within)
{
var proposed = "x";
while (within.Parameters.Any(x => x.Name == proposed))
{
proposed = "_" + proposed;
}
return proposed;
}
Using the SemanticModel.LookupSymbols
seems like a good approach. This is the way Visual Studio moves selected code to new methods. Check out the UniqueNameGenerator
internal class in Roslyn.
As for how to use LookupSymbols
when all you have is a method symbol: you already add your generated DoSomething(x => x.Foo());
to the code, so you have more than just a method symbol, don't you? But in any case, from an IMethodSymbol
you can get the DeclaringSyntaxReferences
to access the corresponding syntax nodes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With