我有这个代码要解析:
int[] tab1 = { 0, 1, 2, 3, 4 };
for (var i = 0; i < tab1.Length - 1; i++) { };
如何使用Microsoft Roslyn获取tab1.Length - 1(本例中为4)的确切值?
我可以使用以下代码找到表达式tab1.Length - 1:
var collector = new ForCollector();
foreach (var statement in collector.ForStatements)
{
Console.WriteLine(statement.Condition.ChildNodes().ElementAt(1));
}
其中ForCollector是一个继承SyntaxWalker的类,具有覆盖函数VisitForStatement但我不知道如何获取tab1.Length的值。我想我必须为此目的使用SemanticModel。
罗斯林版本 - 2012年9月
答案 0 :(得分:1)
此解决方案遍历语法树以查找您要查找的内容。注意:
for
循环,然后检查每个循环。这是源代码,您可以将其转储到控制台应用程序中以运行它。
using System.Linq;
using Roslyn.Compilers.CSharp;
// Snip some console app wrapping
var code = @"
public void FindI()
{
int[] tab1 = { 0, 1, 2, 3, 4 };
for (var i = 0; i < tab1.Length - 1; i++) { };
}";
var syntaxTree = SyntaxTree.ParseText(code);
var forStatement = syntaxTree
.GetRoot()
.DescendantNodes()
.OfType<ForStatementSyntax>()
.First();
// Gets the name 'tab1' from the for statement condition
var conditionMemberName = forStatement
.DescendantNodes()
.OfType<MemberAccessExpressionSyntax>()
.First()
.GetFirstToken()
.Value;
// Finds the first variable: int[] tab1 = { 0, 1, 2, 3, 4 };
var member = syntaxTree
.GetRoot()
.DescendantNodes()
.OfType<VariableDeclarationSyntax>()
.First()
// Finds the variable with the correct name 'tab1'
var variable = member.Variables.Where(x => x.Identifier.Value == conditionMemberName).Single();
// Find the initializer: { 0, 1, 2, 3, 4 };
var initializer = variable.Initializer.Value as InitializerExpressionSyntax;
// Counds the number of items in the initializer
var lengthOfInitializers = initializer.Expressions.Count;