From 2f2b2de96f7aef48b3737f80ce69907a04d8738b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Fri, 19 Jul 2019 12:10:56 +0200 Subject: [PATCH 01/50] make loggers non-static --- .../java/debug/core/DebugSettings.java | 2 +- .../microsoft/java/debug/core/EventHub.java | 2 +- .../java/debug/core/UsageDataSession.java | 23 +++++---- .../debug/core/adapter/BreakpointManager.java | 2 +- .../java/debug/core/adapter/DebugAdapter.java | 2 +- .../debug/core/adapter/ProtocolServer.java | 2 +- .../AbstractDisconnectRequestHandler.java | 2 +- .../handler/AbstractLaunchDelegate.java | 51 +++++++++++++++++++ .../adapter/handler/AttachRequestHandler.java | 2 +- .../ConfigurationDoneRequestHandler.java | 7 ++- .../handler/EvaluateRequestHandler.java | 2 +- .../handler/ExceptionInfoRequestHandler.java | 2 +- .../adapter/handler/LaunchRequestHandler.java | 31 +---------- .../handler/LaunchWithDebuggingDelegate.java | 7 +-- .../LaunchWithoutDebuggingDelegate.java | 7 +-- .../handler/SetBreakpointsRequestHandler.java | 2 +- .../handler/VariablesRequestHandler.java | 2 +- .../core/adapter/variables/VariableUtils.java | 28 +++------- .../core/protocol/AbstractProtocolServer.java | 3 +- 19 files changed, 93 insertions(+), 86 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java index 1c69f88e2..79feedfdc 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java @@ -18,7 +18,7 @@ import com.microsoft.java.debug.core.protocol.JsonUtils; public final class DebugSettings { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private static DebugSettings current = new DebugSettings(); public int maxStringLength = 0; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java index 712ed03ba..034d36fea 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java @@ -31,7 +31,7 @@ import io.reactivex.subjects.PublishSubject; public class EventHub implements IEventHub { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private PublishSubject subject = PublishSubject.create(); @Override diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java index e54727b66..05327b61f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java @@ -28,8 +28,8 @@ import com.sun.jdi.event.Event; public class UsageDataSession { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - private static final Logger usageDataLogger = Logger.getLogger(Configuration.USAGE_DATA_LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger usageDataLogger = Logger.getLogger(Configuration.USAGE_DATA_LOGGER_NAME); private static final long RESPONSE_MAX_DELAY_MS = 1000; private static final ThreadLocal threadLocal = new InheritableThreadLocal<>(); @@ -48,6 +48,10 @@ public static String getSessionGuid() { return threadLocal.get() == null ? "" : threadLocal.get().sessionGuid; } + public static UsageDataSession currentSession() { + return threadLocal.get(); + } + public UsageDataSession() { threadLocal.set(this); } @@ -153,16 +157,13 @@ public void submitUsageData() { /** * Record JDI event. */ - public static void recordEvent(Event event) { + public void recordEvent(Event event) { try { - UsageDataSession currentSession = threadLocal.get(); - if (currentSession != null) { - Map eventEntry = new HashMap<>(); - eventEntry.put("timestamp", String.valueOf(System.currentTimeMillis())); - eventEntry.put("event", event.toString()); - synchronized (currentSession.eventList) { - currentSession.eventList.add(JsonUtils.toJson(eventEntry)); - } + Map eventEntry = new HashMap<>(); + eventEntry.put("timestamp", String.valueOf(System.currentTimeMillis())); + eventEntry.put("event", event.toString()); + synchronized (eventList) { + eventList.add(JsonUtils.toJson(eventEntry)); } } catch (Exception e) { logger.log(Level.SEVERE, String.format("Exception on recording event: %s.", e.toString()), e); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java index 59cacd1d0..e3e1b343a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java @@ -24,7 +24,7 @@ import com.microsoft.java.debug.core.IBreakpoint; public class BreakpointManager { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); /** * A collection of breakpoints registered with this manager. */ diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java index 78f7d5b63..c967726b8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java @@ -47,7 +47,7 @@ import com.microsoft.java.debug.core.protocol.Requests.Command; public class DebugAdapter implements IDebugAdapter { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private IDebugAdapterContext debugContext = null; private Map> requestHandlersForDebug = null; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java index 0526293b9..e9e4d4d7c 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java @@ -29,7 +29,7 @@ import com.sun.jdi.VMDisconnectedException; public class ProtocolServer extends AbstractProtocolServer { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private IDebugAdapter debugAdapter; private UsageDataSession usageDataSession = new UsageDataSession(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java index 3a9653dcd..1f6c0f46b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java @@ -29,7 +29,7 @@ import com.microsoft.java.debug.core.protocol.Requests.Command; public abstract class AbstractDisconnectRequestHandler implements IDebugRequestHandler { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java new file mode 100644 index 000000000..09d109fbc --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java @@ -0,0 +1,51 @@ +/******************************************************************************* +* Copyright (c) 2017 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 com.microsoft.java.debug.core.Configuration; +import com.microsoft.java.debug.core.protocol.Requests; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +abstract class AbstractLaunchDelegate implements ILaunchDelegate { + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + + protected String[] constructEnvironmentVariables(Requests.LaunchArguments launchArguments) { + String[] envVars = null; + if (launchArguments.env != null && !launchArguments.env.isEmpty()) { + Map environment = new HashMap<>(System.getenv()); + List duplicated = new ArrayList<>(); + for (Map.Entry entry : launchArguments.env.entrySet()) { + if (environment.containsKey(entry.getKey())) { + duplicated.add(entry.getKey()); + } + environment.put(entry.getKey(), entry.getValue()); + } + // For duplicated variables, show a warning message. + if (!duplicated.isEmpty()) { + logger.warning(String.format("There are duplicated environment variables. The values specified in launch.json will be used. " + + "Here are the duplicated entries: %s.", String.join(",", duplicated))); + } + + envVars = new String[environment.size()]; + int i = 0; + for (Map.Entry entry : environment.entrySet()) { + envVars[i++] = entry.getKey() + "=" + entry.getValue(); + } + } + return envVars; + } +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java index d9968c3f5..c1a48ec88 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java @@ -41,7 +41,7 @@ import com.sun.jdi.connect.IllegalConnectorArgumentsException; public class AttachRequestHandler implements IDebugRequestHandler { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java index 5e77eff92..85a4e0810 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java @@ -42,7 +42,7 @@ import com.sun.jdi.event.VMStartEvent; public class ConfigurationDoneRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { @@ -120,7 +120,10 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, // record events of important types only, to get rid of noises. if (isImportantEvent) { - UsageDataSession.recordEvent(event); + UsageDataSession session = UsageDataSession.currentSession(); + if (session != null) { + session.recordEvent(event); + } } } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java index 30f98d7a8..35875846d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java @@ -49,7 +49,7 @@ import com.sun.jdi.VoidValue; public class EvaluateRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java index 8052ff745..de6abc90d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java @@ -42,7 +42,7 @@ import com.sun.jdi.Value; public class ExceptionInfoRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java index 31a0a0878..5fc616eba 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java @@ -20,10 +20,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -62,7 +59,7 @@ import com.sun.jdi.event.VMDisconnectEvent; public class LaunchRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; protected ILaunchDelegate activeLaunchHandler; private CompletableFuture waitForDebuggeeConsole = new CompletableFuture<>(); @@ -278,32 +275,6 @@ private static OutputEvent convertToOutputEvent(String message, Category categor return new OutputEvent(category, message); } - protected static String[] constructEnvironmentVariables(LaunchArguments launchArguments) { - String[] envVars = null; - if (launchArguments.env != null && !launchArguments.env.isEmpty()) { - Map environment = new HashMap<>(System.getenv()); - List duplicated = new ArrayList<>(); - for (Entry entry : launchArguments.env.entrySet()) { - if (environment.containsKey(entry.getKey())) { - duplicated.add(entry.getKey()); - } - environment.put(entry.getKey(), entry.getValue()); - } - // For duplicated variables, show a warning message. - if (!duplicated.isEmpty()) { - logger.warning(String.format("There are duplicated environment variables. The values specified in launch.json will be used. " - + "Here are the duplicated entries: %s.", String.join(",", duplicated))); - } - - envVars = new String[environment.size()]; - int i = 0; - for (Entry entry : environment.entrySet()) { - envVars[i++] = entry.getKey() + "=" + entry.getValue(); - } - } - return envVars; - } - public static String parseMainClassWithoutModuleName(String mainClass) { int index = mainClass.indexOf('/'); return mainClass.substring(index + 1); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java index 0f690773a..7b2a65b19 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java @@ -24,7 +24,6 @@ import org.apache.commons.lang3.SystemUtils; import com.google.gson.JsonObject; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.DebugSession; import com.microsoft.java.debug.core.DebugUtility; @@ -52,9 +51,7 @@ import com.sun.jdi.connect.TransportTimeoutException; import com.sun.jdi.connect.VMStartException; -public class LaunchWithDebuggingDelegate implements ILaunchDelegate { - - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); +public class LaunchWithDebuggingDelegate extends AbstractLaunchDelegate { private static final int ATTACH_TERMINAL_TIMEOUT = 20 * 1000; private static final String TERMINAL_TITLE = "Java Debug Console"; protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; @@ -181,7 +178,7 @@ public Process launch(LaunchArguments launchArguments, IDebugAdapterContext cont Arrays.asList(launchArguments.modulePaths), Arrays.asList(launchArguments.classPaths), launchArguments.cwd, - LaunchRequestHandler.constructEnvironmentVariables(launchArguments)); + constructEnvironmentVariables(launchArguments)); context.setDebugSession(debugSession); logger.info("Launching debuggee VM succeeded."); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java index 804ee58ca..0e6e7a401 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java @@ -18,10 +18,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.function.Consumer; -import java.util.logging.Logger; import com.google.gson.JsonObject; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.adapter.ErrorCode; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; @@ -36,8 +34,7 @@ import com.sun.jdi.connect.IllegalConnectorArgumentsException; import com.sun.jdi.connect.VMStartException; -public class LaunchWithoutDebuggingDelegate implements ILaunchDelegate { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); +public class LaunchWithoutDebuggingDelegate extends AbstractLaunchDelegate { protected static final String TERMINAL_TITLE = "Java Process Console"; protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; private Consumer terminateHandler; @@ -54,7 +51,7 @@ public Process launch(LaunchArguments launchArguments, IDebugAdapterContext cont if (launchArguments.cwd != null && Files.isDirectory(Paths.get(launchArguments.cwd))) { workingDir = new File(launchArguments.cwd); } - Process debuggeeProcess = Runtime.getRuntime().exec(cmds, LaunchRequestHandler.constructEnvironmentVariables(launchArguments), + Process debuggeeProcess = Runtime.getRuntime().exec(cmds, constructEnvironmentVariables(launchArguments), workingDir); new Thread() { public void run() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index ca2a002c9..7bb7545b1 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -54,7 +54,7 @@ public class SetBreakpointsRequestHandler implements IDebugRequestHandler { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private BreakpointManager manager = new BreakpointManager(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 45ed9fc34..2eae147a0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -61,7 +61,7 @@ import com.sun.jdi.Value; public class VariablesRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java index 6362d0cee..a6eb356a3 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java @@ -12,13 +12,11 @@ package com.microsoft.java.debug.core.adapter.variables; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.stream.Collectors; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.adapter.formatter.NumericFormatEnum; import com.microsoft.java.debug.core.adapter.formatter.NumericFormatter; @@ -39,8 +37,6 @@ import com.sun.jdi.Value; public abstract class VariableUtils { - private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - /** * Test whether the value has referenced objects. * @@ -82,23 +78,13 @@ public static List listFieldVariables(ObjectReference obj, boolean inc } return res; } + List fields = obj.referenceType().allFields().stream().filter(t -> includeStatic || !t.isStatic()) - .sorted((a, b) -> { - try { - boolean v1isStatic = a.isStatic(); - boolean v2isStatic = b.isStatic(); - if (v1isStatic && !v2isStatic) { - return -1; - } - if (!v1isStatic && v2isStatic) { - return 1; - } - return a.name().compareToIgnoreCase(b.name()); - } catch (Exception e) { - logger.log(Level.SEVERE, String.format("Cannot sort fields: %s", e), e); - return -1; - } - }).collect(Collectors.toList()); + .sorted(Comparator.comparing(Field::isStatic) + .reversed() + .thenComparing(Field::name)) + .collect(Collectors.toList()); + fields.forEach(f -> { Variable var = new Variable(f.name(), obj.getValue(f)); var.field = f; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java index 9bec3c228..7ca187fdc 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java @@ -33,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.protocol.Events.DebugEvent; import io.reactivex.disposables.Disposable; @@ -40,7 +41,7 @@ import io.reactivex.subjects.PublishSubject; public abstract class AbstractProtocolServer implements IProtocolServer { - private static final Logger logger = Logger.getLogger("java-debug"); + private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private static final int BUFFER_SIZE = 4096; private static final String TWO_CRLF = "\r\n\r\n"; private static final Pattern CONTENT_LENGTH_MATCHER = Pattern.compile("Content-Length: (\\d+)"); From 4c35a1f6d371342449406772d007bdb1e901a79f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Fri, 19 Jul 2019 13:36:53 +0200 Subject: [PATCH 02/50] propagate loggers from ProtocolServer --- .../java/debug/core/DebugSession.java | 6 ++-- .../java/debug/core/DebugSettings.java | 11 ++----- .../java/debug/core/DebugUtility.java | 19 +++++++----- .../microsoft/java/debug/core/EventHub.java | 6 +++- .../java/debug/core/UsageDataSession.java | 30 +++++++++++-------- .../debug/core/adapter/BreakpointManager.java | 6 ++-- .../java/debug/core/adapter/DebugAdapter.java | 24 +++++++-------- .../debug/core/adapter/ProtocolServer.java | 18 +++++++---- .../AbstractDisconnectRequestHandler.java | 7 +++-- .../handler/AbstractLaunchDelegate.java | 11 ++++--- .../adapter/handler/AttachRequestHandler.java | 9 ++++-- .../ConfigurationDoneRequestHandler.java | 7 +++-- .../handler/DisconnectRequestHandler.java | 7 +++++ ...connectRequestWithoutDebuggingHandler.java | 7 +++++ .../handler/EvaluateRequestHandler.java | 7 +++-- .../handler/ExceptionInfoRequestHandler.java | 7 +++-- .../adapter/handler/LaunchRequestHandler.java | 12 +++++--- .../handler/LaunchWithDebuggingDelegate.java | 9 ++++-- .../LaunchWithoutDebuggingDelegate.java | 4 ++- .../handler/SetBreakpointsRequestHandler.java | 12 ++++---- .../handler/VariablesRequestHandler.java | 7 +++-- .../core/protocol/AbstractProtocolServer.java | 6 ++-- .../java/debug/core/DebugSessionFactory.java | 4 ++- 23 files changed, 151 insertions(+), 85 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java index 289d36c76..f90fe1708 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; import com.sun.jdi.ThreadReference; import com.sun.jdi.VirtualMachine; @@ -22,10 +23,11 @@ public class DebugSession implements IDebugSession { private VirtualMachine vm; - private EventHub eventHub = new EventHub(); + private EventHub eventHub; - public DebugSession(VirtualMachine virtualMachine) { + public DebugSession(VirtualMachine virtualMachine, Logger logger) { vm = virtualMachine; + eventHub = new EventHub(logger); } @Override diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java index 79feedfdc..b3dfd6f0d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java @@ -11,14 +11,11 @@ package com.microsoft.java.debug.core; -import java.util.logging.Logger; - import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import com.microsoft.java.debug.core.protocol.JsonUtils; public final class DebugSettings { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private static DebugSettings current = new DebugSettings(); public int maxStringLength = 0; @@ -41,12 +38,8 @@ public static DebugSettings getCurrent() { * @param jsonSettings * the new settings represents in json format. */ - public void updateSettings(String jsonSettings) { - try { - current = JsonUtils.fromJson(jsonSettings, DebugSettings.class); - } catch (JsonSyntaxException ex) { - logger.severe(String.format("Invalid json for debugSettings: %s, %s", jsonSettings, ex.getMessage())); - } + public void updateSettings(String jsonSettings) throws JsonSyntaxException { + current = JsonUtils.fromJson(jsonSettings, DebugSettings.class); } private DebugSettings() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java index 4c3275ab6..a921f2960 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; @@ -66,7 +67,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, List modulePaths, List classPaths, String cwd, - String[] envVars) + String[] envVars, + Logger logger) throws IOException, IllegalConnectorArgumentsException, VMStartException { return DebugUtility.launch(vmManager, mainClass, @@ -75,7 +77,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, String.join(File.pathSeparator, modulePaths), String.join(File.pathSeparator, classPaths), cwd, - envVars); + envVars, + logger); } /** @@ -114,7 +117,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, String modulePaths, String classPaths, String cwd, - String[] envVars) + String[] envVars, + Logger logger) throws IOException, IllegalConnectorArgumentsException, VMStartException { List connectors = vmManager.launchingConnectors(); LaunchingConnector connector = connectors.get(0); @@ -176,7 +180,7 @@ public static IDebugSession launch(VirtualMachineManager vmManager, // Without this line, it throws ObjectCollectedException in ExceptionRequest.enable(). // See https://github.com/Microsoft/java-debug/issues/23 vm.version(); - return new DebugSession(vm); + return new DebugSession(vm, logger); } /** @@ -195,7 +199,7 @@ public static IDebugSession launch(VirtualMachineManager vmManager, * @throws IllegalConnectorArgumentsException * when one of the connector arguments is invalid. */ - public static IDebugSession attach(VirtualMachineManager vmManager, String hostName, int port, int attachTimeout) + public static IDebugSession attach(VirtualMachineManager vmManager, String hostName, int port, int attachTimeout, Logger logger) throws IOException, IllegalConnectorArgumentsException { List connectors = vmManager.attachingConnectors(); AttachingConnector connector = connectors.get(0); @@ -211,7 +215,7 @@ public static IDebugSession attach(VirtualMachineManager vmManager, String hostN arguments.get(HOSTNAME).setValue(hostName); arguments.get(PORT).setValue(String.valueOf(port)); arguments.get(TIMEOUT).setValue(String.valueOf(attachTimeout)); - return new DebugSession(connector.attach(arguments)); + return new DebugSession(connector.attach(arguments), logger); } /** @@ -543,8 +547,7 @@ private static List parseArgumentsNonWindows(String args) { * This piece of code is mainly copied from * https://github.com/eclipse/eclipse.platform.debug/blob/master/org.eclipse.debug.core/core/org/eclipse/debug/core/DebugPlugin.java#L1264 * - * @param args - * the command line arguments as a single string. + * @param args the command line arguments as a single string. * @return the individual arguments */ private static List parseArgumentsWindows(String args) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java index 034d36fea..a16f3f667 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/EventHub.java @@ -31,9 +31,13 @@ import io.reactivex.subjects.PublishSubject; public class EventHub implements IEventHub { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger; private PublishSubject subject = PublishSubject.create(); + public EventHub(Logger logger) { + this.logger = logger; + } + @Override public Observable events() { return subject; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java index 05327b61f..f86487d41 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java @@ -1,13 +1,13 @@ /******************************************************************************* -* Copyright (c) 2017 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 -*******************************************************************************/ + * Copyright (c) 2017 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; @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -28,8 +29,8 @@ import com.sun.jdi.event.Event; public class UsageDataSession { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - private final Logger usageDataLogger = Logger.getLogger(Configuration.USAGE_DATA_LOGGER_NAME); + private final Logger logger; + private final Logger usageDataLogger; private static final long RESPONSE_MAX_DELAY_MS = 1000; private static final ThreadLocal threadLocal = new InheritableThreadLocal<>(); @@ -52,7 +53,12 @@ public static UsageDataSession currentSession() { return threadLocal.get(); } - public UsageDataSession() { + /** + * Constructor. + */ + public UsageDataSession(Logger logger, Function loggerFactory) { + this.logger = logger; + this.usageDataLogger = loggerFactory.apply(Configuration.USAGE_DATA_LOGGER_NAME); threadLocal.set(this); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java index e3e1b343a..0a2bc8524 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java @@ -20,11 +20,10 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.IBreakpoint; public class BreakpointManager { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger; /** * A collection of breakpoints registered with this manager. */ @@ -35,7 +34,8 @@ public class BreakpointManager { /** * Constructor. */ - public BreakpointManager() { + public BreakpointManager(Logger logger) { + this.logger = logger; this.breakpoints = Collections.synchronizedList(new ArrayList<>(5)); this.sourceToBreakpoints = new HashMap<>(); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java index c967726b8..7e872054a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java @@ -19,7 +19,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.adapter.handler.AttachRequestHandler; import com.microsoft.java.debug.core.adapter.handler.CompletionsHandler; import com.microsoft.java.debug.core.adapter.handler.ConfigurationDoneRequestHandler; @@ -47,7 +46,7 @@ import com.microsoft.java.debug.core.protocol.Requests.Command; public class DebugAdapter implements IDebugAdapter { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger; private IDebugAdapterContext debugContext = null; private Map> requestHandlersForDebug = null; @@ -56,7 +55,8 @@ public class DebugAdapter implements IDebugAdapter { /** * Constructor. */ - public DebugAdapter(IProtocolServer server, IProviderContext providerContext) { + public DebugAdapter(IProtocolServer server, IProviderContext providerContext, Logger logger) { + this.logger = logger; this.debugContext = new DebugAdapterContext(server, providerContext); requestHandlersForDebug = new HashMap<>(); requestHandlersForNoDebug = new HashMap<>(); @@ -97,29 +97,29 @@ private 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()); - registerHandler(new LaunchRequestHandler()); + registerHandler(new LaunchRequestHandler(logger)); // DEBUG node only - registerHandlerForDebug(new AttachRequestHandler()); - registerHandlerForDebug(new ConfigurationDoneRequestHandler()); - registerHandlerForDebug(new DisconnectRequestHandler()); - registerHandlerForDebug(new SetBreakpointsRequestHandler()); + registerHandlerForDebug(new AttachRequestHandler(logger)); + registerHandlerForDebug(new ConfigurationDoneRequestHandler(logger)); + registerHandlerForDebug(new DisconnectRequestHandler(logger)); + registerHandlerForDebug(new SetBreakpointsRequestHandler(logger)); registerHandlerForDebug(new SetExceptionBreakpointsRequestHandler()); registerHandlerForDebug(new SourceRequestHandler()); registerHandlerForDebug(new ThreadsRequestHandler()); registerHandlerForDebug(new StepRequestHandler()); registerHandlerForDebug(new StackTraceRequestHandler()); registerHandlerForDebug(new ScopesRequestHandler()); - registerHandlerForDebug(new VariablesRequestHandler()); + registerHandlerForDebug(new VariablesRequestHandler(logger)); registerHandlerForDebug(new SetVariableRequestHandler()); - registerHandlerForDebug(new EvaluateRequestHandler()); + registerHandlerForDebug(new EvaluateRequestHandler(logger)); registerHandlerForDebug(new HotCodeReplaceHandler()); registerHandlerForDebug(new RestartFrameHandler()); registerHandlerForDebug(new CompletionsHandler()); - registerHandlerForDebug(new ExceptionInfoRequestHandler()); + registerHandlerForDebug(new ExceptionInfoRequestHandler(logger)); // NO_DEBUG mode only - registerHandlerForNoDebug(new DisconnectRequestWithoutDebuggingHandler()); + registerHandlerForNoDebug(new DisconnectRequestWithoutDebuggingHandler(logger)); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java index e9e4d4d7c..5dec280c7 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java @@ -16,6 +16,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -29,15 +30,23 @@ import com.sun.jdi.VMDisconnectedException; public class ProtocolServer extends AbstractProtocolServer { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - private IDebugAdapter debugAdapter; - private UsageDataSession usageDataSession = new UsageDataSession(); + private UsageDataSession usageDataSession; private Object lock = new Object(); private boolean isDispatchingRequest = false; private ConcurrentLinkedQueue eventQueue = new ConcurrentLinkedQueue<>(); + + /** + * Constructor. + */ + public ProtocolServer(InputStream input, OutputStream output, IProviderContext context, Function loggerFactory) { + super(input, output, loggerFactory.apply(Configuration.LOGGER_NAME)); + debugAdapter = new DebugAdapter(this, context, logger); + usageDataSession = new UsageDataSession(logger, loggerFactory); + } + /** * Constructs a protocol server instance based on the given input stream and output stream. * @param input @@ -48,8 +57,7 @@ public class ProtocolServer extends AbstractProtocolServer { * provider context for a series of provider implementation */ public ProtocolServer(InputStream input, OutputStream output, IProviderContext context) { - super(input, output); - debugAdapter = new DebugAdapter(this, context); + this(input, output, context, Logger::getLogger); } /** diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java index 1f6c0f46b..195a5dd03 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractDisconnectRequestHandler.java @@ -20,7 +20,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.LaunchMode; @@ -29,7 +28,11 @@ import com.microsoft.java.debug.core.protocol.Requests.Command; public abstract class AbstractDisconnectRequestHandler implements IDebugRequestHandler { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger; + + public AbstractDisconnectRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java index 09d109fbc..e35a779ee 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AbstractLaunchDelegate.java @@ -11,17 +11,20 @@ package com.microsoft.java.debug.core.adapter.handler; -import com.microsoft.java.debug.core.Configuration; -import com.microsoft.java.debug.core.protocol.Requests; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Logger; +import com.microsoft.java.debug.core.protocol.Requests; + abstract class AbstractLaunchDelegate implements ILaunchDelegate { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + protected AbstractLaunchDelegate(Logger logger) { + this.logger = logger; + } protected String[] constructEnvironmentVariables(Requests.LaunchArguments launchArguments) { String[] envVars = null; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java index c1a48ec88..296ccbf23 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/AttachRequestHandler.java @@ -20,7 +20,6 @@ import java.util.concurrent.CompletableFuture; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.adapter.AdapterUtils; @@ -41,7 +40,11 @@ import com.sun.jdi.connect.IllegalConnectorArgumentsException; public class AttachRequestHandler implements IDebugRequestHandler { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + private final Logger logger; + + public AttachRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { @@ -61,7 +64,7 @@ public CompletableFuture handle(Command command, Arguments arguments, try { logger.info(String.format("Trying to attach to remote debuggee VM %s:%d .", attachArguments.hostName, attachArguments.port)); IDebugSession debugSession = DebugUtility.attach(vmProvider.getVirtualMachineManager(), attachArguments.hostName, attachArguments.port, - attachArguments.timeout); + attachArguments.timeout, logger); context.setDebugSession(debugSession); logger.info("Attaching to debuggee VM succeeded."); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java index 85a4e0810..37a23b113 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java @@ -16,7 +16,6 @@ import java.util.concurrent.CompletableFuture; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugEvent; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.IDebugSession; @@ -42,7 +41,11 @@ import com.sun.jdi.event.VMStartEvent; public class ConfigurationDoneRequestHandler implements IDebugRequestHandler { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + public ConfigurationDoneRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestHandler.java index 7170e1549..391df6b14 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestHandler.java @@ -11,6 +11,8 @@ package com.microsoft.java.debug.core.adapter.handler; +import java.util.logging.Logger; + import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.protocol.Messages.Response; @@ -18,8 +20,13 @@ import com.microsoft.java.debug.core.protocol.Requests.Command; import com.microsoft.java.debug.core.protocol.Requests.DisconnectArguments; + public class DisconnectRequestHandler extends AbstractDisconnectRequestHandler { + public DisconnectRequestHandler(Logger logger) { + super(logger); + } + @Override public void destroyDebugSession(Command command, Arguments arguments, Response response, IDebugAdapterContext context) { DisconnectArguments disconnectArguments = (DisconnectArguments) arguments; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestWithoutDebuggingHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestWithoutDebuggingHandler.java index bb56d4052..8d33d04bd 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestWithoutDebuggingHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/DisconnectRequestWithoutDebuggingHandler.java @@ -11,14 +11,21 @@ package com.microsoft.java.debug.core.adapter.handler; +import java.util.logging.Logger; + import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; 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.DisconnectArguments; + public class DisconnectRequestWithoutDebuggingHandler extends AbstractDisconnectRequestHandler { + public DisconnectRequestWithoutDebuggingHandler(Logger logger) { + super(logger); + } + @Override public void destroyDebugSession(Command command, Arguments arguments, Response response, IDebugAdapterContext context) { DisconnectArguments disconnectArguments = (DisconnectArguments) arguments; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java index 35875846d..12acbb97e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java @@ -23,7 +23,6 @@ import org.apache.commons.lang3.StringUtils; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.adapter.AdapterUtils; @@ -49,7 +48,11 @@ import com.sun.jdi.VoidValue; public class EvaluateRequestHandler implements IDebugRequestHandler { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + public EvaluateRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java index de6abc90d..645288ae8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ExceptionInfoRequestHandler.java @@ -19,7 +19,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.JdiExceptionReference; import com.microsoft.java.debug.core.adapter.AdapterUtils; @@ -42,7 +41,11 @@ import com.sun.jdi.Value; public class ExceptionInfoRequestHandler implements IDebugRequestHandler { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + public ExceptionInfoRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java index 5fc616eba..56c2c16b7 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java @@ -33,7 +33,6 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.DebugUtility; @@ -59,11 +58,15 @@ import com.sun.jdi.event.VMDisconnectEvent; public class LaunchRequestHandler implements IDebugRequestHandler { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; protected ILaunchDelegate activeLaunchHandler; private CompletableFuture waitForDebuggeeConsole = new CompletableFuture<>(); + public LaunchRequestHandler(Logger logger) { + this.logger = logger; + } + @Override public List getTargetCommands() { return Arrays.asList(Command.LAUNCH); @@ -72,8 +75,9 @@ public List getTargetCommands() { @Override public CompletableFuture handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) { LaunchArguments launchArguments = (LaunchArguments) arguments; - activeLaunchHandler = launchArguments.noDebug ? new LaunchWithoutDebuggingDelegate((daContext) -> handleTerminatedEvent(daContext)) - : new LaunchWithDebuggingDelegate(); + activeLaunchHandler = launchArguments.noDebug + ? new LaunchWithoutDebuggingDelegate(this::handleTerminatedEvent, logger) + : new LaunchWithDebuggingDelegate(logger); return handleLaunchCommand(arguments, response, context); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java index 7b2a65b19..68892aafa 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithDebuggingDelegate.java @@ -56,6 +56,10 @@ public class LaunchWithDebuggingDelegate extends AbstractLaunchDelegate { private static final String TERMINAL_TITLE = "Java Debug Console"; protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; + public LaunchWithDebuggingDelegate(Logger logger) { + super(logger); + } + @Override public CompletableFuture launchInTerminal(LaunchArguments launchArguments, Response response, IDebugAdapterContext context) { CompletableFuture resultFuture = new CompletableFuture<>(); @@ -98,7 +102,7 @@ public CompletableFuture launchInTerminal(LaunchArguments launchArgume if (runResponse.success) { try { VirtualMachine vm = listenConnector.accept(args); - context.setDebugSession(new DebugSession(vm)); + context.setDebugSession(new DebugSession(vm, logger)); logger.info("Launching debuggee in terminal console succeeded."); resultFuture.complete(response); } catch (TransportTimeoutException e) { @@ -178,7 +182,8 @@ public Process launch(LaunchArguments launchArguments, IDebugAdapterContext cont Arrays.asList(launchArguments.modulePaths), Arrays.asList(launchArguments.classPaths), launchArguments.cwd, - constructEnvironmentVariables(launchArguments)); + constructEnvironmentVariables(launchArguments), + logger); context.setDebugSession(debugSession); logger.info("Launching debuggee VM succeeded."); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java index 0e6e7a401..dd096e3f1 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchWithoutDebuggingDelegate.java @@ -18,6 +18,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.function.Consumer; +import java.util.logging.Logger; import com.google.gson.JsonObject; import com.microsoft.java.debug.core.DebugException; @@ -39,7 +40,8 @@ public class LaunchWithoutDebuggingDelegate extends AbstractLaunchDelegate { protected static final long RUNINTERMINAL_TIMEOUT = 10 * 1000; private Consumer terminateHandler; - public LaunchWithoutDebuggingDelegate(Consumer terminateHandler) { + public LaunchWithoutDebuggingDelegate(Consumer terminateHandler, Logger logger) { + super(logger); this.terminateHandler = terminateHandler; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 7bb7545b1..49319ecb8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -21,7 +21,6 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.IBreakpoint; import com.microsoft.java.debug.core.IDebugSession; @@ -53,13 +52,16 @@ import com.sun.jdi.event.StepEvent; public class SetBreakpointsRequestHandler implements IDebugRequestHandler { - - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - - private BreakpointManager manager = new BreakpointManager(); + private final Logger logger; + private final BreakpointManager manager; private boolean registered = false; + public SetBreakpointsRequestHandler(Logger logger) { + this.logger = logger; + this.manager = new BreakpointManager(logger); + } + @Override public List getTargetCommands() { return Arrays.asList(Command.SETBREAKPOINTS); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 2eae147a0..1b1861c29 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -26,7 +26,6 @@ import java.util.logging.Logger; import java.util.stream.Collectors; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.ErrorCode; @@ -61,7 +60,11 @@ import com.sun.jdi.Value; public class VariablesRequestHandler implements IDebugRequestHandler { - protected final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + public VariablesRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java index 7ca187fdc..aa6fc7c69 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java @@ -33,7 +33,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.protocol.Events.DebugEvent; import io.reactivex.disposables.Disposable; @@ -41,7 +40,7 @@ import io.reactivex.subjects.PublishSubject; public abstract class AbstractProtocolServer implements IProtocolServer { - private final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; private static final int BUFFER_SIZE = 4096; private static final String TWO_CRLF = "\r\n\r\n"; private static final Pattern CONTENT_LENGTH_MATCHER = Pattern.compile("Content-Length: (\\d+)"); @@ -68,7 +67,8 @@ public abstract class AbstractProtocolServer implements IProtocolServer { * @param output * the output stream */ - public AbstractProtocolServer(InputStream input, OutputStream output) { + public AbstractProtocolServer(InputStream input, OutputStream output, Logger logger) { + this.logger = logger; this.reader = new BufferedReader(new InputStreamReader(input, PROTOCOL_ENCODING)); this.writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output, PROTOCOL_ENCODING))); this.contentLength = -1; diff --git a/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/DebugSessionFactory.java b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/DebugSessionFactory.java index 9589c9bdc..96156e8bf 100644 --- a/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/DebugSessionFactory.java +++ b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/DebugSessionFactory.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Logger; import org.apache.commons.io.FileUtils; @@ -27,6 +28,7 @@ import com.sun.jdi.event.VMDisconnectEvent; public class DebugSessionFactory { + private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private static final String TEST_ROOT = "../com.microsoft.java.debug.test/project"; private static String rootPath = new File(TEST_ROOT).getAbsolutePath(); private static Set readyForLaunchProjects = new HashSet<>(); @@ -52,7 +54,7 @@ public static IDebugSession getDebugSession(String projectName, String mainClass String projectRoot = new File(rootPath, name).getAbsolutePath(); try { final IDebugSession debugSession = DebugUtility.launch(Bootstrap.virtualMachineManager(), mainClass, "", "", - null, new File(projectRoot, "bin").getAbsolutePath(), null, null); + null, new File(projectRoot, "bin").getAbsolutePath(), null, null, logger); debugSession.getEventHub().events().subscribe(debugEvent -> { if (debugEvent.event instanceof VMDisconnectEvent) { try { From 35367795733b96f3c38868bd8ae5aab70913d04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Mon, 22 Jul 2019 10:14:34 +0200 Subject: [PATCH 03/50] create explicit type for logger factory --- .../java/debug/core/LoggerFactory.java | 19 +++++++++++++++++++ .../java/debug/core/UsageDataSession.java | 5 ++--- .../debug/core/adapter/ProtocolServer.java | 8 ++++---- 3 files changed, 25 insertions(+), 7 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/LoggerFactory.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/LoggerFactory.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/LoggerFactory.java new file mode 100644 index 000000000..8d75df046 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/LoggerFactory.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2017 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; + +import java.util.logging.Logger; + +@FunctionalInterface +public interface LoggerFactory { + Logger create(String name); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java index f86487d41..77c371434 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/UsageDataSession.java @@ -16,7 +16,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; @@ -56,9 +55,9 @@ public static UsageDataSession currentSession() { /** * Constructor. */ - public UsageDataSession(Logger logger, Function loggerFactory) { + public UsageDataSession(Logger logger, LoggerFactory factory) { this.logger = logger; - this.usageDataLogger = loggerFactory.apply(Configuration.USAGE_DATA_LOGGER_NAME); + this.usageDataLogger = factory.create(Configuration.USAGE_DATA_LOGGER_NAME); threadLocal.set(this); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java index 5dec280c7..ac51d1979 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java @@ -16,12 +16,12 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.function.Function; import java.util.logging.Level; import java.util.logging.Logger; import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; +import com.microsoft.java.debug.core.LoggerFactory; import com.microsoft.java.debug.core.UsageDataSession; import com.microsoft.java.debug.core.protocol.AbstractProtocolServer; import com.microsoft.java.debug.core.protocol.Events.DebugEvent; @@ -41,10 +41,10 @@ public class ProtocolServer extends AbstractProtocolServer { /** * Constructor. */ - public ProtocolServer(InputStream input, OutputStream output, IProviderContext context, Function loggerFactory) { - super(input, output, loggerFactory.apply(Configuration.LOGGER_NAME)); + public ProtocolServer(InputStream input, OutputStream output, IProviderContext context, LoggerFactory factory) { + super(input, output, factory.create(Configuration.LOGGER_NAME)); debugAdapter = new DebugAdapter(this, context, logger); - usageDataSession = new UsageDataSession(logger, loggerFactory); + usageDataSession = new UsageDataSession(logger, factory); } /** From 0df2ed694953651cc845f64713fe2978f161d065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=BBarnowski?= Date: Wed, 31 Jul 2019 13:00:48 +0200 Subject: [PATCH 04/50] revert to ignoring case when comparing fields' names --- .../java/debug/core/adapter/variables/VariableUtils.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java index a6eb356a3..e8aac42a4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java @@ -11,6 +11,8 @@ package com.microsoft.java.debug.core.adapter.variables; +import static java.lang.String.CASE_INSENSITIVE_ORDER; + import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -82,7 +84,7 @@ public static List listFieldVariables(ObjectReference obj, boolean inc List fields = obj.referenceType().allFields().stream().filter(t -> includeStatic || !t.isStatic()) .sorted(Comparator.comparing(Field::isStatic) .reversed() - .thenComparing(Field::name)) + .thenComparing(Field::name, CASE_INSENSITIVE_ORDER)) .collect(Collectors.toList()); fields.forEach(f -> { From 0c448122dcf1566110314effe534e9e1a1209ed7 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 14 Jun 2021 11:10:18 +0200 Subject: [PATCH 05/50] Fix logger customization --- .../microsoft/java/debug/core/DebugUtility.java | 15 +++++++++------ .../java/debug/core/adapter/DebugAdapter.java | 6 +++--- .../debug/core/adapter/DebugAdapterContext.java | 7 +++++-- .../handler/InlineValuesRequestHandler.java | 6 +++++- .../handler/SetBreakpointsRequestHandler.java | 4 ++-- .../handler/SetDataBreakpointsRequestHandler.java | 9 ++++++++- 6 files changed, 32 insertions(+), 15 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java index 6645bf85a..641765ee4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugUtility.java @@ -60,7 +60,7 @@ public class DebugUtility { /** * Launch a debuggee in suspend mode. - * @see #launch(VirtualMachineManager, String, String, String, String, String, String, String[]) + * @see #launch(VirtualMachineManager, String, String, String, String, String, String, String[], Logger) */ public static IDebugSession launch(VirtualMachineManager vmManager, String mainClass, @@ -85,7 +85,7 @@ public static IDebugSession launch(VirtualMachineManager vmManager, /** * Launch a debuggee in suspend mode. - * @see #launch(VirtualMachineManager, String, String, String, String, String, String, String[], String) + * @see #launch(VirtualMachineManager, String, String, String, String, String, String, String[], String, Logger) */ public static IDebugSession launch(VirtualMachineManager vmManager, String mainClass, @@ -95,7 +95,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, List classPaths, String cwd, String[] envVars, - String javaExec) + String javaExec, + Logger logger) throws IOException, IllegalConnectorArgumentsException, VMStartException { return DebugUtility.launch(vmManager, mainClass, @@ -105,7 +106,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, String.join(File.pathSeparator, classPaths), cwd, envVars, - javaExec); + javaExec, + logger); } /** @@ -147,7 +149,7 @@ public static IDebugSession launch(VirtualMachineManager vmManager, String[] envVars, Logger logger) throws IOException, IllegalConnectorArgumentsException, VMStartException { - return launch(vmManager, mainClass, programArguments, vmArguments, modulePaths, classPaths, cwd, envVars, null); + return launch(vmManager, mainClass, programArguments, vmArguments, modulePaths, classPaths, cwd, envVars, null, logger); } /** @@ -189,7 +191,8 @@ public static IDebugSession launch(VirtualMachineManager vmManager, String classPaths, String cwd, String[] envVars, - String javaExec) + String javaExec, + Logger logger) throws IOException, IllegalConnectorArgumentsException, VMStartException { List connectors = vmManager.launchingConnectors(); LaunchingConnector connector = connectors.get(0); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java index b258524e9..5bdd5eef7 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java @@ -61,7 +61,7 @@ public class DebugAdapter implements IDebugAdapter { */ public DebugAdapter(IProtocolServer server, IProviderContext providerContext, Logger logger) { this.logger = logger; - this.debugContext = new DebugAdapterContext(server, providerContext); + this.debugContext = new DebugAdapterContext(server, providerContext, logger); requestHandlersForDebug = new HashMap<>(); requestHandlersForNoDebug = new HashMap<>(); initialize(); @@ -122,8 +122,8 @@ private void initialize() { registerHandlerForDebug(new CompletionsHandler()); registerHandlerForDebug(new ExceptionInfoRequestHandler(logger)); registerHandlerForDebug(new DataBreakpointInfoRequestHandler()); - registerHandlerForDebug(new SetDataBreakpointsRequestHandler()); - registerHandlerForDebug(new InlineValuesRequestHandler()); + registerHandlerForDebug(new SetDataBreakpointsRequestHandler(logger)); + registerHandlerForDebug(new InlineValuesRequestHandler(logger)); registerHandlerForDebug(new RefreshVariablesHandler()); // NO_DEBUG mode only diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java index 395d39ec6..a014f04d6 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java @@ -18,6 +18,7 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; +import java.util.logging.Logger; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.IDebugSession; @@ -60,12 +61,14 @@ public class DebugAdapterContext implements IDebugAdapterContext { private IStackFrameManager stackFrameManager = new StackFrameManager(); private IExceptionManager exceptionManager = new ExceptionManager(); - private IBreakpointManager breakpointManager = new BreakpointManager(); + private IBreakpointManager breakpointManager; private IStepResultManager stepResultManager = new StepResultManager(); - public DebugAdapterContext(IProtocolServer server, IProviderContext providerContext) { + public DebugAdapterContext(IProtocolServer server, IProviderContext providerContext, Logger logger) { this.providerContext = providerContext; this.server = server; + this.breakpointManager = new BreakpointManager(logger); + } @Override diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java index e9697f899..3eba54f12 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java @@ -53,7 +53,11 @@ import org.apache.commons.lang3.math.NumberUtils; public class InlineValuesRequestHandler implements IDebugRequestHandler { - protected static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); + protected final Logger logger; + + public InlineValuesRequestHandler(Logger logger) { + this.logger = logger; + } @Override public List getTargetCommands() { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index ac53939c7..29f4b697f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -193,7 +193,7 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { if (expressionBP != null) { CompletableFuture.runAsync(() -> { engine.evaluateForBreakpoint((IEvaluatableBreakpoint) expressionBP, bpThread).whenComplete((value, ex) -> { - boolean resume = handleEvaluationResult(context, bpThread, (IEvaluatableBreakpoint) expressionBP, value, ex); + boolean resume = handleEvaluationResult(context, bpThread, (IEvaluatableBreakpoint) expressionBP, value, ex, logger); // Clear the evaluation environment caused by above evaluation. engine.clearState(bpThread); @@ -217,7 +217,7 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { * Check whether the condition expression is satisfied, and return a boolean value to determine to resume the thread or not. */ public static boolean handleEvaluationResult(IDebugAdapterContext context, ThreadReference bpThread, IEvaluatableBreakpoint breakpoint, - Value value, Throwable ex) { + Value value, Throwable ex, Logger logger) { if (StringUtils.isNotBlank(breakpoint.getLogMessage())) { if (ex != null) { logger.log(Level.SEVERE, String.format("[Logpoint]: %s", ex.getMessage() != null ? ex.getMessage() : ex.toString()), ex); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java index be15852e4..49f69129f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.logging.Logger; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; @@ -43,8 +44,14 @@ import com.sun.jdi.event.WatchpointEvent; public class SetDataBreakpointsRequestHandler implements IDebugRequestHandler { + private final Logger logger; + private boolean registered = false; + public SetDataBreakpointsRequestHandler(Logger logger) { + this.logger = logger; + } + @Override public List getTargetCommands() { return Arrays.asList(Command.SETDATABREAKPOINTS); @@ -144,7 +151,7 @@ private void registerWatchpointHandler(IDebugAdapterContext context) { CompletableFuture.runAsync(() -> { engine.evaluateForBreakpoint((IEvaluatableBreakpoint) watchpoint, bpThread).whenComplete((value, ex) -> { boolean resume = SetBreakpointsRequestHandler.handleEvaluationResult( - context, bpThread, (IEvaluatableBreakpoint) watchpoint, value, ex); + context, bpThread, (IEvaluatableBreakpoint) watchpoint, value, ex, logger); // Clear the evaluation environment caused by above evaluation. engine.clearState(bpThread); From 4a6c57d7a3704d2a95eeb76e75cad0d08b438b21 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 14 Jun 2021 11:22:55 +0200 Subject: [PATCH 06/50] Fix unused imports --- .../core/adapter/handler/InlineValuesRequestHandler.java | 1 - .../java/debug/core/adapter/variables/VariableUtils.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java index 3eba54f12..653210c5f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InlineValuesRequestHandler.java @@ -22,7 +22,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java index 2154c89ac..3d161decc 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableUtils.java @@ -11,15 +11,11 @@ package com.microsoft.java.debug.core.adapter.variables; -import static java.lang.String.CASE_INSENSITIVE_ORDER; - import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import java.util.logging.Level; import java.util.stream.Collectors; import com.microsoft.java.debug.core.DebugSettings; From e3c40cea090ca3a0911e9573c59bce5ab4b096c2 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 15 Jun 2021 13:43:54 +0200 Subject: [PATCH 07/50] Deploy custom java-debug-core --- com.microsoft.java.debug.core/mvnw | 227 +++++++++++++++++++++++++ com.microsoft.java.debug.core/mvnw.cmd | 143 ++++++++++++++++ com.microsoft.java.debug.core/pom.xml | 151 +++++++++++++++- 3 files changed, 513 insertions(+), 8 deletions(-) create mode 100755 com.microsoft.java.debug.core/mvnw create mode 100644 com.microsoft.java.debug.core/mvnw.cmd diff --git a/com.microsoft.java.debug.core/mvnw b/com.microsoft.java.debug.core/mvnw new file mode 100755 index 000000000..e96ccd5fb --- /dev/null +++ b/com.microsoft.java.debug.core/mvnw @@ -0,0 +1,227 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/com.microsoft.java.debug.core/mvnw.cmd b/com.microsoft.java.debug.core/mvnw.cmd new file mode 100644 index 000000000..019bd74d7 --- /dev/null +++ b/com.microsoft.java.debug.core/mvnw.cmd @@ -0,0 +1,143 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 5b6f0c2c3..00e2a1d9d 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -2,16 +2,47 @@ 4.0.0 - - com.microsoft.java - java-debug-parent - 0.32.0 - - com.microsoft.java.debug.core - jar + ch.epfl.scala + com-microsoft-java-debug-core ${base.name} :: Debugger Core + The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. + https://github.com/Microsoft/java-debug + 0.32.0+1-SNAPSHOT + jar + Java Debug Server for Visual Studio Code + UTF-8 + ${basedir}/../ + + + + Eclipse Public License 1.0 + https://github.com/Microsoft/java-debug/blob/master/LICENSE.txt + repo + + + + + + adpi2 + Adrien Piquerez + adrien.piquerez@gmail.com + "https://github.com/adpi2/" + + + + + ch.epfl.scaal + https://scala.epfl.ch/ + + + + scm:git:git://github.com/scalacenter/java-debug.git + scm:git:ssh://github.com:scalacenter/java-debug.git + https://github.com/scalacenter/java-debug/tree/main + + target target/classes @@ -22,6 +53,26 @@ org.apache.maven.plugins maven-failsafe-plugin + 2.15 + + + + integration-tests + + integration-test + verify + + + + ${failsafeArgLine} + + ${skip.integration.tests} + + + org.apache.maven.plugins @@ -35,6 +86,34 @@ org.apache.maven.plugins maven-checkstyle-plugin + 3.1.0 + + + com.puppycrawl.tools + checkstyle + 8.29 + + + com.github.sevntu-checkstyle + sevntu-checkstyle-maven-plugin + 1.24.1 + + + + ${checkstyleDir}/check_style.xml + true + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + true + @@ -79,7 +158,7 @@ - + default-tools.jar (,9) @@ -94,5 +173,61 @@ + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.0.1 + + + attach-javadocs + + jar + + + + + none + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + From cb56e1b44be0a878ba6be89ea72d57b9decf0dcc Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 23 Sep 2021 12:56:29 +0800 Subject: [PATCH 08/50] Bump version to 0.33.0 (#386) --- ThirdPartyNotices.txt | 437 ++++++++++++++++++ com.microsoft.java.debug.core/.classpath | 2 +- com.microsoft.java.debug.core/pom.xml | 9 +- .../debug/core/adapter/ProcessConsole.java | 2 +- .../adapter/handler/CompletionsHandler.java | 4 +- .../handler/EvaluateRequestHandler.java | 48 +- .../adapter/handler/LaunchRequestHandler.java | 17 +- .../core/adapter/handler/LaunchUtils.java | 4 +- .../adapter/handler/StepRequestHandler.java | 14 +- .../handler/VariablesRequestHandler.java | 64 ++- com.microsoft.java.debug.plugin/.classpath | 11 +- .../META-INF/MANIFEST.MF | 8 +- com.microsoft.java.debug.plugin/pom.xml | 17 +- .../internal/JdtSourceLookUpProvider.java | 13 +- .../internal/ResolveMainClassHandler.java | 137 +++++- .../internal/ResolveMainMethodHandler.java | 5 +- .../category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- java.debug.target | 15 +- pom.xml | 8 +- 20 files changed, 717 insertions(+), 102 deletions(-) create mode 100644 ThirdPartyNotices.txt diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt new file mode 100644 index 000000000..b9fc26420 --- /dev/null +++ b/ThirdPartyNotices.txt @@ -0,0 +1,437 @@ +java-debug + +THIRD-PARTY SOFTWARE NOTICES AND INFORMATION +Do Not Translate or Localize + +This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. + +1. ReactiveX/RxJava (https://github.com/ReactiveX/RxJava) +2. reactive-streams/reactive-streams-jvm (https://github.com/reactive-streams/reactive-streams-jvm) +3. apache/commons-io (https://github.com/apache/commons-io) + + +%% ReactiveX/RxJava NOTICES AND INFORMATION BEGIN HERE +========================================= + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +========================================= +END OF ReactiveX/RxJava NOTICES AND INFORMATION + +%% reactive-streams/reactive-streams-jvm NOTICES AND INFORMATION BEGIN HERE +========================================= +MIT No Attribution + +Copyright 2014 Reactive Streams + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +========================================= +END OF reactive-streams/reactive-streams-jvm NOTICES AND INFORMATION + +%% apache/commons-io NOTICES AND INFORMATION BEGIN HERE +========================================= + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +========================================= +END OF apache/commons-io NOTICES AND INFORMATION \ No newline at end of file diff --git a/com.microsoft.java.debug.core/.classpath b/com.microsoft.java.debug.core/.classpath index f0257c5a5..9ba41a249 100644 --- a/com.microsoft.java.debug.core/.classpath +++ b/com.microsoft.java.debug.core/.classpath @@ -13,7 +13,7 @@ - + diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 00e2a1d9d..e0e46a048 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -4,6 +4,7 @@ 4.0.0 ch.epfl.scala com-microsoft-java-debug-core + jar ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug @@ -79,8 +80,8 @@ maven-compiler-plugin 3.7.0 - 1.8 - 1.8 + 11 + 11 @@ -126,7 +127,7 @@ com.google.code.gson gson - 2.7 + 2.8.9 io.reactivex.rxjava2 @@ -141,7 +142,7 @@ commons-io commons-io - 2.5 + 2.10.0 diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java index 6b384c628..3d823df91 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java @@ -129,7 +129,7 @@ public void stop() { } private void monitor(InputStream input, PublishSubject subject) { - BufferedReader reader = new BufferedReader(new InputStreamReader(input, encoding)); + BufferedReader reader = new BufferedReader(encoding == null ? new InputStreamReader(input) : new InputStreamReader(input, encoding)); final int BUFFERSIZE = 4096; char[] buffer = new char[BUFFERSIZE]; while (true) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java index 9f660644a..eba7d5153 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java @@ -11,8 +11,8 @@ package com.microsoft.java.debug.core.adapter.handler; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -46,7 +46,7 @@ public CompletableFuture handle(Command command, Arguments arguments, // completions should be illegal when frameId is zero, it is sent when the program is running, while during running we cannot resolve // the completion candidates if (completionsArgs.frameId == 0) { - response.body = new ArrayList<>(); + response.body = new Responses.CompletionsResponseBody(Collections.emptyList()); return CompletableFuture.completedFuture(response); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java index be78bac64..bd0930931 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2017-2020 Microsoft Corporation and others. +* Copyright (c) 2017-2021 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 @@ -14,7 +14,6 @@ import java.util.Arrays; import java.util.List; import java.util.Map; -import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; @@ -106,10 +105,8 @@ public CompletableFuture handle(Command command, Arguments arguments, indexedVariables = ((IntegerValue) sizeValue).value(); } } - } catch (CancellationException | IllegalArgumentException | InterruptedException - | ExecutionException | UnsupportedOperationException e) { - logger.log(Level.INFO, - String.format("Failed to get the logical size for the type %s.", value.type().name()), e); + } catch (Exception e) { + logger.log(Level.INFO, "Failed to get the logical size of the variable", e); } } int referenceId = 0; @@ -117,20 +114,49 @@ public CompletableFuture handle(Command command, Arguments arguments, referenceId = context.getRecyclableIdPool().addObject(threadId, varProxy); } - String valueString = variableFormatter.valueToString(value, options); + boolean hasErrors = false; + String valueString = null; + try { + valueString = variableFormatter.valueToString(value, options); + } catch (OutOfMemoryError e) { + hasErrors = true; + logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e); + valueString = ""; + } catch (Exception e) { + hasErrors = true; + logger.log(Level.SEVERE, "Failed to resolve the variable value", e); + valueString = ""; + } + String detailsString = null; - if (sizeValue != null) { + if (hasErrors) { + // If failed to resolve the variable value, skip the details info as well. + } else if (sizeValue != null) { detailsString = "size=" + variableFormatter.valueToString(sizeValue, options); } else if (DebugSettings.getCurrent().showToString) { - detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine); + try { + detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine); + } catch (OutOfMemoryError e) { + logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e); + detailsString = ""; + } catch (Exception e) { + logger.log(Level.SEVERE, "Failed to compute the toString() value", e); + detailsString = ""; + } } if ("clipboard".equals(evalArguments.context) && detailsString != null) { response.body = new Responses.EvaluateResponseBody(detailsString, -1, "String", 0); } else { + String typeString = ""; + try { + typeString = variableFormatter.typeToString(value == null ? null : value.type(), options); + } catch (Exception e) { + logger.log(Level.SEVERE, "Failed to resolve the variable type", e); + typeString = ""; + } response.body = new Responses.EvaluateResponseBody((detailsString == null) ? valueString : valueString + " " + detailsString, - referenceId, variableFormatter.typeToString(value == null ? null : value.type(), options), - Math.max(indexedVariables, 0)); + referenceId, typeString, Math.max(indexedVariables, 0)); } return response; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java index c5f6bd611..17b93284f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java @@ -16,7 +16,6 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -91,23 +90,21 @@ protected CompletableFuture handleLaunchCommand(Arguments arguments, R "Failed to launch debuggee VM. Missing mainClass or modulePaths/classPaths options in launch configuration.", ErrorCode.ARGUMENT_MISSING); } - if (StringUtils.isBlank(launchArguments.encoding)) { - context.setDebuggeeEncoding(StandardCharsets.UTF_8); - } else { + if (StringUtils.isNotBlank(launchArguments.encoding)) { if (!Charset.isSupported(launchArguments.encoding)) { throw AdapterUtils.createCompletionException( "Failed to launch debuggee VM. 'encoding' options in the launch configuration is not recognized.", ErrorCode.INVALID_ENCODING); } context.setDebuggeeEncoding(Charset.forName(launchArguments.encoding)); + if (StringUtils.isBlank(launchArguments.vmArgs)) { + launchArguments.vmArgs = String.format("-Dfile.encoding=%s", context.getDebuggeeEncoding().name()); + } else { + // if vmArgs already has the file.encoding settings, duplicate options for jvm will not cause an error, the right most value wins + launchArguments.vmArgs = String.format("%s -Dfile.encoding=%s", launchArguments.vmArgs, context.getDebuggeeEncoding().name()); + } } - if (StringUtils.isBlank(launchArguments.vmArgs)) { - launchArguments.vmArgs = String.format("-Dfile.encoding=%s", context.getDebuggeeEncoding().name()); - } else { - // if vmArgs already has the file.encoding settings, duplicate options for jvm will not cause an error, the right most value wins - launchArguments.vmArgs = String.format("%s -Dfile.encoding=%s", launchArguments.vmArgs, context.getDebuggeeEncoding().name()); - } context.setLaunchMode(launchArguments.noDebug ? LaunchMode.NO_DEBUG : LaunchMode.DEBUG); activeLaunchHandler.preLaunch(launchArguments, context); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java index 17a4f7359..d0d99af40 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java @@ -73,11 +73,11 @@ public static synchronized Path generateClasspathJar(String[] classPaths) throws public static synchronized Path generateArgfile(String[] classPaths, String[] modulePaths) throws IOException { String argfile = ""; if (ArrayUtils.isNotEmpty(classPaths)) { - argfile = "-classpath \"" + String.join(File.pathSeparator, classPaths) + "\""; + argfile = "-cp \"" + String.join(File.pathSeparator, classPaths) + "\""; } if (ArrayUtils.isNotEmpty(modulePaths)) { - argfile = " --module-path \"" + String.join(File.pathSeparator, modulePaths) + "\""; + argfile += " --module-path \"" + String.join(File.pathSeparator, modulePaths) + "\""; } argfile = argfile.replace("\\", "\\\\"); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 94e0d3078..72d14eb5d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -145,12 +145,14 @@ public CompletableFuture handle(Command command, Arguments arguments, private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, IDebugAdapterContext context, ThreadState threadState) { Event event = debugEvent.event; + EventRequestManager eventRequestManager = debugSession.getVM().eventRequestManager(); // When a breakpoint occurs, abort any pending step requests from the same thread. if (event instanceof BreakpointEvent || event instanceof ExceptionEvent) { long threadId = ((LocatableEvent) event).thread().uniqueID(); if (threadId == threadState.threadId && threadState.pendingStepRequest != null) { - threadState.deleteStepRequests(debugSession.getVM().eventRequestManager()); + threadState.deleteStepRequest(eventRequestManager); + threadState.deleteMethodExitRequest(eventRequestManager); context.getStepResultManager().removeMethodResult(threadId); if (threadState.eventSubscription != null) { threadState.eventSubscription.dispose(); @@ -158,7 +160,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } } else if (event instanceof StepEvent) { ThreadReference thread = ((StepEvent) event).thread(); - threadState.deleteStepRequests(debugSession.getVM().eventRequestManager()); + threadState.deleteStepRequest(eventRequestManager); if (isStepFiltersConfigured(context.getStepFilters())) { try { if (threadState.pendingStepType == Command.STEPIN) { @@ -181,6 +183,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, // ignore. } } + threadState.deleteMethodExitRequest(eventRequestManager); if (threadState.eventSubscription != null) { threadState.eventSubscription.dispose(); } @@ -280,10 +283,13 @@ class ThreadState { Location stepLocation = null; Disposable eventSubscription = null; - public void deleteStepRequests(EventRequestManager manager) { - DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); + public void deleteMethodExitRequest(EventRequestManager manager) { DebugUtility.deleteEventRequestSafely(manager, this.pendingMethodExitRequest); this.pendingMethodExitRequest = null; + } + + public void deleteStepRequest(EventRequestManager manager) { + DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); this.pendingStepRequest = null; } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 98451bc81..d6f9f1ca4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2017-2020 Microsoft Corporation and others. +* Copyright (c) 2017-2021 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 @@ -19,9 +19,7 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -136,7 +134,12 @@ public CompletableFuture handle(Command command, Arguments arguments, try { ObjectReference containerObj = (ObjectReference) containerNode.getProxiedVariable(); if (DebugSettings.getCurrent().showLogicalStructure && evaluationEngine != null) { - JavaLogicalStructure logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj); + JavaLogicalStructure logicalStructure = null; + try { + logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj); + } catch (Exception e) { + logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e); + } if (isUnboundedTypeContainer && logicalStructure != null && containerEvaluateName != null) { containerEvaluateName = "((" + logicalStructure.getFullyQualifiedName() + ")" + containerEvaluateName + ")"; isUnboundedTypeContainer = false; @@ -165,11 +168,8 @@ public CompletableFuture handle(Command command, Arguments arguments, childrenList.add(variable); } } - } catch (IllegalArgumentException | CancellationException | InterruptedException | ExecutionException e) { - logger.log(Level.WARNING, - String.format("Failed to get the logical structure for the type %s, fall back to the Object view.", - containerObj.type().name()), - e); + } catch (Exception e) { + logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e); } logicalStructure = null; @@ -244,9 +244,8 @@ public CompletableFuture handle(Command command, Arguments arguments, indexedVariables = ((IntegerValue) sizeValue).value(); } } - } catch (CancellationException | IllegalArgumentException | InterruptedException | ExecutionException | UnsupportedOperationException e) { - logger.log(Level.INFO, - String.format("Failed to get the logical size for the type %s.", value.type().name()), e); + } catch (Exception e) { + logger.log(Level.INFO, "Failed to get the logical size of the variable", e); } } @@ -278,15 +277,46 @@ public CompletableFuture handle(Command command, Arguments arguments, varProxy.setUnboundedType(javaVariable.isUnboundedType()); } - Types.Variable typedVariables = new Types.Variable(name, variableFormatter.valueToString(value, options), - variableFormatter.typeToString(value == null ? null : value.type(), options), - referenceId, evaluateName); + boolean hasErrors = false; + String valueString = null; + try { + valueString = variableFormatter.valueToString(value, options); + } catch (OutOfMemoryError e) { + hasErrors = true; + logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e); + valueString = ""; + } catch (Exception e) { + hasErrors = true; + logger.log(Level.SEVERE, "Failed to resolve the variable value", e); + valueString = ""; + } + + String typeString = ""; + try { + typeString = variableFormatter.typeToString(value == null ? null : value.type(), options); + } catch (Exception e) { + logger.log(Level.SEVERE, "Failed to resolve the variable type", e); + typeString = ""; + } + + Types.Variable typedVariables = new Types.Variable(name, valueString, typeString, referenceId, evaluateName); typedVariables.indexedVariables = Math.max(indexedVariables, 0); + String detailsValue = null; - if (sizeValue != null) { + if (hasErrors) { + // If failed to resolve the variable value, skip the details info as well. + } else if (sizeValue != null) { detailsValue = "size=" + variableFormatter.valueToString(sizeValue, options); } else if (DebugSettings.getCurrent().showToString) { - detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine); + try { + detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine); + } catch (OutOfMemoryError e) { + logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e); + detailsValue = ""; + } catch (Exception e) { + logger.log(Level.SEVERE, "Failed to compute the toString() value", e); + detailsValue = ""; + } } if (detailsValue != null) { diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 8c76f8dd3..de236212a 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -1,11 +1,16 @@ - + + + + + + - + - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 2245a3854..1c0eaf78c 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,8 +2,8 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.32.0 -Bundle-RequiredExecutionEnvironment: JavaSE-1.8 +Bundle-Version: 0.35.0 +Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin Bundle-Vendor: Microsoft @@ -21,8 +21,8 @@ Require-Bundle: org.eclipse.core.runtime, org.apache.commons.lang3, org.eclipse.lsp4j, com.google.guava -Bundle-ClassPath: lib/commons-io-2.5.jar, +Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com.microsoft.java.debug.core-0.32.0.jar + lib/com.microsoft.java.debug.core-0.35.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index f5e0003e3..ffc3ded41 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.32.0 + 0.35.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -17,6 +17,17 @@ tycho-maven-plugin ${tycho-version} true + + + org.eclipse.tycho + tycho-compiler-plugin + ${tycho-version} + + + --limit-modules + java.base,java.logging,java.xml,jdk.jdi,java.compiler + + org.apache.maven.plugins @@ -40,12 +51,12 @@ commons-io commons-io - 2.5 + 2.10.0 com.microsoft.java com.microsoft.java.debug.core - 0.32.0 + 0.35.0 diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index d24d2abdd..efc7ce20c 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017-2020 Microsoft Corporation and others. + * Copyright (c) 2017-2021 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 @@ -17,7 +17,6 @@ import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; @@ -120,11 +119,7 @@ public String[] getFullyQualifiedName(String uri, int[] lines, int[] columns) th String filePath = AdapterUtils.toPath(uri); // For file uri, read the file contents directly and pass them to the ast parser. if (filePath != null && Files.isRegularFile(Paths.get(filePath))) { - Charset cs = (Charset) this.options.get(Constants.DEBUGGEE_ENCODING); - if (cs == null) { - cs = Charset.defaultCharset(); - } - String source = readFile(filePath, cs); + String source = readFile(filePath); parser.setSource(source.toCharArray()); /** * See the java doc for { @link ASTParser#setResolveBindings(boolean) }. @@ -293,10 +288,10 @@ private static IClassFile resolveClassFile(String uriString) { return null; } - private static String readFile(String filePath, Charset cs) { + private static String readFile(String filePath) { StringBuilder builder = new StringBuilder(); try (BufferedReader bufferReader = - new BufferedReader(new InputStreamReader(new FileInputStream(filePath), cs))) { + new BufferedReader(new InputStreamReader(new FileInputStream(filePath)))) { final int BUFFER_SIZE = 4096; char[] buffer = new char[BUFFER_SIZE]; while (true) { diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java index 9d3b1014e..f70d0c044 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017 Microsoft Corporation and others. + * Copyright (c) 2017-2022 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 @@ -12,6 +12,7 @@ package com.microsoft.java.debug.plugin.internal; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -21,6 +22,9 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.lang.model.SourceVersion; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.IFile; @@ -47,8 +51,10 @@ public class ResolveMainClassHandler { private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - // Java command line supports two kinds of main class format: and [/] - private static final String CLASSNAME_REGX = "([$\\w]+\\.)*[$\\w]+(/([$\\w]+\\.)*[$\\w]+)?"; + private static final int CONFIGERROR_INVALID_CLASS_NAME = 1; + private static final int CONFIGERROR_MAIN_CLASS_NOT_EXIST = 2; + private static final int CONFIGERROR_MAIN_CLASS_NOT_UNIQUE = 3; + private static final int CONFIGERROR_INVALID_JAVA_PROJECT = 4; /** * resolve main class and project name. @@ -75,15 +81,26 @@ public Object validateLaunchConfig(List arguments) throws Exception { } private List resolveMainClassCore(List arguments) { - IPath rootPath = null; if (arguments != null && arguments.size() > 0 && arguments.get(0) != null) { - rootPath = ResourceUtils.filePathFromURI((String) arguments.get(0)); - } - final ArrayList targetProjectPath = new ArrayList<>(); - if (rootPath != null) { - targetProjectPath.add(rootPath); + String argument = (String) arguments.get(0); + IProject[] projects = ProjectUtils.getAllProjects(); + if (Stream.of(projects).anyMatch(project -> Objects.equals(project.getName(), argument))) { + return resolveMainClassUnderProject(argument); + } + + IPath rootPath = ResourceUtils.filePathFromURI(argument); + if (rootPath != null) { + return resolveMainClassUnderPaths(Arrays.asList(rootPath)); + } } - IJavaSearchScope searchScope = SearchEngine.createWorkspaceScope(); + + return resolveMainClassUnderPaths(Collections.emptyList()); + } + + private List resolveMainClassUnderPaths(List parentPaths) { + // Limit to search main method from source code only. + IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(ProjectUtils.getJavaProjects(), + IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); final List res = new ArrayList<>(); @@ -108,10 +125,9 @@ public void acceptSearchMatch(SearchMatch match) { } } String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName(); - if (projectName == null - || targetProjectPath.isEmpty() - || ResourceUtils.isContainedIn(project.getLocation(), targetProjectPath) - || isContainedInInvisibleProject(project, targetProjectPath)) { + if (parentPaths.isEmpty() + || ResourceUtils.isContainedIn(project.getLocation(), parentPaths) + || isContainedInInvisibleProject(project, parentPaths)) { String filePath = null; if (match.getResource() instanceof IFile) { @@ -145,6 +161,66 @@ public void acceptSearchMatch(SearchMatch match) { return resolutions; } + private List resolveMainClassUnderProject(final String projectName) { + // Limit to search main method from source code only. + IJavaProject javaProject = ProjectUtils.getJavaProject(projectName); + IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(javaProject == null ? new IJavaProject[0] : new IJavaProject[] {javaProject}, + IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); + SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, + IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + final List res = new ArrayList<>(); + SearchRequestor requestor = new SearchRequestor() { + @Override + public void acceptSearchMatch(SearchMatch match) { + Object element = match.getElement(); + if (element instanceof IMethod) { + IMethod method = (IMethod) element; + try { + if (method.isMainMethod()) { + IResource resource = method.getResource(); + if (resource != null) { + IProject project = resource.getProject(); + if (project != null) { + String mainClass = method.getDeclaringType().getFullyQualifiedName(); + IJavaProject javaProject = JdtUtils.getJavaProject(project); + if (javaProject != null) { + String moduleName = JdtUtils.getModuleName(javaProject); + if (moduleName != null) { + mainClass = moduleName + "/" + mainClass; + } + } + + String filePath = null; + if (match.getResource() instanceof IFile) { + try { + filePath = match.getResource().getLocation().toOSString(); + } catch (Exception ex) { + // ignore + } + } + res.add(new ResolutionItem(mainClass, projectName, filePath)); + } + } + } + } catch (JavaModelException e) { + // ignore + } + } + } + }; + SearchEngine searchEngine = new SearchEngine(); + try { + searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, + searchScope, requestor, null /* progress monitor */); + } catch (Exception e) { + logger.log(Level.SEVERE, String.format("Searching the main class failure: %s", e.toString()), e); + } + + List resolutions = res.stream().distinct().collect(Collectors.toList()); + Collections.sort(resolutions); + return resolutions; + } + private boolean isContainedInInvisibleProject(IProject project, Collection rootPaths) { if (project == null) { return false; @@ -185,23 +261,41 @@ private ValidationResponse validateLaunchConfigCore(List arguments) thro private ValidationResult validateMainClass(final String mainClass, final String projectName, boolean containsExternalClasspaths) throws CoreException { if (StringUtils.isEmpty(mainClass)) { return new ValidationResult(true); - } else if (!mainClass.matches(CLASSNAME_REGX)) { - return new ValidationResult(false, String.format("ConfigError: '%s' is not a valid class name.", mainClass)); + } else if (!isValidMainClassName(mainClass)) { + return new ValidationResult(false, String.format("ConfigError: '%s' is not a valid class name.", mainClass), + CONFIGERROR_INVALID_CLASS_NAME); } if (!containsExternalClasspaths && StringUtils.isEmpty(projectName)) { List javaProjects = searchClassInProjectClasspaths(mainClass); if (javaProjects.size() == 0) { - return new ValidationResult(false, String.format("ConfigError: Main class '%s' doesn't exist in the workspace.", mainClass)); + return new ValidationResult(false, String.format("ConfigError: Main class '%s' doesn't exist in the workspace.", mainClass), + CONFIGERROR_MAIN_CLASS_NOT_EXIST); } if (javaProjects.size() > 1) { - return new ValidationResult(false, String.format("ConfigError: Main class '%s' isn't unique in the workspace.", mainClass)); + return new ValidationResult(false, String.format("ConfigError: Main class '%s' isn't unique in the workspace.", mainClass), + CONFIGERROR_MAIN_CLASS_NOT_UNIQUE); } } return new ValidationResult(true); } + // Java command line supports two kinds of main class format: and [/] + private boolean isValidMainClassName(String mainClass) { + if (StringUtils.isEmpty(mainClass)) { + return true; + } + + int index = mainClass.indexOf('/'); + if (index == -1) { + return SourceVersion.isName(mainClass); + } + + return SourceVersion.isName(mainClass.substring(0, index)) + && SourceVersion.isName(mainClass.substring(index + 1)); + } + private List searchClassInProjectClasspaths(String fullyQualifiedClassName) throws CoreException { return ResolveClasspathsHandler.getJavaProjectFromType(fullyQualifiedClassName); } @@ -212,7 +306,8 @@ private ValidationResult validateProjectName(final String mainClass, final Strin } if (JdtUtils.getJavaProject(projectName) == null) { - return new ValidationResult(false, String.format("ConfigError: The project '%s' is not a valid java project.", projectName)); + return new ValidationResult(false, String.format("ConfigError: The project '%s' is not a valid java project.", projectName), + CONFIGERROR_INVALID_JAVA_PROJECT); } return new ValidationResult(true); @@ -302,14 +397,16 @@ class ValidationResponse { class ValidationResult { boolean isValid; String message; + int kind; ValidationResult(boolean isValid) { this.isValid = isValid; } - ValidationResult(boolean isValid, String message) { + ValidationResult(boolean isValid, String message, int kind) { this.isValid = isValid; this.message = message; + this.kind = kind; } } } diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java index 85ff58978..a3c61e814 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018-2020 Microsoft Corporation and others. + * Copyright (c) 2018-2021 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 @@ -26,6 +26,7 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IOpenable; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; @@ -167,7 +168,7 @@ private static MainMethod extractMainMethodInfo(ICompilationUnit typeRoot, IMeth private static Range getRange(ICompilationUnit typeRoot, IJavaElement element) throws JavaModelException { ISourceRange r = ((ISourceReference) element).getNameRange(); - return JDTUtils.toRange(typeRoot, r.getOffset(), r.getLength()); + return JDTUtils.toRange((IOpenable) typeRoot, r.getOffset(), r.getLength()); } static class MainMethod { diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 88e7c7041..782edf279 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 6e9099962..b21f4ba96 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.32.0 + 0.35.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/java.debug.target b/java.debug.target index 835c63801..dcb0b8c5e 100644 --- a/java.debug.target +++ b/java.debug.target @@ -6,17 +6,26 @@ - + + + + + + + + + + - + - + diff --git a/pom.xml b/pom.xml index 4f7abb14c..007cf78be 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.32.0 + 0.35.0 pom Java Debug Server for Visual Studio Code @@ -154,9 +154,9 @@ - 201912 + 202112 p2 - https://download.eclipse.org/releases/2019-12/ + https://download.eclipse.org/releases/2021-12/202112081000/ oss.sonatype.org @@ -173,7 +173,7 @@ JBOLL.TOOLS p2 - https://download.jboss.org/jbosstools/updates/m2e-extensions/m2e-apt/1.5.0-2018-05-16_00-46-30-H11 + https://download.jboss.org/jbosstools/updates/m2e-extensions/m2e-apt/1.5.3-2019-11-08_11-04-22-H22/ orbit From 9d88e12e3997d2e5782bce3c5de98533861c770f Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 25 Feb 2022 15:24:15 +0100 Subject: [PATCH 09/50] Revert "Bump version to 0.33.0 (#386)" This reverts commit cb56e1b44be0a878ba6be89ea72d57b9decf0dcc. --- ThirdPartyNotices.txt | 437 ------------------ com.microsoft.java.debug.core/.classpath | 2 +- com.microsoft.java.debug.core/pom.xml | 9 +- .../debug/core/adapter/ProcessConsole.java | 2 +- .../adapter/handler/CompletionsHandler.java | 4 +- .../handler/EvaluateRequestHandler.java | 48 +- .../adapter/handler/LaunchRequestHandler.java | 17 +- .../core/adapter/handler/LaunchUtils.java | 4 +- .../adapter/handler/StepRequestHandler.java | 14 +- .../handler/VariablesRequestHandler.java | 64 +-- com.microsoft.java.debug.plugin/.classpath | 11 +- .../META-INF/MANIFEST.MF | 8 +- com.microsoft.java.debug.plugin/pom.xml | 17 +- .../internal/JdtSourceLookUpProvider.java | 13 +- .../internal/ResolveMainClassHandler.java | 137 +----- .../internal/ResolveMainMethodHandler.java | 5 +- .../category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- java.debug.target | 15 +- pom.xml | 8 +- 20 files changed, 102 insertions(+), 717 deletions(-) delete mode 100644 ThirdPartyNotices.txt diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt deleted file mode 100644 index b9fc26420..000000000 --- a/ThirdPartyNotices.txt +++ /dev/null @@ -1,437 +0,0 @@ -java-debug - -THIRD-PARTY SOFTWARE NOTICES AND INFORMATION -Do Not Translate or Localize - -This project incorporates components from the projects listed below. The original copyright notices and the licenses under which Microsoft received such components are set forth below. Microsoft reserves all rights not expressly granted herein, whether by implication, estoppel or otherwise. - -1. ReactiveX/RxJava (https://github.com/ReactiveX/RxJava) -2. reactive-streams/reactive-streams-jvm (https://github.com/reactive-streams/reactive-streams-jvm) -3. apache/commons-io (https://github.com/apache/commons-io) - - -%% ReactiveX/RxJava NOTICES AND INFORMATION BEGIN HERE -========================================= - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -========================================= -END OF ReactiveX/RxJava NOTICES AND INFORMATION - -%% reactive-streams/reactive-streams-jvm NOTICES AND INFORMATION BEGIN HERE -========================================= -MIT No Attribution - -Copyright 2014 Reactive Streams - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -========================================= -END OF reactive-streams/reactive-streams-jvm NOTICES AND INFORMATION - -%% apache/commons-io NOTICES AND INFORMATION BEGIN HERE -========================================= - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -========================================= -END OF apache/commons-io NOTICES AND INFORMATION \ No newline at end of file diff --git a/com.microsoft.java.debug.core/.classpath b/com.microsoft.java.debug.core/.classpath index 9ba41a249..f0257c5a5 100644 --- a/com.microsoft.java.debug.core/.classpath +++ b/com.microsoft.java.debug.core/.classpath @@ -13,7 +13,7 @@ - + diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index e0e46a048..00e2a1d9d 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -4,7 +4,6 @@ 4.0.0 ch.epfl.scala com-microsoft-java-debug-core - jar ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug @@ -80,8 +79,8 @@ maven-compiler-plugin 3.7.0 - 11 - 11 + 1.8 + 1.8 @@ -127,7 +126,7 @@ com.google.code.gson gson - 2.8.9 + 2.7 io.reactivex.rxjava2 @@ -142,7 +141,7 @@ commons-io commons-io - 2.10.0 + 2.5 diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java index 3d823df91..6b384c628 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProcessConsole.java @@ -129,7 +129,7 @@ public void stop() { } private void monitor(InputStream input, PublishSubject subject) { - BufferedReader reader = new BufferedReader(encoding == null ? new InputStreamReader(input) : new InputStreamReader(input, encoding)); + BufferedReader reader = new BufferedReader(new InputStreamReader(input, encoding)); final int BUFFERSIZE = 4096; char[] buffer = new char[BUFFERSIZE]; while (true) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java index eba7d5153..9f660644a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/CompletionsHandler.java @@ -11,8 +11,8 @@ package com.microsoft.java.debug.core.adapter.handler; +import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -46,7 +46,7 @@ public CompletableFuture handle(Command command, Arguments arguments, // completions should be illegal when frameId is zero, it is sent when the program is running, while during running we cannot resolve // the completion candidates if (completionsArgs.frameId == 0) { - response.body = new Responses.CompletionsResponseBody(Collections.emptyList()); + response.body = new ArrayList<>(); return CompletableFuture.completedFuture(response); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java index bd0930931..be78bac64 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/EvaluateRequestHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2017-2021 Microsoft Corporation and others. +* Copyright (c) 2017-2020 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 @@ -14,6 +14,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutionException; @@ -105,8 +106,10 @@ public CompletableFuture handle(Command command, Arguments arguments, indexedVariables = ((IntegerValue) sizeValue).value(); } } - } catch (Exception e) { - logger.log(Level.INFO, "Failed to get the logical size of the variable", e); + } catch (CancellationException | IllegalArgumentException | InterruptedException + | ExecutionException | UnsupportedOperationException e) { + logger.log(Level.INFO, + String.format("Failed to get the logical size for the type %s.", value.type().name()), e); } } int referenceId = 0; @@ -114,49 +117,20 @@ public CompletableFuture handle(Command command, Arguments arguments, referenceId = context.getRecyclableIdPool().addObject(threadId, varProxy); } - boolean hasErrors = false; - String valueString = null; - try { - valueString = variableFormatter.valueToString(value, options); - } catch (OutOfMemoryError e) { - hasErrors = true; - logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e); - valueString = ""; - } catch (Exception e) { - hasErrors = true; - logger.log(Level.SEVERE, "Failed to resolve the variable value", e); - valueString = ""; - } - + String valueString = variableFormatter.valueToString(value, options); String detailsString = null; - if (hasErrors) { - // If failed to resolve the variable value, skip the details info as well. - } else if (sizeValue != null) { + if (sizeValue != null) { detailsString = "size=" + variableFormatter.valueToString(sizeValue, options); } else if (DebugSettings.getCurrent().showToString) { - try { - detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine); - } catch (OutOfMemoryError e) { - logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e); - detailsString = ""; - } catch (Exception e) { - logger.log(Level.SEVERE, "Failed to compute the toString() value", e); - detailsString = ""; - } + detailsString = VariableDetailUtils.formatDetailsValue(value, stackFrameReference.getThread(), variableFormatter, options, engine); } if ("clipboard".equals(evalArguments.context) && detailsString != null) { response.body = new Responses.EvaluateResponseBody(detailsString, -1, "String", 0); } else { - String typeString = ""; - try { - typeString = variableFormatter.typeToString(value == null ? null : value.type(), options); - } catch (Exception e) { - logger.log(Level.SEVERE, "Failed to resolve the variable type", e); - typeString = ""; - } response.body = new Responses.EvaluateResponseBody((detailsString == null) ? valueString : valueString + " " + detailsString, - referenceId, typeString, Math.max(indexedVariables, 0)); + referenceId, variableFormatter.typeToString(value == null ? null : value.type(), options), + Math.max(indexedVariables, 0)); } return response; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java index 17b93284f..c5f6bd611 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchRequestHandler.java @@ -16,6 +16,7 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -90,21 +91,23 @@ protected CompletableFuture handleLaunchCommand(Arguments arguments, R "Failed to launch debuggee VM. Missing mainClass or modulePaths/classPaths options in launch configuration.", ErrorCode.ARGUMENT_MISSING); } - if (StringUtils.isNotBlank(launchArguments.encoding)) { + if (StringUtils.isBlank(launchArguments.encoding)) { + context.setDebuggeeEncoding(StandardCharsets.UTF_8); + } else { if (!Charset.isSupported(launchArguments.encoding)) { throw AdapterUtils.createCompletionException( "Failed to launch debuggee VM. 'encoding' options in the launch configuration is not recognized.", ErrorCode.INVALID_ENCODING); } context.setDebuggeeEncoding(Charset.forName(launchArguments.encoding)); - if (StringUtils.isBlank(launchArguments.vmArgs)) { - launchArguments.vmArgs = String.format("-Dfile.encoding=%s", context.getDebuggeeEncoding().name()); - } else { - // if vmArgs already has the file.encoding settings, duplicate options for jvm will not cause an error, the right most value wins - launchArguments.vmArgs = String.format("%s -Dfile.encoding=%s", launchArguments.vmArgs, context.getDebuggeeEncoding().name()); - } } + if (StringUtils.isBlank(launchArguments.vmArgs)) { + launchArguments.vmArgs = String.format("-Dfile.encoding=%s", context.getDebuggeeEncoding().name()); + } else { + // if vmArgs already has the file.encoding settings, duplicate options for jvm will not cause an error, the right most value wins + launchArguments.vmArgs = String.format("%s -Dfile.encoding=%s", launchArguments.vmArgs, context.getDebuggeeEncoding().name()); + } context.setLaunchMode(launchArguments.noDebug ? LaunchMode.NO_DEBUG : LaunchMode.DEBUG); activeLaunchHandler.preLaunch(launchArguments, context); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java index d0d99af40..17a4f7359 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java @@ -73,11 +73,11 @@ public static synchronized Path generateClasspathJar(String[] classPaths) throws public static synchronized Path generateArgfile(String[] classPaths, String[] modulePaths) throws IOException { String argfile = ""; if (ArrayUtils.isNotEmpty(classPaths)) { - argfile = "-cp \"" + String.join(File.pathSeparator, classPaths) + "\""; + argfile = "-classpath \"" + String.join(File.pathSeparator, classPaths) + "\""; } if (ArrayUtils.isNotEmpty(modulePaths)) { - argfile += " --module-path \"" + String.join(File.pathSeparator, modulePaths) + "\""; + argfile = " --module-path \"" + String.join(File.pathSeparator, modulePaths) + "\""; } argfile = argfile.replace("\\", "\\\\"); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 72d14eb5d..94e0d3078 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -145,14 +145,12 @@ public CompletableFuture handle(Command command, Arguments arguments, private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, IDebugAdapterContext context, ThreadState threadState) { Event event = debugEvent.event; - EventRequestManager eventRequestManager = debugSession.getVM().eventRequestManager(); // When a breakpoint occurs, abort any pending step requests from the same thread. if (event instanceof BreakpointEvent || event instanceof ExceptionEvent) { long threadId = ((LocatableEvent) event).thread().uniqueID(); if (threadId == threadState.threadId && threadState.pendingStepRequest != null) { - threadState.deleteStepRequest(eventRequestManager); - threadState.deleteMethodExitRequest(eventRequestManager); + threadState.deleteStepRequests(debugSession.getVM().eventRequestManager()); context.getStepResultManager().removeMethodResult(threadId); if (threadState.eventSubscription != null) { threadState.eventSubscription.dispose(); @@ -160,7 +158,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } } else if (event instanceof StepEvent) { ThreadReference thread = ((StepEvent) event).thread(); - threadState.deleteStepRequest(eventRequestManager); + threadState.deleteStepRequests(debugSession.getVM().eventRequestManager()); if (isStepFiltersConfigured(context.getStepFilters())) { try { if (threadState.pendingStepType == Command.STEPIN) { @@ -183,7 +181,6 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, // ignore. } } - threadState.deleteMethodExitRequest(eventRequestManager); if (threadState.eventSubscription != null) { threadState.eventSubscription.dispose(); } @@ -283,13 +280,10 @@ class ThreadState { Location stepLocation = null; Disposable eventSubscription = null; - public void deleteMethodExitRequest(EventRequestManager manager) { + public void deleteStepRequests(EventRequestManager manager) { + DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); DebugUtility.deleteEventRequestSafely(manager, this.pendingMethodExitRequest); this.pendingMethodExitRequest = null; - } - - public void deleteStepRequest(EventRequestManager manager) { - DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); this.pendingStepRequest = null; } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index d6f9f1ca4..98451bc81 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2017-2021 Microsoft Corporation and others. +* Copyright (c) 2017-2020 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 @@ -19,7 +19,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -134,12 +136,7 @@ public CompletableFuture handle(Command command, Arguments arguments, try { ObjectReference containerObj = (ObjectReference) containerNode.getProxiedVariable(); if (DebugSettings.getCurrent().showLogicalStructure && evaluationEngine != null) { - JavaLogicalStructure logicalStructure = null; - try { - logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e); - } + JavaLogicalStructure logicalStructure = JavaLogicalStructureManager.getLogicalStructure(containerObj); if (isUnboundedTypeContainer && logicalStructure != null && containerEvaluateName != null) { containerEvaluateName = "((" + logicalStructure.getFullyQualifiedName() + ")" + containerEvaluateName + ")"; isUnboundedTypeContainer = false; @@ -168,8 +165,11 @@ public CompletableFuture handle(Command command, Arguments arguments, childrenList.add(variable); } } - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to get the logical structure for the variable, fall back to the Object view.", e); + } catch (IllegalArgumentException | CancellationException | InterruptedException | ExecutionException e) { + logger.log(Level.WARNING, + String.format("Failed to get the logical structure for the type %s, fall back to the Object view.", + containerObj.type().name()), + e); } logicalStructure = null; @@ -244,8 +244,9 @@ public CompletableFuture handle(Command command, Arguments arguments, indexedVariables = ((IntegerValue) sizeValue).value(); } } - } catch (Exception e) { - logger.log(Level.INFO, "Failed to get the logical size of the variable", e); + } catch (CancellationException | IllegalArgumentException | InterruptedException | ExecutionException | UnsupportedOperationException e) { + logger.log(Level.INFO, + String.format("Failed to get the logical size for the type %s.", value.type().name()), e); } } @@ -277,46 +278,15 @@ public CompletableFuture handle(Command command, Arguments arguments, varProxy.setUnboundedType(javaVariable.isUnboundedType()); } - boolean hasErrors = false; - String valueString = null; - try { - valueString = variableFormatter.valueToString(value, options); - } catch (OutOfMemoryError e) { - hasErrors = true; - logger.log(Level.SEVERE, "Failed to convert the value of a large object to a string", e); - valueString = ""; - } catch (Exception e) { - hasErrors = true; - logger.log(Level.SEVERE, "Failed to resolve the variable value", e); - valueString = ""; - } - - String typeString = ""; - try { - typeString = variableFormatter.typeToString(value == null ? null : value.type(), options); - } catch (Exception e) { - logger.log(Level.SEVERE, "Failed to resolve the variable type", e); - typeString = ""; - } - - Types.Variable typedVariables = new Types.Variable(name, valueString, typeString, referenceId, evaluateName); + Types.Variable typedVariables = new Types.Variable(name, variableFormatter.valueToString(value, options), + variableFormatter.typeToString(value == null ? null : value.type(), options), + referenceId, evaluateName); typedVariables.indexedVariables = Math.max(indexedVariables, 0); - String detailsValue = null; - if (hasErrors) { - // If failed to resolve the variable value, skip the details info as well. - } else if (sizeValue != null) { + if (sizeValue != null) { detailsValue = "size=" + variableFormatter.valueToString(sizeValue, options); } else if (DebugSettings.getCurrent().showToString) { - try { - detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine); - } catch (OutOfMemoryError e) { - logger.log(Level.SEVERE, "Failed to compute the toString() value of a large object", e); - detailsValue = ""; - } catch (Exception e) { - logger.log(Level.SEVERE, "Failed to compute the toString() value", e); - detailsValue = ""; - } + detailsValue = VariableDetailUtils.formatDetailsValue(value, containerNode.getThread(), variableFormatter, options, evaluationEngine); } if (detailsValue != null) { diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index de236212a..8c76f8dd3 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -1,16 +1,11 @@ - - - - - - + - + - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 1c0eaf78c..2245a3854 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,8 +2,8 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.35.0 -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-Version: 0.32.0 +Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin Bundle-Vendor: Microsoft @@ -21,8 +21,8 @@ Require-Bundle: org.eclipse.core.runtime, org.apache.commons.lang3, org.eclipse.lsp4j, com.google.guava -Bundle-ClassPath: lib/commons-io-2.10.0.jar, +Bundle-ClassPath: lib/commons-io-2.5.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com.microsoft.java.debug.core-0.35.0.jar + lib/com.microsoft.java.debug.core-0.32.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index ffc3ded41..f5e0003e3 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.35.0 + 0.32.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -17,17 +17,6 @@ tycho-maven-plugin ${tycho-version} true - - - org.eclipse.tycho - tycho-compiler-plugin - ${tycho-version} - - - --limit-modules - java.base,java.logging,java.xml,jdk.jdi,java.compiler - - org.apache.maven.plugins @@ -51,12 +40,12 @@ commons-io commons-io - 2.10.0 + 2.5 com.microsoft.java com.microsoft.java.debug.core - 0.35.0 + 0.32.0 diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index efc7ce20c..d24d2abdd 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017-2021 Microsoft Corporation and others. + * Copyright (c) 2017-2020 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 @@ -17,6 +17,7 @@ import java.io.InputStreamReader; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.HashMap; @@ -119,7 +120,11 @@ public String[] getFullyQualifiedName(String uri, int[] lines, int[] columns) th String filePath = AdapterUtils.toPath(uri); // For file uri, read the file contents directly and pass them to the ast parser. if (filePath != null && Files.isRegularFile(Paths.get(filePath))) { - String source = readFile(filePath); + Charset cs = (Charset) this.options.get(Constants.DEBUGGEE_ENCODING); + if (cs == null) { + cs = Charset.defaultCharset(); + } + String source = readFile(filePath, cs); parser.setSource(source.toCharArray()); /** * See the java doc for { @link ASTParser#setResolveBindings(boolean) }. @@ -288,10 +293,10 @@ private static IClassFile resolveClassFile(String uriString) { return null; } - private static String readFile(String filePath) { + private static String readFile(String filePath, Charset cs) { StringBuilder builder = new StringBuilder(); try (BufferedReader bufferReader = - new BufferedReader(new InputStreamReader(new FileInputStream(filePath)))) { + new BufferedReader(new InputStreamReader(new FileInputStream(filePath), cs))) { final int BUFFER_SIZE = 4096; char[] buffer = new char[BUFFER_SIZE]; while (true) { diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java index f70d0c044..9d3b1014e 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017-2022 Microsoft Corporation and others. + * Copyright (c) 2017 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 @@ -12,7 +12,6 @@ package com.microsoft.java.debug.plugin.internal; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -22,9 +21,6 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javax.lang.model.SourceVersion; import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.IFile; @@ -51,10 +47,8 @@ public class ResolveMainClassHandler { private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - private static final int CONFIGERROR_INVALID_CLASS_NAME = 1; - private static final int CONFIGERROR_MAIN_CLASS_NOT_EXIST = 2; - private static final int CONFIGERROR_MAIN_CLASS_NOT_UNIQUE = 3; - private static final int CONFIGERROR_INVALID_JAVA_PROJECT = 4; + // Java command line supports two kinds of main class format: and [/] + private static final String CLASSNAME_REGX = "([$\\w]+\\.)*[$\\w]+(/([$\\w]+\\.)*[$\\w]+)?"; /** * resolve main class and project name. @@ -81,26 +75,15 @@ public Object validateLaunchConfig(List arguments) throws Exception { } private List resolveMainClassCore(List arguments) { + IPath rootPath = null; if (arguments != null && arguments.size() > 0 && arguments.get(0) != null) { - String argument = (String) arguments.get(0); - IProject[] projects = ProjectUtils.getAllProjects(); - if (Stream.of(projects).anyMatch(project -> Objects.equals(project.getName(), argument))) { - return resolveMainClassUnderProject(argument); - } - - IPath rootPath = ResourceUtils.filePathFromURI(argument); - if (rootPath != null) { - return resolveMainClassUnderPaths(Arrays.asList(rootPath)); - } + rootPath = ResourceUtils.filePathFromURI((String) arguments.get(0)); } - - return resolveMainClassUnderPaths(Collections.emptyList()); - } - - private List resolveMainClassUnderPaths(List parentPaths) { - // Limit to search main method from source code only. - IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(ProjectUtils.getJavaProjects(), - IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); + final ArrayList targetProjectPath = new ArrayList<>(); + if (rootPath != null) { + targetProjectPath.add(rootPath); + } + IJavaSearchScope searchScope = SearchEngine.createWorkspaceScope(); SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); final List res = new ArrayList<>(); @@ -125,9 +108,10 @@ public void acceptSearchMatch(SearchMatch match) { } } String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName(); - if (parentPaths.isEmpty() - || ResourceUtils.isContainedIn(project.getLocation(), parentPaths) - || isContainedInInvisibleProject(project, parentPaths)) { + if (projectName == null + || targetProjectPath.isEmpty() + || ResourceUtils.isContainedIn(project.getLocation(), targetProjectPath) + || isContainedInInvisibleProject(project, targetProjectPath)) { String filePath = null; if (match.getResource() instanceof IFile) { @@ -161,66 +145,6 @@ public void acceptSearchMatch(SearchMatch match) { return resolutions; } - private List resolveMainClassUnderProject(final String projectName) { - // Limit to search main method from source code only. - IJavaProject javaProject = ProjectUtils.getJavaProject(projectName); - IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(javaProject == null ? new IJavaProject[0] : new IJavaProject[] {javaProject}, - IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); - SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, - IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); - final List res = new ArrayList<>(); - SearchRequestor requestor = new SearchRequestor() { - @Override - public void acceptSearchMatch(SearchMatch match) { - Object element = match.getElement(); - if (element instanceof IMethod) { - IMethod method = (IMethod) element; - try { - if (method.isMainMethod()) { - IResource resource = method.getResource(); - if (resource != null) { - IProject project = resource.getProject(); - if (project != null) { - String mainClass = method.getDeclaringType().getFullyQualifiedName(); - IJavaProject javaProject = JdtUtils.getJavaProject(project); - if (javaProject != null) { - String moduleName = JdtUtils.getModuleName(javaProject); - if (moduleName != null) { - mainClass = moduleName + "/" + mainClass; - } - } - - String filePath = null; - if (match.getResource() instanceof IFile) { - try { - filePath = match.getResource().getLocation().toOSString(); - } catch (Exception ex) { - // ignore - } - } - res.add(new ResolutionItem(mainClass, projectName, filePath)); - } - } - } - } catch (JavaModelException e) { - // ignore - } - } - } - }; - SearchEngine searchEngine = new SearchEngine(); - try { - searchEngine.search(pattern, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, - searchScope, requestor, null /* progress monitor */); - } catch (Exception e) { - logger.log(Level.SEVERE, String.format("Searching the main class failure: %s", e.toString()), e); - } - - List resolutions = res.stream().distinct().collect(Collectors.toList()); - Collections.sort(resolutions); - return resolutions; - } - private boolean isContainedInInvisibleProject(IProject project, Collection rootPaths) { if (project == null) { return false; @@ -261,41 +185,23 @@ private ValidationResponse validateLaunchConfigCore(List arguments) thro private ValidationResult validateMainClass(final String mainClass, final String projectName, boolean containsExternalClasspaths) throws CoreException { if (StringUtils.isEmpty(mainClass)) { return new ValidationResult(true); - } else if (!isValidMainClassName(mainClass)) { - return new ValidationResult(false, String.format("ConfigError: '%s' is not a valid class name.", mainClass), - CONFIGERROR_INVALID_CLASS_NAME); + } else if (!mainClass.matches(CLASSNAME_REGX)) { + return new ValidationResult(false, String.format("ConfigError: '%s' is not a valid class name.", mainClass)); } if (!containsExternalClasspaths && StringUtils.isEmpty(projectName)) { List javaProjects = searchClassInProjectClasspaths(mainClass); if (javaProjects.size() == 0) { - return new ValidationResult(false, String.format("ConfigError: Main class '%s' doesn't exist in the workspace.", mainClass), - CONFIGERROR_MAIN_CLASS_NOT_EXIST); + return new ValidationResult(false, String.format("ConfigError: Main class '%s' doesn't exist in the workspace.", mainClass)); } if (javaProjects.size() > 1) { - return new ValidationResult(false, String.format("ConfigError: Main class '%s' isn't unique in the workspace.", mainClass), - CONFIGERROR_MAIN_CLASS_NOT_UNIQUE); + return new ValidationResult(false, String.format("ConfigError: Main class '%s' isn't unique in the workspace.", mainClass)); } } return new ValidationResult(true); } - // Java command line supports two kinds of main class format: and [/] - private boolean isValidMainClassName(String mainClass) { - if (StringUtils.isEmpty(mainClass)) { - return true; - } - - int index = mainClass.indexOf('/'); - if (index == -1) { - return SourceVersion.isName(mainClass); - } - - return SourceVersion.isName(mainClass.substring(0, index)) - && SourceVersion.isName(mainClass.substring(index + 1)); - } - private List searchClassInProjectClasspaths(String fullyQualifiedClassName) throws CoreException { return ResolveClasspathsHandler.getJavaProjectFromType(fullyQualifiedClassName); } @@ -306,8 +212,7 @@ private ValidationResult validateProjectName(final String mainClass, final Strin } if (JdtUtils.getJavaProject(projectName) == null) { - return new ValidationResult(false, String.format("ConfigError: The project '%s' is not a valid java project.", projectName), - CONFIGERROR_INVALID_JAVA_PROJECT); + return new ValidationResult(false, String.format("ConfigError: The project '%s' is not a valid java project.", projectName)); } return new ValidationResult(true); @@ -397,16 +302,14 @@ class ValidationResponse { class ValidationResult { boolean isValid; String message; - int kind; ValidationResult(boolean isValid) { this.isValid = isValid; } - ValidationResult(boolean isValid, String message, int kind) { + ValidationResult(boolean isValid, String message) { this.isValid = isValid; this.message = message; - this.kind = kind; } } } diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java index a3c61e814..85ff58978 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018-2021 Microsoft Corporation and others. + * Copyright (c) 2018-2020 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 @@ -26,7 +26,6 @@ import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; -import org.eclipse.jdt.core.IOpenable; import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; @@ -168,7 +167,7 @@ private static MainMethod extractMainMethodInfo(ICompilationUnit typeRoot, IMeth private static Range getRange(ICompilationUnit typeRoot, IJavaElement element) throws JavaModelException { ISourceRange r = ((ISourceReference) element).getNameRange(); - return JDTUtils.toRange((IOpenable) typeRoot, r.getOffset(), r.getLength()); + return JDTUtils.toRange(typeRoot, r.getOffset(), r.getLength()); } static class MainMethod { diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 782edf279..88e7c7041 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index b21f4ba96..6e9099962 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.35.0 + 0.32.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/java.debug.target b/java.debug.target index dcb0b8c5e..835c63801 100644 --- a/java.debug.target +++ b/java.debug.target @@ -6,26 +6,17 @@ + - - - - - - - - - - - + - + diff --git a/pom.xml b/pom.xml index 007cf78be..4f7abb14c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.35.0 + 0.32.0 pom Java Debug Server for Visual Studio Code @@ -154,9 +154,9 @@ - 202112 + 201912 p2 - https://download.eclipse.org/releases/2021-12/202112081000/ + https://download.eclipse.org/releases/2019-12/ oss.sonatype.org @@ -173,7 +173,7 @@ JBOLL.TOOLS p2 - https://download.jboss.org/jbosstools/updates/m2e-extensions/m2e-apt/1.5.3-2019-11-08_11-04-22-H22/ + https://download.jboss.org/jbosstools/updates/m2e-extensions/m2e-apt/1.5.0-2018-05-16_00-46-30-H11 orbit From be7fad7de4e2d179969ede6254400b05fa002588 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 7 Jul 2022 13:56:27 +0200 Subject: [PATCH 10/50] Add IStepFilterProvider Allow customization of step filtering by extensions of the java-debug server --- com.microsoft.java.debug.core/pom.xml | 2 +- .../core/adapter/IStepFilterProvider.java | 8 +++ .../core/adapter/StepFilterProvider.java | 26 ++++++++ .../adapter/handler/StepRequestHandler.java | 60 +++++++------------ .../internal/JdtProviderContextFactory.java | 3 + 5 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 4dd95af76..abbae02e8 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -33,7 +33,7 @@ - ch.epfl.scaal + ch.epfl.scala https://scala.epfl.ch/ diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java new file mode 100644 index 000000000..25ec2dce0 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -0,0 +1,8 @@ +package com.microsoft.java.debug.core.adapter; + +import com.microsoft.java.debug.core.protocol.Requests; +import com.sun.jdi.Method; + +public interface IStepFilterProvider extends IProvider { + boolean skip(Method method, Requests.StepFilters filters); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java new file mode 100644 index 000000000..68bb9c25d --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -0,0 +1,26 @@ +package com.microsoft.java.debug.core.adapter; + +import com.microsoft.java.debug.core.protocol.Requests; +import com.sun.jdi.Method; +import org.apache.commons.lang3.ArrayUtils; + +public class StepFilterProvider implements IStepFilterProvider { + @Override + public boolean skip(Method method, Requests.StepFilters filters) { + if (!isConfigured(filters)) { + return false; + } + return (filters.skipStaticInitializers && method.isStaticInitializer()) + || (filters.skipSynthetics && method.isSynthetic()) + || (filters.skipConstructors && method.isConstructor()); + } + + private boolean isConfigured(Requests.StepFilters filters) { + if (filters == null) { + return false; + } + return ArrayUtils.isNotEmpty(filters.allowClasses) || ArrayUtils.isNotEmpty(filters.skipClasses) + || ArrayUtils.isNotEmpty(filters.classNameFilters) || filters.skipConstructors + || filters.skipStaticInitializers || filters.skipSynthetics; + } +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 72d14eb5d..882e15e78 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; +import com.microsoft.java.debug.core.adapter.*; import org.apache.commons.lang3.ArrayUtils; import com.microsoft.java.debug.core.DebugEvent; @@ -22,10 +23,6 @@ import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.JdiExceptionReference; import com.microsoft.java.debug.core.JdiMethodResult; -import com.microsoft.java.debug.core.adapter.AdapterUtils; -import com.microsoft.java.debug.core.adapter.ErrorCode; -import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; -import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; @@ -161,27 +158,26 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } else if (event instanceof StepEvent) { ThreadReference thread = ((StepEvent) event).thread(); threadState.deleteStepRequest(eventRequestManager); - if (isStepFiltersConfigured(context.getStepFilters())) { - try { - if (threadState.pendingStepType == Command.STEPIN) { - int currentStackDepth = thread.frameCount(); - Location currentStepLocation = getTopFrame(thread).location(); + IStepFilterProvider stepFilter = context.getProvider(IStepFilterProvider.class); + try { + if (threadState.pendingStepType == Command.STEPIN) { + int currentStackDepth = thread.frameCount(); + Location currentStepLocation = getTopFrame(thread).location(); - // If the ending step location is filtered, or same as the original location where the step into operation is originated, - // do another step of the same kind. - if (shouldFilterLocation(threadState.stepLocation, currentStepLocation, context) - || shouldDoExtraStepInto(threadState.stackDepth, threadState.stepLocation, currentStackDepth, currentStepLocation)) { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, - context.getStepFilters().allowClasses, - context.getStepFilters().skipClasses); - threadState.pendingStepRequest.enable(); - debugEvent.shouldResume = true; - return; - } + // If the ending step location is filtered, or same as the original location where the step into operation is originated, + // do another step of the same kind. + if (shouldFilterLocation(threadState.stepLocation, currentStepLocation, stepFilter, context) + || shouldDoExtraStepInto(threadState.stackDepth, threadState.stepLocation, currentStackDepth, currentStepLocation)) { + threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, + context.getStepFilters().allowClasses, + context.getStepFilters().skipClasses); + threadState.pendingStepRequest.enable(); + debugEvent.shouldResume = true; + return; } - } catch (IncompatibleThreadStateException | IndexOutOfBoundsException ex) { - // ignore. } + } catch (IncompatibleThreadStateException | IndexOutOfBoundsException ex) { + // ignore. } threadState.deleteMethodExitRequest(eventRequestManager); if (threadState.eventSubscription != null) { @@ -205,33 +201,19 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } } - private boolean isStepFiltersConfigured(StepFilters filters) { - if (filters == null) { - return false; - } - return ArrayUtils.isNotEmpty(filters.allowClasses) || ArrayUtils.isNotEmpty(filters.skipClasses) - || ArrayUtils.isNotEmpty(filters.classNameFilters) || filters.skipConstructors - || filters.skipStaticInitializers || filters.skipSynthetics; - } - /** * Return true if the StepEvent's location is a Method that the user has indicated to filter. * * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldFilterLocation(Location originalLocation, Location currentLocation, IDebugAdapterContext context) + private boolean shouldFilterLocation(Location originalLocation, Location currentLocation, IStepFilterProvider stepFilter, IDebugAdapterContext context) throws IncompatibleThreadStateException { if (originalLocation == null || currentLocation == null) { return false; } - return !shouldFilterMethod(originalLocation.method(), context) && shouldFilterMethod(currentLocation.method(), context); - } - - private boolean shouldFilterMethod(Method method, IDebugAdapterContext context) { - return (context.getStepFilters().skipStaticInitializers && method.isStaticInitializer()) - || (context.getStepFilters().skipSynthetics && method.isSynthetic()) - || (context.getStepFilters().skipConstructors && method.isConstructor()); + return !stepFilter.skip(originalLocation.method(), context.getStepFilters()) + && stepFilter.skip(currentLocation.method(), context.getStepFilters()); } /** diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java index 7213f8e9a..37ebc2dae 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java @@ -16,8 +16,10 @@ import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider; import com.microsoft.java.debug.core.adapter.IProviderContext; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; +import com.microsoft.java.debug.core.adapter.IStepFilterProvider; import com.microsoft.java.debug.core.adapter.IVirtualMachineManagerProvider; import com.microsoft.java.debug.core.adapter.ProviderContext; +import com.microsoft.java.debug.core.adapter.StepFilterProvider; import com.microsoft.java.debug.plugin.internal.eval.JdtEvaluationProvider; /** @@ -35,6 +37,7 @@ public static IProviderContext createProviderContext() { context.registerProvider(IHotCodeReplaceProvider.class, new JavaHotCodeReplaceProvider()); context.registerProvider(IEvaluationProvider.class, new JdtEvaluationProvider()); context.registerProvider(ICompletionsProvider.class, new CompletionsProvider()); + context.registerProvider(IStepFilterProvider.class, new StepFilterProvider()); return context; } From e6560ba4a51b74c817daa3f3298f83ce2f0b5a59 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 7 Jul 2022 16:42:53 +0200 Subject: [PATCH 11/50] fix style --- .../java/debug/core/adapter/IStepFilterProvider.java | 11 +++++++++++ .../java/debug/core/adapter/StepFilterProvider.java | 11 +++++++++++ .../core/adapter/handler/StepRequestHandler.java | 9 +++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index 25ec2dce0..faa92f7b8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2020 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.Requests; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java index 68bb9c25d..f55b85fff 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2017 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.Requests; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 882e15e78..dc200fe38 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -15,20 +15,21 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import com.microsoft.java.debug.core.adapter.*; -import org.apache.commons.lang3.ArrayUtils; - import com.microsoft.java.debug.core.DebugEvent; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.JdiExceptionReference; import com.microsoft.java.debug.core.JdiMethodResult; +import com.microsoft.java.debug.core.adapter.AdapterUtils; +import com.microsoft.java.debug.core.adapter.ErrorCode; +import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; +import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; +import com.microsoft.java.debug.core.adapter.IStepFilterProvider; import com.microsoft.java.debug.core.protocol.Events; 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.StepArguments; -import com.microsoft.java.debug.core.protocol.Requests.StepFilters; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.Location; import com.sun.jdi.Method; From 55b5e6950f4107e19d03f5b49adc907e5756394b Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 8 Jul 2022 13:52:47 +0200 Subject: [PATCH 12/50] Fix pom files --- com.microsoft.java.debug.core/pom.xml | 8 ++++---- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index abbae02e8..73f0b3b93 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -3,12 +3,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 ch.epfl.scala - com-microsoft-java-debug-core + com.microsoft.java.debug.core + jar ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. - https://github.com/Microsoft/java-debug - 0.34.0+1-SNAPSHOT - jar + https://github.com/scalacenter/java-debug + 0.34.0+1 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index ae117b544..cf288b413 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com.microsoft.java.debug.core-0.34.0.jar + lib/com.microsoft.java.debug.core-0.34.0+1.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index d7cd7c6a4..057e51765 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -43,9 +43,9 @@ 2.10.0 - com.microsoft.java + ch.epfl.scala com.microsoft.java.debug.core - 0.34.0 + 0.34.0+1 From 8b510c5a02099d29934ce7bb57dc4783c22fba3a Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 8 Jul 2022 15:47:56 +0200 Subject: [PATCH 13/50] Run CI on branch 0.34.0+x --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58381df99..99ed7f2cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,9 +2,7 @@ name: CI on: push: - branches: [ main ] pull_request: - branches: [ main ] jobs: linux: From 60c4a76923f425c0d42d1faa2f99a41edd3105cd Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 8 Jul 2022 16:02:14 +0200 Subject: [PATCH 14/50] Up version to 0.34.0+2 --- com.microsoft.java.debug.core/pom.xml | 4 ++-- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 73f0b3b93..453c95b2b 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -3,12 +3,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 ch.epfl.scala - com.microsoft.java.debug.core + com-microsoft-java-debug-core jar ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+1 + 0.34.0+2 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index cf288b413..d20e24bf6 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com.microsoft.java.debug.core-0.34.0+1.jar + lib/com-microsoft-java-debug-core-0.34.0+2.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 057e51765..f17108f9a 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -44,8 +44,8 @@ ch.epfl.scala - com.microsoft.java.debug.core - 0.34.0+1 + com-microsoft-java-debug-core + 0.34.0+2 From f56bf57ac9427d26cf8978b1a10ccd70c0c9c843 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 15 Jul 2022 16:24:06 +0200 Subject: [PATCH 15/50] Add filtering for step out --- com.microsoft.java.debug.core/pom.xml | 2 +- .../adapter/handler/StepRequestHandler.java | 18 ++++++++++++------ .../META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 453c95b2b..7f5d71cb5 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+2 + 0.34.0+3-SNAPSHOT Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index dc200fe38..81747c460 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -161,17 +161,23 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, threadState.deleteStepRequest(eventRequestManager); IStepFilterProvider stepFilter = context.getProvider(IStepFilterProvider.class); try { - if (threadState.pendingStepType == Command.STEPIN) { + if (threadState.pendingStepType == Command.STEPIN || threadState.pendingStepType == Command.STEPOUT) { int currentStackDepth = thread.frameCount(); Location currentStepLocation = getTopFrame(thread).location(); // If the ending step location is filtered, or same as the original location where the step into operation is originated, // do another step of the same kind. if (shouldFilterLocation(threadState.stepLocation, currentStepLocation, stepFilter, context) - || shouldDoExtraStepInto(threadState.stackDepth, threadState.stepLocation, currentStackDepth, currentStepLocation)) { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, - context.getStepFilters().allowClasses, - context.getStepFilters().skipClasses); + || shouldDoExtraStep(threadState.stackDepth, threadState.stepLocation, currentStackDepth, currentStepLocation)) { + if (threadState.pendingStepType == Command.STEPIN) { + threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, + context.getStepFilters().allowClasses, + context.getStepFilters().skipClasses); + } else { + threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, + context.getStepFilters().allowClasses, + context.getStepFilters().skipClasses); + } threadState.pendingStepRequest.enable(); debugEvent.shouldResume = true; return; @@ -223,7 +229,7 @@ private boolean shouldFilterLocation(Location originalLocation, Location current * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldDoExtraStepInto(int originalStackDepth, Location originalLocation, int currentStackDepth, Location currentLocation) + private boolean shouldDoExtraStep(int originalStackDepth, Location originalLocation, int currentStackDepth, Location currentLocation) throws IncompatibleThreadStateException { if (originalStackDepth != currentStackDepth) { return false; diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index d20e24bf6..b3831ecb3 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+2.jar + lib/com-microsoft-java-debug-core-0.34.0+3-SNAPSHOT.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index f17108f9a..7ac56ed38 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+2 + 0.34.0+3-SNAPSHOT From 814a43be424f71b65f7ab29dcaf970c946bb01b6 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 15 Jul 2022 17:42:39 +0200 Subject: [PATCH 16/50] fix version of eclipse snapshot --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a0f7c9b9d..e2b2c965b 100644 --- a/pom.xml +++ b/pom.xml @@ -168,7 +168,7 @@ JDT.LS p2 - https://download.eclipse.org/jdtls/snapshots/repository/latest/ + https://download.eclipse.org/jdtls/snapshots/repository/1.5.0.202110111021/ JBOLL.TOOLS From 06e34c6e1b64e154e8b0532262e7f0857ba67617 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 18 Jul 2022 11:31:40 +0200 Subject: [PATCH 17/50] Prepare release 0.34.0+3 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 7f5d71cb5..a5096d8ae 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+3-SNAPSHOT + 0.34.0+3 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index b3831ecb3..608439065 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+3-SNAPSHOT.jar + lib/com-microsoft-java-debug-core-0.34.0+3.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 7ac56ed38..ab531d7ac 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+3-SNAPSHOT + 0.34.0+3 From b880873b95e2d00d05ae0d8a962eb300716fc2b0 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 18 Jul 2022 11:56:22 +0200 Subject: [PATCH 18/50] fix stepping out filter --- .../java/debug/core/adapter/handler/StepRequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 81747c460..68a7ab5e5 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -174,7 +174,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, context.getStepFilters().allowClasses, context.getStepFilters().skipClasses); } else { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, + threadState.pendingStepRequest = DebugUtility.createStepOutRequest(thread, context.getStepFilters().allowClasses, context.getStepFilters().skipClasses); } From b39d1c0faa156f0d6628df3166beb47eea341a15 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 18 Jul 2022 11:57:42 +0200 Subject: [PATCH 19/50] Prepare release 0.34.0+4 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index a5096d8ae..7d5036388 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+3 + 0.34.0+4 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 608439065..016aa1335 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+3.jar + lib/com-microsoft-java-debug-core-0.34.0+4.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index ab531d7ac..3086063a4 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+3 + 0.34.0+4 From 6b3160c6edb5c3d28f303a97f2f4239148cda9c5 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Sun, 2 Oct 2022 11:02:03 +0200 Subject: [PATCH 20/50] Add shouldStepOut in StepFilterProvider --- com.microsoft.java.debug.core/check_style.xml | 303 ++++++++++++++++++ .../microsoft.header | 2 + com.microsoft.java.debug.core/pom.xml | 2 +- .../core/adapter/IStepFilterProvider.java | 5 +- .../core/adapter/StepFilterProvider.java | 8 +- .../adapter/handler/StepRequestHandler.java | 66 ++-- .../META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 8 files changed, 359 insertions(+), 31 deletions(-) create mode 100644 com.microsoft.java.debug.core/check_style.xml create mode 100644 com.microsoft.java.debug.core/microsoft.header diff --git a/com.microsoft.java.debug.core/check_style.xml b/com.microsoft.java.debug.core/check_style.xml new file mode 100644 index 000000000..3f19228a5 --- /dev/null +++ b/com.microsoft.java.debug.core/check_style.xml @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.microsoft.java.debug.core/microsoft.header b/com.microsoft.java.debug.core/microsoft.header new file mode 100644 index 000000000..db463ef1b --- /dev/null +++ b/com.microsoft.java.debug.core/microsoft.header @@ -0,0 +1,2 @@ +^/\*+$ +^\s*\* Copyright \(c\) \d\d\d\d.*$ \ No newline at end of file diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 7d5036388..373c336dc 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+4 + 0.34.0+5-SNAPSHOT Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index faa92f7b8..b2db11cbe 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -12,8 +12,11 @@ package com.microsoft.java.debug.core.adapter; import com.microsoft.java.debug.core.protocol.Requests; +import com.sun.jdi.Location; import com.sun.jdi.Method; public interface IStepFilterProvider extends IProvider { - boolean skip(Method method, Requests.StepFilters filters); + boolean shouldStepInto(Method method, Requests.StepFilters filters); + + boolean shouldStepOut(Location previousLocation, Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java index f55b85fff..ca434980d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -12,12 +12,13 @@ package com.microsoft.java.debug.core.adapter; import com.microsoft.java.debug.core.protocol.Requests; +import com.sun.jdi.Location; import com.sun.jdi.Method; import org.apache.commons.lang3.ArrayUtils; public class StepFilterProvider implements IStepFilterProvider { @Override - public boolean skip(Method method, Requests.StepFilters filters) { + public boolean shouldStepInto(Method method, Requests.StepFilters filters) { if (!isConfigured(filters)) { return false; } @@ -26,6 +27,11 @@ public boolean skip(Method method, Requests.StepFilters filters) { || (filters.skipConstructors && method.isConstructor()); } + @Override + public boolean shouldStepOut(Location previousLocation, Method method) { + return false; + } + private boolean isConfigured(Requests.StepFilters filters) { if (filters == null) { return false; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 68a7ab5e5..a5aa305b7 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -27,6 +27,7 @@ import com.microsoft.java.debug.core.adapter.IStepFilterProvider; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; +import com.microsoft.java.debug.core.protocol.Requests; 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.StepArguments; @@ -161,28 +162,32 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, threadState.deleteStepRequest(eventRequestManager); IStepFilterProvider stepFilter = context.getProvider(IStepFilterProvider.class); try { - if (threadState.pendingStepType == Command.STEPIN || threadState.pendingStepType == Command.STEPOUT) { - int currentStackDepth = thread.frameCount(); - Location currentStepLocation = getTopFrame(thread).location(); - - // If the ending step location is filtered, or same as the original location where the step into operation is originated, - // do another step of the same kind. - if (shouldFilterLocation(threadState.stepLocation, currentStepLocation, stepFilter, context) - || shouldDoExtraStep(threadState.stackDepth, threadState.stepLocation, currentStackDepth, currentStepLocation)) { - if (threadState.pendingStepType == Command.STEPIN) { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, - context.getStepFilters().allowClasses, - context.getStepFilters().skipClasses); - } else { - threadState.pendingStepRequest = DebugUtility.createStepOutRequest(thread, - context.getStepFilters().allowClasses, - context.getStepFilters().skipClasses); - } - threadState.pendingStepRequest.enable(); - debugEvent.shouldResume = true; + Location originalLocation = threadState.stepLocation; + Location currentLocation = getTopFrame(thread).location(); + Location previousLocation = null; + if (thread.frameCount() > 1) { + previousLocation = thread.frame(1).location(); + } + if (originalLocation != null && currentLocation != null) { + boolean steppingIn = threadState.pendingStepType == Command.STEPIN; + Requests.StepFilters stepFilters = context.getStepFilters(); + // If the ending location is the same as the original location do another step into. + if (steppingIn && shouldDoExtraStep(threadState.stackDepth, originalLocation, thread.frameCount(), currentLocation)) { + doExtraStepInto(debugEvent, thread, stepFilters, threadState); + return; + } + // If the ending location should be stepped into + if (shouldStepInto(stepFilter, originalLocation, currentLocation, stepFilters)) { + doExtraStepInto(debugEvent, thread, stepFilters, threadState); + return; + } + // If we stepped into a method that should be stepped out + if (steppingIn && stepFilter.shouldStepOut(previousLocation, currentLocation.method())) { + doExtraStepOut(debugEvent, thread, stepFilters, threadState); return; } } + } catch (IncompatibleThreadStateException | IndexOutOfBoundsException ex) { // ignore. } @@ -209,18 +214,15 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } /** - * Return true if the StepEvent's location is a Method that the user has indicated to filter. + * Return true if the StepEvent's location is a Method that the user has indicated to step into. * * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldFilterLocation(Location originalLocation, Location currentLocation, IStepFilterProvider stepFilter, IDebugAdapterContext context) + private boolean shouldStepInto(IStepFilterProvider stepFilter, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) throws IncompatibleThreadStateException { - if (originalLocation == null || currentLocation == null) { - return false; - } - return !stepFilter.skip(originalLocation.method(), context.getStepFilters()) - && stepFilter.skip(currentLocation.method(), context.getStepFilters()); + return !stepFilter.shouldStepInto(originalLocation.method(), stepFilters) + && stepFilter.shouldStepInto(currentLocation.method(), stepFilters); } /** @@ -248,6 +250,18 @@ private boolean shouldDoExtraStep(int originalStackDepth, Location originalLocat return true; } + private void doExtraStepInto(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, ThreadState threadState) { + threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); + threadState.pendingStepRequest.enable(); + debugEvent.shouldResume = true; + } + + private void doExtraStepOut(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, ThreadState threadState) { + threadState.pendingStepRequest = DebugUtility.createStepOutRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); + threadState.pendingStepRequest.enable(); + debugEvent.shouldResume = true; + } + /** * Return the top stack frame of the target thread. * diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 016aa1335..b25fe028f 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+4.jar + lib/com-microsoft-java-debug-core-0.34.0+5-SNAPSHOT.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 3086063a4..338599ee4 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+4 + 0.34.0+5-SNAPSHOT From 718d7823a60ce2b8ee2d15113a79304e1b6f2664 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Sun, 2 Oct 2022 11:05:05 +0200 Subject: [PATCH 21/50] Release 0.34.0+5 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 373c336dc..ee5d8dd64 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+5-SNAPSHOT + 0.34.0+5 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index b25fe028f..d3f32d9e3 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+5-SNAPSHOT.jar + lib/com-microsoft-java-debug-core-0.34.0+5.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 338599ee4..aee0aa095 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+5-SNAPSHOT + 0.34.0+5 From 4d19fec9777752adb28e8fc905fb9dac0139c8ea Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 3 Oct 2022 11:38:39 +0200 Subject: [PATCH 22/50] Reorder step filter logic --- com.microsoft.java.debug.core/pom.xml | 2 +- .../core/adapter/IStepFilterProvider.java | 2 +- .../adapter/handler/StepRequestHandler.java | 20 ++++++++++++------- .../META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index ee5d8dd64..51fb9891d 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+5 + 0.34.0+6 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index b2db11cbe..0ea2eabb4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -18,5 +18,5 @@ public interface IStepFilterProvider extends IProvider { boolean shouldStepInto(Method method, Requests.StepFilters filters); - boolean shouldStepOut(Location previousLocation, Method method); + boolean shouldStepOut(Location upperLocation, Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index a5aa305b7..7d5799708 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -164,13 +164,18 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, try { Location originalLocation = threadState.stepLocation; Location currentLocation = getTopFrame(thread).location(); - Location previousLocation = null; + Location upperLocation = null; if (thread.frameCount() > 1) { - previousLocation = thread.frame(1).location(); + upperLocation = thread.frame(1).location(); } if (originalLocation != null && currentLocation != null) { boolean steppingIn = threadState.pendingStepType == Command.STEPIN; Requests.StepFilters stepFilters = context.getStepFilters(); + // If we stepped into a method that should be stepped out + if (shouldStepOut(stepFilter, threadState.stackDepth, thread.frameCount(), upperLocation, currentLocation)) { + doExtraStepOut(debugEvent, thread, stepFilters, threadState); + return; + } // If the ending location is the same as the original location do another step into. if (steppingIn && shouldDoExtraStep(threadState.stackDepth, originalLocation, thread.frameCount(), currentLocation)) { doExtraStepInto(debugEvent, thread, stepFilters, threadState); @@ -181,11 +186,6 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, doExtraStepInto(debugEvent, thread, stepFilters, threadState); return; } - // If we stepped into a method that should be stepped out - if (steppingIn && stepFilter.shouldStepOut(previousLocation, currentLocation.method())) { - doExtraStepOut(debugEvent, thread, stepFilters, threadState); - return; - } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException ex) { @@ -225,6 +225,12 @@ private boolean shouldStepInto(IStepFilterProvider stepFilter, Location original && stepFilter.shouldStepInto(currentLocation.method(), stepFilters); } + private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackDepth, int currentStackDepth, Location upperLocation, + Location currentLocation) + throws IncompatibleThreadStateException { + return currentStackDepth > originalStackDepth && stepFilter.shouldStepOut(upperLocation, currentLocation.method()); + } + /** * Check if the current top stack is same as the original top stack. * diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index d3f32d9e3..304af930c 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+5.jar + lib/com-microsoft-java-debug-core-0.34.0+6.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index aee0aa095..e1ed81b2e 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+5 + 0.34.0+6 From be72edb3de54347c776df4655c08f3d90cffaa61 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 4 Oct 2022 14:38:45 +0200 Subject: [PATCH 23/50] Fix restart frame handler StepRequest should be deleted after we receive its corresponding debug event --- .../java/debug/core/adapter/handler/RestartFrameHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java index 3479c9a8a..d2c0388ad 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java @@ -32,6 +32,7 @@ import com.microsoft.java.debug.core.protocol.Requests.RestartFrameArguments; import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; +import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.StepRequest; /** @@ -102,8 +103,10 @@ private void popStackFrames(IDebugAdapterContext context, ThreadReference thread } private void stepInto(IDebugAdapterContext context, ThreadReference thread) { + EventRequestManager manager = context.getDebugSession().getVM().eventRequestManager(); StepRequest request = DebugUtility.createStepIntoRequest(thread, context.getStepFilters().allowClasses, context.getStepFilters().skipClasses); context.getDebugSession().getEventHub().stepEvents().filter(debugEvent -> request.equals(debugEvent.event.request())).take(1).subscribe(debugEvent -> { + DebugUtility.deleteEventRequestSafely(manager, request); debugEvent.shouldResume = false; // Have to send two events to keep the UI sync with the step in operations: context.getProtocolServer().sendEvent(new Events.ContinuedEvent(thread.uniqueID())); From a67da2e63fa19fa69a53302222e315d13e722aaa Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 4 Oct 2022 15:35:33 +0200 Subject: [PATCH 24/50] Bump version to 0.34.0+7-SNAPSHOT --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 51fb9891d..208958c00 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+6 + 0.34.0+7-SNAPSHOT Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 304af930c..8cf046960 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+6.jar + lib/com-microsoft-java-debug-core-0.34.0+7-SNAPSHOT.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index e1ed81b2e..6f3a86fe9 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+6 + 0.34.0+7-SNAPSHOT From 7d928289156689ebdd333ff9ed591889582d146a Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 4 Oct 2022 15:39:17 +0200 Subject: [PATCH 25/50] Fix step handler when upperFrame is null --- .../adapter/handler/StepRequestHandler.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 7d5799708..5492f42a5 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -169,7 +169,6 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, upperLocation = thread.frame(1).location(); } if (originalLocation != null && currentLocation != null) { - boolean steppingIn = threadState.pendingStepType == Command.STEPIN; Requests.StepFilters stepFilters = context.getStepFilters(); // If we stepped into a method that should be stepped out if (shouldStepOut(stepFilter, threadState.stackDepth, thread.frameCount(), upperLocation, currentLocation)) { @@ -177,7 +176,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, return; } // If the ending location is the same as the original location do another step into. - if (steppingIn && shouldDoExtraStep(threadState.stackDepth, originalLocation, thread.frameCount(), currentLocation)) { + if (shouldDoExtraStep(threadState, originalLocation, thread.frameCount(), currentLocation)) { doExtraStepInto(debugEvent, thread, stepFilters, threadState); return; } @@ -228,7 +227,13 @@ private boolean shouldStepInto(IStepFilterProvider stepFilter, Location original private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackDepth, int currentStackDepth, Location upperLocation, Location currentLocation) throws IncompatibleThreadStateException { - return currentStackDepth > originalStackDepth && stepFilter.shouldStepOut(upperLocation, currentLocation.method()); + if (upperLocation == null) { + return false; + } + if (currentStackDepth <= originalStackDepth) { + return false; + } + return stepFilter.shouldStepOut(upperLocation, currentLocation.method()); } /** @@ -237,9 +242,12 @@ private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackD * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldDoExtraStep(int originalStackDepth, Location originalLocation, int currentStackDepth, Location currentLocation) + private boolean shouldDoExtraStep(ThreadState threadState, Location originalLocation, int currentStackDepth, Location currentLocation) throws IncompatibleThreadStateException { - if (originalStackDepth != currentStackDepth) { + if (threadState.pendingStepType != Command.STEPIN) { + return false; + } + if (threadState.stackDepth != currentStackDepth) { return false; } if (originalLocation == null) { From 36a426d19651ca7096450b98d35d95dbf2c8787c Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 5 Oct 2022 20:36:02 +0200 Subject: [PATCH 26/50] Release 0.34.0+7 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 208958c00..533c9d32b 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+7-SNAPSHOT + 0.34.0+7 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 8cf046960..e5918c8f3 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+7-SNAPSHOT.jar + lib/com-microsoft-java-debug-core-0.34.0+7.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 6f3a86fe9..d37b00973 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+7-SNAPSHOT + 0.34.0+7 From 9e23f5b825102dc68aa1766b57d73d23609aa7fd Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 18 Oct 2022 13:46:14 +0200 Subject: [PATCH 27/50] Always disable pending step request before stopping thread This should fix the errors of the kind: [error response][stepOut]: Only one step request allowed per thread --- .../core/adapter/DebugAdapterContext.java | 6 +- .../core/adapter/IDebugAdapterContext.java | 2 +- .../core/adapter/IStepResultManager.java | 24 --- .../core/adapter/StepRequestManager.java | 156 ++++++++++++++++++ .../debug/core/adapter/StepResultManager.java | 42 ----- .../ConfigurationDoneRequestHandler.java | 11 +- .../handler/SetBreakpointsRequestHandler.java | 11 +- .../SetDataBreakpointsRequestHandler.java | 11 +- .../adapter/handler/StepRequestHandler.java | 121 +++++--------- .../handler/ThreadsRequestHandler.java | 27 ++- .../handler/VariablesRequestHandler.java | 2 +- 11 files changed, 248 insertions(+), 165 deletions(-) delete mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepResultManager.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepRequestManager.java delete mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepResultManager.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java index a014f04d6..7ac07673e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java @@ -62,7 +62,7 @@ public class DebugAdapterContext implements IDebugAdapterContext { private IStackFrameManager stackFrameManager = new StackFrameManager(); private IExceptionManager exceptionManager = new ExceptionManager(); private IBreakpointManager breakpointManager; - private IStepResultManager stepResultManager = new StepResultManager(); + private StepRequestManager stepRequestManager = new StepRequestManager(); public DebugAdapterContext(IProtocolServer server, IProviderContext providerContext, Logger logger) { this.providerContext = providerContext; @@ -326,7 +326,7 @@ public IBreakpointManager getBreakpointManager() { } @Override - public IStepResultManager getStepResultManager() { - return stepResultManager; + public StepRequestManager getStepRequestManager() { + return stepRequestManager; } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java index 4f843fd09..9aa0c5341 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java @@ -127,5 +127,5 @@ public interface IDebugAdapterContext { IBreakpointManager getBreakpointManager(); - IStepResultManager getStepResultManager(); + StepRequestManager getStepRequestManager(); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepResultManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepResultManager.java deleted file mode 100644 index c19c0ecd6..000000000 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepResultManager.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2020 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.JdiMethodResult; - -public interface IStepResultManager { - JdiMethodResult setMethodResult(long threadId, JdiMethodResult methodResult); - - JdiMethodResult getMethodResult(long threadId); - - JdiMethodResult removeMethodResult(long threadId); - - void removeAllMethodResults(); -} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepRequestManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepRequestManager.java new file mode 100644 index 000000000..a3794dd07 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepRequestManager.java @@ -0,0 +1,156 @@ +/******************************************************************************* +* Copyright (c) 2020 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 java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.microsoft.java.debug.core.DebugUtility; +import com.microsoft.java.debug.core.JdiMethodResult; +import com.microsoft.java.debug.core.protocol.Requests; +import com.sun.jdi.IncompatibleThreadStateException; +import com.sun.jdi.Location; +import com.sun.jdi.ThreadReference; +import com.sun.jdi.request.EventRequestManager; +import com.sun.jdi.request.MethodExitRequest; +import com.sun.jdi.request.StepRequest; +import io.reactivex.disposables.Disposable; + +public class StepRequestManager { + private final Map threadStates = Collections.synchronizedMap(new HashMap<>()); + + public ThreadState setThreadState(Requests.Command stepType, ThreadReference thread) throws IncompatibleThreadStateException { + long threadId = thread.uniqueID(); + int stackDepth = thread.frameCount(); + Location location = thread.frame(0).location(); + ThreadState threadState = new ThreadState(threadId, stepType, stackDepth, location); + threadStates.put(threadId, threadState); + return threadState; + } + + public ThreadState getThreadState(long threadId) { + return threadStates.get(threadId); + } + + public void setMethodResult(long threadId, JdiMethodResult methodResult) { + ThreadState threadState = getThreadState(threadId); + threadState.methodResult = methodResult; + } + + public JdiMethodResult getMethodResult(long threadId) { + ThreadState threadState = getThreadState(threadId); + if (threadState == null) { + return null; + } + return threadState.methodResult; + } + + public void deletePendingStep(long threadId, EventRequestManager manager) { + ThreadState threadState = getThreadState(threadId); + if (threadState != null) { + threadState.deletePendingStep(manager); + } + } + + public void deleteAllPendingSteps(EventRequestManager manager) { + this.threadStates.forEach((threadId, threadState) -> threadState.deletePendingStep(manager)); + } + + public void removeMethodResult(long threadId) { + ThreadState threadState = getThreadState(threadId); + if (threadState == null) { + return; + } + threadState.methodResult = null; + } + + public void removeAllMethodResults() { + this.threadStates.forEach((threadId, threadState) -> threadState.methodResult = null); + } + + public static class ThreadState { + long threadId; + Requests.Command stepType; + StepRequest pendingStepRequest = null; + MethodExitRequest pendingMethodExitRequest = null; + int stackDepth; + Location stepLocation; + Disposable eventSubscription = null; + JdiMethodResult methodResult = null; + + public ThreadState(long threadId, Requests.Command stepType, int stackDepth, Location stepLocation) { + this.threadId = threadId; + this.stepType = stepType; + this.stackDepth = stackDepth; + this.stepLocation = stepLocation; + } + + public long getThreadId() { + return threadId; + } + + public Requests.Command getStepType() { + return stepType; + } + + public void setPendingMethodExitRequest(MethodExitRequest pendingMethodExitRequest) { + this.pendingMethodExitRequest = pendingMethodExitRequest; + } + + public MethodExitRequest getPendingMethodExitRequest() { + return pendingMethodExitRequest; + } + + public void setPendingStepRequest(StepRequest pendingStepRequest) { + this.pendingStepRequest = pendingStepRequest; + } + + public int getStackDepth() { + return stackDepth; + } + + public StepRequest getPendingStepRequest() { + return pendingStepRequest; + } + + public Location getStepLocation() { + return stepLocation; + } + + public void setEventSubscription(Disposable eventSubscription) { + this.eventSubscription = eventSubscription; + } + + public void deletePendingStep(EventRequestManager manager) { + deleteStepRequest(manager); + deleteMethodExitRequest(manager); + eventSubscription.dispose(); + } + + public void deleteStepRequest(EventRequestManager manager) { + if (this.pendingStepRequest == null) { + return; + } + DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); + this.pendingStepRequest = null; + } + + private void deleteMethodExitRequest(EventRequestManager manager) { + if (this.pendingMethodExitRequest == null) { + return; + } + DebugUtility.deleteEventRequestSafely(manager, this.pendingMethodExitRequest); + this.pendingMethodExitRequest = null; + } + } +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepResultManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepResultManager.java deleted file mode 100644 index dd3937181..000000000 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepResultManager.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* -* Copyright (c) 2020 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 java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.microsoft.java.debug.core.JdiMethodResult; - -public class StepResultManager implements IStepResultManager { - private Map methodResults = Collections.synchronizedMap(new HashMap<>()); - - @Override - public JdiMethodResult setMethodResult(long threadId, JdiMethodResult methodResult) { - return this.methodResults.put(threadId, methodResult); - } - - @Override - public JdiMethodResult getMethodResult(long threadId) { - return this.methodResults.get(threadId); - } - - @Override - public JdiMethodResult removeMethodResult(long threadId) { - return this.methodResults.remove(threadId); - } - - @Override - public void removeAllMethodResults() { - this.methodResults.clear(); - } -} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java index 050e37db8..7263270fb 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java @@ -40,6 +40,7 @@ import com.sun.jdi.event.VMDeathEvent; import com.sun.jdi.event.VMDisconnectEvent; import com.sun.jdi.event.VMStartEvent; +import com.sun.jdi.request.EventRequestManager; public class ConfigurationDoneRequestHandler implements IDebugRequestHandler { protected final Logger logger; @@ -78,7 +79,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (event instanceof VMStartEvent) { if (context.isVmStopOnEntry()) { DebugUtility.stopOnEntry(debugSession, context.getMainClass()).thenAccept(threadId -> { - context.getProtocolServer().sendEvent(new Events.StoppedEvent("entry", threadId)); + notifyStopEvent("entry", threadId, context); }); } } else if (event instanceof VMDeathEvent) { @@ -120,7 +121,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.getProtocolServer().sendEvent(new Events.StoppedEvent("exception", thread.uniqueID())); + notifyStopEvent("exception", thread.uniqueID(), context); debugEvent.shouldResume = false; } else { isImportantEvent = false; @@ -134,4 +135,10 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } } } + + private void notifyStopEvent(String reason, long threadId, IDebugAdapterContext context) { + EventRequestManager eventRequestManager = context.getDebugSession().getVM().eventRequestManager(); + context.getStepRequestManager().deletePendingStep(threadId, eventRequestManager); + context.getProtocolServer().sendEvent(new Events.StoppedEvent(reason, threadId)); + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 29f4b697f..d444e8ef2 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -18,6 +18,7 @@ import java.util.logging.Level; import java.util.logging.Logger; +import com.sun.jdi.request.EventRequestManager; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; @@ -200,12 +201,12 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { if (resume) { debugEvent.eventSet.resume(); } else { - context.getProtocolServer().sendEvent(new Events.StoppedEvent("breakpoint", bpThread.uniqueID())); + notifyStoppedThread(context, bpThread.uniqueID()); } }); }); } else { - context.getProtocolServer().sendEvent(new Events.StoppedEvent("breakpoint", bpThread.uniqueID())); + notifyStoppedThread(context, bpThread.uniqueID()); } debugEvent.shouldResume = false; } @@ -213,6 +214,12 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { } } + private void notifyStoppedThread(IDebugAdapterContext context, long threadId) { + EventRequestManager eventRequestManager = context.getDebugSession().getVM().eventRequestManager(); + context.getStepRequestManager().deletePendingStep(threadId, eventRequestManager); + context.getProtocolServer().sendEvent(new Events.StoppedEvent("breakpoint", threadId)); + } + /** * Check whether the condition expression is satisfied, and return a boolean value to determine to resume the thread or not. */ diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java index 49f69129f..9c7aa73f4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java @@ -19,6 +19,7 @@ import java.util.logging.Logger; import java.util.stream.Stream; +import com.sun.jdi.request.EventRequestManager; import org.apache.commons.lang3.StringUtils; import com.microsoft.java.debug.core.IDebugSession; @@ -158,15 +159,21 @@ private void registerWatchpointHandler(IDebugAdapterContext context) { if (resume) { debugEvent.eventSet.resume(); } else { - context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID())); + notifyStoppedThread(context, bpThread.uniqueID()); } }); }); } else { - context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID())); + notifyStoppedThread(context, bpThread.uniqueID()); } debugEvent.shouldResume = false; }); } } + + private void notifyStoppedThread(IDebugAdapterContext context, long threadId) { + EventRequestManager eventRequestManager = context.getDebugSession().getVM().eventRequestManager(); + context.getStepRequestManager().deletePendingStep(threadId, eventRequestManager); + context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", threadId)); + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 5492f42a5..9fa04e2e2 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -25,6 +25,7 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.IStepFilterProvider; +import com.microsoft.java.debug.core.adapter.StepRequestManager; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests; @@ -39,10 +40,7 @@ import com.sun.jdi.ThreadReference; import com.sun.jdi.Value; import com.sun.jdi.VoidValue; -import com.sun.jdi.event.BreakpointEvent; import com.sun.jdi.event.Event; -import com.sun.jdi.event.ExceptionEvent; -import com.sun.jdi.event.LocatableEvent; import com.sun.jdi.event.MethodExitEvent; import com.sun.jdi.event.StepEvent; import com.sun.jdi.request.EventRequest; @@ -70,38 +68,34 @@ public CompletableFuture handle(Command command, Arguments arguments, ThreadReference thread = DebugUtility.getThread(context.getDebugSession(), threadId); if (thread != null) { JdiExceptionReference exception = context.getExceptionManager().removeException(threadId); - context.getStepResultManager().removeMethodResult(threadId); + context.getStepRequestManager().removeMethodResult(threadId); try { - ThreadState threadState = new ThreadState(); - threadState.threadId = threadId; - threadState.pendingStepType = command; - threadState.stackDepth = thread.frameCount(); - threadState.stepLocation = getTopFrame(thread).location(); - threadState.eventSubscription = context.getDebugSession().getEventHub().events() - .filter(debugEvent -> (debugEvent.event instanceof StepEvent && debugEvent.event.request().equals(threadState.pendingStepRequest)) - || (debugEvent.event instanceof MethodExitEvent && debugEvent.event.request().equals(threadState.pendingMethodExitRequest)) - || debugEvent.event instanceof BreakpointEvent - || debugEvent.event instanceof ExceptionEvent) - .subscribe(debugEvent -> { - handleDebugEvent(debugEvent, context.getDebugSession(), context, threadState); - }); + StepRequestManager stepRequestManager = context.getStepRequestManager(); + StepRequestManager.ThreadState threadState = stepRequestManager.setThreadState(command, thread); + Disposable eventSubscription = context.getDebugSession().getEventHub().events() + .filter(debugEvent -> (debugEvent.event instanceof StepEvent && debugEvent.event.request().equals(threadState.getPendingStepRequest())) + || (debugEvent.event instanceof MethodExitEvent && debugEvent.event.request().equals(threadState.getPendingMethodExitRequest()))) + .subscribe(debugEvent -> handleDebugEvent(debugEvent, context.getDebugSession(), context, threadState)); + threadState.setEventSubscription(eventSubscription); + StepRequest stepRequest; if (command == Command.STEPIN) { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, - context.getStepFilters().allowClasses, - context.getStepFilters().skipClasses); + stepRequest = DebugUtility.createStepIntoRequest(thread, + context.getStepFilters().allowClasses, + context.getStepFilters().skipClasses); } else if (command == Command.STEPOUT) { - threadState.pendingStepRequest = DebugUtility.createStepOutRequest(thread, + stepRequest = DebugUtility.createStepOutRequest(thread, context.getStepFilters().allowClasses, context.getStepFilters().skipClasses); } else { - threadState.pendingStepRequest = DebugUtility.createStepOverRequest(thread, null); + stepRequest = DebugUtility.createStepOverRequest(thread, null); } - threadState.pendingStepRequest.enable(); + threadState.setPendingStepRequest(stepRequest); + stepRequest.enable(); MethodExitRequest methodExitRequest = thread.virtualMachine().eventRequestManager().createMethodExitRequest(); methodExitRequest.addThreadFilter(thread); - methodExitRequest.addClassFilter(threadState.stepLocation.declaringType()); + methodExitRequest.addClassFilter(threadState.getStepLocation().declaringType()); if (thread.virtualMachine().canUseInstanceFilters()) { try { ObjectReference thisObject = getTopFrame(thread).thisObject(); @@ -113,7 +107,7 @@ public CompletableFuture handle(Command command, Arguments arguments, } } methodExitRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); - threadState.pendingMethodExitRequest = methodExitRequest; + threadState.setPendingMethodExitRequest(methodExitRequest); methodExitRequest.enable(); DebugUtility.resumeThread(thread); @@ -142,27 +136,16 @@ public CompletableFuture handle(Command command, Arguments arguments, } private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, IDebugAdapterContext context, - ThreadState threadState) { + StepRequestManager.ThreadState threadState) { Event event = debugEvent.event; EventRequestManager eventRequestManager = debugSession.getVM().eventRequestManager(); - // When a breakpoint occurs, abort any pending step requests from the same thread. - if (event instanceof BreakpointEvent || event instanceof ExceptionEvent) { - long threadId = ((LocatableEvent) event).thread().uniqueID(); - if (threadId == threadState.threadId && threadState.pendingStepRequest != null) { - threadState.deleteStepRequest(eventRequestManager); - threadState.deleteMethodExitRequest(eventRequestManager); - context.getStepResultManager().removeMethodResult(threadId); - if (threadState.eventSubscription != null) { - threadState.eventSubscription.dispose(); - } - } - } else if (event instanceof StepEvent) { + if (event instanceof StepEvent) { ThreadReference thread = ((StepEvent) event).thread(); threadState.deleteStepRequest(eventRequestManager); IStepFilterProvider stepFilter = context.getProvider(IStepFilterProvider.class); try { - Location originalLocation = threadState.stepLocation; + Location originalLocation = threadState.getStepLocation(); Location currentLocation = getTopFrame(thread).location(); Location upperLocation = null; if (thread.frameCount() > 1) { @@ -171,7 +154,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (originalLocation != null && currentLocation != null) { Requests.StepFilters stepFilters = context.getStepFilters(); // If we stepped into a method that should be stepped out - if (shouldStepOut(stepFilter, threadState.stackDepth, thread.frameCount(), upperLocation, currentLocation)) { + if (shouldStepOut(stepFilter, threadState.getStackDepth(), thread.frameCount(), upperLocation, currentLocation)) { doExtraStepOut(debugEvent, thread, stepFilters, threadState); return; } @@ -190,22 +173,19 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } catch (IncompatibleThreadStateException | IndexOutOfBoundsException ex) { // ignore. } - threadState.deleteMethodExitRequest(eventRequestManager); - if (threadState.eventSubscription != null) { - threadState.eventSubscription.dispose(); - } - context.getProtocolServer().sendEvent(new Events.StoppedEvent("step", thread.uniqueID())); + threadState.deletePendingStep(eventRequestManager); + context.getProtocolServer().sendEvent(new Events.StoppedEvent("step", threadState.getThreadId())); debugEvent.shouldResume = false; } else if (event instanceof MethodExitEvent) { MethodExitEvent methodExitEvent = (MethodExitEvent) event; long threadId = methodExitEvent.thread().uniqueID(); - if (threadId == threadState.threadId && methodExitEvent.method().equals(threadState.stepLocation.method())) { + if (threadId == threadState.getThreadId() && methodExitEvent.method().equals(threadState.getStepLocation().method())) { Value returnValue = methodExitEvent.returnValue(); if (returnValue instanceof VoidValue) { - context.getStepResultManager().removeMethodResult(threadId); + context.getStepRequestManager().removeMethodResult(threadId); } else { JdiMethodResult methodResult = new JdiMethodResult(methodExitEvent.method(), returnValue); - context.getStepResultManager().setMethodResult(threadId, methodResult); + context.getStepRequestManager().setMethodResult(threadId, methodResult); } } debugEvent.shouldResume = true; @@ -242,12 +222,12 @@ private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackD * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldDoExtraStep(ThreadState threadState, Location originalLocation, int currentStackDepth, Location currentLocation) + private boolean shouldDoExtraStep(StepRequestManager.ThreadState threadState, Location originalLocation, int currentStackDepth, Location currentLocation) throws IncompatibleThreadStateException { - if (threadState.pendingStepType != Command.STEPIN) { + if (threadState.getStepType() != Command.STEPIN) { return false; } - if (threadState.stackDepth != currentStackDepth) { + if (threadState.getStackDepth() != currentStackDepth) { return false; } if (originalLocation == null) { @@ -258,21 +238,20 @@ private boolean shouldDoExtraStep(ThreadState threadState, Location originalLoca if (!originalMethod.equals(currentMethod)) { return false; } - if (originalLocation.lineNumber() != currentLocation.lineNumber()) { - return false; - } - return true; + return originalLocation.lineNumber() == currentLocation.lineNumber(); } - private void doExtraStepInto(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, ThreadState threadState) { - threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); - threadState.pendingStepRequest.enable(); + private void doExtraStepInto(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, StepRequestManager.ThreadState threadState) { + StepRequest stepRequest = DebugUtility.createStepIntoRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); + threadState.setPendingStepRequest(stepRequest); + stepRequest.enable(); debugEvent.shouldResume = true; } - private void doExtraStepOut(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, ThreadState threadState) { - threadState.pendingStepRequest = DebugUtility.createStepOutRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); - threadState.pendingStepRequest.enable(); + private void doExtraStepOut(DebugEvent debugEvent, ThreadReference thread, Requests.StepFilters stepFilters, StepRequestManager.ThreadState threadState) { + StepRequest stepRequest = DebugUtility.createStepOutRequest(thread, stepFilters.allowClasses, stepFilters.skipClasses); + threadState.setPendingStepRequest(stepRequest); + stepRequest.enable(); debugEvent.shouldResume = true; } @@ -290,24 +269,4 @@ private void doExtraStepOut(DebugEvent debugEvent, ThreadReference thread, Reque private StackFrame getTopFrame(ThreadReference thread) throws IncompatibleThreadStateException { return thread.frame(0); } - - class ThreadState { - long threadId = -1; - Command pendingStepType; - StepRequest pendingStepRequest = null; - MethodExitRequest pendingMethodExitRequest = null; - int stackDepth = -1; - Location stepLocation = null; - Disposable eventSubscription = null; - - public void deleteMethodExitRequest(EventRequestManager manager) { - DebugUtility.deleteEventRequestSafely(manager, this.pendingMethodExitRequest); - this.pendingMethodExitRequest = null; - } - - public void deleteStepRequest(EventRequestManager manager) { - DebugUtility.deleteEventRequestSafely(manager, this.pendingStepRequest); - this.pendingStepRequest = null; - } - } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java index 3e4b481d5..20e2bf868 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java @@ -17,11 +17,13 @@ import java.util.concurrent.CompletableFuture; import com.microsoft.java.debug.core.DebugUtility; +import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.ErrorCode; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.IEvaluationProvider; +import com.microsoft.java.debug.core.adapter.StepRequestManager; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests; @@ -36,6 +38,7 @@ import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ThreadReference; import com.sun.jdi.VMDisconnectedException; +import com.sun.jdi.request.EventRequestManager; public class ThreadsRequestHandler implements IDebugRequestHandler { @@ -93,14 +96,19 @@ private CompletableFuture threads(Requests.ThreadsArguments arguments, } private CompletableFuture pause(Requests.PauseArguments arguments, Response response, IDebugAdapterContext context) { - ThreadReference thread = DebugUtility.getThread(context.getDebugSession(), arguments.threadId); + StepRequestManager stepRequestManager = context.getStepRequestManager(); + IDebugSession debugSession = context.getDebugSession(); + EventRequestManager eventRequestManager = debugSession.getVM().eventRequestManager(); + ThreadReference thread = DebugUtility.getThread(debugSession, arguments.threadId); if (thread != null) { - context.getStepResultManager().removeMethodResult(arguments.threadId); + stepRequestManager.removeMethodResult(arguments.threadId); + stepRequestManager.deletePendingStep(arguments.threadId, eventRequestManager); thread.suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId)); } else { - context.getStepResultManager().removeAllMethodResults(); - context.getDebugSession().suspend(); + stepRequestManager.removeAllMethodResults(); + stepRequestManager.deleteAllPendingSteps(eventRequestManager); + debugSession.suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId, true)); } return CompletableFuture.completedFuture(response); @@ -115,13 +123,13 @@ private CompletableFuture resume(Requests.ContinueArguments arguments, * be resumed (through ThreadReference#resume() or VirtualMachine#resume()) the same number of times it has been suspended. */ if (thread != null) { - context.getStepResultManager().removeMethodResult(arguments.threadId); + context.getStepRequestManager().removeMethodResult(arguments.threadId); context.getExceptionManager().removeException(arguments.threadId); allThreadsContinued = false; DebugUtility.resumeThread(thread); checkThreadRunningAndRecycleIds(thread, context); } else { - context.getStepResultManager().removeAllMethodResults(); + context.getStepRequestManager().removeAllMethodResults(); context.getExceptionManager().removeAllExceptions(); context.getDebugSession().resume(); context.getRecyclableIdPool().removeAllObjects(); @@ -154,7 +162,12 @@ private CompletableFuture resumeOthers(Requests.ThreadOperationArgumen } private CompletableFuture pauseAll(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) { - context.getDebugSession().suspend(); + StepRequestManager stepRequestManager = context.getStepRequestManager(); + IDebugSession debugSession = context.getDebugSession(); + EventRequestManager eventRequestManager = debugSession.getVM().eventRequestManager(); + stepRequestManager.removeAllMethodResults(); + stepRequestManager.deleteAllPendingSteps(eventRequestManager); + debugSession.suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId, true)); return CompletableFuture.completedFuture(response); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index d6f9f1ca4..73574e238 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -111,7 +111,7 @@ public CompletableFuture handle(Command command, Arguments arguments, } try { long threadId = stackFrameReference.getThread().uniqueID(); - JdiMethodResult result = context.getStepResultManager().getMethodResult(threadId); + JdiMethodResult result = context.getStepRequestManager().getMethodResult(threadId); if (result != null) { String returnIcon = (AdapterUtils.isWin || AdapterUtils.isMac) ? "⎯►" : "->"; childrenList.add(new Variable(returnIcon + result.method.name() + "()", result.value, null)); From d2899748ae3a8bb94065c6dd15ec83b29cff2649 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 18 Oct 2022 14:42:34 +0200 Subject: [PATCH 28/50] Skip breakpoint if shouldSkipOver Do not stop on a breakpoint if the IStepFilterProvider says the step should be skip over --- .../debug/core/adapter/IStepFilterProvider.java | 4 ++-- .../debug/core/adapter/StepFilterProvider.java | 4 ++-- .../handler/SetBreakpointsRequestHandler.java | 9 +++++++++ .../core/adapter/handler/StepRequestHandler.java | 14 +++++++------- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index 0ea2eabb4..6199cca3d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -16,7 +16,7 @@ import com.sun.jdi.Method; public interface IStepFilterProvider extends IProvider { - boolean shouldStepInto(Method method, Requests.StepFilters filters); + boolean shouldSkipOver(Method method, Requests.StepFilters filters); - boolean shouldStepOut(Location upperLocation, Method method); + boolean shouldSkipOut(Location upperLocation, Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java index ca434980d..f7200d547 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -18,7 +18,7 @@ public class StepFilterProvider implements IStepFilterProvider { @Override - public boolean shouldStepInto(Method method, Requests.StepFilters filters) { + public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { if (!isConfigured(filters)) { return false; } @@ -28,7 +28,7 @@ public boolean shouldStepInto(Method method, Requests.StepFilters filters) { } @Override - public boolean shouldStepOut(Location previousLocation, Method method) { + public boolean shouldSkipOut(Location previousLocation, Method method) { return false; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index d444e8ef2..78c844f11 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -34,6 +34,7 @@ import com.microsoft.java.debug.core.adapter.IEvaluationProvider; import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; +import com.microsoft.java.debug.core.adapter.IStepFilterProvider; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; @@ -43,6 +44,7 @@ import com.microsoft.java.debug.core.protocol.Types; import com.sun.jdi.BooleanValue; import com.sun.jdi.Field; +import com.sun.jdi.Method; import com.sun.jdi.ObjectReference; import com.sun.jdi.ReferenceType; import com.sun.jdi.ThreadReference; @@ -175,6 +177,7 @@ private IBreakpoint getAssociatedEvaluatableBreakpoint(IDebugAdapterContext cont private void registerBreakpointHandler(IDebugAdapterContext context) { IDebugSession debugSession = context.getDebugSession(); + IStepFilterProvider stepFilterProvider = context.getProvider(IStepFilterProvider.class); if (debugSession != null) { debugSession.getEventHub().events().filter(debugEvent -> debugEvent.event instanceof BreakpointEvent).subscribe(debugEvent -> { Event event = debugEvent.event; @@ -185,6 +188,12 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { ThreadReference bpThread = ((BreakpointEvent) event).thread(); IEvaluationProvider engine = context.getProvider(IEvaluationProvider.class); if (engine.isInEvaluation(bpThread)) { + debugEvent.shouldResume = true; + return; + } + Method method = bpThread.frame(0).location().method(); + if (stepFilterProvider.shouldSkipOver(method, context.getStepFilters())) { + debugEvent.shouldResume = true; return; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 9fa04e2e2..c785004de 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -154,7 +154,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (originalLocation != null && currentLocation != null) { Requests.StepFilters stepFilters = context.getStepFilters(); // If we stepped into a method that should be stepped out - if (shouldStepOut(stepFilter, threadState.getStackDepth(), thread.frameCount(), upperLocation, currentLocation)) { + if (shouldSkipOut(stepFilter, threadState.getStackDepth(), thread.frameCount(), upperLocation, currentLocation)) { doExtraStepOut(debugEvent, thread, stepFilters, threadState); return; } @@ -164,7 +164,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, return; } // If the ending location should be stepped into - if (shouldStepInto(stepFilter, originalLocation, currentLocation, stepFilters)) { + if (shouldSkipOver(stepFilter, originalLocation, currentLocation, stepFilters)) { doExtraStepInto(debugEvent, thread, stepFilters, threadState); return; } @@ -198,13 +198,13 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldStepInto(IStepFilterProvider stepFilter, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) + private boolean shouldSkipOver(IStepFilterProvider stepFilter, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) throws IncompatibleThreadStateException { - return !stepFilter.shouldStepInto(originalLocation.method(), stepFilters) - && stepFilter.shouldStepInto(currentLocation.method(), stepFilters); + return !stepFilter.shouldSkipOver(originalLocation.method(), stepFilters) + && stepFilter.shouldSkipOver(currentLocation.method(), stepFilters); } - private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackDepth, int currentStackDepth, Location upperLocation, + private boolean shouldSkipOut(IStepFilterProvider stepFilter, int originalStackDepth, int currentStackDepth, Location upperLocation, Location currentLocation) throws IncompatibleThreadStateException { if (upperLocation == null) { @@ -213,7 +213,7 @@ private boolean shouldStepOut(IStepFilterProvider stepFilter, int originalStackD if (currentStackDepth <= originalStackDepth) { return false; } - return stepFilter.shouldStepOut(upperLocation, currentLocation.method()); + return stepFilter.shouldSkipOut(upperLocation, currentLocation.method()); } /** From 11bf651b44720cd5edb9162b4fc2e0667bc1aeb9 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 19 Oct 2022 11:54:29 +0200 Subject: [PATCH 29/50] Release 0.34.0+8 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 533c9d32b..8255f64ec 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+7 + 0.34.0+8 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index e5918c8f3..84f8b804f 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+7.jar + lib/com-microsoft-java-debug-core-0.34.0+8.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index d37b00973..85c34d4a3 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+7 + 0.34.0+8 From acd27e0ee826c9ad61802b97ecfb715886852639 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 20 Oct 2022 15:23:26 +0200 Subject: [PATCH 30/50] Deactivate evaluate for hovers --- .../debug/core/adapter/handler/InitializeRequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java index 4733170eb..e01d4b370 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/InitializeRequestHandler.java @@ -54,7 +54,7 @@ public CompletableFuture handle(Requests.Command command, Req caps.supportsCompletionsRequest = true; caps.supportsRestartFrame = true; caps.supportsLogPoints = true; - caps.supportsEvaluateForHovers = true; + caps.supportsEvaluateForHovers = false; Types.ExceptionBreakpointFilter[] exceptionFilters = { Types.ExceptionBreakpointFilter.UNCAUGHT_EXCEPTION_FILTER, Types.ExceptionBreakpointFilter.CAUGHT_EXCEPTION_FILTER, From d91006d6f744c4c356b7cf21cd782c085739032f Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 20 Oct 2022 15:24:19 +0200 Subject: [PATCH 31/50] Release 0.34.0+9 --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 8255f64ec..e4cb6aba9 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -8,7 +8,7 @@ ${base.name} :: Debugger Core The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/scalacenter/java-debug - 0.34.0+8 + 0.34.0+9 Java Debug Server for Visual Studio Code UTF-8 diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 84f8b804f..83ac9c400 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.10.0.jar, ., lib/rxjava-2.1.1.jar, lib/reactive-streams-1.0.0.jar, - lib/com-microsoft-java-debug-core-0.34.0+8.jar + lib/com-microsoft-java-debug-core-0.34.0+9.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 85c34d4a3..d672ac5ee 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -45,7 +45,7 @@ ch.epfl.scala com-microsoft-java-debug-core - 0.34.0+8 + 0.34.0+9 From c4af5524199767f0162a8aae624a27ffc0f3310e Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 28 Oct 2022 16:52:29 +0200 Subject: [PATCH 32/50] Fix Java doc generation --- .../com/microsoft/java/debug/core/adapter/AdapterUtils.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java index 74d3fb292..414d01daf 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java @@ -73,9 +73,9 @@ public static String sourceLookup(String[] sourcePaths, String sourceName) { /** * Get the enclosing type name of the given fully qualified name. *
-     * a.b.c        ->   a.b.c
-     * a.b.c$1      ->   a.b.c
-     * a.b.c$1$2    ->   a.b.c
+     * a.b.c     = a.b.c
+     * a.b.c$1   = a.b.c
+     * a.b.c$1$2 = a.b.c
      * 
* @param fullyQualifiedName * fully qualified name From bdf8433cd446815b7a556571c30b78aada32a34c Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 3 Nov 2022 08:36:51 +0100 Subject: [PATCH 33/50] update .project --- .project | 4 ++-- com.microsoft.java.debug.core/.project | 4 ++-- com.microsoft.java.debug.plugin/.project | 4 ++-- com.microsoft.java.debug.repository/.project | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.project b/.project index d34865de3..71876c8c9 100644 --- a/.project +++ b/.project @@ -16,12 +16,12 @@ - 1600224298170 + 1667383449012 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ diff --git a/com.microsoft.java.debug.core/.project b/com.microsoft.java.debug.core/.project index a7480133e..5215cd389 100644 --- a/com.microsoft.java.debug.core/.project +++ b/com.microsoft.java.debug.core/.project @@ -28,12 +28,12 @@ - 1599036548523 + 1667383449000 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ diff --git a/com.microsoft.java.debug.plugin/.project b/com.microsoft.java.debug.plugin/.project index 72ba17ff7..e24c2da8b 100644 --- a/com.microsoft.java.debug.plugin/.project +++ b/com.microsoft.java.debug.plugin/.project @@ -39,12 +39,12 @@ - 1599036548577 + 1667383449005 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ diff --git a/com.microsoft.java.debug.repository/.project b/com.microsoft.java.debug.repository/.project index 887e4a7a8..88af6b38a 100644 --- a/com.microsoft.java.debug.repository/.project +++ b/com.microsoft.java.debug.repository/.project @@ -16,12 +16,12 @@ - 1600224298119 + 1667383449009 30 org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ From 798d5f7bd9959e6c2b89a808d7772227346c313e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 30 Mar 2023 14:35:55 +0200 Subject: [PATCH 34/50] Add format in IStepFilterProvider --- .../core/adapter/IStepFilterProvider.java | 3 ++ .../core/adapter/StepFilterProvider.java | 15 ++++++++ .../handler/StackTraceRequestHandler.java | 38 +++++++++++++------ .../formatter/CharacterFormatterTest.java | 6 +-- 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index 6199cca3d..8e2e5906e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -14,9 +14,12 @@ import com.microsoft.java.debug.core.protocol.Requests; import com.sun.jdi.Location; import com.sun.jdi.Method; +import java.util.Optional; public interface IStepFilterProvider extends IProvider { boolean shouldSkipOver(Method method, Requests.StepFilters filters); + boolean shouldSkipFrame(Method method); + Optional formatMethodName(Method method ); boolean shouldSkipOut(Location upperLocation, Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java index f7200d547..d0ecc4ccc 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -15,6 +15,7 @@ import com.sun.jdi.Location; import com.sun.jdi.Method; import org.apache.commons.lang3.ArrayUtils; +import java.util.Optional; public class StepFilterProvider implements IStepFilterProvider { @Override @@ -26,6 +27,7 @@ public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { || (filters.skipSynthetics && method.isSynthetic()) || (filters.skipConstructors && method.isConstructor()); } + @Override public boolean shouldSkipOut(Location previousLocation, Method method) { @@ -40,4 +42,17 @@ private boolean isConfigured(Requests.StepFilters filters) { || ArrayUtils.isNotEmpty(filters.classNameFilters) || filters.skipConstructors || filters.skipStaticInitializers || filters.skipSynthetics; } + + + @Override + public boolean shouldSkipFrame(Method method) { + return false; + } + + + @Override + public Optional formatMethodName(Method method) { + return Optional.of(method.name()); + } + } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 089a55b9d..ee0ada993 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -19,6 +19,7 @@ import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; +import org.apache.commons.io.filefilter.TrueFileFilter; import org.apache.commons.lang3.StringUtils; import com.microsoft.java.debug.core.DebugUtility; @@ -26,12 +27,14 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; +import com.microsoft.java.debug.core.adapter.IStepFilterProvider; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; 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.StackTraceArguments; +import com.microsoft.java.debug.core.protocol.Requests; import com.microsoft.java.debug.core.protocol.Responses; import com.microsoft.java.debug.core.protocol.Types; import com.sun.jdi.AbsentInformationException; @@ -41,6 +44,7 @@ import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; +import java.util.Optional; public class StackTraceRequestHandler implements IDebugRequestHandler { @@ -61,22 +65,30 @@ public CompletableFuture handle(Command command, Arguments arguments, int totalFrames = 0; if (thread != null) { try { + totalFrames = thread.frameCount(); if (totalFrames <= stacktraceArgs.startFrame) { response.body = new Responses.StackTraceResponseBody(result, totalFrames); return CompletableFuture.completedFuture(response); } StackFrame[] frames = context.getStackFrameManager().reloadStackFrames(thread); - + int count = stacktraceArgs.levels == 0 ? totalFrames - stacktraceArgs.startFrame : Math.min(totalFrames - stacktraceArgs.startFrame, stacktraceArgs.levels); for (int i = stacktraceArgs.startFrame; i < frames.length && count-- > 0; i++) { StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); - result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context)); + IStepFilterProvider stackTraceFilterProvider = context.getProvider(IStepFilterProvider.class); + Optional optionalFormattedName = stackTraceFilterProvider.formatMethodName(thread.frame(i).location().method()); + + + if(!stackTraceFilterProvider.shouldSkipFrame(thread.frame(i).location().method()) && !optionalFormattedName.isEmpty() ) + result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context,optionalFormattedName.get())); } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { + e.printStackTrace(); + System.out.println(e.getMessage()); // when error happens, the possible reason is: // 1. the vscode has wrong parameter/wrong uri // 2. the thread actually terminates @@ -87,25 +99,26 @@ public CompletableFuture handle(Command command, Arguments arguments, return CompletableFuture.completedFuture(response); } - private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context) + private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context,String formattedName) throws URISyntaxException, AbsentInformationException { Location location = stackFrame.location(); Method method = location.method(); Types.Source clientSource = this.convertDebuggerSourceToClient(location, context); - String methodName = formatMethodName(method, true, true); + //String methodName = formatMethodName(method, true, true,formattedName); int lineNumber = AdapterUtils.convertLineNumber(location.lineNumber(), context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); // Line number returns -1 if the information is not available; specifically, always returns -1 for native methods. if (lineNumber < 0) { if (method.isNative()) { // For native method, display a tip text "native method" in the Call Stack View. - methodName += "[native method]"; + formattedName += "[native method]"; } else { // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, // display "Unknown Source" in the Call Stack View. clientSource = null; } } - return new Types.StackFrame(frameId, methodName, clientSource, lineNumber, context.isClientColumnsStartAt1() ? 1 : 0); + + return new Types.StackFrame(frameId, formattedName, clientSource, lineNumber, context.isClientColumnsStartAt1() ? 1 : 0); } private Types.Source convertDebuggerSourceToClient(Location location, IDebugAdapterContext context) throws URISyntaxException { @@ -133,6 +146,7 @@ public static Types.Source convertDebuggerSourceToClient(String fullyQualifiedNa IDebugAdapterContext context) throws URISyntaxException { // use a lru cache for better performance String uri = context.getSourceLookupCache().computeIfAbsent(fullyQualifiedName, key -> { + String fromProvider = context.getProvider(ISourceLookUpProvider.class).getSourceFileURI(key, relativeSourcePath); // avoid return null which will cause the compute function executed again return StringUtils.isBlank(fromProvider) ? "" : fromProvider; @@ -162,14 +176,14 @@ public static Types.Source convertDebuggerSourceToClient(String fullyQualifiedNa } } - private String formatMethodName(Method method, boolean showContextClass, boolean showParameter) { + private String formatMethodName(Method method, boolean showContextClass, boolean showParameter,String formattedNameString) { StringBuilder formattedName = new StringBuilder(); - if (showContextClass) { - String fullyQualifiedClassName = method.declaringType().name(); - formattedName.append(SimpleTypeFormatter.trimTypeName(fullyQualifiedClassName)); + /* if (showContextClass) { + // String fullyQualifiedClassName = method.declaringType().name(); + formattedName.append(SimpleTypeFormatter.trimTypeName(formattedNameString)); formattedName.append("."); - } - formattedName.append(method.name()); + }*/ + formattedName.append(formattedNameString); if (showParameter) { List argumentTypeNames = method.argumentTypeNames().stream().map(SimpleTypeFormatter::trimTypeName).collect(Collectors.toList()); formattedName.append("("); diff --git a/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/adapter/formatter/CharacterFormatterTest.java b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/adapter/formatter/CharacterFormatterTest.java index 3c6bd0700..1c0505407 100644 --- a/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/adapter/formatter/CharacterFormatterTest.java +++ b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/adapter/formatter/CharacterFormatterTest.java @@ -71,9 +71,9 @@ public void testToString() throws Exception { assertEquals("Should be able to format char type.", "?", formatter.toString(charVar, options)); - charVar = getVM().mirrorOf('中'); - assertEquals("Should be able to format char type.", "中", - formatter.toString(charVar, options)); + // charVar = getVM().mirrorOf('中'); + // assertEquals("Should be able to format char type.", "中", + // formatter.toString(charVar, options)); } @Test From 5c4ff53a69a76593c76bf55886aa28cd3d6f8deb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 May 2023 14:32:42 +0200 Subject: [PATCH 35/50] rename formatMethodSig --- .../microsoft/java/debug/core/adapter/IStepFilterProvider.java | 2 +- .../microsoft/java/debug/core/adapter/StepFilterProvider.java | 2 +- .../debug/core/adapter/handler/StackTraceRequestHandler.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java index 8e2e5906e..5173bb035 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java @@ -19,7 +19,7 @@ public interface IStepFilterProvider extends IProvider { boolean shouldSkipOver(Method method, Requests.StepFilters filters); boolean shouldSkipFrame(Method method); - Optional formatMethodName(Method method ); + Optional formatMethodSig(Method method ); boolean shouldSkipOut(Location upperLocation, Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java index d0ecc4ccc..19216cbe9 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java @@ -51,7 +51,7 @@ public boolean shouldSkipFrame(Method method) { @Override - public Optional formatMethodName(Method method) { + public Optional formatMethodSig(Method method) { return Optional.of(method.name()); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index ee0ada993..10e401d5e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -79,7 +79,7 @@ public CompletableFuture handle(Command command, Arguments arguments, StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); IStepFilterProvider stackTraceFilterProvider = context.getProvider(IStepFilterProvider.class); - Optional optionalFormattedName = stackTraceFilterProvider.formatMethodName(thread.frame(i).location().method()); + Optional optionalFormattedName = stackTraceFilterProvider.formatMethodSig(thread.frame(i).location().method()); if(!stackTraceFilterProvider.shouldSkipFrame(thread.frame(i).location().method()) && !optionalFormattedName.isEmpty() ) From bf0ce152b92a8fe897006429e045c4047912aa28 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 11 May 2023 14:39:23 +0200 Subject: [PATCH 36/50] Fix Java 8 compat --- .../debug/core/adapter/handler/StackTraceRequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 10e401d5e..0b7a8dbb1 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -82,7 +82,7 @@ public CompletableFuture handle(Command command, Arguments arguments, Optional optionalFormattedName = stackTraceFilterProvider.formatMethodSig(thread.frame(i).location().method()); - if(!stackTraceFilterProvider.shouldSkipFrame(thread.frame(i).location().method()) && !optionalFormattedName.isEmpty() ) + if(!stackTraceFilterProvider.shouldSkipFrame(thread.frame(i).location().method()) && optionalFormattedName.isPresent() ) result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context,optionalFormattedName.get())); } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException From 14854c6282c86eba6e084f81b92b6f9788f35fe4 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 16 Jun 2023 10:53:01 +0200 Subject: [PATCH 37/50] Rename IStepFilterProvider to IStackTraceProvider --- ...Provider.java => IStackTraceProvider.java} | 6 ++--- ...rProvider.java => StackTraceProvider.java} | 22 ++++++------------- .../handler/SetBreakpointsRequestHandler.java | 6 ++--- .../handler/StackTraceRequestHandler.java | 10 ++++----- .../adapter/handler/StepRequestHandler.java | 18 +++++++-------- 5 files changed, 26 insertions(+), 36 deletions(-) rename com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/{IStepFilterProvider.java => IStackTraceProvider.java} (84%) rename com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/{StepFilterProvider.java => StackTraceProvider.java} (88%) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java similarity index 84% rename from com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java rename to com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java index 5173bb035..1bec8e33b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java @@ -16,10 +16,8 @@ import com.sun.jdi.Method; import java.util.Optional; -public interface IStepFilterProvider extends IProvider { +public interface IStackTraceProvider extends IProvider { boolean shouldSkipOver(Method method, Requests.StepFilters filters); - boolean shouldSkipFrame(Method method); - Optional formatMethodSig(Method method ); - boolean shouldSkipOut(Location upperLocation, Method method); + Optional formatMethod(Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java similarity index 88% rename from com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java rename to com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java index 19216cbe9..5c8d2a7a9 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StepFilterProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java @@ -17,7 +17,7 @@ import org.apache.commons.lang3.ArrayUtils; import java.util.Optional; -public class StepFilterProvider implements IStepFilterProvider { +public class StackTraceProvider implements IStackTraceProvider { @Override public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { if (!isConfigured(filters)) { @@ -27,13 +27,18 @@ public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { || (filters.skipSynthetics && method.isSynthetic()) || (filters.skipConstructors && method.isConstructor()); } - @Override public boolean shouldSkipOut(Location previousLocation, Method method) { return false; } + + @Override + public Optional formatMethod(Method method) { + return Optional.of(method.name()); + } + private boolean isConfigured(Requests.StepFilters filters) { if (filters == null) { return false; @@ -42,17 +47,4 @@ private boolean isConfigured(Requests.StepFilters filters) { || ArrayUtils.isNotEmpty(filters.classNameFilters) || filters.skipConstructors || filters.skipStaticInitializers || filters.skipSynthetics; } - - - @Override - public boolean shouldSkipFrame(Method method) { - return false; - } - - - @Override - public Optional formatMethodSig(Method method) { - return Optional.of(method.name()); - } - } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 78c844f11..75fc91484 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -34,7 +34,7 @@ import com.microsoft.java.debug.core.adapter.IEvaluationProvider; import com.microsoft.java.debug.core.adapter.IHotCodeReplaceProvider; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; -import com.microsoft.java.debug.core.adapter.IStepFilterProvider; +import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; @@ -177,7 +177,7 @@ private IBreakpoint getAssociatedEvaluatableBreakpoint(IDebugAdapterContext cont private void registerBreakpointHandler(IDebugAdapterContext context) { IDebugSession debugSession = context.getDebugSession(); - IStepFilterProvider stepFilterProvider = context.getProvider(IStepFilterProvider.class); + IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); if (debugSession != null) { debugSession.getEventHub().events().filter(debugEvent -> debugEvent.event instanceof BreakpointEvent).subscribe(debugEvent -> { Event event = debugEvent.event; @@ -192,7 +192,7 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { return; } Method method = bpThread.frame(0).location().method(); - if (stepFilterProvider.shouldSkipOver(method, context.getStepFilters())) { + if (stackTraceProvider.shouldSkipOver(method, context.getStepFilters())) { debugEvent.shouldResume = true; return; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 0b7a8dbb1..0f7f0f3ee 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -27,7 +27,7 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; -import com.microsoft.java.debug.core.adapter.IStepFilterProvider; +import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; import com.microsoft.java.debug.core.protocol.Messages.Response; @@ -78,12 +78,12 @@ public CompletableFuture handle(Command command, Arguments arguments, for (int i = stacktraceArgs.startFrame; i < frames.length && count-- > 0; i++) { StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); - IStepFilterProvider stackTraceFilterProvider = context.getProvider(IStepFilterProvider.class); - Optional optionalFormattedName = stackTraceFilterProvider.formatMethodSig(thread.frame(i).location().method()); + IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); + Optional formattedMethod = stackTraceProvider.formatMethod(thread.frame(i).location().method()); - if(!stackTraceFilterProvider.shouldSkipFrame(thread.frame(i).location().method()) && optionalFormattedName.isPresent() ) - result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context,optionalFormattedName.get())); + if(formattedMethod.isPresent() ) + result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, formattedMethod.get())); } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index c785004de..ae87035c8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -24,7 +24,7 @@ import com.microsoft.java.debug.core.adapter.ErrorCode; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; -import com.microsoft.java.debug.core.adapter.IStepFilterProvider; +import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.StepRequestManager; import com.microsoft.java.debug.core.protocol.Events; import com.microsoft.java.debug.core.protocol.Messages.Response; @@ -143,7 +143,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (event instanceof StepEvent) { ThreadReference thread = ((StepEvent) event).thread(); threadState.deleteStepRequest(eventRequestManager); - IStepFilterProvider stepFilter = context.getProvider(IStepFilterProvider.class); + IStackTraceProvider stackTrace = context.getProvider(IStackTraceProvider.class); try { Location originalLocation = threadState.getStepLocation(); Location currentLocation = getTopFrame(thread).location(); @@ -154,7 +154,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (originalLocation != null && currentLocation != null) { Requests.StepFilters stepFilters = context.getStepFilters(); // If we stepped into a method that should be stepped out - if (shouldSkipOut(stepFilter, threadState.getStackDepth(), thread.frameCount(), upperLocation, currentLocation)) { + if (shouldSkipOut(stackTrace, threadState.getStackDepth(), thread.frameCount(), upperLocation, currentLocation)) { doExtraStepOut(debugEvent, thread, stepFilters, threadState); return; } @@ -164,7 +164,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, return; } // If the ending location should be stepped into - if (shouldSkipOver(stepFilter, originalLocation, currentLocation, stepFilters)) { + if (shouldSkipOver(stackTrace, originalLocation, currentLocation, stepFilters)) { doExtraStepInto(debugEvent, thread, stepFilters, threadState); return; } @@ -198,13 +198,13 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, * @throws IncompatibleThreadStateException * if the thread is not suspended in the target VM. */ - private boolean shouldSkipOver(IStepFilterProvider stepFilter, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) + private boolean shouldSkipOver(IStackTraceProvider stackTrace, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) throws IncompatibleThreadStateException { - return !stepFilter.shouldSkipOver(originalLocation.method(), stepFilters) - && stepFilter.shouldSkipOver(currentLocation.method(), stepFilters); + return !stackTrace.shouldSkipOver(originalLocation.method(), stepFilters) + && stackTrace.shouldSkipOver(currentLocation.method(), stepFilters); } - private boolean shouldSkipOut(IStepFilterProvider stepFilter, int originalStackDepth, int currentStackDepth, Location upperLocation, + private boolean shouldSkipOut(IStackTraceProvider stackTrace, int originalStackDepth, int currentStackDepth, Location upperLocation, Location currentLocation) throws IncompatibleThreadStateException { if (upperLocation == null) { @@ -213,7 +213,7 @@ private boolean shouldSkipOut(IStepFilterProvider stepFilter, int originalStackD if (currentStackDepth <= originalStackDepth) { return false; } - return stepFilter.shouldSkipOut(upperLocation, currentLocation.method()); + return stackTrace.shouldSkipOut(upperLocation, currentLocation.method()); } /** From 23df7eb041adbcfbde6a4b4f9118605c1bae9d16 Mon Sep 17 00:00:00 2001 From: Lucas Nouguier Date: Tue, 20 Jun 2023 09:53:56 +0200 Subject: [PATCH 38/50] Open VariableUtils API (#9) * created provider for VariableUtils * name fix --- .../adapter/handler/VariablesRequestHandler.java | 6 ++++-- .../core/adapter/variables/IVariableProvider.java | 14 ++++++++++++++ .../core/adapter/variables/VariableProvider.java | 8 ++++++++ .../plugin/internal/JdtProviderContextFactory.java | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/IVariableProvider.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableProvider.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 73574e238..982a58011 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -33,6 +33,7 @@ import com.microsoft.java.debug.core.adapter.IEvaluationProvider; import com.microsoft.java.debug.core.adapter.IStackFrameManager; import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter; +import com.microsoft.java.debug.core.adapter.variables.IVariableProvider; import com.microsoft.java.debug.core.adapter.variables.JavaLogicalStructure; import com.microsoft.java.debug.core.adapter.variables.JavaLogicalStructure.LogicalStructureExpression; import com.microsoft.java.debug.core.adapter.variables.JavaLogicalStructure.LogicalVariable; @@ -78,6 +79,7 @@ public CompletableFuture handle(Command command, Arguments arguments, boolean showStaticVariables = DebugSettings.getCurrent().showStaticVariables; Map options = variableFormatter.getDefaultOptions(); + IVariableProvider variableProvider = context.getProvider(IVariableProvider.class); VariableUtils.applyFormatterOptions(options, varArgs.format != null && varArgs.format.hex); IEvaluationProvider evaluationEngine = context.getProvider(IEvaluationProvider.class); @@ -260,12 +262,12 @@ public CompletableFuture handle(Command command, Arguments arguments, String typeName = ((ObjectReference) containerNode.getProxiedVariable()).referenceType().name(); // TODO: This replacement will possibly change the $ in the class name itself. typeName = typeName.replaceAll("\\$", "."); - evaluateName = VariableUtils.getEvaluateName(javaVariable.evaluateName, "((" + typeName + ")" + containerEvaluateName + ")", false); + evaluateName = variableProvider.getEvaluateName(javaVariable.evaluateName, "((" + typeName + ")" + containerEvaluateName + ")", false); } else { if (containerEvaluateName != null && containerEvaluateName.contains("%s")) { evaluateName = String.format(containerEvaluateName, javaVariable.evaluateName); } else { - evaluateName = VariableUtils.getEvaluateName(javaVariable.evaluateName, containerEvaluateName, containerNode.isIndexedVariable()); + evaluateName = variableProvider.getEvaluateName(javaVariable.evaluateName, containerEvaluateName, containerNode.isIndexedVariable()); } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/IVariableProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/IVariableProvider.java new file mode 100644 index 000000000..2311ae0a0 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/IVariableProvider.java @@ -0,0 +1,14 @@ +package com.microsoft.java.debug.core.adapter.variables; + +import com.microsoft.java.debug.core.adapter.IProvider; + +public interface IVariableProvider extends IProvider { + /** + * Get the name for evaluation of variable. + * + * @param name the variable name, if any + * @param containerName the container name, if any + * @param isArrayElement is the variable an array element? + */ + public String getEvaluateName(String name, String containerName, boolean isArrayElement); +} \ No newline at end of file diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableProvider.java new file mode 100644 index 000000000..76b48d5af --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/variables/VariableProvider.java @@ -0,0 +1,8 @@ +package com.microsoft.java.debug.core.adapter.variables; + +public class VariableProvider implements IVariableProvider { + @Override + public String getEvaluateName(String name, String containerName, boolean isArrayElement) { + return VariableUtils.getEvaluateName(name, containerName, isArrayElement); + } +} \ No newline at end of file diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java index 37ebc2dae..92e4eb986 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtProviderContextFactory.java @@ -38,6 +38,7 @@ public static IProviderContext createProviderContext() { context.registerProvider(IEvaluationProvider.class, new JdtEvaluationProvider()); context.registerProvider(ICompletionsProvider.class, new CompletionsProvider()); context.registerProvider(IStepFilterProvider.class, new StepFilterProvider()); + context.registerProvider(IVariableProvider.class, new VariableProvider()); return context; } From a4018d0deeea6763b1ad9ac5949c4515adb9aa4f Mon Sep 17 00:00:00 2001 From: Lucas Nouguier Date: Wed, 9 Aug 2023 10:54:30 +0200 Subject: [PATCH 39/50] all providers getter --- .../java/debug/core/adapter/ProviderContext.java | 4 ++++ .../core/adapter/handler/StackTraceRequestHandler.java | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java index 756eb30e6..556096427 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java @@ -62,4 +62,8 @@ public void registerProvider(Class clazz, IProvider provide providerMap.put(clazz, provider); } + public Map, IProvider> getProviders() { + return providerMap; + } + } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 0f7f0f3ee..83e731908 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -78,12 +78,12 @@ public CompletableFuture handle(Command command, Arguments arguments, for (int i = stacktraceArgs.startFrame; i < frames.length && count-- > 0; i++) { StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); - IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); - Optional formattedMethod = stackTraceProvider.formatMethod(thread.frame(i).location().method()); + IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); + Optional formattedMethod = stackTraceProvider.formatMethod(thread.frame(i).location().method()); - - if(formattedMethod.isPresent() ) - result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, formattedMethod.get())); + if(formattedMethod.isPresent()) { + result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, formattedMethod.get())); + } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { From 57e71e9918a237f9937144e3e1350d78c7c5313b Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 15 Aug 2023 20:57:35 +0200 Subject: [PATCH 40/50] getProviders returns a list --- .../java/debug/core/adapter/IProviderContext.java | 4 ++++ .../microsoft/java/debug/core/adapter/ProviderContext.java | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IProviderContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IProviderContext.java index c6310172d..c710a8ba0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IProviderContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IProviderContext.java @@ -11,9 +11,13 @@ package com.microsoft.java.debug.core.adapter; +import java.util.List; + public interface IProviderContext { T getProvider(Class clazz); void registerProvider(Class clazz, IProvider provider); + + List getProviders(); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java index 556096427..781c9f08b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProviderContext.java @@ -11,7 +11,9 @@ package com.microsoft.java.debug.core.adapter; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class ProviderContext implements IProviderContext { @@ -62,8 +64,9 @@ public void registerProvider(Class clazz, IProvider provide providerMap.put(clazz, provider); } - public Map, IProvider> getProviders() { - return providerMap; + @Override + public List getProviders() { + return new ArrayList(providerMap.values()); } } From d5608e5d38a122f5741fec67e1a0d49ebf9b26ff Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 21 Dec 2023 14:06:06 +0100 Subject: [PATCH 41/50] catch all throwables from dispatch request --- .../java/debug/core/protocol/AbstractProtocolServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java index aa6fc7c69..5146faf97 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/AbstractProtocolServer.java @@ -77,7 +77,7 @@ public AbstractProtocolServer(InputStream input, OutputStream output, Logger log requestSubject.observeOn(Schedulers.newThread()).subscribe(request -> { try { this.dispatchRequest(request); - } catch (Exception e) { + } catch (Throwable e) { logger.log(Level.SEVERE, String.format("Dispatch debug protocol error: %s", e.toString()), e); } }); From 39b44d171fa22ec4cd497f73db1c769f19f3e44d Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 9 Feb 2024 08:12:41 +0100 Subject: [PATCH 42/50] Reinstall all breakpoints in files that changed Previously we did not try to reinstall unverified breakpoints --- .../debug/core/adapter/BreakpointManager.java | 3 +- .../handler/SetBreakpointsRequestHandler.java | 102 +++++++++++------- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java index bc6297b73..d7fd0473d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/BreakpointManager.java @@ -108,7 +108,8 @@ private void addBreakpointsInternally(String source, IBreakpoint[] breakpoints) if (breakpoints != null && breakpoints.length > 0) { for (IBreakpoint breakpoint : breakpoints) { - breakpoint.putProperty("id", this.nextBreakpointId.getAndIncrement()); + if (breakpoint.getProperty("id") == null) + breakpoint.putProperty("id", this.nextBreakpointId.getAndIncrement()); this.breakpoints.add(breakpoint); breakpointMap.put(String.valueOf(breakpoint.getLineNumber()), breakpoint); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 75fc91484..3815ba4e0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -17,6 +17,7 @@ import java.util.concurrent.CompletableFuture; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.stream.Collectors; import com.sun.jdi.request.EventRequestManager; import org.apache.commons.io.FilenameUtils; @@ -130,31 +131,10 @@ public CompletableFuture handle(Command command, Arguments arguments, IBreakpoint[] toAdds = this.convertClientBreakpointsToDebugger(sourcePath, bpArguments.breakpoints, context); // See the VSCode bug https://github.com/Microsoft/vscode/issues/36471. // The source uri sometimes is encoded by VSCode, the debugger will decode it to keep the uri consistent. - IBreakpoint[] added = context.getBreakpointManager() - .setBreakpoints(AdapterUtils.decodeURIComponent(sourcePath), toAdds, bpArguments.sourceModified); - for (int i = 0; i < bpArguments.breakpoints.length; i++) { - // For newly added breakpoint, should install it to debuggee first. - if (toAdds[i] == added[i] && added[i].className() != null) { - added[i].install().thenAccept(bp -> { - Events.BreakpointEvent bpEvent = new Events.BreakpointEvent("new", this.convertDebuggerBreakpointToClient(bp, context)); - context.getProtocolServer().sendEvent(bpEvent); - }); - } else if (added[i].className() != null) { - if (toAdds[i].getHitCount() != added[i].getHitCount()) { - // Update hitCount condition. - added[i].setHitCount(toAdds[i].getHitCount()); - } - - if (!StringUtils.equals(toAdds[i].getLogMessage(), added[i].getLogMessage())) { - added[i].setLogMessage(toAdds[i].getLogMessage()); - } - - if (!StringUtils.equals(toAdds[i].getCondition(), added[i].getCondition())) { - added[i].setCondition(toAdds[i].getCondition()); - } - - } - res.add(this.convertDebuggerBreakpointToClient(added[i], context)); + String decodedSourcePath = AdapterUtils.decodeURIComponent(sourcePath); + IBreakpoint[] added = installBreakpoints(decodedSourcePath, toAdds, "new", bpArguments.sourceModified, context); + for (IBreakpoint addedBreakpoint : added) { + res.add(this.convertDebuggerBreakpointToClient(addedBreakpoint, context)); } response.body = new Responses.SetBreakpointsResponseBody(res); return CompletableFuture.completedFuture(response); @@ -165,6 +145,34 @@ public CompletableFuture handle(Command command, Arguments arguments, } } + private IBreakpoint[] installBreakpoints(String sourcePath, IBreakpoint[] toAdds, String reason, boolean sourceModified, IDebugAdapterContext context) { + IBreakpoint[] added = context.getBreakpointManager().setBreakpoints(sourcePath, toAdds, sourceModified); + for (int i = 0; i < toAdds.length; i++) { + // For newly added breakpoint, should install it to debuggee first. + if (toAdds[i] == added[i] && added[i].className() != null) { + added[i].install().thenAccept(bp -> { + Events.BreakpointEvent bpEvent = new Events.BreakpointEvent(reason, this.convertDebuggerBreakpointToClient(bp, context)); + context.getProtocolServer().sendEvent(bpEvent); + }); + } else if (added[i].className() != null) { + if (toAdds[i].getHitCount() != added[i].getHitCount()) { + // Update hitCount condition. + added[i].setHitCount(toAdds[i].getHitCount()); + } + + if (!StringUtils.equals(toAdds[i].getLogMessage(), added[i].getLogMessage())) { + added[i].setLogMessage(toAdds[i].getLogMessage()); + } + + if (!StringUtils.equals(toAdds[i].getCondition(), added[i].getCondition())) { + added[i].setCondition(toAdds[i].getCondition()); + } + + } + } + return added; + } + private IBreakpoint getAssociatedEvaluatableBreakpoint(IDebugAdapterContext context, BreakpointEvent event) { return Arrays.asList(context.getBreakpointManager().getBreakpoints()).stream().filter( bp -> { @@ -310,24 +318,38 @@ private IBreakpoint[] convertClientBreakpointsToDebugger(String sourceFile, Type return breakpoints; } - private void reinstallBreakpoints(IDebugAdapterContext context, List typenames) { - if (typenames == null || typenames.isEmpty()) { - return; + private IBreakpoint[] createFreshBreakpoints(String sourceFile, IBreakpoint[] oldBreakpoints, IDebugAdapterContext context) + throws DebugException { + int[] lines = Arrays.asList(oldBreakpoints).stream().mapToInt(b -> b.getLineNumber()).toArray(); + ISourceLookUpProvider sourceProvider = context.getProvider(ISourceLookUpProvider.class); + String[] fqns = sourceProvider.getFullyQualifiedName(sourceFile, lines, null); + IBreakpoint[] breakpoints = new IBreakpoint[lines.length]; + for (int i = 0; i < lines.length; i++) { + IBreakpoint oldBreakpoint = oldBreakpoints[i]; + breakpoints[i] = context.getDebugSession().createBreakpoint(fqns[i], lines[i], oldBreakpoint.getHitCount(), + oldBreakpoint.getCondition(), oldBreakpoint.getLogMessage()); + breakpoints[i].putProperty("id", oldBreakpoint.getProperty("id")); + if (sourceProvider.supportsRealtimeBreakpointVerification() && StringUtils.isNotBlank(fqns[i])) { + breakpoints[i].putProperty("verified", true); + } } - IBreakpoint[] breakpoints = context.getBreakpointManager().getBreakpoints(); + return breakpoints; + } - for (IBreakpoint breakpoint : breakpoints) { - if (typenames.contains(breakpoint.className())) { - try { - breakpoint.close(); - breakpoint.install().thenAccept(bp -> { - Events.BreakpointEvent bpEvent = new Events.BreakpointEvent("new", this.convertDebuggerBreakpointToClient(bp, context)); - context.getProtocolServer().sendEvent(bpEvent); - }); - } catch (Exception e) { - logger.log(Level.SEVERE, String.format("Remove breakpoint exception: %s", e.toString()), e); - } + private void reinstallBreakpoints(IDebugAdapterContext context, List fqcns) { + try { + ISourceLookUpProvider sourceProvider = context.getProvider(ISourceLookUpProvider.class); + List sourceFiles = fqcns.stream() + .map(fqcn -> sourceProvider.getSourceFileURI(fqcn, "")) + .distinct() + .collect(Collectors.toList()); + + for (String sourceFile : sourceFiles) { + IBreakpoint[] breakpoints = createFreshBreakpoints(sourceFile, context.getBreakpointManager().getBreakpoints(sourceFile), context); + IBreakpoint[] added = installBreakpoints(sourceFile, breakpoints, "changed", true, context); } + } catch (Exception e) { + logger.log(Level.SEVERE, String.format("Failed to reinstall breakpoints: %s", e.toString()), e); } } } From 901d5413bb2c6a51e7c1a311bc6b10cb13391da1 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 22 Feb 2024 11:56:07 +0100 Subject: [PATCH 43/50] Introduce DecodedMethod --- .../core/adapter/IStackTraceProvider.java | 7 +-- .../core/adapter/StackTraceProvider.java | 10 +++-- .../handler/SetBreakpointsRequestHandler.java | 2 +- .../handler/StackTraceRequestHandler.java | 45 +++++-------------- .../adapter/handler/StepRequestHandler.java | 6 +-- .../adapter/stacktrace/DecodedMethod.java | 7 +++ .../core/adapter/stacktrace/JavaMethod.java | 37 +++++++++++++++ 7 files changed, 69 insertions(+), 45 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedMethod.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaMethod.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java index 1bec8e33b..4376a9be1 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java @@ -12,12 +12,13 @@ package com.microsoft.java.debug.core.adapter; import com.microsoft.java.debug.core.protocol.Requests; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; import com.sun.jdi.Location; import com.sun.jdi.Method; import java.util.Optional; public interface IStackTraceProvider extends IProvider { - boolean shouldSkipOver(Method method, Requests.StepFilters filters); - boolean shouldSkipOut(Location upperLocation, Method method); - Optional formatMethod(Method method); + boolean skipOver(Method method, Requests.StepFilters filters); + boolean skipOut(Location upperLocation, Method method); + DecodedMethod decode(Method method); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java index 5c8d2a7a9..c20ab773e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java @@ -12,6 +12,8 @@ package com.microsoft.java.debug.core.adapter; import com.microsoft.java.debug.core.protocol.Requests; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; +import com.microsoft.java.debug.core.adapter.stacktrace.JavaMethod; import com.sun.jdi.Location; import com.sun.jdi.Method; import org.apache.commons.lang3.ArrayUtils; @@ -19,7 +21,7 @@ public class StackTraceProvider implements IStackTraceProvider { @Override - public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { + public boolean skipOver(Method method, Requests.StepFilters filters) { if (!isConfigured(filters)) { return false; } @@ -29,14 +31,14 @@ public boolean shouldSkipOver(Method method, Requests.StepFilters filters) { } @Override - public boolean shouldSkipOut(Location previousLocation, Method method) { + public boolean skipOut(Location previousLocation, Method method) { return false; } @Override - public Optional formatMethod(Method method) { - return Optional.of(method.name()); + public DecodedMethod decode(Method method) { + return new JavaMethod(method); } private boolean isConfigured(Requests.StepFilters filters) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 3815ba4e0..6a6bd42dc 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -200,7 +200,7 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { return; } Method method = bpThread.frame(0).location().method(); - if (stackTraceProvider.shouldSkipOver(method, context.getStepFilters())) { + if (stackTraceProvider.skipOver(method, context.getStepFilters())) { debugEvent.shouldResume = true; return; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 83e731908..4a3aa437f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -29,6 +29,7 @@ import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; @@ -79,10 +80,10 @@ public CompletableFuture handle(Command command, Arguments arguments, StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); - Optional formattedMethod = stackTraceProvider.formatMethod(thread.frame(i).location().method()); - - if(formattedMethod.isPresent()) { - result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, formattedMethod.get())); + DecodedMethod decodedMethod = stackTraceProvider.decode(thread.frame(i).location().method()); + + if(!decodedMethod.isGenerated()) { + result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, decodedMethod)); } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException @@ -99,25 +100,18 @@ public CompletableFuture handle(Command command, Arguments arguments, return CompletableFuture.completedFuture(response); } - private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context,String formattedName) + private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame, int frameId, IDebugAdapterContext context, DecodedMethod decodedMethod) throws URISyntaxException, AbsentInformationException { Location location = stackFrame.location(); - Method method = location.method(); Types.Source clientSource = this.convertDebuggerSourceToClient(location, context); - //String methodName = formatMethodName(method, true, true,formattedName); + String formattedName = decodedMethod.format(); int lineNumber = AdapterUtils.convertLineNumber(location.lineNumber(), context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); // Line number returns -1 if the information is not available; specifically, always returns -1 for native methods. - if (lineNumber < 0) { - if (method.isNative()) { - // For native method, display a tip text "native method" in the Call Stack View. - formattedName += "[native method]"; - } else { - // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, - // display "Unknown Source" in the Call Stack View. - clientSource = null; - } + if (lineNumber < 0 && !location.method().isNative()) { + // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, + // display "Unknown Source" in the Call Stack View. + clientSource = null; } - return new Types.StackFrame(frameId, formattedName, clientSource, lineNumber, context.isClientColumnsStartAt1() ? 1 : 0); } @@ -175,21 +169,4 @@ public static Types.Source convertDebuggerSourceToClient(String fullyQualifiedNa } } } - - private String formatMethodName(Method method, boolean showContextClass, boolean showParameter,String formattedNameString) { - StringBuilder formattedName = new StringBuilder(); - /* if (showContextClass) { - // String fullyQualifiedClassName = method.declaringType().name(); - formattedName.append(SimpleTypeFormatter.trimTypeName(formattedNameString)); - formattedName.append("."); - }*/ - formattedName.append(formattedNameString); - if (showParameter) { - List argumentTypeNames = method.argumentTypeNames().stream().map(SimpleTypeFormatter::trimTypeName).collect(Collectors.toList()); - formattedName.append("("); - formattedName.append(String.join(",", argumentTypeNames)); - formattedName.append(")"); - } - return formattedName.toString(); - } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index ae87035c8..e87a97afa 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -200,8 +200,8 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, */ private boolean shouldSkipOver(IStackTraceProvider stackTrace, Location originalLocation, Location currentLocation, Requests.StepFilters stepFilters) throws IncompatibleThreadStateException { - return !stackTrace.shouldSkipOver(originalLocation.method(), stepFilters) - && stackTrace.shouldSkipOver(currentLocation.method(), stepFilters); + return !stackTrace.skipOver(originalLocation.method(), stepFilters) + && stackTrace.skipOver(currentLocation.method(), stepFilters); } private boolean shouldSkipOut(IStackTraceProvider stackTrace, int originalStackDepth, int currentStackDepth, Location upperLocation, @@ -213,7 +213,7 @@ private boolean shouldSkipOut(IStackTraceProvider stackTrace, int originalStackD if (currentStackDepth <= originalStackDepth) { return false; } - return stackTrace.shouldSkipOut(upperLocation, currentLocation.method()); + return stackTrace.skipOut(upperLocation, currentLocation.method()); } /** diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedMethod.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedMethod.java new file mode 100644 index 000000000..0b997b267 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedMethod.java @@ -0,0 +1,7 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +public interface DecodedMethod { + String format(); + + boolean isGenerated(); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaMethod.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaMethod.java new file mode 100644 index 000000000..f3cde6682 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaMethod.java @@ -0,0 +1,37 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +import java.util.List; +import java.util.stream.Collectors; + +import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; +import com.sun.jdi.Method; + +public class JavaMethod implements DecodedMethod { + private Method method; + + public JavaMethod(Method method) { + this.method = method; + } + + @Override + public String format() { + StringBuilder formattedName = new StringBuilder(); + String fullyQualifiedClassName = method.declaringType().name(); + formattedName.append(SimpleTypeFormatter.trimTypeName(fullyQualifiedClassName)); + formattedName.append("."); + List argumentTypeNames = method.argumentTypeNames().stream().map(SimpleTypeFormatter::trimTypeName).collect(Collectors.toList()); + formattedName.append("("); + formattedName.append(String.join(",", argumentTypeNames)); + formattedName.append(")"); + if (method.isNative()) { + // For native method, display a tip text "native method" in the Call Stack View. + formattedName.append("[native method]"); + } + return formattedName.toString(); + } + + @Override + public boolean isGenerated() { + return method.isBridge() || method.isSynthetic(); + } +} From f94ff12f4d03ff49b52277b0f2c550d4a21927b3 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 22 Feb 2024 15:28:40 +0100 Subject: [PATCH 44/50] Quick and dirty fix of scala-debug-adapter#664 --- .../core/adapter/IStackFrameManager.java | 4 ++++ .../debug/core/adapter/StackFrameManager.java | 19 +++++++++++++++++++ .../handler/StackTraceRequestHandler.java | 18 ++++++++++++------ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java index de10319f6..14fec681d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java @@ -31,4 +31,8 @@ public interface IStackFrameManager { * @return all the stackframes in the specified thread */ StackFrame[] reloadStackFrames(ThreadReference thread); + + void setStackFrameOffset(ThreadReference thread, int frame, int offset); + + int getStackFrameOffset(ThreadReference thread, int frame); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java index 9e1a86970..6d9f6cf34 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java @@ -15,6 +15,8 @@ import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang3.tuple.Pair; + import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.StackFrame; @@ -22,6 +24,8 @@ public class StackFrameManager implements IStackFrameManager { private Map threadStackFrameMap = Collections.synchronizedMap(new HashMap<>()); + private Map, Integer> threadStackFrameOffsetMap = + Collections.synchronizedMap(new HashMap<>()); @Override public StackFrame getStackFrame(StackFrameReference ref) { @@ -41,4 +45,19 @@ public StackFrame[] reloadStackFrames(ThreadReference thread) { } }); } + + @Override + public void setStackFrameOffset(ThreadReference thread, int frame, int offset) { + threadStackFrameOffsetMap.put(Pair.of(thread.uniqueID(), frame), offset); + return; + } + + @Override + public int getStackFrameOffset(ThreadReference thread, int frame) { + Pair key = Pair.of(thread.uniqueID(), frame); + if (threadStackFrameOffsetMap.containsKey(key)) { + return threadStackFrameOffsetMap.get(key); + } + return 0; + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 4a3aa437f..bfe571cb0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -27,6 +27,7 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; +import com.microsoft.java.debug.core.adapter.IStackFrameManager; import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; @@ -45,7 +46,6 @@ import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; -import java.util.Optional; public class StackTraceRequestHandler implements IDebugRequestHandler { @@ -63,20 +63,20 @@ public CompletableFuture handle(Command command, Arguments arguments, return CompletableFuture.completedFuture(response); } ThreadReference thread = DebugUtility.getThread(context.getDebugSession(), stacktraceArgs.threadId); + IStackFrameManager stackFrameManager = context.getStackFrameManager(); int totalFrames = 0; if (thread != null) { try { - totalFrames = thread.frameCount(); if (totalFrames <= stacktraceArgs.startFrame) { response.body = new Responses.StackTraceResponseBody(result, totalFrames); return CompletableFuture.completedFuture(response); } - StackFrame[] frames = context.getStackFrameManager().reloadStackFrames(thread); + StackFrame[] frames = stackFrameManager.reloadStackFrames(thread); + int offset = stackFrameManager.getStackFrameOffset(thread, stacktraceArgs.startFrame); - int count = stacktraceArgs.levels == 0 ? totalFrames - stacktraceArgs.startFrame - : Math.min(totalFrames - stacktraceArgs.startFrame, stacktraceArgs.levels); - for (int i = stacktraceArgs.startFrame; i < frames.length && count-- > 0; i++) { + int maxSize = stacktraceArgs.levels == 0 ? frames.length : stacktraceArgs.levels; + for (int i = offset; i < frames.length && result.size() < maxSize; i++) { StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); @@ -85,6 +85,12 @@ public CompletableFuture handle(Command command, Arguments arguments, if(!decodedMethod.isGenerated()) { result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, decodedMethod)); } + + stackFrameManager.setStackFrameOffset(thread, stacktraceArgs.startFrame + result.size(), i + 1); + + if (i == frames.length - 1) { + totalFrames = stacktraceArgs.startFrame + result.size(); + } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { From b87d91040014943dcffabc89618db9aa2af6fece Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 6 Mar 2024 14:22:18 +0100 Subject: [PATCH 45/50] Revert "Quick and dirty fix of scala-debug-adapter#664" This reverts commit f94ff12f4d03ff49b52277b0f2c550d4a21927b3. --- .../core/adapter/IStackFrameManager.java | 4 ---- .../debug/core/adapter/StackFrameManager.java | 19 ------------------- .../handler/StackTraceRequestHandler.java | 18 ++++++------------ 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java index 14fec681d..de10319f6 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackFrameManager.java @@ -31,8 +31,4 @@ public interface IStackFrameManager { * @return all the stackframes in the specified thread */ StackFrame[] reloadStackFrames(ThreadReference thread); - - void setStackFrameOffset(ThreadReference thread, int frame, int offset); - - int getStackFrameOffset(ThreadReference thread, int frame); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java index 6d9f6cf34..9e1a86970 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackFrameManager.java @@ -15,8 +15,6 @@ import java.util.HashMap; import java.util.Map; -import org.apache.commons.lang3.tuple.Pair; - import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.StackFrame; @@ -24,8 +22,6 @@ public class StackFrameManager implements IStackFrameManager { private Map threadStackFrameMap = Collections.synchronizedMap(new HashMap<>()); - private Map, Integer> threadStackFrameOffsetMap = - Collections.synchronizedMap(new HashMap<>()); @Override public StackFrame getStackFrame(StackFrameReference ref) { @@ -45,19 +41,4 @@ public StackFrame[] reloadStackFrames(ThreadReference thread) { } }); } - - @Override - public void setStackFrameOffset(ThreadReference thread, int frame, int offset) { - threadStackFrameOffsetMap.put(Pair.of(thread.uniqueID(), frame), offset); - return; - } - - @Override - public int getStackFrameOffset(ThreadReference thread, int frame) { - Pair key = Pair.of(thread.uniqueID(), frame); - if (threadStackFrameOffsetMap.containsKey(key)) { - return threadStackFrameOffsetMap.get(key); - } - return 0; - } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index bfe571cb0..4a3aa437f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -27,7 +27,6 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; -import com.microsoft.java.debug.core.adapter.IStackFrameManager; import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; @@ -46,6 +45,7 @@ import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.StackFrame; import com.sun.jdi.ThreadReference; +import java.util.Optional; public class StackTraceRequestHandler implements IDebugRequestHandler { @@ -63,20 +63,20 @@ public CompletableFuture handle(Command command, Arguments arguments, return CompletableFuture.completedFuture(response); } ThreadReference thread = DebugUtility.getThread(context.getDebugSession(), stacktraceArgs.threadId); - IStackFrameManager stackFrameManager = context.getStackFrameManager(); int totalFrames = 0; if (thread != null) { try { + totalFrames = thread.frameCount(); if (totalFrames <= stacktraceArgs.startFrame) { response.body = new Responses.StackTraceResponseBody(result, totalFrames); return CompletableFuture.completedFuture(response); } - StackFrame[] frames = stackFrameManager.reloadStackFrames(thread); - int offset = stackFrameManager.getStackFrameOffset(thread, stacktraceArgs.startFrame); + StackFrame[] frames = context.getStackFrameManager().reloadStackFrames(thread); - int maxSize = stacktraceArgs.levels == 0 ? frames.length : stacktraceArgs.levels; - for (int i = offset; i < frames.length && result.size() < maxSize; i++) { + int count = stacktraceArgs.levels == 0 ? totalFrames - stacktraceArgs.startFrame + : Math.min(totalFrames - stacktraceArgs.startFrame, stacktraceArgs.levels); + for (int i = stacktraceArgs.startFrame; i < frames.length && count-- > 0; i++) { StackFrameReference stackframe = new StackFrameReference(thread, i); int frameId = context.getRecyclableIdPool().addObject(thread.uniqueID(), stackframe); IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); @@ -85,12 +85,6 @@ public CompletableFuture handle(Command command, Arguments arguments, if(!decodedMethod.isGenerated()) { result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, decodedMethod)); } - - stackFrameManager.setStackFrameOffset(thread, stacktraceArgs.startFrame + result.size(), i + 1); - - if (i == frames.length - 1) { - totalFrames = stacktraceArgs.startFrame + result.size(); - } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { From d53200ac85dead420bfeed4a4bd9e44162d4edce Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 11 Mar 2024 10:33:09 +0100 Subject: [PATCH 46/50] Use subtle presentation hint for generated methods --- .../core/adapter/handler/StackTraceRequestHandler.java | 7 +++---- .../java/com/microsoft/java/debug/core/protocol/Types.java | 4 +++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 4a3aa437f..b96358d35 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -82,9 +82,7 @@ public CompletableFuture handle(Command command, Arguments arguments, IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); DecodedMethod decodedMethod = stackTraceProvider.decode(thread.frame(i).location().method()); - if(!decodedMethod.isGenerated()) { - result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, decodedMethod)); - } + result.add(convertDebuggerStackFrameToClient(frames[i], frameId, context, decodedMethod)); } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException e) { @@ -112,7 +110,8 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrame stackFrame // display "Unknown Source" in the Call Stack View. clientSource = null; } - return new Types.StackFrame(frameId, formattedName, clientSource, lineNumber, context.isClientColumnsStartAt1() ? 1 : 0); + String presentationHint = decodedMethod.isGenerated() ? "subtle" : null; + return new Types.StackFrame(frameId, formattedName, clientSource, lineNumber, context.isClientColumnsStartAt1() ? 1 : 0, presentationHint); } private Types.Source convertDebuggerSourceToClient(Location location, IDebugAdapterContext context) throws URISyntaxException { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java index 0b9a0494a..728ff2955 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Types.java @@ -43,6 +43,7 @@ public static class StackFrame { public int line; public int column; public String name; + public String presentationHint; /** * Constructs a StackFrame with the given information. @@ -58,12 +59,13 @@ public static class StackFrame { * @param col * column number of the stack frame */ - public StackFrame(int id, String name, Source src, int ln, int col) { + public StackFrame(int id, String name, Source src, int ln, int col, String hint) { this.id = id; this.name = name; this.source = src; this.line = ln; this.column = col; + this.presentationHint = hint; } } From 2f1fd9b765d35551711e0fad37063e6d3f5de934 Mon Sep 17 00:00:00 2001 From: Saad Aissaoui Date: Tue, 9 Jul 2024 16:08:40 +0200 Subject: [PATCH 47/50] decode variable --- .../core/adapter/IStackTraceProvider.java | 4 ++++ .../core/adapter/StackTraceProvider.java | 8 ++++++++ .../handler/VariablesRequestHandler.java | 10 +++++++++- .../adapter/stacktrace/DecodedVariable.java | 5 +++++ .../adapter/stacktrace/JavaLocalVariable.java | 20 +++++++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedVariable.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaLocalVariable.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java index 4376a9be1..bec57ad87 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java @@ -13,12 +13,16 @@ import com.microsoft.java.debug.core.protocol.Requests; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; import com.sun.jdi.Location; import com.sun.jdi.Method; +import com.sun.jdi.LocalVariable; import java.util.Optional; public interface IStackTraceProvider extends IProvider { boolean skipOver(Method method, Requests.StepFilters filters); boolean skipOut(Location upperLocation, Method method); DecodedMethod decode(Method method); + // TODO // p1i8 + DecodedVariable decode(LocalVariable variable); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java index c20ab773e..57ad1152d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java @@ -13,9 +13,12 @@ import com.microsoft.java.debug.core.protocol.Requests; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; import com.microsoft.java.debug.core.adapter.stacktrace.JavaMethod; +import com.microsoft.java.debug.core.adapter.stacktrace.JavaLocalVariable; import com.sun.jdi.Location; import com.sun.jdi.Method; +import com.sun.jdi.LocalVariable; import org.apache.commons.lang3.ArrayUtils; import java.util.Optional; @@ -41,6 +44,11 @@ public DecodedMethod decode(Method method) { return new JavaMethod(method); } + @Override + public DecodedVariable decode(LocalVariable variable) { + return new JavaLocalVariable(variable); + } + private boolean isConfigured(Requests.StepFilters filters) { if (filters == null) { return false; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 982a58011..cbbdfcc34 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -31,7 +31,9 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.IEvaluationProvider; +import com.microsoft.java.debug.core.adapter.IStackTraceProvider; import com.microsoft.java.debug.core.adapter.IStackFrameManager; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter; import com.microsoft.java.debug.core.adapter.variables.IVariableProvider; import com.microsoft.java.debug.core.adapter.variables.JavaLogicalStructure; @@ -54,6 +56,7 @@ import com.sun.jdi.IntegerValue; import com.sun.jdi.InternalException; import com.sun.jdi.InvalidStackFrameException; +import com.sun.jdi.Method; import com.sun.jdi.ObjectReference; import com.sun.jdi.StackFrame; import com.sun.jdi.Type; @@ -101,11 +104,14 @@ public CompletableFuture handle(Command command, Arguments arguments, VariableProxy containerNode = (VariableProxy) container; List childrenList = new ArrayList<>(); IStackFrameManager stackFrameManager = context.getStackFrameManager(); + IStackTraceProvider stackTraceProvider = context.getProvider(IStackTraceProvider.class); String containerEvaluateName = containerNode.getEvaluateName(); boolean isUnboundedTypeContainer = containerNode.isUnboundedType(); + Method method = null; if (containerNode.getProxiedVariable() instanceof StackFrameReference) { StackFrameReference stackFrameReference = (StackFrameReference) containerNode.getProxiedVariable(); StackFrame frame = stackFrameManager.getStackFrame(stackFrameReference); + method = frame.location().method(); if (frame == null) { throw AdapterUtils.createCompletionException( String.format("Invalid stackframe id %d to get variables.", varArgs.variablesReference), @@ -229,7 +235,9 @@ public CompletableFuture handle(Command command, Arguments arguments, } for (Variable javaVariable : childrenList) { Value value = javaVariable.value; - String name = javaVariable.name; + // TODO // p2i1 + DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method); + String name = decodedVariable.format(); if (variableNameMap.containsKey(javaVariable)) { name = variableNameMap.get(javaVariable); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedVariable.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedVariable.java new file mode 100644 index 000000000..d43bfe430 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedVariable.java @@ -0,0 +1,5 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +public interface DecodedVariable { + String format(); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaLocalVariable.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaLocalVariable.java new file mode 100644 index 000000000..ff75ebc7a --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaLocalVariable.java @@ -0,0 +1,20 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +import java.util.List; +import java.util.stream.Collectors; + +import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; +import com.sun.jdi.LocalVariable; + +public class JavaLocalVariable implements DecodedVariable { + private LocalVariable variable; + + public JavaLocalVariable(LocalVariable variable) { + this.variable = variable; + } + + @Override + public String format() { + return variable.name(); + } +} From a49309b84030ee05f21dd90ecbc0e4f31cabf601 Mon Sep 17 00:00:00 2001 From: Saad Aissaoui Date: Tue, 16 Jul 2024 13:38:28 +0200 Subject: [PATCH 48/50] decode variables and fields basics --- .../core/adapter/IStackTraceProvider.java | 5 +++- .../core/adapter/StackTraceProvider.java | 10 +++++++- .../handler/VariablesRequestHandler.java | 24 ++++++++++++++++-- .../core/adapter/stacktrace/DecodedField.java | 7 ++++++ .../core/adapter/stacktrace/JavaField.java | 25 +++++++++++++++++++ 5 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedField.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java index bec57ad87..a16f68974 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IStackTraceProvider.java @@ -14,9 +14,11 @@ import com.microsoft.java.debug.core.protocol.Requests; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedField; import com.sun.jdi.Location; import com.sun.jdi.Method; import com.sun.jdi.LocalVariable; +import com.sun.jdi.Field; import java.util.Optional; public interface IStackTraceProvider extends IProvider { @@ -24,5 +26,6 @@ public interface IStackTraceProvider extends IProvider { boolean skipOut(Location upperLocation, Method method); DecodedMethod decode(Method method); // TODO // p1i8 - DecodedVariable decode(LocalVariable variable); + DecodedVariable decode(LocalVariable variable, Method method, int sourceLine); + DecodedField decode(Field field); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java index 57ad1152d..10599e549 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/StackTraceProvider.java @@ -14,11 +14,14 @@ import com.microsoft.java.debug.core.protocol.Requests; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedMethod; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedField; import com.microsoft.java.debug.core.adapter.stacktrace.JavaMethod; import com.microsoft.java.debug.core.adapter.stacktrace.JavaLocalVariable; +import com.microsoft.java.debug.core.adapter.stacktrace.JavaField; import com.sun.jdi.Location; import com.sun.jdi.Method; import com.sun.jdi.LocalVariable; +import com.sun.jdi.Field; import org.apache.commons.lang3.ArrayUtils; import java.util.Optional; @@ -45,10 +48,15 @@ public DecodedMethod decode(Method method) { } @Override - public DecodedVariable decode(LocalVariable variable) { + public DecodedVariable decode(LocalVariable variable, Method method, int sourceLine) { return new JavaLocalVariable(variable); } + @Override + public DecodedField decode(Field field) { + return new JavaField(field); + } + private boolean isConfigured(Requests.StepFilters filters) { if (filters == null) { return false; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index cbbdfcc34..c3c72e0e0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -32,8 +32,10 @@ import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.IEvaluationProvider; import com.microsoft.java.debug.core.adapter.IStackTraceProvider; +import com.microsoft.java.debug.core.adapter.StackTraceProvider; import com.microsoft.java.debug.core.adapter.IStackFrameManager; import com.microsoft.java.debug.core.adapter.stacktrace.DecodedVariable; +import com.microsoft.java.debug.core.adapter.stacktrace.DecodedField; import com.microsoft.java.debug.core.adapter.variables.IVariableFormatter; import com.microsoft.java.debug.core.adapter.variables.IVariableProvider; import com.microsoft.java.debug.core.adapter.variables.JavaLogicalStructure; @@ -234,10 +236,28 @@ public CompletableFuture handle(Command command, Arguments arguments, }); } for (Variable javaVariable : childrenList) { + // StackTraceProvider s = stackTraceProvider. Value value = javaVariable.value; // TODO // p2i1 - DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method); - String name = decodedVariable.format(); + String name = javaVariable.name; + if (javaVariable.local != null) { + StackFrameReference stackFrameReference = (StackFrameReference) containerNode.getProxiedVariable(); + StackFrame frame = stackFrameManager.getStackFrame(stackFrameReference); + DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method, frame.location().lineNumber()); + name = decodedVariable.format(); + if (name == "") { + // toRemove.add(javaVariable); + continue; + } + } else + if (javaVariable.field != null) { + DecodedField decodedField = stackTraceProvider.decode(javaVariable.field); + name = decodedField.format(); + if (name == "") { + // toRemove.add(javaVariable); + continue; + } + } else if (variableNameMap.containsKey(javaVariable)) { name = variableNameMap.get(javaVariable); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedField.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedField.java new file mode 100644 index 000000000..10a290a52 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/DecodedField.java @@ -0,0 +1,7 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +public interface DecodedField { + String format(); + + boolean show(); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java new file mode 100644 index 000000000..0e0e38aba --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java @@ -0,0 +1,25 @@ +package com.microsoft.java.debug.core.adapter.stacktrace; + +import java.util.List; +import java.util.stream.Collectors; + +import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; +import com.sun.jdi.Field; + +public class JavaField implements DecodedField { + private Field field; + + public JavaField(Field field) { + this.field = field; + } + + @Override + public String format() { + return field.name(); + } + + @Override + public boolean show() { + return !field.isStatic() || true; // TODO // p2i3: This is a bug. It should be !field.isStatic() || field.isValDef_in_an_Object + } +} From f6b68c74fb823d8267c17dbba8d79e0e117ff276 Mon Sep 17 00:00:00 2001 From: Saad Aissaoui Date: Tue, 23 Jul 2024 18:05:56 +0200 Subject: [PATCH 49/50] exceptions when notFound --- .../handler/VariablesRequestHandler.java | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index c3c72e0e0..73ed1581c 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -243,20 +243,39 @@ public CompletableFuture handle(Command command, Arguments arguments, if (javaVariable.local != null) { StackFrameReference stackFrameReference = (StackFrameReference) containerNode.getProxiedVariable(); StackFrame frame = stackFrameManager.getStackFrame(stackFrameReference); - DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method, frame.location().lineNumber()); - name = decodedVariable.format(); - if (name == "") { - // toRemove.add(javaVariable); - continue; + try { + DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method, frame.location().lineNumber()); + name = decodedVariable.format(); + if (name == "") { + // toRemove.add(javaVariable); + continue; + } + } catch (Exception e) { + String notFound = "ch.epfl.scala.decoder.NotFoundException"; + String ambiguous = "ch.epfl.scala.decoder.AmbiguousException"; + if (e.getMessage().contains(notFound) || e.getMessage().contains(ambiguous)) { + logger.log(Level.INFO, "Failed to decode the variable", e); + } else { + throw e; + } } } else if (javaVariable.field != null) { - DecodedField decodedField = stackTraceProvider.decode(javaVariable.field); - name = decodedField.format(); - if (name == "") { - // toRemove.add(javaVariable); - continue; - } + try { + DecodedField decodedField = stackTraceProvider.decode(javaVariable.field); + name = decodedField.format(); + if (name == "") { + // toRemove.add(javaVariable); + continue; + } + } catch (Exception e) { + String notFound = "ch.epfl.scala.decoder.NotFoundException"; + String ambiguous = "ch.epfl.scala.decoder.AmbiguousException"; + if (e.getMessage().contains(notFound) || e.getMessage().contains(ambiguous)) { + logger.log(Level.INFO, "Failed to decode the variable", e); + } else { + throw e; + } } } else if (variableNameMap.containsKey(javaVariable)) { name = variableNameMap.get(javaVariable); From 9a8cf3b02ce5d155ffb9dbe6fb7cd25c74dcb79c Mon Sep 17 00:00:00 2001 From: Saad Aissaoui Date: Wed, 24 Jul 2024 12:15:32 +0200 Subject: [PATCH 50/50] don't show static fields --- .../adapter/handler/VariablesRequestHandler.java | 12 ++++++------ .../debug/core/adapter/stacktrace/JavaField.java | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java index 73ed1581c..966c9780a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/VariablesRequestHandler.java @@ -64,6 +64,8 @@ import com.sun.jdi.Type; import com.sun.jdi.Value; +import com.microsoft.java.debug.core.adapter.stacktrace.JavaField; + public class VariablesRequestHandler implements IDebugRequestHandler { protected final Logger logger; @@ -236,9 +238,7 @@ public CompletableFuture handle(Command command, Arguments arguments, }); } for (Variable javaVariable : childrenList) { - // StackTraceProvider s = stackTraceProvider. Value value = javaVariable.value; - // TODO // p2i1 String name = javaVariable.name; if (javaVariable.local != null) { StackFrameReference stackFrameReference = (StackFrameReference) containerNode.getProxiedVariable(); @@ -247,7 +247,6 @@ public CompletableFuture handle(Command command, Arguments arguments, DecodedVariable decodedVariable = stackTraceProvider.decode(javaVariable.local, method, frame.location().lineNumber()); name = decodedVariable.format(); if (name == "") { - // toRemove.add(javaVariable); continue; } } catch (Exception e) { @@ -264,8 +263,8 @@ public CompletableFuture handle(Command command, Arguments arguments, try { DecodedField decodedField = stackTraceProvider.decode(javaVariable.field); name = decodedField.format(); - if (name == "") { - // toRemove.add(javaVariable); + JavaField javaField = new JavaField(javaVariable.field); + if (name == "" || !javaField.show()) { continue; } } catch (Exception e) { @@ -275,7 +274,8 @@ public CompletableFuture handle(Command command, Arguments arguments, logger.log(Level.INFO, "Failed to decode the variable", e); } else { throw e; - } } + } + } } else if (variableNameMap.containsKey(javaVariable)) { name = variableNameMap.get(javaVariable); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java index 0e0e38aba..fe13b71c6 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/stacktrace/JavaField.java @@ -20,6 +20,6 @@ public String format() { @Override public boolean show() { - return !field.isStatic() || true; // TODO // p2i3: This is a bug. It should be !field.isStatic() || field.isValDef_in_an_Object + return !field.isStatic() || field.declaringType().name().endsWith("$"); } }