如何使用Roslyn查找被调用方法的参数是变量(通过“ var / string”)还是嵌入式字符串

迈克尔·麦卡锡

我目前正在尝试查找.ExecuteSqlCommand的调用,并检查传递给sql参数的第一个值。

这是我在我们的代码库中发现的差异的示例。

ExecuteSqlCommand("[sql statement here]");

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

到目前为止,我有这个:

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.
    }
}

如果参数不是字符串,而是var,那么我需要获取var的值(与运行时定义的一样多)。

我不太确定这是SemanticModel还是SyntaxTree的工作,但是我的GUESS是SemanticModel应该具有我需要的更丰富的信息,以便让我发现想要的东西。

我的总体目标是询问传递给ExecuteSqlCommand方法的sql。

谢谢!

射线

语法API可用于提取sql语句值,但取决于是否将变量声明(即var sql = "sql statement";)作为提交给语法树的代码的一部分包括在内。

例如,如果它ExcuteSqlCommand()是与调用where相同的方法实现的一部分,那么您可以首先获取sql传递给它的变量的名称(即),然后使用该名称在同一方法内找到匹配的变量声明语句最后,"sql statement"可以从中提取sql语句值(即)。

以下代码首先检查sql值是否作为字符串文字传递,否则将查找变量声明。假设全部在同一方法中:

        // whatever c# *method* code contains the sql. 
        // otherwise the root of the tree would need to be changed to filter to a specific single `MethodDeclarationSyntax`.
        string submittedCode = "public void SomeMethodContainingSql(){ ...//rest of code...";

        var tree = CSharpSyntaxTree.ParseText(submittedCode);
        var root = (CompilationUnitSyntax) tree.GetRoot();

        var arguments = root
            .DescendantNodes()
            .OfType<InvocationExpressionSyntax>()
            .First(node => node.DescendantNodes().OfType<IdentifierNameSyntax>()
                               .First()
                               .Identifier.Text == "ExecuteSqlCommand")
            .ArgumentList.DescendantNodes().ToList();

        string sqlStatementValue = "";

        var literalExpression = arguments.OfType<LiteralExpressionSyntax>().FirstOrDefault();

        if (literalExpression != null)
        {
            sqlStatementValue = literalExpression.GetText().ToString();
        }
        else
        {
            var variableName = arguments
                .First()
                .ToFullString();

            var variableDeclaration = root
                .DescendantNodes()
                .OfType<VariableDeclarationSyntax>()
                .Single(node => node.DescendantNodes().OfType<VariableDeclaratorSyntax>()
                                    .First()
                                    .Identifier.Text == variableName);

            sqlStatementValue = variableDeclaration.DescendantNodes()
                .OfType<LiteralExpressionSyntax>()
                .First()
                .DescendantTokens()
                .First()
                .Text;
        }

否则,可能需要在提交的代码的其他部分(例如,类字段,属性,其他方法等)中查找变量声明,这会比较麻烦。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何正确地将带有String()方法的嵌入式结构序列化为JSON字符串?

在嵌入式C中以字符串形式传递变量

如何将HTML字符串加载到嵌入式WebBrowser控件?

如何删除Java字符串中的嵌入式花括号?

如何将查询字符串从 Shopify 传递到嵌入式应用程序?

如何在js中读取嵌入式html字符串?

如何编写连接字符串以访问Visual Studio 2017嵌入式SQL Server

如何将包含嵌入式对象的字符串转换为对象类型?

不能使用字符串 ("1") 作为 HASH 引用,嵌入式哈希问题

有没有办法使用FOR JSON返回字符串或嵌入式JSON?

具有嵌入式变量的现有字符串上的Scala字符串插值器

Python,通过字符串更改var

如何通过嵌入式Linux设备上的重新引导使/ var / log持久化

如何通过使用变量和字符串构造名称来访问 var

通过二进制字符串或base64在Internet Explorer 11中显示嵌入式PDF

如何在Swift中为自定义结构和类更改默认的嵌入式字符串

如何在 RPGLE 的“XMLTABLE”嵌入式 SQL 语句中跨多行中断长字符串?

如何将字符串 var 作为函数调用?

通过LAN向嵌入式设备发送自定义命令:字符还是整数?

将字符串从var1映射到var2(查找)

如何检查var是否为JavaScript中的字符串?

Swift 2如何更改公共var字符串

如何在var中保留html字符串

使用字符串代替PY_VAR

bash +如何从var2中删除var2中定义的字符串

var str:字符串可变还是不可变?

flutter评估var是整数还是字符串

通过传递变量PHP来给filter_var()过滤器(filter_var()期望参数2长,给定字符串)

有没有一种简单的方法可以从嵌入式C ++ GNU ARM中的字符串中解析浮点数?