Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if a parameter to an invoked method is a variable (via "var/string") or an in-line string using Roslyn

I'm currently trying to find invocations of .ExecuteSqlCommand and examine the first value being passed to the sql param.

Here is an example of the differences I've found in our code base.

ExecuteSqlCommand("[sql statement here]");

vs.

var sql = "sql statement";
ExecuteSqlCommand(sql);

So far, I have this:

var invocations = root.DescendantNodes()
    .OfType<InvocationExpressionSyntax>()
    .Select(ie => ModelExtensions.GetSymbolInfo(model, ie).Symbol)
    .Where(symbol => symbol != null && symbol.Name == "ExecuteSqlCommand");

foreach (var invocation in invocations)
{
    var method = (IMethodSymbol)invocation;
    foreach (var param in method.Parameters)
    {
        //I can't quite seem to get information from IParameterSymbol about whether the param is a string literal, or a reference to a string via a variable.
    }
}

If the param is not a string, and instead, a var, then I'll need to get the value of the var (as much as it's defined at runtime).

I'm not too sure if this is a job for the SemanticModel or the SyntaxTree, but my GUESS is that the SemanticModel should have the richer information I need to let me discover what I'm looking for.

My overall goal is to interrogate the sql being passed to the ExecuteSqlCommand method.

Thanks!

like image 309
Michael McCarthy Avatar asked Oct 18 '25 11:10

Michael McCarthy


1 Answers

SemanticModel.GetConstantValue is the API we have for handling this situation.

It can accept both a syntax node and an expression. You will still need to track the state of variables back to their declaration sites and determine if they were given a constant expression.

I would use SemanticModel.GetSymbolInfo.Symbol?.DeclaringSyntaxReferences.First() to find the declaration site of a variable and then check to see if its a constant expression.

like image 175
Jonathon Marolf Avatar answered Oct 21 '25 00:10

Jonathon Marolf