Problem casting PsiFile to PhpFile in PhpStorm


I'm trying to write a plugin for PhpStorm, but I hit a problem. When I try to access the PsiFile object and cast it to a com.jetbrains.php.lang.psi.PhpFile (which is what getClass() on the PsiFile returns), the cast throws an exception. Doing "psiFile instanceof PhpFile" also returns false. From looking at some other open source plugin's code, it seems I should be able to do this.

Is there something wrong with my configuration for building the plugin? It appears the class loaders for the the class I'm comparing to and the PhpFile are different. I do have multiple versions of PhpStorm installed, but I'm sure I'm running the right one. Is it possible I'm compiling against a different version? But would that create this problem?

Here's the code for the update action I was trying to write:

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.PsiFile;
import com.jetbrains.php.lang.psi.PhpFile;
import com.jetbrains.php.lang.psi.PhpFileImpl;

public class TestAction2 extends AnAction {

public void update(AnActionEvent e) {
Object psiFile = e.getData(CommonDataKeys.PSI_FILE);
PsiFile file = (PsiFile)psiFile;
FileType type = file.getFileType();
boolean enabled = type.getName() == "PHP";

Boolean assignable = PhpFile.class.isAssignableFrom(psiFile.getClass());
System.out.println("file class:" +file.getClass().getName());
System.out.println("file instanceof PhpFile: "+(file instanceof PhpFile));
System.out.println("assignable: "+assignable);
System.out.println("file: "+file.hashCode());
ClassLoader l1 = psiFile.getClass().getClassLoader();
ClassLoader l2 = PhpFileImpl.class.getClassLoader();
System.out.println("l1.hashCode: "+l1.hashCode());
System.out.println("l2.hashCode: "+l2.hashCode());

And here's the output for the code:

file class:com.jetbrains.php.lang.psi.PhpFileImpl

file instanceof PhpFile: false

assignable: false

file: 1033125183

l1.hashCode: 1639805934

l2.hashCode: 721831218

Official comment

Hi David,

Does the plugin you develop have any dependencies on the PHP plugin libraries? You can find them under File | Project Structure | Modules | Dependencies. If yes do they have the "Provided" scope? It's possible that the plugin has php.jar bundled for some reason. This may cause the PhpFileImpl class loaded twice. To be sure you can extract the plugin's zip file manually and take a look at the "lib" directory or look inside the "out" dir under your project depending on how do you run the plugin.

Hi Artem,

Yes you were right. The zip file had a copy of the php plugin inside it. I had the plugin libraries configured as "Compile" instead of "Provided". The code now works as expected. Thanks a lot!


Please sign in to leave a comment.