Skip to content

Commit

Permalink
Merge branch 'main' into generic_lambda_methods
Browse files Browse the repository at this point in the history
  • Loading branch information
gayanper authored Nov 25, 2023
2 parents b154da4 + b0c70e3 commit 40a89fa
Show file tree
Hide file tree
Showing 27 changed files with 361 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip
2 changes: 1 addition & 1 deletion com.microsoft.java.debug.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.microsoft.java</groupId>
<artifactId>java-debug-parent</artifactId>
<version>0.47.0</version>
<version>0.50.0</version>
</parent>
<artifactId>com.microsoft.java.debug.core</artifactId>
<packaging>jar</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.microsoft.java.debug.core.adapter.handler.InlineValuesRequestHandler;
import com.microsoft.java.debug.core.adapter.handler.LaunchRequestHandler;
import com.microsoft.java.debug.core.adapter.handler.ProcessIdHandler;
import com.microsoft.java.debug.core.adapter.handler.RefreshFramesHandler;
import com.microsoft.java.debug.core.adapter.handler.RefreshVariablesHandler;
import com.microsoft.java.debug.core.adapter.handler.RestartFrameHandler;
import com.microsoft.java.debug.core.adapter.handler.ScopesRequestHandler;
Expand Down Expand Up @@ -101,7 +102,7 @@ public CompletableFuture<Messages.Response> dispatchRequest(Messages.Request req
}
}

private void initialize() {
protected void initialize() {
// Register request handlers.
// When there are multiple handlers registered for the same request, follow the rule "first register, first execute".
registerHandler(new InitializeRequestHandler());
Expand Down Expand Up @@ -133,21 +134,22 @@ private void initialize() {
registerHandlerForDebug(new SetFunctionBreakpointsRequestHandler());
registerHandlerForDebug(new BreakpointLocationsRequestHander());
registerHandlerForDebug(new StepInTargetsRequestHandler());
registerHandlerForDebug(new RefreshFramesHandler());

// NO_DEBUG mode only
registerHandlerForNoDebug(new DisconnectRequestWithoutDebuggingHandler());
registerHandlerForNoDebug(new ProcessIdHandler());
}

private void registerHandlerForDebug(IDebugRequestHandler handler) {
protected void registerHandlerForDebug(IDebugRequestHandler handler) {
registerHandler(requestHandlersForDebug, handler);
}

private void registerHandlerForNoDebug(IDebugRequestHandler handler) {
protected void registerHandlerForNoDebug(IDebugRequestHandler handler) {
registerHandler(requestHandlersForNoDebug, handler);
}

private void registerHandler(IDebugRequestHandler handler) {
protected void registerHandler(IDebugRequestHandler handler) {
registerHandler(requestHandlersForDebug, handler);
registerHandler(requestHandlersForNoDebug, handler);
}
Expand All @@ -163,4 +165,5 @@ private void registerHandler(Map<Command, List<IDebugRequestHandler>> requestHan
handlerList.add(handler);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*******************************************************************************
* Copyright (c) 2023 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*******************************************************************************/

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

import com.microsoft.java.debug.core.protocol.IProtocolServer;

@FunctionalInterface
public interface IDebugAdapterFactory {
public IDebugAdapter create(IProtocolServer server);
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ public ProtocolServer(InputStream input, OutputStream output, IProviderContext c
debugAdapter = new DebugAdapter(this, context);
}

/**
* Constructs a protocol server instance based on the given input stream and output stream.
* @param input
* the input stream
* @param output
* the output stream
* @param debugAdapterFactory
* factory to create debug adapter that implements DAP communication
*/
public ProtocolServer(InputStream input, OutputStream output, IDebugAdapterFactory debugAdapterFactory) {
super(input, output);
debugAdapter = debugAdapterFactory.create(this);
}

/**
* A while-loop to parse input data and send output data constantly.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
Expand All @@ -32,6 +33,8 @@ protected boolean removeEldestEntry(java.util.Map.Entry<Long, Boolean> eldest) {
}
});
private Map<Long, ThreadReference> eventThreads = new ConcurrentHashMap<>();
private Map<Long, Set<String>> decompiledClassesByThread = new HashMap<>();
private Map<Long, String> threadStoppedReasons = new HashMap<>();

public synchronized void resetThreads(List<ThreadReference> threads) {
allThreads.clear();
Expand Down Expand Up @@ -80,6 +83,13 @@ public void addEventThread(ThreadReference thread) {
eventThreads.put(thread.uniqueID(), thread);
}

public void addEventThread(ThreadReference thread, String reason) {
eventThreads.put(thread.uniqueID(), thread);
if (reason != null) {
threadStoppedReasons.put(thread.uniqueID(), reason);
}
}

public void removeEventThread(long threadId) {
eventThreads.remove(threadId);
}
Expand Down Expand Up @@ -113,4 +123,40 @@ public List<ThreadReference> visibleThreads(IDebugAdapterContext context) {

return visibleThreads;
}

public Set<String> getDecompiledClassesByThread(long threadId) {
return decompiledClassesByThread.get(threadId);
}

public void setDecompiledClassesByThread(long threadId, Set<String> decompiledClasses) {
if (decompiledClasses == null || decompiledClasses.isEmpty()) {
decompiledClassesByThread.remove(threadId);
return;
}

decompiledClassesByThread.put(threadId, decompiledClasses);
}

public String getThreadStoppedReason(long threadId) {
return threadStoppedReasons.get(threadId);
}

public void setThreadStoppedReason(long threadId, String reason) {
if (reason == null) {
threadStoppedReasons.remove(threadId);
return;
}

threadStoppedReasons.put(threadId, reason);
}

public void clearThreadStoppedState(long threadId) {
threadStoppedReasons.remove(threadId);
decompiledClassesByThread.remove(threadId);
}

public void clearAllThreadStoppedState() {
threadStoppedReasons.clear();
decompiledClassesByThread.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession,
if (context.isVmStopOnEntry()) {
DebugUtility.stopOnEntry(debugSession, context.getMainClass()).thenAccept(threadId -> {
context.getProtocolServer().sendEvent(new Events.StoppedEvent("entry", threadId));
context.getThreadCache().setThreadStoppedReason(threadId, "entry");
});
}
} else if (event instanceof VMDeathEvent) {
Expand Down Expand Up @@ -117,7 +118,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession,
JdiExceptionReference jdiException = new JdiExceptionReference(((ExceptionEvent) event).exception(),
((ExceptionEvent) event).catchLocation() == null);
context.getExceptionManager().setException(thread.uniqueID(), jdiException);
context.getThreadCache().addEventThread(thread);
context.getThreadCache().addEventThread(thread, "exception");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("exception", thread.uniqueID()));
debugEvent.shouldResume = false;
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*******************************************************************************
* Copyright (c) 2023 Microsoft Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*******************************************************************************/

package com.microsoft.java.debug.core.adapter.handler;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

import com.microsoft.java.debug.core.AsyncJdwpUtils;
import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
import com.microsoft.java.debug.core.adapter.IDebugRequestHandler;
import com.microsoft.java.debug.core.protocol.Events.StoppedEvent;
import com.microsoft.java.debug.core.protocol.Messages.Response;
import com.microsoft.java.debug.core.protocol.Requests.Arguments;
import com.microsoft.java.debug.core.protocol.Requests.Command;
import com.microsoft.java.debug.core.protocol.Requests.RefreshFramesArguments;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ThreadReference;

public class RefreshFramesHandler implements IDebugRequestHandler {

@Override
public List<Command> getTargetCommands() {
return Arrays.asList(Command.REFRESHFRAMES);
}

@Override
public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response,
IDebugAdapterContext context) {
RefreshFramesArguments refreshArgs = (RefreshFramesArguments) arguments;
String[] affectedRootPaths = refreshArgs == null ? null : refreshArgs.affectedRootPaths;
List<Long> pausedThreads = getPausedThreads(context);
for (long threadId : pausedThreads) {
if (affectedRootPaths == null || affectedRootPaths.length == 0) {
refreshFrames(threadId, context);
continue;
}

Set<String> decompiledClasses = context.getThreadCache().getDecompiledClassesByThread(threadId);
if (decompiledClasses == null || decompiledClasses.isEmpty()) {
continue;
}

if (anyInAffectedRootPaths(decompiledClasses, affectedRootPaths)) {
refreshFrames(threadId, context);
}
}

return CompletableFuture.completedFuture(response);
}

List<Long> getPausedThreads(IDebugAdapterContext context) {
List<Long> results = new ArrayList<>();
List<CompletableFuture<Long>> futures = new ArrayList<>();
List<ThreadReference> threads = context.getThreadCache().visibleThreads(context);
for (ThreadReference thread : threads) {
if (context.asyncJDWP()) {
futures.add(AsyncJdwpUtils.supplyAsync(() -> {
try {
if (thread.isSuspended()) {
return thread.uniqueID();
}
} catch (ObjectCollectedException ex) {
// Ignore it if the thread is garbage collected.
}

return -1L;
}));
} else {
try {
if (thread.isSuspended()) {
results.add(thread.uniqueID());
}
} catch (ObjectCollectedException ex) {
// Ignore it if the thread is garbage collected.
}
}
}

List<Long> awaitedResutls = AsyncJdwpUtils.await(futures);
for (Long threadId : awaitedResutls) {
if (threadId > 0) {
results.add(threadId);
}
}

return results;
}

/**
* See https://github.com/microsoft/vscode/issues/188606,
* VS Code doesn't provide a simple way to refetch the stack frames.
* We're going to resend a thread stopped event to trick the client
* into refetching the thread stack frames.
*/
void refreshFrames(long threadId, IDebugAdapterContext context) {
StoppedEvent stoppedEvent = new StoppedEvent(context.getThreadCache().getThreadStoppedReason(threadId), threadId);
stoppedEvent.preserveFocusHint = true;
context.getProtocolServer().sendEvent(stoppedEvent);
}

boolean anyInAffectedRootPaths(Collection<String> classes, String[] affectedRootPaths) {
if (affectedRootPaths == null || affectedRootPaths.length == 0) {
return true;
}

for (String classUri : classes) {
// decompiled class uri is like 'jdt://contents/rt.jar/java.io/PrintStream.class?=1.helloworld/%5C/usr%5C/lib%5C/jvm%5C/
// java-8-oracle%5C/jre%5C/lib%5C/rt.jar%3Cjava.io(PrintStream.class'.
if (classUri.startsWith("jdt://contents/")) {
String jarName = classUri.substring("jdt://contents/".length());
int sep = jarName.indexOf("/");
jarName = sep >= 0 ? jarName.substring(0, sep) : jarName;
for (String affectedRootPath : affectedRootPaths) {
if (affectedRootPath.endsWith("/" + jarName) || affectedRootPath.endsWith("\\" + jarName)) {
return true;
}
}
}
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ private void stepInto(IDebugAdapterContext context, ThreadReference thread) {
// Have to send two events to keep the UI sync with the step in operations:
context.getProtocolServer().sendEvent(new Events.ContinuedEvent(thread.uniqueID()));
context.getProtocolServer().sendEvent(new Events.StoppedEvent("restartframe", thread.uniqueID()));
context.getThreadCache().setThreadStoppedReason(thread.uniqueID(), "restartframe");
});
request.enable();
thread.resume();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ private void registerBreakpointHandler(IDebugAdapterContext context) {
if (resume) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, breakpointName);
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
breakpointName, bpThread.uniqueID()));
}
});
});
} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, breakpointName);
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
breakpointName, bpThread.uniqueID()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ private void registerWatchpointHandler(IDebugAdapterContext context) {
if (resume) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, "data breakpoint");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID()));
}
});
});
} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, "data breakpoint");
context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID()));
}
debugEvent.shouldResume = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,15 @@ private void registerMethodBreakpointHandler(IDebugAdapterContext context) {
if (resume) {
debugEvent.eventSet.resume();
} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, "function breakpoint");
context.getProtocolServer().sendEvent(new Events.StoppedEvent(
"function breakpoint", bpThread.uniqueID()));
}
});
});

} else {
context.getThreadCache().addEventThread(bpThread);
context.getThreadCache().addEventThread(bpThread, "function breakpoint");
context.getProtocolServer()
.sendEvent(new Events.StoppedEvent("function breakpoint", bpThread.uniqueID()));
}
Expand Down
Loading

0 comments on commit 40a89fa

Please sign in to comment.