Search code examples
javaintellij-ideaclassloaderintellij-pluginpsi

PsiClass to java.lang.Class


I'm developing plugin for IntelliJ IDEA. How can plugin get the name and version of libraries that are imported to the project that is being checked by plugin? I have PsiClass of the project, but cannot convert it to java.lang.Class. Maybe there's the way to get ClassLoader from PsiElement?

super.visitImportStatement(psiImport);
Class importedClass = Class.forName(psiImport.getQualifiedName(), true, psiImport.getClass().getClassLoader());

PsiImport.getClass().GetClassLoader() - returns ClassLoader of class PsiImportStatementImpl instead of ClassLoader of class that I've imported.


Solution

  • IntelliJ does mostly static analysis on your code. In fact, the IDE and the projects you run/debug have completely different classpaths. When you open a project, your dependencies are not added to the IDE classpath. Instead, the IDE will index the JARs, meaning it will automatically discover all the declarations (classes, methods, interfaces etc) and save them for later in a cache.

    When you write code in your editor, the static analysis tool will leverage the contents of this index to validate your code and show errors when you're trying to use unknown definitions for example.

    On the other hand, when you run a Main class from your project, it will spawn a new java process that has its own classpath. This classpath will likely contain every dependency declared in your module.

    Knowing this, you should now understand why you can't "transform" a PsiClass to a corresponding Class.

    Back to your original question:

    How can plugin get the name and version of libraries that are imported to the project that is being checked by plugin?

    You don't need to access Class objects for this. Instead, you can use IntelliJ SDK libraries. Here's an example:

    Module mod = ModuleUtil.findModuleForFile(virtualFile,myProject);
    
    ModuleRootManager.getInstance(mod).orderEntries().forEachLibrary(library -> {
    
      // do your thing here with `library`
    
      return true;
    });