how can I reliably get MethodInfo (reflection) from IMethodSymbol (Roslyn syntax tree). I can get the Type from the IMethodSymbol, and the type has many methods, of which one matches the IMethodSymbol instance.
e.g.
int i = 0;
i.Equals(5);
where the IMethodSymbol identifies 'Equals'
Note that there are 2 [Equals] methods on an [Int32] type, one taking and [Object], the other taking [Int32] parameter.
I'm parsing scripts, I don't have any workspace instances.
Any ideas? Stevo
It's not possible to reliably get a MethodInfo from an IMethodSymbol because you need to have the assembly loaded that contains the type that the method is on, which might be the case for the script that is being parsed but might not be the case for the code that is performing the analysis.
In other words, the script code you're running might have assembly X loaded which contains type T that has method M on it (and so the script code can have code that calls method M) but the analyser might not have assembly X loaded and so it can not load type T and so it can not get a MethodInfo instance for method M.
However, for an assembly like System, it's probably a fairly safe bet that you can access it from the analyser code.
So, all you'd need to do is get the namespace and type name of the type that has the method and get a TypeInfo instance for it. Then use GetMethod - passing it the name of the method and argument types to get a MethodInfo. Something like this:
var invocation = (InvocationExpressionSyntax)context.Node;
var methodSymbol = (IMethodSymbol)context.SemanticModel.GetSymbolInfo(invocation).Symbol;
var declaringTypeName = string.Format(
"{0}.{1}",
methodSymbol.ContainingType.ContainingAssembly.Name,
methodSymbol.ContainingType.Name
);
var methodName = methodSymbol.Name;
var methodArgumentTypeNames = methodSymbol.Parameters.Select(
p => p.Type.ContainingNamespace.Name + "." + p.Type.Name
);
var methodInfo = Type.GetType(declaringTypeName).GetMethod(
methodName,
methodArgumentTypeNames.Select(typeName => Type.GetType(typeName)).ToArray()
);
It's worth noting that analysers are often portable class libraries that don't have access to the full reflection API (meaning that the above code won't work) but if you're just using Roslyn in a project to analyse some scripts then you probably don't have to have that limitation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With