mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
encoding review followup
This commit is contained in:
@@ -94,12 +94,12 @@ public class CharsetToolkit {
|
||||
public static final byte[] UTF32LE_BOM = {-1, -2, 0, 0 };
|
||||
@NonNls public static final String FILE_ENCODING_PROPERTY = "file.encoding";
|
||||
|
||||
@NonNls private static final Map<Charset, byte[]> CHARSET_TO_BOM = new THashMap<Charset, byte[]>(2);
|
||||
@NonNls private static final Map<Charset, byte[]> CHARSET_TO_MANDATORY_BOM = new THashMap<Charset, byte[]>(2);
|
||||
static {
|
||||
CHARSET_TO_BOM.put(UTF_16LE_CHARSET, UTF16LE_BOM);
|
||||
CHARSET_TO_BOM.put(UTF_16BE_CHARSET, UTF16BE_BOM);
|
||||
CHARSET_TO_BOM.put(UTF_32BE_CHARSET, UTF32BE_BOM);
|
||||
CHARSET_TO_BOM.put(UTF_32LE_CHARSET, UTF32LE_BOM);
|
||||
CHARSET_TO_MANDATORY_BOM.put(UTF_16LE_CHARSET, UTF16LE_BOM);
|
||||
CHARSET_TO_MANDATORY_BOM.put(UTF_16BE_CHARSET, UTF16BE_BOM);
|
||||
CHARSET_TO_MANDATORY_BOM.put(UTF_32BE_CHARSET, UTF32BE_BOM);
|
||||
CHARSET_TO_MANDATORY_BOM.put(UTF_32LE_CHARSET, UTF32LE_BOM);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,12 +503,13 @@ public class CharsetToolkit {
|
||||
|
||||
@Nullable
|
||||
public static byte[] getBom(@NotNull Charset charset) {
|
||||
return CHARSET_TO_BOM.get(charset);
|
||||
return CHARSET_TO_MANDATORY_BOM.get(charset);
|
||||
}
|
||||
|
||||
// byte sequence for this encoding is allowed to be prepended with this BOM
|
||||
public static boolean canHaveBom(@NotNull Charset charset, @NotNull byte[] bom) {
|
||||
return charset.equals(UTF8_CHARSET) && Arrays.equals(bom, UTF8_BOM) || Arrays.equals(getBom(charset), bom);
|
||||
return charset.equals(UTF8_CHARSET) && Arrays.equals(bom, UTF8_BOM)
|
||||
|| Arrays.equals(getBom(charset), bom);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -138,6 +138,9 @@ public class LossyEncodingInspection extends LocalInspectionTool {
|
||||
@NotNull String text,
|
||||
@NotNull Charset charset,
|
||||
@NotNull Project project) {
|
||||
FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
Document document = documentManager.getDocument(virtualFile);
|
||||
if (document == null) return true;
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = virtualFile.contentsToByteArray();
|
||||
@@ -145,9 +148,6 @@ public class LossyEncodingInspection extends LocalInspectionTool {
|
||||
catch (IOException e) {
|
||||
return true;
|
||||
}
|
||||
FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
Document document = documentManager.getDocument(virtualFile);
|
||||
if (document == null) return true;
|
||||
String separator = LoadTextUtil.detectLineSeparator(virtualFile, false);
|
||||
if (separator == null) {
|
||||
separator = documentManager.isDocumentUnsaved(document) ?
|
||||
|
||||
+9
-9
@@ -62,10 +62,7 @@ public class ChangeFileEncodingAction extends AnAction implements DumbAware {
|
||||
Document document = documentManager.getDocument(virtualFile);
|
||||
if (document == null) return false;
|
||||
|
||||
boolean canConvert = EncodingUtil.checkCanConvert(virtualFile) == null;
|
||||
boolean canReload = EncodingUtil.checkCanReload(virtualFile).second == null;
|
||||
|
||||
return canConvert || canReload;
|
||||
return EncodingUtil.checkCanConvert(virtualFile) == null || EncodingUtil.checkCanReload(virtualFile).second == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,7 +91,7 @@ public class ChangeFileEncodingAction extends AnAction implements DumbAware {
|
||||
Editor editor = PlatformDataKeys.EDITOR.getData(dataContext);
|
||||
FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
final Document document = documentManager.getDocument(virtualFile);
|
||||
if (!allowDirectories && !virtualFile.isDirectory() && document == null) return null;
|
||||
if (!allowDirectories && virtualFile.isDirectory() || document == null && !virtualFile.isDirectory()) return null;
|
||||
|
||||
final byte[] bytes;
|
||||
try {
|
||||
@@ -127,9 +124,13 @@ public class ChangeFileEncodingAction extends AnAction implements DumbAware {
|
||||
return createCharsetsActionGroup(clearItemText, null, new Function<Charset, String>() {
|
||||
@Override
|
||||
public String fun(Charset charset) {
|
||||
assert text != null : charset;
|
||||
EncodingUtil.Magic8 safeToReload = myFile.isDirectory() ? EncodingUtil.Magic8.ABSOLUTELY : EncodingUtil.isSafeToReloadIn(myFile, text, bytes, charset);
|
||||
EncodingUtil.Magic8 safeToConvert = myFile.isDirectory() ? EncodingUtil.Magic8.ABSOLUTELY : EncodingUtil.isSafeToConvertTo(myFile, text, bytes, charset);
|
||||
boolean enabled = safeToReload != EncodingUtil.Magic8.NO_WAY || safeToConvert != EncodingUtil.Magic8.NO_WAY;
|
||||
boolean enabled = safeToReload != EncodingUtil.Magic8.NO_WAY;
|
||||
if (!enabled) {
|
||||
EncodingUtil.Magic8 safeToConvert = myFile.isDirectory() ? EncodingUtil.Magic8.ABSOLUTELY : EncodingUtil.isSafeToConvertTo(myFile, text, bytes, charset);
|
||||
enabled = safeToConvert != EncodingUtil.Magic8.NO_WAY;
|
||||
}
|
||||
return enabled ? "Change encoding to '"+charset.displayName()+"'" : null;
|
||||
}
|
||||
}); // no 'clear'
|
||||
@@ -163,7 +164,6 @@ public class ChangeFileEncodingAction extends AnAction implements DumbAware {
|
||||
|
||||
if (isSafeToConvert == EncodingUtil.Magic8.ABSOLUTELY && isSafeToReload == EncodingUtil.Magic8.ABSOLUTELY) {
|
||||
//change and forget
|
||||
EncodingManager.getInstance().setEncoding(virtualFile, charset);
|
||||
undo = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -178,7 +178,7 @@ public class ChangeFileEncodingAction extends AnAction implements DumbAware {
|
||||
};
|
||||
}
|
||||
else {
|
||||
IncompatibleEncodingDialog dialog = new IncompatibleEncodingDialog(document, virtualFile, bytes, charset, isSafeToReload, isSafeToConvert);
|
||||
IncompatibleEncodingDialog dialog = new IncompatibleEncodingDialog(virtualFile, charset, isSafeToReload, isSafeToConvert);
|
||||
dialog.show();
|
||||
if (dialog.getExitCode() == IncompatibleEncodingDialog.RELOAD_EXIT_CODE) {
|
||||
undo = new Runnable() {
|
||||
|
||||
+13
-9
@@ -48,6 +48,7 @@ import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -315,15 +316,17 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
|
||||
if (!changed.isEmpty()) {
|
||||
final Processor<VirtualFile> reloadProcessor = createChangeCharsetProcessor();
|
||||
startReloadWithProgress(new Runnable() {
|
||||
tryStartReloadWithProgress(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Set<VirtualFile> processed = new THashSet<VirtualFile>();
|
||||
next:
|
||||
for (VirtualFile changedFile : changed) {
|
||||
final Charset newCharset = newMap.get(changedFile);
|
||||
Charset oldCharset = oldMap.get(changedFile);
|
||||
if (!Comparing.equal(newCharset, oldCharset)) {
|
||||
processSubFiles(changedFile, reloadProcessor);
|
||||
for (VirtualFile processedFile : processed) {
|
||||
if (VfsUtilCore.isAncestor(processedFile, changedFile, false)) continue next;
|
||||
}
|
||||
processSubFiles(changedFile, reloadProcessor);
|
||||
processed.add(changedFile);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -400,9 +403,9 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean startReloadWithProgress(@NotNull final Runnable reloadAction) {
|
||||
private boolean tryStartReloadWithProgress(@NotNull final Runnable reloadAction) {
|
||||
Boolean suppress = SUPPRESS_RELOAD.get();
|
||||
if (suppress != null && suppress) return false;
|
||||
if (suppress == Boolean.TRUE) return false;
|
||||
FileDocumentManager.getInstance().saveAllDocuments(); // consider all files as unmodified
|
||||
return ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() {
|
||||
@Override
|
||||
@@ -413,7 +416,7 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
}
|
||||
|
||||
private void reloadAllFilesUnder(final VirtualFile root) {
|
||||
startReloadWithProgress(new Runnable() {
|
||||
tryStartReloadWithProgress(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
processSubFiles(root, new Processor<VirtualFile>() {
|
||||
@@ -430,7 +433,8 @@ public class EncodingProjectManagerImpl extends EncodingProjectManager {
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (file.isCharsetSet()) {
|
||||
// for not loaded files deep under project, reset encoding to give them chance re-detect the right one later
|
||||
else if (file.isCharsetSet() && !file.equals(root)) {
|
||||
file.setCharset(null);
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -103,18 +103,6 @@ public class EncodingUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isSafeToChangeSilentlyTo(@NotNull VirtualFile virtualFile, @NotNull String text, @NotNull byte[] bytes, @NotNull Charset charset) {
|
||||
String loaded = LoadTextUtil.getTextByBinaryPresentation(bytes, charset).toString();
|
||||
boolean canReloadSilently = loaded.equals(text);
|
||||
|
||||
Pair<Charset, byte[]> chosen = LoadTextUtil.chooseMostlyHarmlessCharset(virtualFile.getCharset(), charset, text);
|
||||
byte[] saved = chosen.second;
|
||||
boolean canSaveSilently = Arrays.equals(saved, bytes);
|
||||
|
||||
return canReloadSilently && canSaveSilently;
|
||||
}
|
||||
|
||||
|
||||
public static void saveIn(@NotNull final Document document, final Editor editor, @NotNull final VirtualFile virtualFile, @NotNull final Charset charset) {
|
||||
FileDocumentManager documentManager = FileDocumentManager.getInstance();
|
||||
documentManager.saveDocument(document);
|
||||
@@ -125,6 +113,7 @@ public class EncodingUtil {
|
||||
return;
|
||||
}
|
||||
|
||||
// first, save the file in the new charset and then mark the file as having the correct encoding
|
||||
virtualFile.setCharset(charset);
|
||||
try {
|
||||
LoadTextUtil.write(project, virtualFile, virtualFile, document.getText(), document.getModificationStamp());
|
||||
|
||||
+1
-9
@@ -16,7 +16,6 @@
|
||||
package com.intellij.openapi.vfs.encoding;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -30,24 +29,17 @@ import java.awt.event.ActionEvent;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class IncompatibleEncodingDialog extends DialogWrapper {
|
||||
|
||||
@NotNull private final Document document;
|
||||
@NotNull private final VirtualFile virtualFile;
|
||||
@NotNull private final byte[] bytes;
|
||||
@NotNull private final Charset charset;
|
||||
@NotNull private final EncodingUtil.Magic8 safeToReload;
|
||||
@NotNull private final EncodingUtil.Magic8 safeToConvert;
|
||||
|
||||
public IncompatibleEncodingDialog(@NotNull Document document,
|
||||
@NotNull VirtualFile virtualFile,
|
||||
@NotNull byte[] bytes,
|
||||
public IncompatibleEncodingDialog(@NotNull VirtualFile virtualFile,
|
||||
@NotNull final Charset charset,
|
||||
@NotNull EncodingUtil.Magic8 safeToReload,
|
||||
@NotNull EncodingUtil.Magic8 safeToConvert) {
|
||||
super(false);
|
||||
this.document = document;
|
||||
this.virtualFile = virtualFile;
|
||||
this.bytes = bytes;
|
||||
this.charset = charset;
|
||||
this.safeToReload = safeToReload;
|
||||
this.safeToConvert = safeToConvert;
|
||||
|
||||
@@ -217,7 +217,7 @@ public class EncodingPanel extends EditorBasedWidget implements StatusBarWidget.
|
||||
|
||||
String toolTip = "File Encoding" +
|
||||
(currentCharset == null ? "" : ": "+currentCharset.displayName()) +
|
||||
(failReason == null ? "" : actionEnabled ? " ("+failReason+")" : " (change disabled: " + failReason + ")");
|
||||
(actionEnabled ? "" : " (change disabled: " + failReason + ")");
|
||||
myComponent.setToolTipText(toolTip);
|
||||
myComponent.setText(text);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user