简体   繁体   中英

Roslyn get all object creations and its identifier name

I am looking for a solution to get all object creations inside a method. I came up with following solution to get a list of all creations:

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

But now I am looking for the identifier name(variable name). While debugging I figured out, that this variable has this information - but the identifier property is no accessible.

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

So i would be very pleased if someone has a solution for my problem.

EDIT

I am trying to analyze unittests. Eg:

[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);
}

I want to count the references used in the Assert.AreEqual checks. So the example from above should return 3, because myVar and myVar3 are from the same type and myVar4 is not used in the Assert.AreEqual check.

You need to cast creations.First().Parent.Parent to a Type that has an Identifier property - in your case it's most likely VariableDeclaratorSyntax - then you will be able to access its Identifier . This is of course dangerous because you might find an ObjectCreationSyntax whose grandparent is different.

Take a look at this example:

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

You'll successfully get the Identifier of the people ObjectCreation , but not its elements' (since they do not have a variable name at all). There are lots of corner cases to work around, with lots of possible solutions.

A dirty workaround would be to check if the grandparent is of kind VariableDeclarator and cast it only then. Maybe if you share what you are trying to accomplish (in the grand scheme of things) I can advice better.

EDIT

If I understood you correctly, you want to count the number of distinct types created in a method. ObjectCreationExpressionSyntax objects have a Type property, which shows what type of object is being created. This is exactly what you need, however getting the type itself is troublesome , but you can look at the names like so:

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

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

You can't just count the node.Type -s, becuase those are SyntaxNode -s, and will not be identical. But their symbol will be, and using a HashSet will ensure that you are getting no duplicates. You can get the SemanticModel object from the context if you use RegisterSemanticModelAction .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM