Do not overwrite detected line separator with null if no line breaks are found in (an empty) file to fix IDEA-242677 Unable to set line separator for empty file

GitOrigin-RevId: cb3fd7c2bd49bd43335a8d8adbe2fbef94a69388
This commit is contained in:
Alexey Kudravtsev
2020-06-05 18:48:08 +03:00
committed by intellij-monorepo-bot
parent 3c9f27e509
commit c732e37238
2 changed files with 50 additions and 13 deletions
@@ -533,12 +533,7 @@ public final class LoadTextUtil {
boolean saveDetectedSeparators,
boolean saveBOM) {
DetectResult info = detectInternalCharsetAndSetBOM(virtualFile, bytes, bytes.length, saveBOM, virtualFile.getFileType());
byte[] bom = info.BOM;
ConvertResult result = convertBytes(bytes, Math.min(bom == null ? 0 : bom.length, bytes.length), bytes.length,
info.hardCodedCharset);
if (saveDetectedSeparators) {
virtualFile.setDetectedLineSeparator(result.majorLineSeparator());
}
ConvertResult result = convertBytesAndSetSeparator(bytes, bytes.length, virtualFile, saveDetectedSeparators, info, info.hardCodedCharset);
return result.text;
}
@@ -574,17 +569,33 @@ public final class LoadTextUtil {
toProcess = null;
}
else {
byte[] bom = info.BOM;
int BOMEndOffset = Math.min(length, bom == null ? 0 : bom.length);
ConvertResult result = convertBytes(bytes, BOMEndOffset, length, internalCharset);
if (saveDetectedSeparators) {
virtualFile.setDetectedLineSeparator(result.majorLineSeparator());
}
ConvertResult result =
convertBytesAndSetSeparator(bytes, length, virtualFile, saveDetectedSeparators, info, internalCharset);
toProcess = result.text;
}
return fileTextProcessor.fun(toProcess);
}
@NotNull
private static ConvertResult convertBytesAndSetSeparator(byte @NotNull [] bytes,
int length,
@NotNull VirtualFile virtualFile,
boolean saveDetectedSeparators,
@NotNull DetectResult info,
@NotNull Charset internalCharset) {
byte[] bom = info.BOM;
int BOMEndOffset = Math.min(length, bom == null ? 0 : bom.length);
ConvertResult result = convertBytes(bytes, BOMEndOffset, length, internalCharset);
if (saveDetectedSeparators) {
String separator = result.majorLineSeparator();
// when in doubt, leave old separator
if (separator != null) {
virtualFile.setDetectedLineSeparator(separator);
}
}
return result;
}
/**
* Get detected line separator, if the file never been loaded, is loaded if checkFile parameter is specified.
*
@@ -5,13 +5,20 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.impl.SimpleDataContext;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.HeavyPlatformTestCase;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ConvertLineSeparatorsActionTest extends HeavyPlatformTestCase {
public void testLF2CRLF() throws IOException {
@@ -27,12 +34,31 @@ public class ConvertLineSeparatorsActionTest extends HeavyPlatformTestCase {
checkConvert("a\r\nb", new ConvertToMacLineSeparatorsAction(), "a\rb");
}
private void checkConvert(String oldContent, AbstractConvertLineSeparatorsAction action, String expectedContent) throws IOException {
@NotNull
private VirtualFile checkConvert(@NotNull String oldContent, @NotNull AbstractConvertLineSeparatorsAction action, @NotNull String expectedContent) throws IOException {
VirtualFile vf = createTempFile("txt", null, oldContent, CharsetToolkit.UTF8_CHARSET);
DataContext context = SimpleDataContext
.getSimpleContext(CommonDataKeys.VIRTUAL_FILE_ARRAY.getName(), new VirtualFile[]{vf}, SimpleDataContext.getProjectContext(getProject()));
action.actionPerformed(AnActionEvent.createFromDataContext("", null, context));
String newContent = FileUtil.loadFile(new File(vf.getPath()));
assertEquals(expectedContent, newContent);
return vf;
}
public void testChangeLineSeparatorOnEmptyFileShouldPersist() throws IOException {
VirtualFile vf = createTempFile("txt", null, "", CharsetToolkit.UTF8_CHARSET);
String separator = FileDocumentManager.getInstance().getLineSeparator(vf, getProject());
AbstractConvertLineSeparatorsAction action = separator.equals("\n") ? new ConvertToWindowsLineSeparatorsAction() : new ConvertToUnixLineSeparatorsAction();
VirtualFile file = checkConvert("", action, "");
String newSeparator = FileDocumentManager.getInstance().getLineSeparator(file, getProject());
String expectedSeparator = separator.equals("\n") ? "\r\n" : "\n";
assertEquals(expectedSeparator, newSeparator);
Document document = FileDocumentManager.getInstance().getDocument(file);
WriteAction.run(() -> document.setText("a\nb"));
FileDocumentManager.getInstance().saveAllDocuments();
assertEquals("a\nb", LoadTextUtil.loadText(file).toString());
assertEquals(StringUtil.toHexString(("a" + expectedSeparator + "b").getBytes(StandardCharsets.UTF_8)), StringUtil.toHexString(file.contentsToByteArray()));
}
}