Add source highlighting and revision-checked diagnostic fixes in both hosts

This commit is contained in:
2026-11-13 18:19:39 +01:00
parent 8a4f456e38
commit 9bc4569407
18 changed files with 1033 additions and 14 deletions
+176
View File
@@ -82,6 +82,175 @@ public final class WorkflowProbe implements StartupActivity.DumbAware {
});
}
private static com.intellij.codeInsight.daemon.impl.HighlightInfo directionHighlight(
Project project, VirtualFile file) {
var document = FileDocumentManager.getInstance().getDocument(file);
var result = new java.util.ArrayList<com.intellij.codeInsight.daemon.impl.HighlightInfo>();
com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx.processHighlights(
document,
project,
com.intellij.lang.annotation.HighlightSeverity.ERROR,
0,
document.getTextLength(),
info -> {
if (info.getDescription() != null
&& info.getDescription().startsWith("Invalid or missing direction:"))
result.add(info);
return true;
});
return result.isEmpty() ? null : result.getFirst();
}
private static void checkNativeFixes(
Project project,
VirtualFile file,
DesignerPane pane,
de.neitzel.fxdesigner.host.DocumentSession document)
throws Exception {
var before = document.snapshot().toCompletableFuture().get();
String bad = before.text().replaceFirst("direction=\"both\"", "direction = 'bad'");
if (bad.equals(before.text())) throw new AssertionError("Fixture has no direction");
document
.apply(
new de.neitzel.fxdesigner.contracts.EditBatch(
before.revision(),
"Native fix fixture",
java.util.List.of(
new de.neitzel.fxdesigner.contracts.EditBatch.Replacement(
0, before.text().length(), bad))))
.toCompletableFuture()
.get();
await(
() ->
fx(
() ->
((javafx.scene.control.TextArea) pane.lookup("#fxml-source"))
.getText()
.equals(bad)));
int at = bad.indexOf("'bad'") + 1;
edt(
() -> {
new OpenFileDescriptor(project, file, at).navigate(true);
return null;
});
await(() -> edt(() -> directionHighlight(project, file) != null));
var info = edt(() -> directionHighlight(project, file));
if (info.getStartOffset() != at || info.getEndOffset() != at + 3)
throw new AssertionError("Wrong native diagnostic range");
var action =
edt(
() ->
info.findRegisteredQuickFix(
(descriptor, range) ->
"Set binding direction to both".equals(descriptor.getAction().getText())
? descriptor.getAction()
: null));
if (action == null) throw new AssertionError("Native Alt+Enter fix not registered");
edt(
() -> {
var editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
var psi =
com.intellij.psi.PsiDocumentManager.getInstance(project)
.getPsiFile(editor.getDocument());
if (!action.isAvailable(project, editor, psi))
throw new AssertionError("Native fix unavailable");
action.invoke(project, editor, psi);
return null;
});
String fixed = bad.replace("direction = 'bad'", "direction = 'both'");
await(() -> document.snapshot().toCompletableFuture().get().text().equals(fixed));
await(
() ->
fx(
() ->
((javafx.scene.control.TextArea) pane.lookup("#fxml-source"))
.getText()
.equals(fixed)));
await(() -> edt(() -> directionHighlight(project, file) == null));
edt(
() -> {
var editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
var psi =
com.intellij.psi.PsiDocumentManager.getInstance(project)
.getPsiFile(editor.getDocument());
if (action.isAvailable(project, editor, psi))
throw new AssertionError("Old fix survived source change");
action.invoke(project, editor, psi);
return null;
});
if (!document.snapshot().toCompletableFuture().get().text().equals(fixed))
throw new AssertionError("Stale native fix changed source");
edt(
() -> {
var editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
com.intellij.openapi.command.undo.UndoManager.getInstance(project)
.undo(
com.intellij
.openapi
.fileEditor
.impl
.text
.TextEditorProvider
.getInstance()
.getTextEditor(editor));
return null;
});
await(
() ->
fx(
() ->
((javafx.scene.control.TextArea) pane.lookup("#fxml-source"))
.getText()
.equals(bad)));
if (!document.snapshot().toCompletableFuture().get().text().equals(bad))
throw new AssertionError("Native fix Undo not exact");
edt(
() -> {
var editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
com.intellij.openapi.command.undo.UndoManager.getInstance(project)
.redo(
com.intellij
.openapi
.fileEditor
.impl
.text
.TextEditorProvider
.getInstance()
.getTextEditor(editor));
return null;
});
await(
() ->
fx(
() ->
((javafx.scene.control.TextArea) pane.lookup("#fxml-source"))
.getText()
.equals(fixed)));
if (!document.snapshot().toCompletableFuture().get().text().equals(fixed))
throw new AssertionError("Native fix Redo not exact");
var current = document.snapshot().toCompletableFuture().get();
document
.apply(
new de.neitzel.fxdesigner.contracts.EditBatch(
current.revision(),
"Restore native fixture",
java.util.List.of(
new de.neitzel.fxdesigner.contracts.EditBatch.Replacement(
0, current.text().length(), before.text()))))
.toCompletableFuture()
.get();
await(
() ->
fx(
() ->
((javafx.scene.control.TextArea) pane.lookup("#fxml-source"))
.getText()
.equals(before.text())));
System.out.println(
"PASS native source highlighting and Alt+Enter fix: exact ranges, source-preserving"
+ " transaction, Undo/Redo, stale action rejection and highlight withdrawal");
}
private static void checkProblems(
Project project,
VirtualFile file,
@@ -386,6 +555,13 @@ public final class WorkflowProbe implements StartupActivity.DumbAware {
});
try (var document =
pane.kit().host().documents().open(path.toUri()).toCompletableFuture().get()) {
checkNativeFixes(project, file, pane, document);
edt(
() -> {
FileEditorManager.getInstance(project)
.setSelectedEditor(file, "neitzel-fx-designer");
return null;
});
de.neitzel.fxdesigner.kit.ProjectionHostChecks.run(pane, document);
checkProblems(project, file, pane, document);
}