Search in sources :

Example 1 with ISlapResponse

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);
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) ISlapResponse(nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse) SlapErrorException(nl.ramsolutions.sw.magik.debugadapter.slap.SlapErrorException) SourceBreakpoint(org.eclipse.lsp4j.debug.SourceBreakpoint) Source(org.eclipse.lsp4j.debug.Source) ErrorResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.ErrorResponse) Test(org.junit.jupiter.api.Test)

Example 2 with ISlapResponse

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");
}
Also used : ThreadInfoResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadInfoResponse) ThreadListResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadListResponse) ISlapResponse(nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse) Thread(org.eclipse.lsp4j.debug.Thread) Test(org.junit.jupiter.api.Test)

Example 3 with ISlapResponse

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();
}
Also used : ISlapResponse(nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse) EvalResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.EvalResponse)

Example 4 with ISlapResponse

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");
}
Also used : ISlapResponse(nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse) Scope(org.eclipse.lsp4j.debug.Scope) MagikVariable(nl.ramsolutions.sw.magik.debugadapter.VariableManager.MagikVariable) ArrayList(java.util.ArrayList) StackFrameLocalsResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.StackFrameLocalsResponse) Test(org.junit.jupiter.api.Test)

Example 5 with ISlapResponse

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);
}
Also used : ISlapResponse(nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse) ThreadStackResponse(nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadStackResponse) StoppedEventArguments(org.eclipse.lsp4j.debug.StoppedEventArguments)

Aggregations

ISlapResponse (nl.ramsolutions.sw.magik.debugadapter.slap.ISlapResponse)10 SlapErrorException (nl.ramsolutions.sw.magik.debugadapter.slap.SlapErrorException)5 Test (org.junit.jupiter.api.Test)5 ArrayList (java.util.ArrayList)3 ExecutionException (java.util.concurrent.ExecutionException)3 EvalResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.EvalResponse)3 ThreadStackResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadStackResponse)3 CompletableFuture (java.util.concurrent.CompletableFuture)2 ErrorResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.ErrorResponse)2 SourceFileResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.SourceFileResponse)2 ThreadInfoResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadInfoResponse)2 ThreadListResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.ThreadListResponse)2 Source (org.eclipse.lsp4j.debug.Source)2 SourceBreakpoint (org.eclipse.lsp4j.debug.SourceBreakpoint)2 StackFrame (org.eclipse.lsp4j.debug.StackFrame)2 Thread (org.eclipse.lsp4j.debug.Thread)2 Path (java.nio.file.Path)1 MagikVariable (nl.ramsolutions.sw.magik.debugadapter.VariableManager.MagikVariable)1 BreakpointSetResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.BreakpointSetResponse)1 StackFrameLocalsResponse (nl.ramsolutions.sw.magik.debugadapter.slap.responses.StackFrameLocalsResponse)1