I'm trying to analyze something like blah.SomeMethod(x => x.PropertyA)
in a method call and get the class of 'x' and property referenced so I can go verify that property has an expected attribute attached. I want to analyze the first argument to the method call.
So I make a Roslyn visitor and give it a compilation/SemanticModel from the VS Project (in an existing solution) and find the method invocations like so:
var workspace = MSBuildWorkspace.Create();
workspace.LoadMetadataForReferencedProjects = true;
var solution = await workspace.OpenSolutionAsync(pathToSolution);
var project1 = solution.Projects.FirstOrDefault(proj => proj.Name == projectName);
var document1 = project1.Documents.Single(d => d.Name == documentFilename);
var tree = await document1.GetSyntaxTreeAsync();
var compilation = project1.GetCompilationAsync().Result;
Debug.Assert(compilation.ContainsSyntaxTree(tree));
var semanticModel = compilation.GetSemanticModel(tree);
public override void VisitInvocationExpression(InvocationExpressionSyntax node)
{
string methodName = node.Expression.ToString();
if (methodName.Contains("SomeMethod"))
{
// Analyze each parameter in the method call
foreach (ArgumentSyntax argument in node.ArgumentList.Arguments)
{
// FIRST ARGUMENT HERE IS x => x.PropertyA. I want to get the
// class and property names.
// The below returns an object with properties:
// CandidateReason: None
// CandidateSymbols: Length = 0
// Symbol: null
// Type: null
var typeinfo = semanticModel.GetTypeInfo(argument.Expression);
// node type info is empty, too, and its parent.
var nodeTypeinfo = semanticModel.GetTypeInfo(node.Expression);
var nodeParentTypeinfo = semanticModel.GetTypeInfo(node.Parent);
ITypeSymbol parameterType = typeinfo.Type;
if (parameterType = null)
{
// Always null, doesn't break.
Debugger.Break();
}
//...
}
}
As you see, the GetTypeInfo() always return None/NULL on the argument, the method (node), and the node's parent.
Even GetSymbolInfo() on all the above returns None/null as well.
I know the types are compiled as part of the project, so why can't Roslyn find anything? It's like the semantic model (from the project's compilation) contains nothing.
All I can imagine is that since some of the classes used are in a different project which is referenced by the project I'm compiling, the semantic model of the main project won't work at all?