How do I get the current value of a given variable name when writing a Roslyn Analyser?
How do I get the current value of a given variable name when writing a Roslyn Analyser?
The following code snippet is the code I wish to analyse:
var name = "Michael";
name = "John";
var person = new Person(name);
And let's say my analyser should complain if the length of name
given to the constructor
of Person
is less than 5.
name
constructor
Person
I know how to get the value of a string literal var person = new Person("John")
that is passed in to this object creation expression, check the first arguments type and then if it's a string literal grab it's Value
property.
var person = new Person("John")
Value
But how do I get the analyser to give me the value of name
at the Person
object creation expression site. This name
is clearly well defined in the code, so should be possible in this case.
name
Person
name
Thus far I've tried something along the lines of...
var nameExpr = (IdentifierNameSyntax)objectCreation.ArgumentList?.Arguments.First()?.Expression;
var nameDataFlow = context.SemanticModel.AnalyzeDataFlow(nameExpr);
It looks like I can figure out by using this data flow the value of name
, but it would seem to involve a very complex and flaky set of code, and would appear to me to only work if the declarations were inside the data flow code block. I'd like it to be able to resolve this token to it's actual value (if possible) even across the global compilation.
name
Even if I wrote global compilation hooks myself, I'd have to manually track every assignment to the variable (including from other variables and method calls etc.)
Is there an easy way to ask the library to do this for me, and just give me the variable's value at the call site if it can?
name
Console.ReadLine()
Aye I've done some more research on this, it seems roslyn doesn't have an algorithm for this at the moment. But it can be implemented, if it resolves to an expression finally (rather than a value) then I can do some analysis based on that, even in multi-threaded environments, I can report on the possible values of it, and if the analysis reaches a certain complexity then I could finally bail on it and say "I don't know" what this variable's value is or could be.
– starlight54
2 days ago
1 Answer
1
Is there an easy way to ask the library to do this for me, and just give me the variable's value at the call site if it can?
No, in fact this is provably impossible for an arbitrary program with arbitrary inputs.
One exception is when the variable is a compile-type constant (const
), in which case you can get its value using SemanticModel.GetConstantValue
.
const
SemanticModel.GetConstantValue
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
An analyzer operates at compile-time. You cannot build a compile-time tool that will always know what the run-time values of your variable are. Imagine that you assign
name
a value from userinput (eg. fromConsole.ReadLine()
)– JoshVarty
2 days ago