Skip to content

Commit c79d7ff

Browse files
authored
Add auto completions support interface for debug console. (microsoft#168)
1 parent ab4bf73 commit c79d7ff

File tree

7 files changed

+153
-1
lines changed

7 files changed

+153
-1
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public enum ErrorCode {
3030
VM_TERMINATED(1013),
3131
LAUNCH_IN_TERMINAL_FAILURE(1014),
3232
STEP_FAILURE(1015),
33-
RESTARTFRAME_FAILURE(1016);
33+
RESTARTFRAME_FAILURE(1016),
34+
COMPLETIONS_FAILURE(1017);
3435

3536
private int id;
3637

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 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+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core.adapter;
13+
14+
import java.util.List;
15+
16+
import com.microsoft.java.debug.core.protocol.Types.CompletionItem;
17+
import com.sun.jdi.StackFrame;
18+
19+
public interface ICompletionsProvider extends IProvider {
20+
21+
/**
22+
* Complete the code snippet on the target frame.
23+
*
24+
* @param frame
25+
* the target frame that the completions on
26+
* @param snippet
27+
* the code snippet text
28+
* @param line
29+
* the line number of the operation happens inside the snippet
30+
* @param column
31+
* the column number of the operation happens inside the snippet
32+
* @return a list of {@link CompletionItem}
33+
*/
34+
List<CompletionItem> codeComplete(StackFrame frame, String snippet, int line, int column);
35+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2018 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+
* Microsoft Corporation - initial API and implementation
10+
*******************************************************************************/
11+
12+
package com.microsoft.java.debug.core.adapter.handler;
13+
14+
import java.util.Arrays;
15+
import java.util.List;
16+
import java.util.concurrent.CompletableFuture;
17+
import java.util.concurrent.CompletionException;
18+
import java.util.logging.Level;
19+
import java.util.logging.Logger;
20+
21+
import com.microsoft.java.debug.core.Configuration;
22+
import com.microsoft.java.debug.core.adapter.AdapterUtils;
23+
import com.microsoft.java.debug.core.adapter.ErrorCode;
24+
import com.microsoft.java.debug.core.adapter.ICompletionsProvider;
25+
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
26+
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
27+
import com.microsoft.java.debug.core.adapter.variables.StackFrameReference;
28+
import com.microsoft.java.debug.core.protocol.Messages.Response;
29+
import com.microsoft.java.debug.core.protocol.Requests;
30+
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
31+
import com.microsoft.java.debug.core.protocol.Requests.Command;
32+
import com.microsoft.java.debug.core.protocol.Requests.CompletionsArguments;
33+
import com.microsoft.java.debug.core.protocol.Responses;
34+
import com.microsoft.java.debug.core.protocol.Types.CompletionItem;
35+
import com.sun.jdi.IncompatibleThreadStateException;
36+
import com.sun.jdi.ThreadReference;
37+
38+
public class CompletionsHandler implements IDebugRequestHandler {
39+
40+
private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME);
41+
42+
@Override
43+
public List<Command> getTargetCommands() {
44+
return Arrays.asList(Requests.Command.COMPLETIONS);
45+
}
46+
47+
@Override
48+
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
49+
CompletionsArguments completionsArgs = (CompletionsArguments) arguments;
50+
StackFrameReference stackFrameReference = (StackFrameReference) context.getRecyclableIdPool().getObjectById(completionsArgs.frameId);
51+
52+
if (stackFrameReference == null) {
53+
return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.COMPLETIONS_FAILURE,
54+
String.format("Completions: cannot find the stack frame with frameID %s", completionsArgs.frameId));
55+
}
56+
57+
return CompletableFuture.supplyAsync(() -> {
58+
try {
59+
ICompletionsProvider completionsProvider = context.getProvider(ICompletionsProvider.class);
60+
if (completionsProvider != null) {
61+
ThreadReference thread = stackFrameReference.getThread();
62+
63+
List<CompletionItem> res = completionsProvider.codeComplete(thread.frame(stackFrameReference.getDepth()), completionsArgs.text,
64+
completionsArgs.line, completionsArgs.column);
65+
response.body = new Responses.CompletionsResponseBody(res);
66+
}
67+
return response;
68+
} catch (IncompatibleThreadStateException e) {
69+
logger.log(Level.WARNING, String.format("Cannot provide code completions because of %s.", e.toString()), e);
70+
throw new CompletionException(e);
71+
}
72+
});
73+
}
74+
}

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
@@ -50,6 +50,7 @@ public CompletableFuture<Messages.Response> handle(Requests.Command command, Req
5050
caps.supportsConditionalBreakpoints = true;
5151
caps.supportsSetVariable = true;
5252
caps.supportTerminateDebuggee = true;
53+
caps.supportsCompletionsRequest = true;
5354
caps.supportsRestartFrame = true;
5455
Types.ExceptionBreakpointFilter[] exceptionFilters = {
5556
Types.ExceptionBreakpointFilter.UNCAUGHT_EXCEPTION_FILTER,

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ public static class RestartFrameArguments extends Arguments {
263263
public int frameId;
264264
}
265265

266+
public static class CompletionsArguments extends Arguments {
267+
public int frameId;
268+
public String text;
269+
public int line;
270+
public int column;
271+
}
272+
266273
public static enum Command {
267274
INITIALIZE("initialize", InitializeArguments.class),
268275
LAUNCH("launch", LaunchArguments.class),
@@ -285,6 +292,7 @@ public static enum Command {
285292
SETEXCEPTIONBREAKPOINTS("setExceptionBreakpoints", SetExceptionBreakpointsArguments.class),
286293
SETFUNCTIONBREAKPOINTS("setFunctionBreakpoints", SetFunctionBreakpointsArguments.class),
287294
EVALUATE("evaluate", EvaluateArguments.class),
295+
COMPLETIONS("completions", CompletionsArguments.class),
288296
RUNINTERMINAL("runInTerminal", RunInTerminalRequestArguments.class),
289297
REDEFINECLASSES("redefineClasses", RedefineClassesArguments.class),
290298
UNSUPPORTED("", Arguments.class);

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Responses.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,21 @@ public EvaluateResponseBody(String value, int ref, String type, int indexedVaria
172172
}
173173
}
174174

175+
public static class CompletionsResponseBody extends ResponseBody {
176+
public Types.CompletionItem[] targets;
177+
178+
/**
179+
* Constructor.
180+
*/
181+
public CompletionsResponseBody(List<Types.CompletionItem> items) {
182+
if (items == null) {
183+
targets = new Types.CompletionItem[0];
184+
} else {
185+
targets = items.toArray(new Types.CompletionItem[0]);
186+
}
187+
}
188+
}
189+
175190
public static class SetBreakpointsResponseBody extends ResponseBody {
176191
public Types.Breakpoint[] breakpoints;
177192

com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,23 @@ public FunctionBreakpoint(String name) {
190190
}
191191
}
192192

193+
public static class CompletionItem {
194+
public String label;
195+
public String text;
196+
public String type;
197+
198+
public int start;
199+
public int number;
200+
201+
public CompletionItem() {
202+
}
203+
204+
public CompletionItem(String label, String text) {
205+
this.label = label;
206+
this.text = text;
207+
}
208+
}
209+
193210
public static class ExceptionBreakpointFilter {
194211
public static final String UNCAUGHT_EXCEPTION_FILTER_NAME = "uncaught";
195212
public static final String CAUGHT_EXCEPTION_FILTER_NAME = "caught";
@@ -215,6 +232,7 @@ public static class Capabilities {
215232
public boolean supportsHitConditionalBreakpoints;
216233
public boolean supportsConditionalBreakpoints;
217234
public boolean supportsEvaluateForHovers;
235+
public boolean supportsCompletionsRequest;
218236
public boolean supportsRestartFrame;
219237
public boolean supportsSetVariable;
220238
public boolean supportsRestartRequest;

0 commit comments

Comments
 (0)