mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-121182 Plain text autodetection isn't rerun on file content change
This commit is contained in:
@@ -22,6 +22,7 @@ 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;
|
||||
@@ -33,7 +34,7 @@ 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.PsiDocumentManagerImpl;
|
||||
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;
|
||||
@@ -87,7 +88,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCreated(VirtualFileEvent event) {
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(
|
||||
@@ -124,7 +125,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFileDeletion(VirtualFileEvent event) {
|
||||
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
VirtualFile parent = vFile.getParent();
|
||||
@@ -159,7 +160,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileDeleted(final VirtualFileEvent event) {
|
||||
public void fileDeleted(@NotNull final VirtualFileEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
VirtualFile parent = event.getParent();
|
||||
@@ -202,7 +203,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforePropertyChange(final VirtualFilePropertyEvent event) {
|
||||
public void beforePropertyChange(@NotNull final VirtualFilePropertyEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
final String propertyName = event.getPropertyName();
|
||||
|
||||
@@ -301,7 +302,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChanged(final VirtualFilePropertyEvent event) {
|
||||
public void propertyChanged(@NotNull final VirtualFilePropertyEvent event) {
|
||||
final String propertyName = event.getPropertyName();
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
@@ -318,29 +319,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
final PsiDirectory parentDir = getCachedDirectory(parent);
|
||||
|
||||
if (FileContentUtilCore.FORCE_RELOAD_REQUESTOR.equals(event.getRequestor())) {
|
||||
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) {
|
||||
PsiDocumentManagerImpl.cachePsi(document, newPsiFile);
|
||||
}
|
||||
}
|
||||
if (parentDir != null) {
|
||||
PsiTreeChangeEventImpl treeEvent = new PsiTreeChangeEventImpl(myManager);
|
||||
treeEvent.setParent(parentDir);
|
||||
|
||||
treeEvent.setOldChild(oldPsiFile);
|
||||
treeEvent.setNewChild(newPsiFile);
|
||||
myManager.childReplaced(treeEvent);
|
||||
}
|
||||
forceReload(vFile, oldPsiFile, parentDir);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -450,8 +429,34 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
);
|
||||
}
|
||||
|
||||
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(VirtualFileMoveEvent event) {
|
||||
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
final PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent());
|
||||
@@ -504,7 +509,7 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileMoved(VirtualFileMoveEvent event) {
|
||||
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
|
||||
final VirtualFile vFile = event.getFile();
|
||||
|
||||
final PsiDirectory oldParentDir = myFileManager.findDirectory(event.getOldParent());
|
||||
@@ -647,13 +652,16 @@ public class PsiVFSListener extends VirtualFileAdapter {
|
||||
|
||||
private class MyFileDocumentManagerAdapter extends FileDocumentManagerAdapter {
|
||||
@Override
|
||||
public void fileWithNoDocumentChanged(@NotNull VirtualFile file) {
|
||||
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!
|
||||
}
|
||||
}
|
||||
|
||||
+33
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -40,10 +40,7 @@ import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.*;
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl;
|
||||
import com.intellij.openapi.fileTypes.BinaryFileTypeDecompilers;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.UnknownFileType;
|
||||
import com.intellij.openapi.fileTypes.*;
|
||||
import com.intellij.openapi.project.*;
|
||||
import com.intellij.openapi.project.ex.ProjectEx;
|
||||
import com.intellij.openapi.ui.DialogBuilder;
|
||||
@@ -93,6 +90,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
private static final Key<String> LINE_SEPARATOR_KEY = Key.create("LINE_SEPARATOR_KEY");
|
||||
public static final Key<Reference<Document>> DOCUMENT_KEY = Key.create("DOCUMENT_KEY");
|
||||
private static final Key<VirtualFile> FILE_KEY = Key.create("FILE_KEY");
|
||||
private static final Key<Boolean> MUST_RECOMPUTE_FILE_TYPE = Key.create("Must recompute file type");
|
||||
|
||||
private final Set<Document> myUnsavedDocuments = new ConcurrentHashSet<Document>();
|
||||
|
||||
@@ -513,7 +511,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadFiles(final VirtualFile... files) {
|
||||
public void reloadFiles(@NotNull final VirtualFile... files) {
|
||||
for (VirtualFile file : files) {
|
||||
if (file.exists()) {
|
||||
final Document doc = getCachedDocument(file);
|
||||
@@ -547,7 +545,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertyChanged(VirtualFilePropertyEvent event) {
|
||||
public void propertyChanged(@NotNull VirtualFilePropertyEvent event) {
|
||||
final VirtualFile file = event.getFile();
|
||||
if (VirtualFile.PROP_WRITABLE.equals(event.getPropertyName())) {
|
||||
final Document document = getCachedDocument(file);
|
||||
@@ -576,18 +574,18 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isBinaryWithDecompiler(VirtualFile file) {
|
||||
private static boolean isBinaryWithDecompiler(@NotNull VirtualFile file) {
|
||||
final FileType ft = file.getFileType();
|
||||
return ft.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(ft) != null;
|
||||
}
|
||||
|
||||
private static boolean isBinaryWithoutDecompiler(VirtualFile file) {
|
||||
private static boolean isBinaryWithoutDecompiler(@NotNull VirtualFile file) {
|
||||
final FileType fileType = file.getFileType();
|
||||
return fileType.isBinary() && BinaryFileTypeDecompilers.INSTANCE.forFileType(fileType) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contentsChanged(VirtualFileEvent event) {
|
||||
public void contentsChanged(@NotNull VirtualFileEvent event) {
|
||||
if (event.isFromSave()) return;
|
||||
final VirtualFile file = event.getFile();
|
||||
final Document document = getCachedDocument(file);
|
||||
@@ -716,11 +714,11 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCreated(VirtualFileEvent event) {
|
||||
public void fileCreated(@NotNull VirtualFileEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileDeleted(VirtualFileEvent event) {
|
||||
public void fileDeleted(@NotNull VirtualFileEvent event) {
|
||||
Document doc = getCachedDocument(event.getFile());
|
||||
if (doc != null) {
|
||||
myTrailingSpacesStripper.documentDeleted(doc);
|
||||
@@ -728,24 +726,37 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileMoved(VirtualFileMoveEvent event) {
|
||||
public void fileMoved(@NotNull VirtualFileMoveEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fileCopied(VirtualFileCopyEvent event) {
|
||||
public void fileCopied(@NotNull VirtualFileCopyEvent event) {
|
||||
fileCreated(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforePropertyChange(VirtualFilePropertyEvent event) {
|
||||
public void beforePropertyChange(@NotNull VirtualFilePropertyEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeContentsChange(VirtualFileEvent event) {
|
||||
public void beforeContentsChange(@NotNull VirtualFileEvent event) {
|
||||
VirtualFile virtualFile = event.getFile();
|
||||
if (virtualFile.getFileType() == UnknownFileType.INSTANCE && virtualFile.getLength() == 0) {
|
||||
virtualFile.putUserData(MUST_RECOMPUTE_FILE_TYPE, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean recomputeFileTypeIfNecessary(@NotNull VirtualFile virtualFile) {
|
||||
if (virtualFile.getUserData(MUST_RECOMPUTE_FILE_TYPE) != null) {
|
||||
FileTypeRegistry.getInstance().detectFileTypeFromContent(virtualFile);
|
||||
virtualFile.putUserData(MUST_RECOMPUTE_FILE_TYPE, null);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFileDeletion(VirtualFileEvent event) {
|
||||
public void beforeFileDeletion(@NotNull VirtualFileEvent event) {
|
||||
/*
|
||||
if (!event.isFromRefresh()) {
|
||||
VirtualFile file = event.getFile();
|
||||
@@ -768,7 +779,7 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeFileMovement(VirtualFileMoveEvent event) {
|
||||
public void beforeFileMovement(@NotNull VirtualFileMoveEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -818,14 +829,15 @@ public class FileDocumentManagerImpl extends FileDocumentManager implements Appl
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected FileDocumentManagerListener[] getListeners() {
|
||||
private static FileDocumentManagerListener[] getListeners() {
|
||||
return FileDocumentManagerListener.EP_NAME.getExtensions();
|
||||
}
|
||||
|
||||
private void handleErrorsOnSave(@NotNull Map<Document, IOException> failures) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
for (IOException exception : failures.values()) {
|
||||
throw new RuntimeException(exception);
|
||||
IOException ioException = failures.isEmpty() ? null : failures.values().iterator().next();
|
||||
if (ioException != null) {
|
||||
throw new RuntimeException(ioException);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+12
-5
@@ -325,7 +325,7 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
|
||||
}
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0, size = mySpecialFileTypes.size(); i < size; i++) {
|
||||
for (int i = 0; i < mySpecialFileTypes.size(); i++) {
|
||||
FileTypeIdentifiableByVirtualFile type = mySpecialFileTypes.get(i);
|
||||
if (type.isMyFileType(file)) {
|
||||
return type;
|
||||
@@ -335,28 +335,35 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME
|
||||
fileType = getFileTypeByFileName(file.getName());
|
||||
if (fileType != UnknownFileType.INSTANCE) return fileType;
|
||||
|
||||
fileType = file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY);
|
||||
fileType = cachedDetectedFromContent(file);
|
||||
if (fileType != null) return fileType;
|
||||
|
||||
return UnknownFileType.INSTANCE;
|
||||
}
|
||||
|
||||
private static FileType cachedDetectedFromContent(@NotNull VirtualFile file) {
|
||||
return file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FileType detectFileTypeFromContent(@NotNull VirtualFile file) {
|
||||
if (file.isDirectory() || !file.isValid() || file.is(VFileProperty.SPECIAL)) {
|
||||
return UnknownFileType.INSTANCE;
|
||||
}
|
||||
FileType fileType = file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY);
|
||||
FileType fileType = cachedDetectedFromContent(file);
|
||||
if (fileType == null) {
|
||||
fileType = detectFromContent(file);
|
||||
file.putUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY, fileType);
|
||||
// for empty file there is still hope its type will change
|
||||
if (file.getLength() != 0) {
|
||||
file.putUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY, fileType);
|
||||
}
|
||||
}
|
||||
return fileType;
|
||||
}
|
||||
|
||||
public static boolean isFileTypeDetectedFromContent(@NotNull VirtualFile file) {
|
||||
return file.getUserData(DETECTED_FROM_CONTENT_FILE_TYPE_KEY) != null;
|
||||
return cachedDetectedFromContent(file) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user