How to get argument type in Roslyn?

So, I'm trying to find out the type of some variables in an argument when calling a method. For instance:

class Program { static void Main(string[] args) { string a = "astring" string.Format("zzzz{0}", a); } } 

So, I want to know the type of the variable a in string.Format ("zzzz {0}, a"); I am trying to change the code, so I am using a rewriter, and this is what I got:

 public class CustomFormatRewriter : CSharpSyntaxRewriter{ public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax rootNode){ if (null != rootNode){ var arguments = from n in secondNode.DescendantNodes() where (n.Kind() == SyntaxKind.Argument) select n; foreach (var argument in arguments) { var compilation = CSharpCompilation.Create("arg") .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) .AddSyntaxTrees(rootNode.SyntaxTree); var model = compilation.GetSemanticModel(rootNode.SyntaxTree); var symbolInfo = model.GetSymbolInfo(argument); Console.WriteLine(symbolInfo.Symbol); } } return rootNode; } } 

But the symbol.Symbol symbol that I received is null.

Any idea? Thanks!!

+5
source share
3 answers

If you want to know the type of something, you can call SemanticModel.GetTypeInfo . This works for all expressions, not just those that are directly variable. Thus, not only passing the expression for a will give you the type of a , but a.SomeMethod() will determine which Overload SomeMethod is called on a , and give you the return type. If your expression is just a number, it will tell you what type is Int32.

GetSymbolInfo only works if the thing you pass directly is a symbol reference, that is, the name of a local or field, or something else. In your case, the first argument is that the string will not give you a character. It has a type (in particular, System.String), but it is not a character.

+9
source

Ok, I found out why I always get zero. A message just in case someone might find it useful in the future.

I found this post very helpful in identifying my problem. So it turns out that I am not checking the type at the correct "level" as I call it. I used the method in the message (in the parser, right-click node → view typeSymbol) to check the type of my argument. I found that if I check the "Argument", then there is nothing, which explains why I got zero. And if I checked the node at the level under "Argument", it will give you the correct type.

So, I changed my code to:

 var typeInfo = model.GetTypeInfo(argument.ChildNodes().First()); Console.WriteLine(typeInfo); 

And it works.

+2
source

Pass it to ILocalSymbol , then read the Type property.

-1
source

All Articles