blob: 64d535c2a5ae1eaf47930aa197b3480c92f0419f [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.psi.impl.file.impl;
import com.intellij.AppTopics;
import com.intellij.ProjectTopics;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeEvent;
import com.intellij.openapi.fileTypes.FileTypeListener;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerBase;
import com.intellij.psi.impl.PsiManagerImpl;
import com.intellij.psi.impl.PsiTreeChangeEventImpl;
import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl;
import com.intellij.util.FileContentUtilCore;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PsiVFSListener extends VirtualFileAdapter {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.file.impl.PsiVFSListener");
private final FileTypeManager myFileTypeManager;
private final ProjectRootManager myProjectRootManager;
private final ProjectFileIndex myProjectFileIndex;
private final PsiManagerImpl myManager;
private final FileManagerImpl myFileManager;
private final MessageBusConnection myConnection;
public PsiVFSListener(StartupManager startupManager,
FileTypeManager fileTypeManager,
PsiManager psiManager,
ProjectRootManager projectRootManager) {
myFileTypeManager = fileTypeManager;
myProjectRootManager = projectRootManager;
myProjectFileIndex = myProjectRootManager.getFileIndex();
myManager = (PsiManagerImpl) psiManager;
myFileManager = (FileManagerImpl) myManager.getFileManager();
myConnection = psiManager.getProject().getMessageBus().connect(psiManager.getProject());
startupManager.registerPreStartupActivity(new Runnable() {
@Override
public void run() {
myConnection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkVirtualFileListenerAdapter(PsiVFSListener.this));
myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new MyModuleRootListener());
myConnection.subscribe(FileTypeManager.TOPIC, new FileTypeListener.Adapter() {
@Override
public void fileTypesChanged(FileTypeEvent e) {
myFileManager.processFileTypesChanged();
}
});
myConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new MyFileDocumentManagerAdapter());
myFileManager.markInitialized();
}
});
}
@Nullable
private PsiDirectory getCachedDirectory(VirtualFile parent) {
return parent == null ? null : myFileManager.getCachedDirectory(parent);
}
@Override
public void fileCreated(@NotNull VirtualFileEvent event) {
final VirtualFile vFile = event.getFile();
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
VirtualFile parent = vFile.getParent();
PsiDirectory parentDir = getCachedDirectory(parent);
if (parentDir == null) return; // do not notifyListeners event if parent directory was never accessed via PSI
if (!vFile.isDirectory()) {
PsiFile psiFile = myFileManager.findFile(vFile);
if (psiFile != null && psiFile.getProject() == myManager.getProject()) {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
myManager.beforeChildAddition(treeEvent);
treeEvent.setChild(psiFile);
myManager.childAdded(treeEvent);
}
}
else {
PsiDirectory psiDir = myFileManager.findDirectory(vFile);
if (psiDir != null && psiDir.getProject() == myManager.getProject()) {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
myManager.beforeChildAddition(treeEvent);
treeEvent.setChild(psiDir);
myManager.childAdded(treeEvent);
}
}
}
}
);
}
@Override
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {
final VirtualFile vFile = event.getFile();
VirtualFile parent = vFile.getParent();
final PsiDirectory parentDir = getCachedDirectory(parent);
if (parentDir == null) return; // do not notify listeners if parent directory was never accessed via PSI
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
if (!vFile.isDirectory()) {
PsiFile psiFile = myFileManager.getCachedPsiFile(vFile);
if (psiFile != null) {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
treeEvent.setChild(psiFile);
myManager.beforeChildRemoval(treeEvent);
}
}
else {
PsiDirectory psiDir = myFileManager.findDirectory(vFile);
if (psiDir != null) {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
treeEvent.setChild(psiDir);
myManager.beforeChildRemoval(treeEvent);
}
}
}
}
);
}
@Override
public void fileDeleted(@NotNull final VirtualFileEvent event) {
final VirtualFile vFile = event.getFile();
VirtualFile parent = event.getParent();
final PsiDirectory parentDir = getCachedDirectory(parent);
final PsiFile psiFile = myFileManager.getCachedPsiFileInner(vFile);
if (psiFile != null) {
myFileManager.removeCachedViewProvider(vFile);
if (parentDir != null) {
ApplicationManager.getApplication().runWriteAction(new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
treeEvent.setChild(psiFile);
myManager.childRemoved(treeEvent);
}
});
}
}
else {
final PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile);
if (psiDir != null) {
myFileManager.removeInvalidFilesAndDirs(false);
if (parentDir != null) {
ApplicationManager.getApplication().runWriteAction(new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
treeEvent.setChild(psiDir);
myManager.childRemoved(treeEvent);
}
});
}
}
}
}
@Override
public void beforePropertyChange(@NotNull final VirtualFilePropertyEvent event) {
final VirtualFile vFile = event.getFile();
final String propertyName = event.getPropertyName();
VirtualFile parent = vFile.getParent();
final PsiDirectory parentDir = getCachedDirectory(parent);
if (parent != null && parentDir == null) return; // do not notifyListeners event if parent directory was never accessed via PSI
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
if (VirtualFile.PROP_NAME.equals(propertyName)) {
final String newName = (String)event.getNewValue();
if (parentDir == null) return;
if (vFile.isDirectory()) {
PsiDirectory psiDir = myFileManager.findDirectory(vFile);
if (psiDir != null) {
if (!myFileTypeManager.isFileIgnored(newName)) {
treeEvent.setChild(psiDir);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME);
treeEvent.setOldValue(vFile.getName());
treeEvent.setNewValue(newName);
myManager.beforePropertyChange(treeEvent);
}
else {
treeEvent.setChild(psiDir);
myManager.beforeChildRemoval(treeEvent);
}
}
else {
if (!isExcludeRoot(vFile) && !myFileTypeManager.isFileIgnored(newName)) {
myManager.beforeChildAddition(treeEvent);
}
}
}
else {
final FileViewProvider viewProvider = myFileManager.findViewProvider(vFile);
PsiFile psiFile = viewProvider.getPsi(viewProvider.getBaseLanguage());
PsiFile psiFile1 = createFileCopyWithNewName(vFile, newName);
if (psiFile != null) {
if (psiFile1 == null) {
treeEvent.setChild(psiFile);
myManager.beforeChildRemoval(treeEvent);
}
else if (!psiFile1.getClass().equals(psiFile.getClass())) {
treeEvent.setOldChild(psiFile);
myManager.beforeChildReplacement(treeEvent);
}
else {
treeEvent.setChild(psiFile);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_FILE_NAME);
treeEvent.setOldValue(vFile.getName());
treeEvent.setNewValue(newName);
myManager.beforePropertyChange(treeEvent);
}
}
else {
if (psiFile1 != null) {
myManager.beforeChildAddition(treeEvent);
}
}
}
}
else if (VirtualFile.PROP_WRITABLE.equals(propertyName)) {
PsiFile psiFile = myFileManager.getCachedPsiFileInner(vFile);
if (psiFile == null) return;
treeEvent.setElement(psiFile);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_WRITABLE);
treeEvent.setOldValue(event.getOldValue());
treeEvent.setNewValue(event.getNewValue());
myManager.beforePropertyChange(treeEvent);
}
}
}
);
}
private boolean isExcludeRoot(VirtualFile file) {
VirtualFile parent = file.getParent();
if (parent == null) return false;
Module module = myProjectRootManager.getFileIndex().getModuleForFile(parent);
if (module == null) return false;
VirtualFile[] excludeRoots = ModuleRootManager.getInstance(module).getExcludeRoots();
for (VirtualFile root : excludeRoots) {
if (root.equals(file)) return true;
}
return false;
}
@Override
public void propertyChanged(@NotNull final VirtualFilePropertyEvent event) {
final String propertyName = event.getPropertyName();
final VirtualFile vFile = event.getFile();
final FileViewProvider oldFileViewProvider = myFileManager.findCachedViewProvider(vFile);
final PsiFile oldPsiFile;
if (oldFileViewProvider instanceof SingleRootFileViewProvider) {
oldPsiFile = ((SingleRootFileViewProvider)oldFileViewProvider).getCachedPsi(oldFileViewProvider.getBaseLanguage());
}
else {
oldPsiFile = null;
}
VirtualFile parent = vFile.getParent();
final PsiDirectory parentDir = getCachedDirectory(parent);
if (oldFileViewProvider != null // there is no need to rebuild if there were no PSI in the first place
&& FileContentUtilCore.FORCE_RELOAD_REQUESTOR.equals(event.getRequestor())) {
forceReload(vFile, oldPsiFile, parentDir);
return;
}
// do not suppress reparse request for light files
if (parentDir == null) {
boolean fire = VirtualFile.PROP_NAME.equals(propertyName) && vFile.isDirectory();
if (fire) {
PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile);
fire = psiDir != null;
}
if (!fire) return; // do not fire event if parent directory was never accessed via PSI
}
if (oldPsiFile != null && oldPsiFile.isPhysical()) {
((SmartPointerManagerImpl)SmartPointerManager.getInstance(myManager.getProject())).fastenBelts(oldPsiFile, 0, null);
}
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
if (VirtualFile.PROP_NAME.equals(propertyName)) {
if (vFile.isDirectory()) {
PsiDirectory psiDir = myFileManager.getCachedDirectory(vFile);
if (psiDir != null) {
if (myFileTypeManager.isFileIgnored(vFile)) {
myFileManager.removeFilesAndDirsRecursively(vFile);
treeEvent.setChild(psiDir);
myManager.childRemoved(treeEvent);
}
else {
treeEvent.setElement(psiDir);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_DIRECTORY_NAME);
treeEvent.setOldValue(event.getOldValue());
treeEvent.setNewValue(event.getNewValue());
myManager.propertyChanged(treeEvent);
}
}
else {
PsiDirectory psiDir1 = myFileManager.findDirectory(vFile);
if (psiDir1 != null) {
treeEvent.setChild(psiDir1);
myManager.childAdded(treeEvent);
}
}
}
else {
final FileViewProvider fileViewProvider = myFileManager.createFileViewProvider(vFile, true);
final PsiFile newPsiFile = fileViewProvider.getPsi(fileViewProvider.getBaseLanguage());
if(oldPsiFile != null) {
if (newPsiFile == null) {
myFileManager.removeCachedViewProvider(vFile);
treeEvent.setChild(oldPsiFile);
myManager.childRemoved(treeEvent);
}
else if (!newPsiFile.getClass().equals(oldPsiFile.getClass()) ||
newPsiFile.getFileType() != myFileTypeManager.getFileTypeByFileName((String)event.getOldValue()) ||
languageDialectChanged(newPsiFile, (String)event.getOldValue()) ||
!oldFileViewProvider.getLanguages().equals(fileViewProvider.getLanguages())) {
myFileManager.cacheViewProvider(vFile, fileViewProvider);
treeEvent.setOldChild(oldPsiFile);
treeEvent.setNewChild(newPsiFile);
myManager.childReplaced(treeEvent);
}
else {
treeEvent.setElement(oldPsiFile);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_FILE_NAME);
treeEvent.setOldValue(event.getOldValue());
treeEvent.setNewValue(event.getNewValue());
myManager.propertyChanged(treeEvent);
}
}
else if (newPsiFile != null) {
myFileManager.cacheViewProvider(vFile, fileViewProvider);
if (parentDir != null) {
treeEvent.setChild(newPsiFile);
myManager.childAdded(treeEvent);
}
}
}
}
else if (VirtualFile.PROP_WRITABLE.equals(propertyName)) {
if (oldPsiFile == null) return;
treeEvent.setElement(oldPsiFile);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_WRITABLE);
treeEvent.setOldValue(event.getOldValue());
treeEvent.setNewValue(event.getNewValue());
myManager.propertyChanged(treeEvent);
}
else if (VirtualFile.PROP_ENCODING.equals(propertyName)) {
if (oldPsiFile == null) return;
treeEvent.setElement(oldPsiFile);
treeEvent.setPropertyName(VirtualFile.PROP_ENCODING);
treeEvent.setOldValue(event.getOldValue());
treeEvent.setNewValue(event.getNewValue());
myManager.propertyChanged(treeEvent);
}
}
}
);
}
private void forceReload(@NotNull VirtualFile vFile, PsiFile oldPsiFile, PsiDirectory parentDir) {
FileViewProvider viewProvider = myFileManager.createFileViewProvider(vFile, true);
myFileManager.setViewProvider(vFile, viewProvider);
PsiFile newPsiFile = myManager.findFile(vFile);
if (newPsiFile == null) {
// psi file here can be null for any custom file with null parent
// that is currently open in a file editor, e.g. db table editor
//LOG.error("null psi file for "+vFile+"; provider: "+viewProvider);
return;
}
if (!viewProvider.isPhysical()) {
Document document = viewProvider.getDocument();
if (document != null) {
PsiDocumentManagerBase.cachePsi(document, newPsiFile);
}
}
if (parentDir != null) {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setParent(parentDir);
treeEvent.setOldChild(oldPsiFile);
treeEvent.setNewChild(newPsiFile);
myManager.childReplaced(treeEvent);
}
}
@Override
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {
final VirtualFile vFile = event.getFile();
final PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent());
final PsiDirectory newParentDir = myFileManager.findDirectory(event.getNewParent());
if (oldParentDir == null && newParentDir == null) return;
if (myFileTypeManager.isFileIgnored(vFile)) return;
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
boolean isExcluded = vFile.isDirectory() && myProjectFileIndex.isIgnored(vFile);
if (oldParentDir != null && !isExcluded) {
if (newParentDir != null) {
treeEvent.setOldParent(oldParentDir);
treeEvent.setNewParent(newParentDir);
if (vFile.isDirectory()) {
PsiDirectory psiDir = myFileManager.findDirectory(vFile);
treeEvent.setChild(psiDir);
}
else {
PsiFile psiFile = myFileManager.findFile(vFile);
treeEvent.setChild(psiFile);
}
myManager.beforeChildMovement(treeEvent);
}
else {
treeEvent.setParent(oldParentDir);
if (vFile.isDirectory()) {
PsiDirectory psiDir = myFileManager.findDirectory(vFile);
treeEvent.setChild(psiDir);
}
else {
PsiFile psiFile = myFileManager.findFile(vFile);
treeEvent.setChild(psiFile);
}
myManager.beforeChildRemoval(treeEvent);
}
}
else {
LOG.assertTrue(newParentDir != null); // checked above
treeEvent.setParent(newParentDir);
myManager.beforeChildAddition(treeEvent);
}
}
}
);
}
@Override
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
final VirtualFile vFile = event.getFile();
final PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent());
final PsiDirectory newParentDir = myFileManager.findDirectory(event.getNewParent());
if (oldParentDir == null && newParentDir == null) return;
final PsiElement oldElement = vFile.isDirectory()
? myFileManager.getCachedDirectory(vFile)
: myFileManager.getCachedPsiFileInner(vFile);
myFileManager.removeInvalidFilesAndDirs(true);
final PsiElement newElement;
final FileViewProvider newViewProvider;
if (!vFile.isDirectory()){
newViewProvider = myFileManager.createFileViewProvider(vFile, true);
newElement = newViewProvider.getPsi(myFileManager.findViewProvider(vFile).getBaseLanguage());
}
else {
newElement = myFileManager.findDirectory(vFile);
newViewProvider = null;
}
if (oldElement == null && newElement == null) return;
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
if (oldElement == null) {
myFileManager.cacheViewProvider(vFile, newViewProvider);
treeEvent.setParent(newParentDir);
treeEvent.setChild(newElement);
myManager.childAdded(treeEvent);
}
else {
if (newElement == null) {
myFileManager.removeCachedViewProvider(vFile);
treeEvent.setParent(oldParentDir);
treeEvent.setChild(oldElement);
myManager.childRemoved(treeEvent);
}
else {
if (oldElement.getClass().equals(newElement.getClass())) {
treeEvent.setOldParent(oldParentDir);
treeEvent.setNewParent(newParentDir);
treeEvent.setChild(newElement);
myManager.childMoved(treeEvent);
}
else {
myFileManager.cacheViewProvider(vFile, newViewProvider);
PsiTreeChangeEventImpl treeRemoveEvent = new PsiTreeChangeEventImpl(myManager);
treeRemoveEvent.setParent(oldParentDir);
treeRemoveEvent.setChild(oldElement);
myManager.childRemoved(treeRemoveEvent);
PsiTreeChangeEventImpl treeAddEvent = new PsiTreeChangeEventImpl(myManager);
treeAddEvent.setParent(newParentDir);
treeAddEvent.setChild(newElement);
myManager.childAdded(treeAddEvent);
}
}
}
}
}
);
}
@Nullable
private PsiFile createFileCopyWithNewName(VirtualFile vFile, String name) {
// TODO[ik] remove this. Event handling and generation must be in view providers mechanism since we
// need to track changes in _all_ psi views (e.g. namespace changes in XML)
final FileTypeManager instance = FileTypeManager.getInstance();
if(instance.isFileIgnored(name)) return null;
final FileType fileTypeByFileName = instance.getFileTypeByFileName(name);
final Document document = FileDocumentManager.getInstance().getDocument(vFile);
return PsiFileFactory.getInstance(myManager.getProject()).createFileFromText(name, fileTypeByFileName,
document != null ? document.getCharsSequence() : "", vFile.getModificationStamp(),
true, false);
}
// When file is renamed so that extension changes then language dialect might change and thus psiFile should be invalidated
private static boolean languageDialectChanged(final PsiFile newPsiFile, String oldFileName) {
return newPsiFile != null && !FileUtilRt.extensionEquals(oldFileName, FileUtilRt.getExtension(newPsiFile.getName()));
}
private class MyModuleRootListener implements ModuleRootListener {
private VirtualFile[] myOldContentRoots = null;
private volatile int depthCounter = 0;
@Override
public void beforeRootsChange(final ModuleRootEvent event) {
if (!myFileManager.isInitialized()) return;
if (event.isCausedByFileTypesChange()) return;
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
depthCounter++;
if (depthCounter > 1) return;
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS);
final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots();
LOG.assertTrue(myOldContentRoots == null);
myOldContentRoots = contentRoots;
treeEvent.setOldValue(contentRoots);
myManager.beforePropertyChange(treeEvent);
}
}
);
}
@Override
public void rootsChanged(final ModuleRootEvent event) {
myFileManager.dispatchPendingEvents();
if (!myFileManager.isInitialized()) return;
if (event.isCausedByFileTypesChange()) return;
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
depthCounter--;
assert depthCounter >= 0 : depthCounter;
if (depthCounter > 0) return;
myFileManager.removeInvalidFilesAndDirs(true);
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
treeEvent.setPropertyName(PsiTreeChangeEvent.PROP_ROOTS);
final VirtualFile[] contentRoots = myProjectRootManager.getContentRoots();
treeEvent.setNewValue(contentRoots);
LOG.assertTrue(myOldContentRoots != null);
treeEvent.setOldValue(myOldContentRoots);
myOldContentRoots = null;
myManager.propertyChanged(treeEvent);
}
}
);
}
}
private class MyFileDocumentManagerAdapter extends FileDocumentManagerAdapter {
@Override
public void fileWithNoDocumentChanged(@NotNull final VirtualFile file) {
final PsiFile psiFile = myFileManager.getCachedPsiFileInner(file);
if (psiFile != null) {
ApplicationManager.getApplication().runWriteAction(
new ExternalChangeAction() {
@Override
public void run() {
if (FileDocumentManagerImpl.recomputeFileTypeIfNecessary(file)) {
forceReload(file, psiFile, null);
}
myFileManager.reloadFromDisk(psiFile, true); // important to ignore document which might appear already!
}
}
);
}
}
}
}