How to find a type by FQN in a solution?

147 Views Asked by At

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?

1

There are 1 best solutions below

1
On BEST ANSWER

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))
  {
    // ...
  }
}