7

using Roslyn/Microsoft.CodeAnalysis, how can I get the ISymbolfor a third-party type, ie, a type defined in a referenced assembly which is not part of the solution? In my particular case, I'm looking for JSON.NET's JObject, but actually the same question would be valid for BCL stuff like StringBuilder etc.

The only idea I've come up so far is to implement a CSharpSyntaxWalker which looks for all method invocations, property accesses and constructor calls, checks whether they are made on the type I'm interested in and if yes, gets the symbol from the respective SyntaxNode. I'm going to implement this now, but it seems awfully cumbersome. I think there must a better way, but my google-fu has not yielded any relevant results.

Maybe about the background: what I'm trying to do is replace the usage of JObject with the usage of another class.

svick
  • 236,525
  • 50
  • 385
  • 514
Modern Ronin
  • 571
  • 1
  • 5
  • 13

1 Answers1

9

If you can get access to a Compilation you can call Compilation.GetTypeByMetadataName() and pass in the fully qualified metadata name for the symbol.

Be careful of nested classes and generics, their metadata names are different than they're normal fully qualified names. For more see: Having a "+" in the class name?

Once you have the symbol you can find all usages via SymbolFinder.FindAllReferences()

JoshVarty
  • 9,066
  • 4
  • 52
  • 80
  • the fully qualified name would be something like `Newtonsoft.Json.Linq.JObject`, right? Is it relevant that I'm looking at a specific project in a loaded solution? Right now I do: `project.GetCompilationAsync().Result.GetTypeByMetadataName(typeName);` with the above fully qualified name. And I get null :/ (The solution builds just fine in VS.) – Modern Ronin Oct 27 '15 at 21:01
  • (btw, your blog has been invaluable in my journey of finding my way round Roslyn! thanks for writing those articles!) – Modern Ronin Oct 27 '15 at 21:04
  • That should be the correct name. How are you getting the solution? Via `VisualStudioWorkspace` or `MSBuildWorkspace` or something? Check that `compilation.GetDiagnostics()` doesn't return any errors. (Glad they've helped, it's always nice to hear that!) – JoshVarty Oct 27 '15 at 21:38
  • Actually, I just do: `var workspace = MSBuildWorkspace.Create(); var project = workspace.OpenProjectAsync(mInputProjectPath).Result;` - but the project is part of a solution. (It's just that I only need to perform work on that specific project). I'll look into the .GetDiagnostics(). – Modern Ronin Oct 27 '15 at 21:56
  • hmm. Diagnostics has errors like "Predefined type System.void not defined...", tons of them. Might it be relevant that I'm using VS 2015 + .NET 4.6, but the target project is a VS 2013 + .NET 4.5 solution? – Modern Ronin Oct 27 '15 at 22:00
  • Is your project a PCL or a WPF project? – JoshVarty Oct 27 '15 at 22:15
  • I temporarily changed the project under analysis (and all other projects it depends on) to .NET 4.5.2 and did the same for the all projects in my analyzer solution. No effect, still get those 2500 errors. – Modern Ronin Oct 27 '15 at 22:18
  • Analyzer solution consists of a class library and a console project. The project under analysis is a class library. – Modern Ronin Oct 27 '15 at 22:19
  • (regular class libraries, not portable, I should add) – Modern Ronin Oct 27 '15 at 23:28
  • If you use `.OpenSolutionAsync()` and then choose the project that way, does it compile? I'm really not sure what's wrong with it at this point. :( – JoshVarty Oct 28 '15 at 00:15
  • did not change anything, either. Anyway, I accepted your answer as this is really a different problem now. – Modern Ronin Oct 28 '15 at 15:49