Implement isolated Build and Refresh with immutable leased snapshots
This commit is contained in:
+27
-1
@@ -90,6 +90,26 @@ public final class IntellijDocuments implements HostServices.Documents, AutoClos
|
||||
});
|
||||
}
|
||||
|
||||
public CompletionStage<List<DocumentSnapshot>> unsaved() {
|
||||
return edt(
|
||||
() -> {
|
||||
var result = new ArrayList<DocumentSnapshot>();
|
||||
var manager = FileDocumentManager.getInstance();
|
||||
for (var document : manager.getUnsavedDocuments()) {
|
||||
var file = manager.getFile(document);
|
||||
if (file == null || !file.isInLocalFileSystem()) continue;
|
||||
var handle =
|
||||
(Handle) open(Path.of(file.getPath()).toUri()).toCompletableFuture().join();
|
||||
try {
|
||||
result.add(snapshot(handle.s));
|
||||
} finally {
|
||||
handle.release();
|
||||
}
|
||||
}
|
||||
return List.copyOf(result);
|
||||
});
|
||||
}
|
||||
|
||||
private DocumentSnapshot snapshot(State s) {
|
||||
return new DocumentSnapshot(
|
||||
Path.of(s.file.getPath()).toUri(),
|
||||
@@ -171,7 +191,13 @@ public final class IntellijDocuments implements HostServices.Documents, AutoClos
|
||||
if (!s.document.isWritable() || !s.file.isWritable())
|
||||
throw new IllegalStateException("Read-only document");
|
||||
Path file = Path.of(s.file.getPath());
|
||||
if (!Files.readString(file).equals(s.disk))
|
||||
String onDisk = Files.readString(file);
|
||||
if (!FileDocumentManager.getInstance().isDocumentUnsaved(s.document)
|
||||
&& onDisk.equals(s.document.getText())) {
|
||||
s.disk = onDisk;
|
||||
return IntellijDocuments.this.snapshot(s);
|
||||
}
|
||||
if (!onDisk.equals(s.disk))
|
||||
throw new ConcurrentModificationException("External change; draft retained");
|
||||
FileDocumentManager.getInstance().saveDocument(s.document);
|
||||
if (FileDocumentManager.getInstance().isDocumentUnsaved(s.document))
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package de.neitzel.fxdesigner.intellij;
|
||||
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.testFramework.fixtures.BasePlatformTestCase;
|
||||
import java.nio.file.*;
|
||||
|
||||
public final class BuildInputInventoryTest extends BasePlatformTestCase {
|
||||
public void testNativeJavaDraftInventoryAndAutosaveBeforeExplicitSave() throws Exception {
|
||||
Path file = Files.createTempFile("designer-build-input-", ".java").toRealPath();
|
||||
Files.writeString(file, "class Original {}");
|
||||
VfsRootAccess.allowRootAccess(getTestRootDisposable(), file.toString());
|
||||
try (var documents = new IntellijDocuments(getProject())) {
|
||||
var virtual = LocalFileSystem.getInstance().refreshAndFindFileByNioFile(file);
|
||||
var nativeDocument = FileDocumentManager.getInstance().getDocument(virtual);
|
||||
WriteCommandAction.runWriteCommandAction(
|
||||
getProject(), () -> nativeDocument.setText("class Edited {}"));
|
||||
var draft =
|
||||
documents.unsaved().toCompletableFuture().get().stream()
|
||||
.filter(d -> d.document().equals(file.toUri()))
|
||||
.findFirst()
|
||||
.orElseThrow();
|
||||
assertTrue(draft.dirty());
|
||||
FileDocumentManager.getInstance().saveDocument(nativeDocument);
|
||||
try (var handle = documents.open(file.toUri()).toCompletableFuture().get()) {
|
||||
assertFalse(handle.save(draft.revision()).toCompletableFuture().get().dirty());
|
||||
}
|
||||
assertEquals("class Edited {}", Files.readString(file));
|
||||
} finally {
|
||||
Files.deleteIfExists(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user