I am writing a Rider/ReSharper nav-from-here plugin which is supposed to determine a target type based on a symbol I am standing on using some simple rules, and finally, navigate to it.
The first part is okay, I have managed to form the FQN needed, but I am struggling with the navigation. I found this StackOverflow post, and thought I might try this approach. So I have been trying to use TypeFactory.CreateTypeByCLRName
for like two hours to create an IDeclaredType
instance to be able to get the IDeclaredElement
using GetTypeElement()
and eventually get its declarations. But the API seems to have changed and no matter what I do I cannot get my code to work.
Here is what I've got so far:
// does not work with Modules.GetModules(), either
foreach (var psiModule in solution.GetPsiServices().Modules.GetSourceModules())
{
var type = TypeFactory.CreateTypeByCLRName("MyNamespace.MyClassName", psiModule);
var typeElement = type.GetTypeElement();
if (typeElement != null)
{
MessageBox.ShowInfo(psiModule.Name); // to make sure sth is happening
break;
}
}
The weird part is, I actually see a message box - but only when the tab with MyClassName.cs
is active. When it is in focus, everything is fine. When it's not or the file is closed, the class does not get resolved, type.IsResolved
is false
.
What am I doing wrong?
To do this, you should have a IPsiModule
instance from the context where you plan to use the type you're looking for. You can get it from some syntax node you're working with via .GetPsiModule()
method or via many other ways (like dataContext.GetData(PsiDataConstants.SOURCE_FILE)?.GetPsiModule()
.
void FindTypes(string fullTypeName, IPsiModule psiModule)
{
// access the symbol cache where all the solution types are stored
var symbolCache = psiModule.GetPsiServices().Symbols;
// get a view on that cache from specific IPsiModule, include all referenced assemblies
var symbolScope = symbolCache.GetSymbolScope(psiModule, withReferences: true, caseSensitive: true);
// or use this to search through all of the solution types
// var symbolScope = symbolCache.GetSymbolScope(LibrarySymbolScope.FULL, caseSensitive: true);
// request all the type symbols with the specified full type name
foreach (var typeElement in symbolScope.GetTypeElementsByCLRName(fullTypeName))
{
// ...
}
}