Roslyn 获取所有对象创建及其标识符名称

Roslyn get all object creations and its identifier name

我正在寻找一种解决方案,以便在一个方法中创建所有对象。我想出了以下解决方案来获取所有创作的列表:

var creations = MethodDeclaration.Body.DescendantNodes().OfType<ObjectCreationExpressionSyntax>();

但现在我正在寻找标识符名称(变量名称)。在调试时我发现,这个变量有这个信息——但是标识符 属性 不可访问。

creations.First().Parent.Parent.Identifier.ValueText;

所以如果有人能解决我的问题我会很高兴。

编辑

我正在尝试分析单元测试。例如:

[TestMethod]
public void WarningOverReferencedTest()
{
    var myVar = new MyObject();
    var myVar1 = new MyObject1();
    var myVar2 = new MyObject2();
    var myVar3 = new MyObject();
    var myVar4 = new MyObject3();
    Assert.AreEqual(true, myVar.someProperty);
    Assert.AreEqual(true, myVar3.someProperty2);
    Assert.AreEqual(true, myVar1.someProperty);
    Assert.AreEqual(true, myVar2.someProperty);
}

我想计算 Assert.AreEqual 检查中使用的引用。所以上面的例子应该 return 3,因为 myVarmyVar3 来自同一类型并且 myVar4 没有在 Assert.AreEqual 检查中使用。

您需要将 creations.First().Parent.Parent 转换为具有 Identifier 属性 的类型 - 在您的情况下很可能是 VariableDeclaratorSyntax - 然后您将能够访问它 Identifier。这当然很危险,因为您可能会发现 ObjectCreationSyntax 的祖父母不同。

看看这个例子:

List<Person> people = new List<Person>() {
      new Person("Jim"),
      new Person("Frank")
};

您将成功获得 people ObjectCreationIdentifier,但不是其元素(因为它们根本没有变量名)。有很多极端情况需要解决,有很多可能的解决方案。

一个肮脏的解决方法是检查祖父母是否善良 VariableDeclarator 然后才施放它。也许如果你分享你正在努力完成的事情(在宏伟的计划中),我可以提供更好的建议。

编辑

如果我没理解错的话,您想计算方法中创建的不同类型的数量。 ObjectCreationExpressionSyntax objects 有一个 Type 属性,显示正在创建什么类型的 object。这正是您所需要的,但是获取类型本身是 ,但是您可以这样查看名称:

HashSet<ITypeSymbol> types = new HashSet<ITypeSymbol>();

foreach (ObjectCreationExpressionSyntax node in creations)
{
    var typeSymbol = semanticModel.GetTypeInfo(node).Type;
    types.Add(typeSymbol);
}
int numberOfTypes = types.Count;

您不能只计算 node.Type-s,因为它们是 SyntaxNode-s,并且不会相同。但是他们的符号将是,并且使用 HashSet 将确保您没有重复。如果使用 RegisterSemanticModelAction.

,则可以从上下文中获取 SemanticModel object