use of nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse in project magik-tools by StevenLooman.
the class BreakpointManagerTest method testAddBreakpointInvalidLine.
@Test
void testAddBreakpointInvalidLine() throws IOException, InterruptedException, ExecutionException {
final TestSlapProtocol slapProtocol = new TestSlapProtocol() {
@Override
public CompletableFuture<ISlapResponse> setBreakpoint(String method, int line) {
ErrorResponse errorResponse = new ErrorResponse(RequestType.BREAKPOINT_SET, ErrorMessage.INVALID_LINE_NUMBER);
SlapErrorException exception = new SlapErrorException(errorResponse);
CompletableFuture<ISlapResponse> future = new CompletableFuture<>();
future.completeExceptionally(exception);
return future;
}
};
final BreakpointManager manager = new BreakpointManager(slapProtocol, null);
final SourceBreakpoint sourceBreakpoint = new SourceBreakpoint();
sourceBreakpoint.setLine(18);
final Source source = new Source();
source.setPath(getPath("magik-debug-adapter/src/test/resources/bpt.magik").toString());
final BreakpointManager.MagikBreakpoint breakpoint = manager.addBreakpoint(source, sourceBreakpoint);
assertThat(breakpoint.getMethodName()).isEqualTo("user:bpt.t()");
assertThat(breakpoint.getMethodLine()).isEqualTo(18);
assertThat(breakpoint.getCondition()).isNull();
assertThat(breakpoint.getMessage()).isEqualTo("INVALID_LINE_NUMBER");
assertThat(breakpoint.getBreakpointId()).isEqualTo(ISlapProtocol.INVALID_BREAKPOINT_ID);
}
use of nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse in project magik-tools by StevenLooman.
the class ThreadManagerTest method testThreads.
@Test
void testThreads() throws IOException, InterruptedException, ExecutionException {
final TestSlapProtocol slapProtocol = new TestSlapProtocol() {
@Override
public CompletableFuture<ISlapResponse> getThreadList() throws IOException {
final ThreadListResponse response = new ThreadListResponse(List.of(1L, 2L));
return CompletableFuture.completedFuture(response);
}
@Override
public CompletableFuture<ISlapResponse> getThreadInfo(long threadId) throws IOException {
final String name = "Thread: " + threadId;
final ThreadInfoResponse response = new ThreadInfoResponse(// priority
1, // daemon
false, name, ThreadInfoResponse.ThreadState.RUNNABLE, EnumSet.noneOf(ThreadInfoResponse.ThreadFlag.class));
return CompletableFuture.completedFuture(response);
}
};
final ThreadManager manager = new ThreadManager(slapProtocol, null);
final List<Thread> threads = manager.threads();
assertThat(threads).hasSize(2);
assertThat(threads.get(0).getId()).isEqualTo(1);
assertThat(threads.get(0).getName()).isEqualTo("Thread: 1");
assertThat(threads.get(1).getId()).isEqualTo(2);
assertThat(threads.get(1).getName()).isEqualTo("Thread: 2");
}
use of nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse in project magik-tools by StevenLooman.
the class ThreadManager method evaluate.
/**
* Evaluate an expression in a stack frame.
* @param frameId Stack frame.
* @param expression Expression to evaluate.
* @return Result of evalutate.
* @throws IOException -
* @throws InterruptedException -
* @throws ExecutionException -
*/
String evaluate(@Nullable final Integer frameId, final String expression) throws IOException, InterruptedException, ExecutionException {
// TODO: Which threadId to choose here? Or do we abort?
final long threadId = frameId != null ? Lsp4jConversion.frameIdToThreadId(frameId) : 0;
final int level = frameId != null ? Lsp4jConversion.frameIdToLevel(frameId) : 0;
final CompletableFuture<ISlapResponse> evaluateFuture = this.slapProtocol.evaluate(threadId, level, expression);
final EvalResponse response = (EvalResponse) evaluateFuture.get();
return response.getResult();
}
use of nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse in project magik-tools by StevenLooman.
the class VariableManagerTest method testVariablesInScope.
@Test
void testVariablesInScope() throws IOException, InterruptedException, ExecutionException {
final TestSlapProtocol slapProtocol = new TestSlapProtocol() {
@Override
public CompletableFuture<ISlapResponse> getStackFrameLocals(long threadId, int level) throws IOException {
final List<ISlapResponse> subResponses = new ArrayList<>();
subResponses.add(new StackFrameLocalsResponse.Local(LocalType.TYPE_INT, "var1", "value1", EnumSet.noneOf(StackFrameLocalsResponse.VariableType.class)));
subResponses.add(new StackFrameLocalsResponse.Local(LocalType.TYPE_INT, "var2", "value2", EnumSet.noneOf(StackFrameLocalsResponse.VariableType.class)));
final StackFrameLocalsResponse response = new StackFrameLocalsResponse(subResponses);
return CompletableFuture.completedFuture(response);
}
};
final VariableManager manager = new VariableManager(slapProtocol);
final int frameId = Lsp4jConversion.threadIdLevelToFrameId(20, 0);
final Scope[] scopes = manager.getScopes(frameId);
final Scope localScope = scopes[0];
final int reference = localScope.getVariablesReference();
final List<MagikVariable> variables = manager.getVariables(reference);
assertThat(variables).hasSize(2);
final MagikVariable variable0 = variables.get(0);
assertThat(variable0.getName()).isEqualTo("var1");
assertThat(variable0.getValue()).isEqualTo("value1");
final MagikVariable variable1 = variables.get(1);
assertThat(variable1.getName()).isEqualTo("var2");
assertThat(variable1.getValue()).isEqualTo("value2");
}
use of nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse in project magik-tools by StevenLooman.
the class ThreadManager method step.
private void step(final long threadId, final StepType stepType) throws IOException, InterruptedException, ExecutionException {
// Record what the stack looks like now.
CompletableFuture<ISlapResponse> threadStackFuture = this.slapProtocol.getThreadStack(threadId);
ThreadStackResponse threadStack = (ThreadStackResponse) threadStackFuture.get();
ThreadStackResponse.StackElement topElement = threadStack.getStackFrames().get(0);
final String startMethod = topElement.getName();
final int startLine = topElement.getOffset();
final int startStackDepth = threadStack.getStackFrames().size();
LOGGER.trace("Current state: thread id: {}, top element: {}, line: {}, stack depth: {}", threadId, topElement.getName(), startLine, startStackDepth);
// Do the stepping.
boolean stepping = true;
while (stepping) {
this.handleBreakpointEvent(null);
LOGGER.trace("Single step start: thread: {}, step type: {}", threadId, stepType);
// Do a single step.
this.slapProtocol.step(threadId, stepType, 1).get();
LOGGER.trace("Single step done: thread: {}, step type: {}", threadId, stepType);
// Wait for the STEP_COMPLETED event.
this.waitForStepCompletedEvent();
// A BreakpointEvent disrupts the stepping.
if (this.didReceiveBreakpointEvent()) {
LOGGER.debug("Stop stepping, received breakpoint event");
return;
}
threadStackFuture = this.slapProtocol.getThreadStack(threadId);
threadStack = (ThreadStackResponse) threadStackFuture.get();
topElement = threadStack.getStackFrames().get(0);
final String currentMethod = topElement.getName();
final int currentLine = topElement.getOffset();
final int currentStackDepth = threadStack.getStackFrames().size();
LOGGER.trace("Current state: thread id: {}, top element: {}, line: {}, stack depth: {}", threadId, topElement.getName(), currentLine, currentStackDepth);
// If not, otherwise continue stepping anyway.
if (!topElement.getLanguage().equals(LANGUAGE_MAGIK) || currentMethod.equals(UNKNOWN_EXEMPLAR_UNKNOWN_METHOD)) {
continue;
}
switch(stepType) {
case LINE:
// Continue stepping if:
// - method is the same, and
// - current line not changed
stepping = currentMethod.equals(startMethod) && currentLine == startLine;
break;
case OUT:
// Continue stepping if:
// - stack depth has not decreased
stepping = currentStackDepth > startStackDepth;
break;
case OVER:
// Continue stepping if:
// - method is the same, and
// - current line not changed
stepping = currentMethod.equals(startMethod) && currentLine == startLine;
break;
default:
break;
}
}
// Signal client step is completed.
final StoppedEventArguments args = new StoppedEventArguments();
args.setThreadId((int) threadId);
args.setReason(StoppedEventArgumentsReason.STEP);
this.debugClient.stopped(args);
}
Aggregations