diff --git a/main/external/debugger-libs b/main/external/debugger-libs index 0befb5c77cd..9642e79c628 160000 --- a/main/external/debugger-libs +++ b/main/external/debugger-libs @@ -1 +1 @@ -Subproject commit 0befb5c77cd1b9c87895f8c63b68131fb6799b44 +Subproject commit 9642e79c6284ece9ad9f1bba2c88d13127b4d992 diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol.csproj b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol.csproj index abfc017abb4..f0b646539a8 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol.csproj +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol.csproj @@ -44,10 +44,12 @@ - - + + - + + + diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeBacktrace.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeBacktrace.cs deleted file mode 100644 index 9a7c611876a..00000000000 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeBacktrace.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System; -using System.Linq; -using System.Collections.Generic; - -using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; - -using Mono.Debugging.Backend; -using Mono.Debugging.Client; - -using VsFormat = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrameFormat; - -namespace MonoDevelop.Debugger.VsCodeDebugProtocol -{ - class VSCodeDebuggerBacktrace : IBacktrace - { - readonly int threadId; - VSCodeDebuggerSession vsCodeDebuggerSession; - int totalFramesCount; - Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrame [] frames; - VsFormat frame0Format; - - public VSCodeDebuggerBacktrace (VSCodeDebuggerSession vsCodeDebuggerSession, int threadId) - { - this.threadId = threadId; - this.vsCodeDebuggerSession = vsCodeDebuggerSession; - frame0Format = VsCodeStackFrame.GetStackFrameFormat (vsCodeDebuggerSession.EvaluationOptions); - var body = vsCodeDebuggerSession.protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = 0, Levels = 1, Format = frame0Format }); - totalFramesCount = body.TotalFrames ?? 0; - frames = new Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrame [totalFramesCount]; - if (totalFramesCount > 0 && body.StackFrames.Count > 0) - frames [0] = body.StackFrames [0]; - } - - public int FrameCount { - get { - return totalFramesCount; - } - } - - public AssemblyLine [] Disassemble (int frameIndex, int firstLine, int count) - { - throw new NotImplementedException (); - } - - public ObjectValue [] GetAllLocals (int frameIndex, EvaluationOptions options) - { - List results = new List (); - var scopeBody = vsCodeDebuggerSession.protocolClient.SendRequestSync (new ScopesRequest (frames [frameIndex].Id)); - foreach (var variablesGroup in scopeBody.Scopes) { - using (var timer = vsCodeDebuggerSession.EvaluationStats.StartTimer ()) { - var varibles = vsCodeDebuggerSession.protocolClient.SendRequestSync (new VariablesRequest (variablesGroup.VariablesReference)); - foreach (var variable in varibles.Variables) { - results.Add (VsCodeVariableToObjectValue (vsCodeDebuggerSession, variable.Name, variable.EvaluateName, variable.Type, variable.Value, variable.VariablesReference, variablesGroup.VariablesReference, frames [frameIndex].Id)); - } - timer.Success = true; - } - } - return results.ToArray (); - } - - public ExceptionInfo GetException (int frameIndex, EvaluationOptions options) - { - return new ExceptionInfo (GetAllLocals (frameIndex, options).FirstOrDefault (o => o.Name == "$exception")); - } - - public CompletionData GetExpressionCompletionData (int frameIndex, string exp) - { - return new CompletionData (); - } - - public ObjectValue [] GetExpressionValues (int frameIndex, string [] expressions, EvaluationOptions options) - { - var results = new List (); - foreach (var expr in expressions) { - using (var timer = vsCodeDebuggerSession.EvaluationStats.StartTimer ()) { - var responseBody = vsCodeDebuggerSession.protocolClient.SendRequestSync (new EvaluateRequest (expr) { FrameId = frames[frameIndex].Id }); - results.Add (VsCodeVariableToObjectValue (vsCodeDebuggerSession, expr, expr, responseBody.Type, responseBody.Result, responseBody.VariablesReference, 0, frames [frameIndex].Id)); - timer.Success = true; - } - } - return results.ToArray (); - } - - internal static ObjectValue VsCodeVariableToObjectValue (VSCodeDebuggerSession vsCodeDebuggerSession, string name, string evalName, string type, string value, int variablesReference, int parentVariablesReference, int frameId) - { - return new VSCodeObjectSource (vsCodeDebuggerSession, variablesReference, parentVariablesReference, name, type, evalName, frameId, value).GetValue (default (ObjectPath), null); - } - - public ObjectValue [] GetLocalVariables (int frameIndex, EvaluationOptions options) - { - List results = new List (); - var scopeBody = vsCodeDebuggerSession.protocolClient.SendRequestSync (new ScopesRequest (frames [frameIndex].Id)); - foreach (var variablesGroup in scopeBody.Scopes) { - using (var timer = vsCodeDebuggerSession.EvaluationStats.StartTimer ()) { - var varibles = vsCodeDebuggerSession.protocolClient.SendRequestSync (new VariablesRequest (variablesGroup.VariablesReference)); - foreach (var variable in varibles.Variables) { - results.Add (ObjectValue.CreatePrimitive (null, new ObjectPath (variable.Name), variable.Type ?? "", new EvaluationResult (variable.Value), ObjectValueFlags.None)); - } - timer.Success = true; - } - } - return results.ToArray (); - } - - public ObjectValue [] GetParameters (int frameIndex, EvaluationOptions options) - { - return new ObjectValue [0];//TODO: Find out how to seperate Params from other Locals - } - - public Mono.Debugging.Client.StackFrame [] GetStackFrames (int firstIndex, int lastIndex) - { - //Optimisation for getting 1st frame of thread(used for ThreadPad) - if (firstIndex == 0 && lastIndex == 1 && totalFramesCount > 0) { - return new Mono.Debugging.Client.StackFrame [] { new VsCodeStackFrame (frame0Format, threadId, 0, frames [0]) }; - } - var stackFrames = new Mono.Debugging.Client.StackFrame [Math.Min (lastIndex - firstIndex, totalFramesCount - firstIndex)]; - var format = VsCodeStackFrame.GetStackFrameFormat (vsCodeDebuggerSession.EvaluationOptions); - var body = vsCodeDebuggerSession.protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = firstIndex, Levels = stackFrames.Length, Format = format }); - for (int i = 0; i < stackFrames.Length; i++) { - frames [i + firstIndex] = body.StackFrames [i]; - stackFrames [i] = new VsCodeStackFrame (format, threadId, i, body.StackFrames [i]); - } - return stackFrames; - } - - public ObjectValue GetThisReference (int frameIndex, EvaluationOptions options) - { - return GetAllLocals (frameIndex, options).FirstOrDefault (l => l.Name == "this"); - } - - public ValidationResult ValidateExpression (int frameIndex, string expression, EvaluationOptions options) - { - return new ValidationResult (true, null); - } - } -} diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerAdaptor.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerAdaptor.cs new file mode 100644 index 00000000000..f53b5e1711d --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerAdaptor.cs @@ -0,0 +1,187 @@ +// +// VsCodeDebuggerAdaptor.cs +// +// Author: +// Jeffrey Stedfast +// +// Copyright (c) 2019 Microsoft Corp. +// +// 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, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// 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. + +using System; +using System.Reflection; +using System.Collections.Generic; + +using Mono.Debugging.Evaluation; + +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; + +namespace MonoDevelop.Debugger.VsCodeDebugProtocol +{ + public class VsCodeDebuggerAdaptor : ObjectValueAdaptor + { + readonly VsCodeDebuggerSession session; + + public VsCodeDebuggerAdaptor (VsCodeDebuggerSession session) + { + this.session = session; + } + + protected override ValueReference OnGetLocalVariable (EvaluationContext ctx, string name) + { + var cx = (VsCodeDebuggerEvaluationContext) ctx; + + var scopeBody = session.protocolClient.SendRequestSync (new ScopesRequest (cx.Frame.Id)); + + foreach (var scope in scopeBody.Scopes) { + using (var timer = session.EvaluationStats.StartTimer ()) { + var variables = session.protocolClient.SendRequestSync (new VariablesRequest (scope.VariablesReference)); + foreach (var variable in variables.Variables) { + if (variable.Name.Equals (name, ctx.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) { + + } + + results.Add (ObjectValue.CreatePrimitive (null, new ObjectPath (variable.Name), variable.Type ?? "", new EvaluationResult (variable.Value), ObjectValueFlags.None)); + } + timer.Success = true; + } + } + } + + protected override ValueReference OnGetThisReference (EvaluationContext ctx) + { + return base.OnGetThisReference (ctx); + } + + public override ICollectionAdaptor CreateArrayAdaptor (EvaluationContext ctx, object arr) + { + throw new NotImplementedException (); + } + + public override object CreateNullValue (EvaluationContext ctx, object type) + { + throw new NotImplementedException (); + } + + public override IStringAdaptor CreateStringAdaptor (EvaluationContext ctx, object str) + { + throw new NotImplementedException (); + } + + public override object CreateValue (EvaluationContext ctx, object value) + { + throw new NotImplementedException (); + } + + public override object CreateValue (EvaluationContext ctx, object type, params object[] args) + { + throw new NotImplementedException (); + } + + public override object GetBaseType (EvaluationContext ctx, object type) + { + throw new NotImplementedException (); + } + + public override object GetType (EvaluationContext ctx, string name, object[] typeArgs) + { + throw new NotImplementedException (); + } + + public override object[] GetTypeArgs (EvaluationContext ctx, object type) + { + throw new NotImplementedException (); + } + + public override string GetTypeName (EvaluationContext ctx, object type) + { + throw new NotImplementedException (); + } + + public override object GetValueType (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool HasMember (EvaluationContext ctx, object type, string memberName, BindingFlags bindingFlags) + { + throw new NotImplementedException (); + } + + public override bool HasMethod (EvaluationContext ctx, object targetType, string methodName, object[] genericTypeArgs, object[] argTypes, BindingFlags flags) + { + throw new NotImplementedException (); + } + + public override bool IsArray (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsClass (EvaluationContext ctx, object type) + { + throw new NotImplementedException (); + } + + public override bool IsEnum (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsNull (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsPointer (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsPrimitive (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsString (EvaluationContext ctx, object val) + { + throw new NotImplementedException (); + } + + public override bool IsValueType (object type) + { + throw new NotImplementedException (); + } + + public override object RuntimeInvoke (EvaluationContext ctx, object targetType, object target, string methodName, object [] genericTypeArgs, object [] argTypes, object [] argValues) + { + throw new NotImplementedException (); + } + + public override object TryCast (EvaluationContext ctx, object val, object type) + { + throw new NotImplementedException (); + } + + protected override IEnumerable GetMembers (EvaluationContext ctx, object t, object co, BindingFlags bindingFlags) + { + throw new NotImplementedException (); + } + } +} diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerBacktrace.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerBacktrace.cs new file mode 100644 index 00000000000..f2ffa9901b3 --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerBacktrace.cs @@ -0,0 +1,147 @@ +using System; +using System.Linq; +using System.Collections.Generic; + +using Mono.Debugging.Backend; +using Mono.Debugging.Client; +using Mono.Debugging.Evaluation; + +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; + +using VsStackFrameFormat = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrameFormat; +using VsStackFrame = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrame; +using StackFrame = Mono.Debugging.Client.StackFrame; + +namespace MonoDevelop.Debugger.VsCodeDebugProtocol +{ + class VSCodeDebuggerBacktrace : IBacktrace + { + readonly VsCodeDebuggerSession session; + readonly VsStackFrameFormat frame0Format; + readonly VsStackFrame[] frames; + readonly int totalFramesCount; + readonly int threadId; + + public VSCodeDebuggerBacktrace (VsCodeDebuggerSession session, int threadId) + { + this.threadId = threadId; + this.session = session; + + frame0Format = VsCodeDebuggerStackFrame.GetStackFrameFormat (session.EvaluationOptions); + var body = session.protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = 0, Levels = 1, Format = frame0Format }); + totalFramesCount = body.TotalFrames ?? 0; + frames = new VsStackFrame [totalFramesCount]; + if (totalFramesCount > 0 && body.StackFrames.Count > 0) + frames[0] = body.StackFrames[0]; + } + + public int FrameCount { + get { + return totalFramesCount; + } + } + + public AssemblyLine[] Disassemble (int frameIndex, int firstLine, int count) + { + throw new NotImplementedException (); + } + + public ObjectValue[] GetAllLocals (int frameIndex, EvaluationOptions options) + { + var results = new List (); + var scopeBody = session.protocolClient.SendRequestSync (new ScopesRequest (frames[frameIndex].Id)); + foreach (var variablesGroup in scopeBody.Scopes) { + using (var timer = session.EvaluationStats.StartTimer ()) { + var varibles = session.protocolClient.SendRequestSync (new VariablesRequest (variablesGroup.VariablesReference)); + foreach (var variable in varibles.Variables) { + results.Add (VsCodeVariableToObjectValue (session, variable.Name, variable.EvaluateName, variable.Type, variable.Value, variable.VariablesReference, variablesGroup.VariablesReference, frames[frameIndex].Id)); + } + timer.Success = true; + } + } + return results.ToArray (); + } + + public ExceptionInfo GetException (int frameIndex, EvaluationOptions options) + { + return new ExceptionInfo (GetAllLocals (frameIndex, options).FirstOrDefault (o => o.Name == "$exception")); + } + + public CompletionData GetExpressionCompletionData (int frameIndex, string exp) + { + return new CompletionData (); + } + + public EvaluationContext GetEvaluationContext (int frameIndex, EvaluationOptions options) + { + return new VsCodeDebuggerEvaluationContext (session, frames[frameIndex], threadId, options); + } + + public ObjectValue[] GetExpressionValues (int frameIndex, string[] expressions, EvaluationOptions options) + { + var results = new List (); + + foreach (var expr in expressions) { + using (var timer = session.EvaluationStats.StartTimer ()) { + var responseBody = session.protocolClient.SendRequestSync (new EvaluateRequest (expr) { FrameId = frames[frameIndex].Id }); + results.Add (VsCodeVariableToObjectValue (session, expr, expr, responseBody.Type, responseBody.Result, responseBody.VariablesReference, 0, frames[frameIndex].Id)); + timer.Success = true; + } + } + + return results.ToArray (); + } + + internal static ObjectValue VsCodeVariableToObjectValue (VsCodeDebuggerSession session, string name, string evalName, string type, string value, int variablesReference, int parentVariablesReference, int frameId) + { + return new VSCodeObjectSource (session, variablesReference, parentVariablesReference, name, type, evalName, frameId, value).GetValue (default (ObjectPath), null); + } + + public ObjectValue[] GetLocalVariables (int frameIndex, EvaluationOptions options) + { + var results = new List (); + var scopeBody = session.protocolClient.SendRequestSync (new ScopesRequest (frames[frameIndex].Id)); + foreach (var variablesGroup in scopeBody.Scopes) { + using (var timer = session.EvaluationStats.StartTimer ()) { + var variables = session.protocolClient.SendRequestSync (new VariablesRequest (variablesGroup.VariablesReference)); + foreach (var variable in variables.Variables) { + results.Add (ObjectValue.CreatePrimitive (null, new ObjectPath (variable.Name), variable.Type ?? "", new EvaluationResult (variable.Value), ObjectValueFlags.None)); + } + timer.Success = true; + } + } + return results.ToArray (); + } + + public ObjectValue[] GetParameters (int frameIndex, EvaluationOptions options) + { + return new ObjectValue [0];//TODO: Find out how to seperate Params from other Locals + } + + public StackFrame[] GetStackFrames (int firstIndex, int lastIndex) + { + //Optimisation for getting 1st frame of thread(used for ThreadPad) + if (firstIndex == 0 && lastIndex == 1 && totalFramesCount > 0) { + return new StackFrame[] { new VsCodeDebuggerStackFrame (frame0Format, threadId, 0, frames[0]) }; + } + var stackFrames = new StackFrame [Math.Min (lastIndex - firstIndex, totalFramesCount - firstIndex)]; + var format = VsCodeDebuggerStackFrame.GetStackFrameFormat (session.EvaluationOptions); + var body = session.protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = firstIndex, Levels = stackFrames.Length, Format = format }); + for (int i = 0; i < stackFrames.Length; i++) { + frames[i + firstIndex] = body.StackFrames[i]; + stackFrames[i] = new VsCodeDebuggerStackFrame (format, threadId, i, body.StackFrames[i]); + } + return stackFrames; + } + + public ObjectValue GetThisReference (int frameIndex, EvaluationOptions options) + { + return GetAllLocals (frameIndex, options).FirstOrDefault (l => l.Name == "this"); + } + + public ValidationResult ValidateExpression (int frameIndex, string expression, EvaluationOptions options) + { + return new ValidationResult (true, null); + } + } +} diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerEvaluationContext.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerEvaluationContext.cs new file mode 100644 index 00000000000..653d0347ca3 --- /dev/null +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerEvaluationContext.cs @@ -0,0 +1,69 @@ +// +// VsCodeDebuggerEvaluationContext.cs +// +// Author: +// Jeffrey Stedfast +// +// Copyright (c) 2019 Microsoft Corp. +// +// 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, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// 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. + +using Mono.Debugging.Client; +using Mono.Debugging.Evaluation; + +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; + +using VsStackFrameFormat = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrameFormat; +using VsStackFrame = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrame; + +namespace MonoDevelop.Debugger.VsCodeDebugProtocol +{ + public class VsCodeDebuggerEvaluationContext : EvaluationContext + { + public VsCodeDebuggerEvaluationContext (VsCodeDebuggerSession session, VsStackFrame frame, int threadId, EvaluationOptions options) : base (options) + { + Adapter = session.Adapter; + Session = session; + ThreadId = threadId; + Frame = frame; + } + + public VsCodeDebuggerSession Session { + get; private set; + } + + public VsStackFrame Frame { + get; private set; + } + + public int ThreadId { + get; private set; + } + + public override void CopyFrom (EvaluationContext ctx) + { + base.CopyFrom (ctx); + + var other = (VsCodeDebuggerEvaluationContext) ctx; + Session = other.Session; + ThreadId = other.ThreadId; + Frame = other.Frame; + } + } +} diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerSession.cs similarity index 93% rename from main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs rename to main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerSession.cs index 5da7eda0934..b1bb08cbfc8 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerSession.cs @@ -23,29 +23,53 @@ // 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. + using System; -using Mono.Debugging.Client; -using System.Diagnostics; -using Mono.Debugging.Backend; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; using System.IO; +using System.Linq; using System.Text; -using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; -using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol; -using System.Threading; +using System.Diagnostics; +using System.Threading.Tasks; +using System.Collections.Generic; + +using Mono.Debugging.Client; +using Mono.Debugging.Backend; +using Mono.Debugging.Evaluation; + using MonoDevelop.Core; using MonoDevelop.Core.Execution; + +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol; + using MonoFunctionBreakpoint = Mono.Debugging.Client.FunctionBreakpoint; using VsCodeFunctionBreakpoint = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.FunctionBreakpoint; namespace MonoDevelop.Debugger.VsCodeDebugProtocol { - public abstract class VSCodeDebuggerSession : DebuggerSession + public abstract class VsCodeDebuggerSession : DebuggerSession { int currentThreadId; + protected VsCodeDebuggerSession () + { + Adapter = new VsCodeDebuggerAdaptor (this); + } + + public VsCodeDebuggerAdaptor Adapter { + get; private set; + } + + protected override string OnResolveExpression (EvaluationContext ctx, string expression, SourceLocation location) + { + return expression; + } + + public override string ResolveExpression (EvaluationContext ctx, string expression, SourceLocation location) + { + return OnResolveExpression (ctx, expression, location); + } + protected override void OnContinue () { protocolClient.SendRequestSync (new ContinueRequest (currentThreadId)); @@ -76,7 +100,7 @@ protected override void OnFinish () protocolClient.SendRequestSync (new StepOutRequest (currentThreadId)); } - List processInfo = new List(); + readonly List processInfo = new List(); protected override ProcessInfo [] OnGetProcesses () { return processInfo.ToArray(); @@ -155,7 +179,7 @@ protected override BreakEventInfo OnInsertBreakEvent (BreakEvent breakEvent) return breakEventInfo; } - bool currentExceptionState = false; + bool currentExceptionState; void UpdateExceptions () { //Disposed @@ -227,16 +251,20 @@ void StartDebugAgent () startInfo.StandardOutputEncoding = Encoding.UTF8; startInfo.StandardOutputEncoding = Encoding.UTF8; startInfo.UseShellExecute = false; - if (!MonoDevelop.Core.Platform.IsWindows) + + if (!Platform.IsWindows) startInfo.EnvironmentVariables ["PATH"] = Environment.GetEnvironmentVariable ("PATH") + ":/usr/local/share/dotnet/"; + debugAgentProcess = Process.Start (startInfo); debugAgentProcess.EnableRaisingEvents = true; debugAgentProcess.Exited += DebugAgentProcess_Exited; + protocolClient = new DebugProtocolHost (debugAgentProcess.StandardInput.BaseStream, debugAgentProcess.StandardOutput.BaseStream); protocolClient.RequestReceived += OnDebugAdaptorRequestReceived; protocolClient.Run (); protocolClient.EventReceived += HandleEvent; - InitializeRequest initRequest = CreateInitRequest (); + + var initRequest = CreateInitRequest (); Capabilities = protocolClient.SendRequestSync (initRequest); } @@ -265,7 +293,8 @@ protected void Launch (DebuggerStartInfo startInfo) { pauseWhenFinished = !startInfo.CloseExternalConsoleOnExit; StartDebugAgent (); - LaunchRequest launchRequest = CreateLaunchRequest (startInfo); + + var launchRequest = CreateLaunchRequest (startInfo); protocolClient.SendRequestSync (launchRequest); protocolClient.SendRequestSync (new ConfigurationDoneRequest ()); } @@ -314,14 +343,14 @@ string EvaluateTrace(int frameId, string exp) return sb.ToString(); } - bool? EvaluateCondition (int frameId, string exp) + bool? EvaluateCondition (int frameId, string expression) { - var response = protocolClient.SendRequestSync (new EvaluateRequest (exp, frameId)).Result; + var response = protocolClient.SendRequestSync (new EvaluateRequest (expression) { FrameId = frameId }).Result; if (bool.TryParse (response, out var result)) return result; - OnDebuggerOutput (false, $"The condition for an exception catchpoint failed to execute. The condition was '{exp}'. The error returned was '{response}'.\n"); + OnDebuggerOutput (false, $"The condition for an exception catchpoint failed to execute. The condition was '{expression}'. The error returned was '{response}'.\n"); return null; } @@ -359,7 +388,7 @@ protected void HandleEvent (object sender, EventReceivedEventArgs obj) var body = (StoppedEvent)obj.Body; switch (body.Reason) { case StoppedEvent.ReasonValue.Breakpoint: - var stackFrame = (VsCodeStackFrame)this.GetThreadBacktrace (body.ThreadId ?? -1).GetFrame (0); + var stackFrame = (VsCodeDebuggerStackFrame)this.GetThreadBacktrace (body.ThreadId ?? -1).GetFrame (0); args = new TargetEventArgs (TargetEventType.TargetHitBreakpoint); var bp = breakpoints.Select (b => b.Key).OfType ().FirstOrDefault (b => b.FileName == stackFrame.SourceLocation.FileName && b.Line == stackFrame.SourceLocation.Line); if (bp == null) @@ -389,7 +418,7 @@ protected void HandleEvent (object sender, EventReceivedEventArgs obj) if (Options.ProjectAssembliesOnly) { // We can't evaluate expressions in external code frames, the debugger will hang for (int i = 0; i < backtrace.FrameCount; i++) { - var frame = stackFrame = (VsCodeStackFrame)backtrace.GetFrame (i); + var frame = stackFrame = (VsCodeDebuggerStackFrame)backtrace.GetFrame (i); if (!frame.IsExternalCode) { stackFrame = frame; break; @@ -401,7 +430,7 @@ protected void HandleEvent (object sender, EventReceivedEventArgs obj) } } else { // It's OK to evaluate expressions in external code - stackFrame = (VsCodeStackFrame)backtrace.GetFrame (0); + stackFrame = (VsCodeDebuggerStackFrame)backtrace.GetFrame (0); } if (!breakpoints.Select (b => b.Key).OfType ().Any (c => ShouldStopOnExceptionCatchpoint (c, stackFrame.frameId))) { diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeStackFrame.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerStackFrame.cs similarity index 78% rename from main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeStackFrame.cs rename to main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerStackFrame.cs index 9beb86d07a2..360d06670f9 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeStackFrame.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeDebuggerStackFrame.cs @@ -1,21 +1,19 @@ using System; -using System.Collections.Generic; -using System.Linq; - -using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; using Mono.Debugging.Client; +using Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages; + using VsStackFrame = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrame; -using VsFormat = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrameFormat; +using VsStackFrameFormat = Microsoft.VisualStudio.Shared.VSCodeDebugProtocol.Messages.StackFrameFormat; namespace MonoDevelop.Debugger.VsCodeDebugProtocol { - public class VsCodeStackFrame : Mono.Debugging.Client.StackFrame + public class VsCodeDebuggerStackFrame : Mono.Debugging.Client.StackFrame { - public static VsFormat GetStackFrameFormat (EvaluationOptions evalOptions) + public static VsStackFrameFormat GetStackFrameFormat (EvaluationOptions evalOptions) { - return new VsFormat { + return new VsStackFrameFormat { Parameters = evalOptions.StackFrameFormat.ParameterTypes || evalOptions.StackFrameFormat.ParameterNames || evalOptions.StackFrameFormat.ParameterValues, ParameterTypes = evalOptions.StackFrameFormat.ParameterTypes, ParameterNames = evalOptions.StackFrameFormat.ParameterNames, @@ -38,7 +36,7 @@ static string GetLanguage (string path) return null; } - static SourceLink GetSourceLink(VSSourceLinkInfo info) + static SourceLink GetSourceLink (VSSourceLinkInfo info) { if (info == null) return null; @@ -51,13 +49,13 @@ static SourceLocation GetSourceLocation (VsStackFrame frame) return new SourceLocation (frame.Name, frame.Source?.Path, frame.Line, frame.Column, frame.EndLine ?? -1, frame.EndColumn ?? -1, GetHashBytes (frame.Source), sourceLink); } - VsFormat format; + VsStackFrameFormat format; readonly int threadId; readonly int frameIndex; internal readonly int frameId; string fullStackframeText; - public VsCodeStackFrame (VsFormat format, int threadId, int frameIndex, VsStackFrame frame) + public VsCodeDebuggerStackFrame (VsStackFrameFormat format, int threadId, int frameIndex, VsStackFrame frame) : base (0, GetSourceLocation (frame), GetLanguage (frame.Source?.Path)) { this.format = format; @@ -70,29 +68,29 @@ public VsCodeStackFrame (VsFormat format, int threadId, int frameIndex, VsStackF static byte ToXDigit (char c) { if (c >= 'A' && c <= 'F') - return (byte) ((c - 'A') + 10); + return (byte)((c - 'A') + 10); if (c >= 'a' && c <= 'f') - return (byte) ((c - 'a') + 10); + return (byte)((c - 'a') + 10); if (c >= '0' && c <= '9') - return (byte) (c - '0'); + return (byte)(c - '0'); throw new ArgumentException (); } - public static byte[] HexToByteArray (string hex) + public static byte [] HexToByteArray (string hex) { if (hex.Length % 2 == 1) return null; try { - var bytes = new byte[hex.Length / 2]; + var bytes = new byte [hex.Length / 2]; for (int i = 0, j = 0; i < bytes.Length; i++, j += 2) { - var x1 = ToXDigit (hex[j]); - var x2 = ToXDigit (hex[j + 1]); + var x1 = ToXDigit (hex [j]); + var x2 = ToXDigit (hex [j + 1]); - bytes[i] = (byte) ((x1 << 4) | x2); + bytes [i] = (byte)((x1 << 4) | x2); } return bytes; @@ -101,7 +99,7 @@ public static byte[] HexToByteArray (string hex) } } - static byte[] GetHashBytes (Source source) + static byte [] GetHashBytes (Source source) { if (source == null) return null; @@ -133,7 +131,7 @@ public override string FullStackframeText { currentFormat.ParameterTypes != format.ParameterTypes || currentFormat.ParameterValues != format.ParameterValues) { format = currentFormat; - var body = ((VSCodeDebuggerSession)DebuggerSession).protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = frameIndex, Levels = 1, Format = currentFormat }); + var body = ((VsCodeDebuggerSession)DebuggerSession).protocolClient.SendRequestSync (new StackTraceRequest (threadId) { StartFrame = frameIndex, Levels = 1, Format = currentFormat }); fullStackframeText = body.StackFrames [0].Name; } return fullStackframeText; diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs index 19c8c4fa772..058db4957bb 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs @@ -14,13 +14,13 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol class VSCodeObjectSource : IObjectValueSource { const VariablePresentationHint.AttributesValue ConstantReadOnlyStatic = VariablePresentationHint.AttributesValue.Constant | VariablePresentationHint.AttributesValue.ReadOnly | VariablePresentationHint.AttributesValue.Static; - static readonly char[] CommaDotOrSquareEndBracket = { ',', '.', ']' }; - static readonly char[] CommaOrSquareEndBracket = { ',', ']' }; - static readonly char[] LessThanOrSquareBracket = { '<', '[' }; + static readonly char [] CommaDotOrSquareEndBracket = { ',', '.', ']' }; + static readonly char [] CommaOrSquareEndBracket = { ',', ']' }; + static readonly char [] LessThanOrSquareBracket = { '<', '[' }; - ObjectValue[] objValChildren; + ObjectValue [] objValChildren; - readonly VSCodeDebuggerSession vsCodeDebuggerSession; + readonly VsCodeDebuggerSession vsCodeDebuggerSession; readonly int parentVariablesReference; readonly ObjectValueFlags flags; readonly int variablesReference; @@ -71,24 +71,24 @@ static bool IsMultiDimensionalArray (string type, out int arrayIndexer) if (index == -1) return false; - if (type[index] == '<') { + if (type [index] == '<') { int depth = 1; index++; while (index < type.Length && depth > 0) { - switch (type[index++]) { + switch (type [index++]) { case '<': depth++; break; case '>': depth--; break; } } - if (index >= type.Length || type[index] != '[') + if (index >= type.Length || type [index] != '[') return false; } arrayIndexer = index++; - return index < type.Length && type[index] == ','; + return index < type.Length && type [index] == ','; } // Note: displayType will often have spaces after commas @@ -111,7 +111,7 @@ string GetFixedValue (string value, string canonType, string displayType) if (endIndex == -1) return value; - if (endIndex + 1 < value.Length && value[endIndex] == '.' && value[endIndex + 1] == '.') { + if (endIndex + 1 < value.Length && value [endIndex] == '.' && value [endIndex + 1] == '.') { int min, max; number = value.Substring (index, endIndex - index); @@ -134,13 +134,13 @@ string GetFixedValue (string value, string canonType, string displayType) compacted.Append (value, index, endIndex - index); } - compacted.Append (value[endIndex]); + compacted.Append (value [endIndex]); index = endIndex + 1; - if (value[endIndex] == ']') + if (value [endIndex] == ']') break; - if (index < value.Length && value[index] == ' ') + if (index < value.Length && value [index] == ' ') index++; } @@ -207,13 +207,13 @@ static bool IsCSError (int code, string message, string value, out string newVal int startIndex = prefix.Length; int index = startIndex; - while (index < value.Length && value[index] != '\'') + while (index < value.Length && value [index] != '\'') index++; newValue = value.Substring (startIndex, index - startIndex); index++; - if (index >= value.Length || value[index] != ' ') + if (index >= value.Length || value [index] != ' ') return false; index++; @@ -224,7 +224,7 @@ static bool IsCSError (int code, string message, string value, out string newVal return string.CompareOrdinal (value, index, message, 0, message.Length) == 0; } - public VSCodeObjectSource (VSCodeDebuggerSession vsCodeDebuggerSession, int variablesReference, int parentVariablesReference, string name, string type, string evalName, int frameId, string val) + public VSCodeObjectSource (VsCodeDebuggerSession vsCodeDebuggerSession, int variablesReference, int parentVariablesReference, string name, string type, string evalName, int frameId, string val) { this.vsCodeDebuggerSession = vsCodeDebuggerSession; this.parentVariablesReference = parentVariablesReference; @@ -263,18 +263,18 @@ public VSCodeObjectSource (VSCodeDebuggerSession vsCodeDebuggerSession, int vari this.val = "No return value."; this.display = val; - if (this.name[0] == '[') + if (this.name [0] == '[') flags |= ObjectValueFlags.ArrayElement; if (type == null || val == $"'{this.name}' threw an exception of type '{this.type}'") flags |= ObjectValueFlags.Error; } - public ObjectValue[] GetChildren (ObjectPath path, int index, int count, EvaluationOptions options) + public ObjectValue [] GetChildren (ObjectPath path, int index, int count, EvaluationOptions options) { if (objValChildren == null) { if (variablesReference <= 0) { - objValChildren = new ObjectValue[0]; + objValChildren = new ObjectValue [0]; } else { using (var timer = vsCodeDebuggerSession.EvaluationStats.StartTimer ()) { var children = vsCodeDebuggerSession.protocolClient.SendRequestSync (new VariablesRequest ( diff --git a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/VsCodeStackFrameTests.cs b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/VsCodeStackFrameTests.cs index 3576b8d19fe..4494843ec36 100644 --- a/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/VsCodeStackFrameTests.cs +++ b/main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger.Tests/VsCodeStackFrameTests.cs @@ -36,7 +36,7 @@ public class VsCodeStackFrameTests [Test] public void TestHexDecode () { - var result = VsCodeStackFrame.HexToByteArray ("fFaAbB0012a1"); + var result = VsCodeDebuggerStackFrame.HexToByteArray ("fFaAbB0012a1"); Assert.AreEqual ((byte) 0xff, result[0], "result[0]"); Assert.AreEqual ((byte) 0xaa, result[1], "result[1]");