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,因为 myVar
和 myVar3
来自同一类型并且 myVar4
没有在 Assert.AreEqual
检查中使用。
您需要将 creations.First().Parent.Parent
转换为具有 Identifier
属性 的类型 - 在您的情况下很可能是 VariableDeclaratorSyntax
- 然后您将能够访问它 Identifier
。这当然很危险,因为您可能会发现 ObjectCreationSyntax
的祖父母不同。
看看这个例子:
List<Person> people = new List<Person>() {
new Person("Jim"),
new Person("Frank")
};
您将成功获得 people
ObjectCreation
的 Identifier
,但不是其元素(因为它们根本没有变量名)。有很多极端情况需要解决,有很多可能的解决方案。
一个肮脏的解决方法是检查祖父母是否善良 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
我正在寻找一种解决方案,以便在一个方法中创建所有对象。我想出了以下解决方案来获取所有创作的列表:
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,因为 myVar
和 myVar3
来自同一类型并且 myVar4
没有在 Assert.AreEqual
检查中使用。
您需要将 creations.First().Parent.Parent
转换为具有 Identifier
属性 的类型 - 在您的情况下很可能是 VariableDeclaratorSyntax
- 然后您将能够访问它 Identifier
。这当然很危险,因为您可能会发现 ObjectCreationSyntax
的祖父母不同。
看看这个例子:
List<Person> people = new List<Person>() {
new Person("Jim"),
new Person("Frank")
};
您将成功获得 people
ObjectCreation
的 Identifier
,但不是其元素(因为它们根本没有变量名)。有很多极端情况需要解决,有很多可能的解决方案。
一个肮脏的解决方法是检查祖父母是否善良 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