我目前正在尝试查找.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] 删除。
我来说两句