Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,28 @@ public UndoManager(DesignPage designPage, ICompilationUnit unit) throws Exceptio
public void activate() {
if (!m_active) {
m_active = true;
if (!Objects.equals(m_currentSource, m_buffer.getContents())) {
refreshDesignerEditor();
}
refreshIfSourceChanged();
addBufferListener();
}
}

/**
* Reparses if the buffer no longer matches the parsed source, waiting for a running parse first.
*/
private void refreshIfSourceChanged() {
if (!m_active) {
return;
}
// the progress dialog of a running parse spins the event loop, so wait for it to finish
if (m_designPage.getDesignerState() == DesignerState.Parsing) {
Display.getDefault().timerExec(1, this::refreshIfSourceChanged);
return;
}
if (!Objects.equals(m_currentSource, m_buffer.getContents())) {
refreshDesignerEditor();
}
}

/**
* Deactivates {@link UndoManager}, so it stops listening for buffer changes.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,22 @@ public void run() {
}

/**
* Runs given {@link RunnableEx} inside of UI thread, using {@link Display#syncExec(Runnable)}.
* Runs given {@link RunnableEx} inside of UI thread, using {@link Display#syncExec(Runnable)},
* and re-throws its exceptions in the calling thread.
*/
public static void runRethrowUI(final RunnableEx runnable) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
ExecutionUtils.runRethrow(runnable);
// the workbench's display exception handler swallows what a syncExec runnable throws
Throwable[] failure = new Throwable[1];
Display.getDefault().syncExec(() -> {
try {
runnable.run();
} catch (Throwable e) {
failure[0] = e;
}
});
if (failure[0] != null) {
throw ReflectionUtils.propagate(failure[0]);
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import java.beans.Beans;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

/**
* Tests for {@link ExecutionUtils} and {@link RunnableEx}.
Expand Down Expand Up @@ -458,6 +460,38 @@ public void test_runRethrowUI() throws Exception {
}
}

/**
* Test for {@link ExecutionUtils#runRethrowUI(RunnableEx)} when the display's exception handler
* swallows exceptions, as the workbench's does.
*/
@Test
public void test_runRethrowUI_exception() throws Exception {
Display display = Display.getCurrent();
Consumer<RuntimeException> oldHandler = display.getRuntimeExceptionHandler();
display.setRuntimeExceptionHandler(e -> {
});
try {
IllegalStateException exception = new IllegalStateException();
AtomicReference<Throwable> caught = new AtomicReference<>();
Thread thread = new Thread(() -> {
try {
ExecutionUtils.runRethrowUI(() -> {
throw exception;
});
} catch (Throwable e) {
caught.set(e);
}
});
thread.start();
while (thread.isAlive()) {
waitEventLoop(0);
}
assertSame(exception, caught.get());
} finally {
display.setRuntimeExceptionHandler(oldHandler);
}
}

/**
* Test for {@link ExecutionUtils#runAsync(RunnableEx)}.
*/
Expand Down
Loading