Skip to content

Commit c471efc

Browse files
gayanpertestforstephen
authored andcommitted
Add support for StepInTarget request
The change implement the StepInTarget request and also update the StepRequestHandler to support StepInTarget as well.
1 parent f5ab690 commit c471efc

File tree

13 files changed

+551
-124
lines changed

13 files changed

+551
-124
lines changed

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.microsoft.java.debug.core.adapter.handler.SetVariableRequestHandler;
4545
import com.microsoft.java.debug.core.adapter.handler.SourceRequestHandler;
4646
import com.microsoft.java.debug.core.adapter.handler.StackTraceRequestHandler;
47+
import com.microsoft.java.debug.core.adapter.handler.StepInTargetsRequestHandler;
4748
import com.microsoft.java.debug.core.adapter.handler.StepRequestHandler;
4849
import com.microsoft.java.debug.core.adapter.handler.ThreadsRequestHandler;
4950
import com.microsoft.java.debug.core.adapter.handler.VariablesRequestHandler;
@@ -131,6 +132,8 @@ private void initialize() {
131132
registerHandlerForDebug(new ProcessIdHandler());
132133
registerHandlerForDebug(new SetFunctionBreakpointsRequestHandler());
133134
registerHandlerForDebug(new BreakpointLocationsRequestHander());
135+
registerHandlerForDebug(new StepInTargetsRequestHandler());
136+
134137
// NO_DEBUG mode only
135138
registerHandlerForNoDebug(new DisconnectRequestWithoutDebuggingHandler());
136139
registerHandlerForNoDebug(new ProcessIdHandler());

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@
1111

1212
package com.microsoft.java.debug.core.adapter;
1313

14+
import java.util.List;
15+
import java.util.Objects;
16+
1417
import com.microsoft.java.debug.core.DebugException;
1518
import com.microsoft.java.debug.core.JavaBreakpointLocation;
1619
import com.microsoft.java.debug.core.protocol.Types.SourceBreakpoint;
1720

21+
import com.sun.jdi.StackFrame;
22+
1823
public interface ISourceLookUpProvider extends IProvider {
1924
boolean supportsRealtimeBreakpointVerification();
2025

@@ -60,4 +65,51 @@ public interface ISourceLookUpProvider extends IProvider {
6065
default String getJavaRuntimeVersion(String projectName) {
6166
return null;
6267
}
68+
69+
/**
70+
* Return method invocation found in the statement as the given line number of
71+
* the source file.
72+
*
73+
* @param stackframe The stack frame where the invocation must be searched.
74+
*
75+
* @return List of found method invocation or empty if not method invocations
76+
* can be found.
77+
*/
78+
List<MethodInvocation> findMethodInvocations(StackFrame stackframe);
79+
80+
public static class MethodInvocation {
81+
public String expression;
82+
public String methodName;
83+
public String methodSignature;
84+
public String declaringTypeName;
85+
public int lineStart;
86+
public int lineEnd;
87+
public int columnStart;
88+
public int columnEnd;
89+
90+
@Override
91+
public int hashCode() {
92+
return Objects.hash(columnEnd, columnStart, declaringTypeName, expression, lineEnd, lineStart, methodName,
93+
methodSignature);
94+
}
95+
96+
@Override
97+
public boolean equals(Object obj) {
98+
if (this == obj) {
99+
return true;
100+
}
101+
if (obj == null) {
102+
return false;
103+
}
104+
if (getClass() != obj.getClass()) {
105+
return false;
106+
}
107+
MethodInvocation other = (MethodInvocation) obj;
108+
return columnEnd == other.columnEnd && columnStart == other.columnStart
109+
&& Objects.equals(declaringTypeName, other.declaringTypeName)
110+
&& Objects.equals(expression, other.expression) && lineEnd == other.lineEnd
111+
&& lineStart == other.lineStart && Objects.equals(methodName, other.methodName)
112+
&& Objects.equals(methodSignature, other.methodSignature);
113+
}
114+
}
63115
}

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public CompletableFuture<Messages.Response> handle(Requests.Command command, Req
6565
caps.supportsFunctionBreakpoints = true;
6666
caps.supportsClipboardContext = true;
6767
caps.supportsBreakpointLocationsRequest = true;
68+
caps.supportsStepInTargetsRequest = true;
6869
response.body = caps;
6970
return CompletableFuture.completedFuture(response);
7071
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2022 Microsoft Corporation and others.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Gayan Perera - initial API and implementation
10+
*******************************************************************************/
11+
package com.microsoft.java.debug.core.adapter.handler;
12+
13+
import java.util.ArrayList;
14+
import java.util.Arrays;
15+
import java.util.Collections;
16+
import java.util.List;
17+
import java.util.Optional;
18+
import java.util.concurrent.CompletableFuture;
19+
20+
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
21+
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
22+
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider;
23+
import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider.MethodInvocation;
24+
import com.microsoft.java.debug.core.adapter.variables.StackFrameReference;
25+
import com.microsoft.java.debug.core.protocol.Messages.Response;
26+
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
27+
import com.microsoft.java.debug.core.protocol.Requests.Command;
28+
import com.microsoft.java.debug.core.protocol.Requests.StepInTargetsArguments;
29+
import com.microsoft.java.debug.core.protocol.Responses.StepInTargetsResponse;
30+
import com.microsoft.java.debug.core.protocol.Types.StepInTarget;
31+
import com.sun.jdi.StackFrame;
32+
33+
public class StepInTargetsRequestHandler implements IDebugRequestHandler {
34+
35+
@Override
36+
public List<Command> getTargetCommands() {
37+
return Arrays.asList(Command.STEPIN_TARGETS);
38+
}
39+
40+
@Override
41+
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response,
42+
IDebugAdapterContext context) {
43+
final StepInTargetsArguments stepInTargetsArguments = (StepInTargetsArguments) arguments;
44+
45+
final int frameId = stepInTargetsArguments.frameId;
46+
return CompletableFuture.supplyAsync(() -> {
47+
response.body = new StepInTargetsResponse(
48+
findFrame(frameId, context).map(f -> findTargets(f.thread().uniqueID(), f, context))
49+
.orElse(Collections.emptyList()).toArray(StepInTarget[]::new));
50+
return response;
51+
});
52+
}
53+
54+
private Optional<StackFrame> findFrame(int frameId, IDebugAdapterContext context) {
55+
Object object = context.getRecyclableIdPool().getObjectById(frameId);
56+
if (object instanceof StackFrameReference) {
57+
return Optional.of(context.getStackFrameManager().getStackFrame((StackFrameReference) object));
58+
}
59+
return Optional.empty();
60+
}
61+
62+
private List<StepInTarget> findTargets(long threadId, StackFrame stackframe, IDebugAdapterContext context) {
63+
ISourceLookUpProvider sourceLookUpProvider = context.getProvider(ISourceLookUpProvider.class);
64+
List<MethodInvocation> invocations = sourceLookUpProvider.findMethodInvocations(stackframe);
65+
if (invocations.isEmpty()) {
66+
return Collections.emptyList();
67+
}
68+
69+
List<StepInTarget> targets = new ArrayList<>(invocations.size());
70+
for (MethodInvocation methodInvocation : invocations) {
71+
int id = context.getRecyclableIdPool().addObject(threadId, methodInvocation);
72+
StepInTarget target = new StepInTarget(id, methodInvocation.expression);
73+
target.column = methodInvocation.columnStart;
74+
target.endColumn = methodInvocation.columnEnd;
75+
target.line = methodInvocation.lineStart;
76+
target.endLine = methodInvocation.lineEnd;
77+
targets.add(target);
78+
}
79+
return targets;
80+
}
81+
}

0 commit comments

Comments
 (0)