protected override void HandleSetBreakpointsRequestAsync(IRequestResponder <SetBreakpointsArguments, SetBreakpointsResponse> responder)
        {
            // Ignore breakpoints for files that are not solidity sources
            if (!responder.Arguments.Source.Path.EndsWith(".sol", StringComparison.OrdinalIgnoreCase))
            {
                responder.SetResponse(new SetBreakpointsResponse());
                return;
            }

            if (!responder.Arguments.Source.Path.StartsWith(ConfigurationProperties.WorkspaceDirectory, StringComparison.OrdinalIgnoreCase))
            {
                throw new Exception($"Unexpected breakpoint source path: {responder.Arguments.Source.Path}, workspace: {ConfigurationProperties.WorkspaceDirectory}");
            }

            if (responder.Arguments.SourceModified.GetValueOrDefault())
            {
                throw new Exception("Debugging modified sources is not supported.");
            }


            // Obtain our internal path from a vs code path
            var relativeFilePath = ConvertVSCodePathToInternalPath(responder.Arguments.Source.Path);

            _sourceBreakpoints[relativeFilePath] = responder.Arguments.Breakpoints.Select(b => b.Line).ToArray();

            responder.SetResponse(new SetBreakpointsResponse());
        }
예제 #2
0
        protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder)
        {
            // Obtain relevant variable resolving information.
            int  threadId              = 0;
            int  traceIndex            = 0;
            bool isLocalVariableScope  = false;
            bool isStateVariableScope  = false;
            bool isParentVariableScope = false;
            UnderlyingVariableValuePair parentVariableValuePair = new UnderlyingVariableValuePair(null, null);

            // Try to obtain the variable reference as a local variable scope.
            isLocalVariableScope = ReferenceContainer.ResolveLocalVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex);
            if (!isLocalVariableScope)
            {
                // Try to obtain the variable reference as a state variable scope.
                isStateVariableScope = ReferenceContainer.ResolveStateVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex);
                if (!isStateVariableScope)
                {
                    // Try to obtain the variable reference as a sub-variable scope.
                    isParentVariableScope = ReferenceContainer.ResolveParentVariable(responder.Arguments.VariablesReference, out threadId, out parentVariableValuePair);
                }
            }

            // Using our thread id, obtain our thread state
            ThreadStates.TryGetValue(threadId, out var threadState);

            // Verify the thread state is valid
            if (threadState == null)
            {
                responder.SetResponse(new VariablesResponse());
                return;
            }

            // Obtain the trace index for this scope.
            List <Variable> variableList = new List <Variable>();

            try
            {
                ResolveVariables(
                    variableList,
                    responder.Arguments.VariablesReference,
                    isLocalVariableScope,
                    isStateVariableScope,
                    isParentVariableScope,
                    traceIndex,
                    parentVariableValuePair,
                    threadState);
            }
            catch (Exception ex)
            {
                LogException(ex, threadState);
            }

            // Respond with our variable list.
            responder.SetResponse(new VariablesResponse(variableList));
        }
        protected override void HandleThreadsRequestAsync(IRequestResponder <ThreadsArguments, ThreadsResponse> responder)
        {
            // Create a list of threads from our thread states.
            List <Thread> threads = ThreadStates.Values.Select(x => new Thread(x.ThreadId, $"thread_{x.ThreadId}")).ToList();

            responder.SetResponse(new ThreadsResponse(threads));
        }
        protected override void HandleScopesRequestAsync(IRequestResponder <ScopesArguments, ScopesResponse> responder)
        {
            // Create our scope list
            List <Scope> scopeList = new List <Scope>();

            // Obtain all relevant ids.
            int stackFrameId = responder.Arguments.FrameId;
            int?localScopeId = ReferenceContainer.GetLocalScopeId(stackFrameId);
            int?stateScopeId = ReferenceContainer.GetStateScopeId(stackFrameId);

            // Add state variable scope if applicable.
            if (stateScopeId.HasValue)
            {
                scopeList.Add(new Scope("State Variables", stateScopeId.Value, false));
            }

            // Add local variable scope if applicable.
            if (localScopeId.HasValue)
            {
                scopeList.Add(new Scope("Local Variables", localScopeId.Value, false));
            }

            // Set our response.
            responder.SetResponse(new ScopesResponse(scopeList));
        }
예제 #5
0
 protected override void HandleDisconnectRequestAsync(IRequestResponder <DisconnectArguments> responder)
 {
     responder.SetResponse(new DisconnectResponse());
     Protocol.SendEvent(new TerminatedEvent());
     Protocol.SendEvent(new ExitedEvent(0));
     _terminatedTcs.TrySetResult(null);
 }
예제 #6
0
        protected override void HandleLaunchRequestAsync(IRequestResponder <LaunchArguments> responder)
        {
            if (session != null)
            {
                var ex = new InvalidOperationException();
                Log(ex.Message, LogCategory.DebugAdapterOutput);
                responder.SetError(new ProtocolException(ex.Message, ex));
                return;
            }

            _ = LaunchConfigParser.CreateDebugSessionAsync(responder.Arguments, Protocol.SendEvent, defaultDebugView)
                .ContinueWith(t =>
            {
                if (t.IsCompletedSuccessfully)
                {
                    session = t.Result;
                    session.Start();
                    Protocol.SendEvent(new InitializedEvent());
                    responder.SetResponse(new LaunchResponse());
                }
                else
                {
                    if (t.Exception != null)
                    {
                        responder.SetError(new ProtocolException(t.Exception.Message, t.Exception));
                    }
                    else
                    {
                        responder.SetError(new ProtocolException($"Unknown error in {nameof(LaunchConfigParser.CreateDebugSessionAsync)}"));
                    }
                }
            }, TaskScheduler.Current);
        }
예제 #7
0
 protected override void HandleSetExceptionBreakpointsRequestAsync(IRequestResponder <SetExceptionBreakpointsArguments> responder)
 {
     lock (_exceptionBreakpointFilters)
     {
         _exceptionBreakpointFilters = new HashSet <string>(responder.Arguments.Filters);
         var response = new SetExceptionBreakpointsResponse();
         responder.SetResponse(response);
     }
 }
        protected override void HandleExceptionInfoRequestAsync(IRequestResponder <ExceptionInfoArguments, ExceptionInfoResponse> responder)
        {
            // Obtain the current thread state
            bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState);

            if (success)
            {
                string exceptionMessage = threadState.ExecutionTraceAnalysis.GetException(threadState.CurrentStepIndex.Value).Message;
                responder.SetResponse(new ExceptionInfoResponse(exceptionMessage, ExceptionBreakMode.Always));
            }
        }
        protected override void HandleStepBackRequestAsync(IRequestResponder <StepBackArguments> responder)
        {
            // Set our response
            responder.SetResponse(new StepBackResponse());

            // Obtain the current thread state
            bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState);

            if (success)
            {
                // Continue executing
                ContinueExecution(threadState, DesiredControlFlow.StepBackwards);
            }
        }
        protected override void HandleContinueRequestAsync(IRequestResponder <ContinueArguments, ContinueResponse> responder)
        {
            // Set our response
            responder.SetResponse(new ContinueResponse());

            // Obtain the current thread state
            bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState);

            if (success)
            {
                // Continue executing, taking one step before continuing, as evaluation occurs before steps occur, and we want
                // to ensure we advanced position from our last and don't re-evaluate the same trace point. We only do this on
                // startup since we want the initial trace point to be evaluated. After that, we want to force advancement by
                // at least one step before continuation/re-evaluation.
                ContinueExecution(threadState, DesiredControlFlow.Continue, 1);
            }
        }
예제 #11
0
        protected override void HandleEvaluateRequestAsync(IRequestResponder <EvaluateArguments, EvaluateResponse> responder)
        {
            EvaluateResponse evalResponse = null;

            if (responder.Arguments.Expression.StartsWith(VARIABLE_EVAL_TYPE, StringComparison.Ordinal))
            {
                var id = int.Parse(responder.Arguments.Expression.Substring(VARIABLE_EVAL_TYPE.Length), CultureInfo.InvariantCulture);
                if (_variableEvaluationValues.TryGetValue(id, out var evalResult))
                {
                    evalResponse = new EvaluateResponse {
                        Result = evalResult
                    };
                }
            }

            responder.SetResponse(evalResponse ?? new EvaluateResponse());
        }
예제 #12
0
        protected override void HandleContinueRequestAsync(IRequestResponder <ContinueArguments, ContinueResponse> responder)
        {
            // Set our response
            responder.SetResponse(new ContinueResponse());

            // Obtain the current thread state
            bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState);

            if (success)
            {
                // Advance our step from our current position
                threadState.IncrementStep();

                // Continue executing
                ContinueExecution(threadState, DesiredControlFlow.Continue);
            }
        }
        protected override void HandleInitializeRequestAsync(IRequestResponder <InitializeArguments, InitializeResponse> responder)
        {
            var response = new InitializeResponse
            {
                SupportsConfigurationDoneRequest = true,
                SupportsEvaluateForHovers        = true,
                SupportsStepBack             = true,
                SupportsStepInTargetsRequest = true,
                SupportTerminateDebuggee     = false,
                SupportsRestartRequest       = false,
                SupportsRestartFrame         = false,
                SupportedChecksumAlgorithms  = new List <ChecksumAlgorithm> {
                    ChecksumAlgorithm.SHA256
                }
            };

            responder.SetResponse(response);
            Protocol.SendEvent(new InitializedEvent());
            CompletedInitializationRequest.SetResult(null);
        }
        private void OnPromptRequest(IRequestResponder <PromptArgs, PromptResponse> responder)
        {
            IVsUIShell shell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell;

            try
            {
                this.context.Logger.Log("Responding to 'prompt' request.");

                shell.EnableModeless(0);
                DialogResult result = MessageBox.Show(responder.Arguments.Message, "Prompt from Debug Adapter", MessageBoxButtons.OKCancel);

                responder.SetResponse(
                    new PromptResponse()
                {
                    Response = result == DialogResult.OK ? PromptResponse.ResponseValue.OK : PromptResponse.ResponseValue.Cancel
                });
            }
            finally
            {
                shell.EnableModeless(1);
            }
        }
예제 #15
0
        protected override void HandleInitializeRequestAsync(IRequestResponder <InitializeArguments, InitializeResponse> responder)
        {
            var response = new InitializeResponse
            {
                SupportsConfigurationDoneRequest = true,
                SupportsEvaluateForHovers        = true,
                SupportsStepBack             = true,
                SupportsStepInTargetsRequest = true,
                SupportTerminateDebuggee     = false,
                SupportsRestartRequest       = false,
                SupportsRestartFrame         = false,
                SupportedChecksumAlgorithms  = new List <ChecksumAlgorithm> {
                    ChecksumAlgorithm.SHA256
                },
                SupportsExceptionInfoRequest = true
            };

            response.ExceptionBreakpointFilters = new List <ExceptionBreakpointsFilter>
            {
                new ExceptionBreakpointsFilter
                {
                    Filter  = EXCEPTION_BREAKPOINT_FILTER_ALL,
                    Label   = EXCEPTION_BREAKPOINT_FILTER_ALL,
                    Default = false
                },
                new ExceptionBreakpointsFilter
                {
                    Filter  = EXCEPTION_BREAKPOINT_FILTER_UNHANDLED,
                    Label   = EXCEPTION_BREAKPOINT_FILTER_UNHANDLED,
                    Default = true
                }
            };

            responder.SetResponse(response);
            Protocol.SendEvent(new InitializedEvent());
            CompletedInitializationRequest.SetResult(null);
        }
예제 #16
0
        protected override void HandleExceptionInfoRequestAsync(IRequestResponder <ExceptionInfoArguments, ExceptionInfoResponse> responder)
        {
            // Obtain the current thread state
            bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState);

            if (success)
            {
                var ex = threadState.ExecutionTraceAnalysis.GetException(threadState.CurrentStepIndex.Value);

                // Get the exception call stack lines.
                var exStackTrace = threadState.ExecutionTraceAnalysis.GetCallStackString(ex.TraceIndex.Value);

                responder.SetResponse(new ExceptionInfoResponse("Error", ExceptionBreakMode.Always)
                {
                    Description = ex.Message,
                    Details     = new ExceptionDetails
                    {
                        Message = ex.Message,
                        FormattedDescription = ex.Message,
                        StackTrace           = exStackTrace
                    }
                });
            }
        }
        protected override void HandleDisconnectRequestAsync(IRequestResponder <DisconnectArguments> responder)
        {
            // Set our exiting status
            Exiting = true;

            // Loop for each thread
            foreach (var threadStateKeyValuePair in ThreadStates)
            {
                // Release the execution lock on this thread state.
                // NOTE: This already happens when setting exiting status,
                // but only if the thread is currently stepping/continuing,
                // and not paused. This will allow it to continue if stopped.
                threadStateKeyValuePair.Value.Semaphore.Release();
            }

            // Set our response to the disconnect request.
            responder.SetResponse(new DisconnectResponse());
            Protocol.SendEvent(new TerminatedEvent());
            Protocol.SendEvent(new ExitedEvent(0));
            _terminatedTcs.TrySetResult(null);

            // If we have an event, invoke it
            OnDebuggerDisconnect?.Invoke(this);
        }
예제 #18
0
        protected override void HandleStackTraceRequestAsync(IRequestResponder <StackTraceArguments, StackTraceResponse> responder)
        {
            // Create a list of stack frames or try to get cached ones.
            List <StackFrame> stackFrames;
            bool cachedStackFrames = ReferenceContainer.TryGetStackFrames(responder.Arguments.ThreadId, out stackFrames);

            // Verify we have a thread state for this thread, and a valid step to represent in it.
            if (!cachedStackFrames && ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState) && threadState.CurrentStepIndex.HasValue)
            {
                // Initialize our stack frame list
                stackFrames = new List <StackFrame>();

                // Obtain the callstack
                var callstack = threadState.ExecutionTraceAnalysis.GetCallStack(threadState.CurrentStepIndex.Value);

                // Loop through our scopes.
                for (int i = 0; i < callstack.Length; i++)
                {
                    // Grab our current call frame
                    var currentCallFrame = callstack[i];

                    // If the scope is invalid, then we skip it.
                    if (currentCallFrame.FunctionDefinition == null)
                    {
                        continue;
                    }

                    // We obtain our relevant source lines for this call stack frame.
                    SourceFileLine[] lines = null;

                    // If it's the most recent call, we obtain the line for the current trace.
                    int traceIndex = -1;
                    if (i == 0)
                    {
                        traceIndex = threadState.CurrentStepIndex.Value;
                        lines      = threadState.ExecutionTraceAnalysis.GetSourceLines(traceIndex);
                    }
                    else
                    {
                        // If it's not the most recent call, we obtain the position at our
                        var previousCallFrame = callstack[i - 1];
                        if (previousCallFrame.ParentFunctionCall != null)
                        {
                            traceIndex = previousCallFrame.ParentFunctionCallIndex.Value;
                            lines      = threadState.ExecutionTraceAnalysis.GetSourceLines(previousCallFrame.ParentFunctionCall);
                        }
                        else
                        {
                            throw new Exception("TODO: Stack Trace could not be generated because previous call frame's function call could not be resolved. Update behavior in this case.");
                        }
                    }

                    // Obtain the method name we are executing in.
                    string frameName = currentCallFrame.FunctionDefinition.Name;
                    if (string.IsNullOrEmpty(frameName))
                    {
                        frameName = currentCallFrame.FunctionDefinition.IsConstructor ? $".ctor ({currentCallFrame.ContractDefinition.Name})" : "<unresolved>";
                    }

                    // Determine the bounds of our stack frame.
                    int startLine   = 0;
                    int startColumn = 0;
                    int endLine     = 0;
                    int endColumn   = 0;

                    // Loop through all of our lines for this position.
                    for (int x = 0; x < lines.Length; x++)
                    {
                        // Obtain our indexed line.
                        SourceFileLine line = lines[x];

                        // Set our start position if relevant.
                        if (x == 0 || line.LineNumber <= startLine)
                        {
                            // Set our starting line number.
                            startLine = line.LineNumber;

                            // TODO: Determine our column start
                        }

                        // Set our end position if relevant.
                        if (x == 0 || line.LineNumber >= endLine)
                        {
                            // Set our ending line number.
                            endLine = line.LineNumber;

                            // TODO: Determine our column
                            endColumn = line.Length;
                        }
                    }

                    // Format agnostic path to platform specific path
                    var sourceFilePath = lines[0].SourceFileMapParent.SourceFilePath;
                    if (Path.DirectorySeparatorChar == '\\')
                    {
                        sourceFilePath = sourceFilePath.Replace('/', Path.DirectorySeparatorChar);
                    }

                    // Create our source object
                    Source stackFrameSource = new Source()
                    {
                        Name = lines[0].SourceFileMapParent.SourceFileName,
                        Path = Path.Join(ConfigurationProperties.WorkspaceDirectory, _contractsDirectory, sourceFilePath)
                    };

                    var stackFrame = new StackFrame()
                    {
                        Id        = ReferenceContainer.GetUniqueId(),
                        Name      = frameName,
                        Line      = startLine,
                        Column    = startColumn,
                        Source    = stackFrameSource,
                        EndLine   = endLine,
                        EndColumn = endColumn
                    };

                    // Add the stack frame to our reference list
                    ReferenceContainer.LinkStackFrame(threadState.ThreadId, stackFrame, traceIndex);

                    // Add our stack frame to the result list
                    stackFrames.Add(stackFrame);
                }
            }

            // Return our stack frames in our response.
            responder.SetResponse(new StackTraceResponse(stackFrames));
        }
예제 #19
0
 protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder)
 {
     responder.SetResponse(
         new VariablesResponse(
             GetVariables(responder.Arguments.VariablesReference)));
 }
 protected override void HandleEvaluateRequestAsync(IRequestResponder <EvaluateArguments, EvaluateResponse> responder)
 {
     responder.SetResponse(new EvaluateResponse());
 }
 protected override void HandleLaunchRequestAsync(IRequestResponder <LaunchArguments> responder)
 {
     SetupConfigurationProperties(responder.Arguments.ConfigurationProperties);
     responder.SetResponse(new LaunchResponse());
     CompletedLaunchRequest.SetResult(null);
 }
 protected override void HandleConfigurationDoneRequestAsync(IRequestResponder <ConfigurationDoneArguments> responder)
 {
     responder.SetResponse(new ConfigurationDoneResponse());
     CompletedConfigurationDoneRequest.SetResult(null);
 }
        protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder)
        {
            // Obtain relevant variable resolving information.
            int  threadId              = 0;
            int  traceIndex            = 0;
            bool isLocalVariableScope  = false;
            bool isStateVariableScope  = false;
            bool isParentVariableScope = false;
            UnderlyingVariableValuePair parentVariableValuePair = new UnderlyingVariableValuePair(null, null);

            // Try to obtain the variable reference as a local variable scope.
            isLocalVariableScope = ReferenceContainer.ResolveLocalVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex);
            if (!isLocalVariableScope)
            {
                // Try to obtain the variable reference as a state variable scope.
                isStateVariableScope = ReferenceContainer.ResolveStateVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex);
                if (!isStateVariableScope)
                {
                    // Try to obtain the variable reference as a sub-variable scope.
                    isParentVariableScope = ReferenceContainer.ResolveParentVariable(responder.Arguments.VariablesReference, out threadId, out parentVariableValuePair);
                }
            }

            // Using our thread id, obtain our thread state
            ThreadStates.TryGetValue(threadId, out var threadState);

            // Verify the thread state is valid
            if (threadState == null)
            {
                responder.SetResponse(new VariablesResponse());
                return;
            }

            // Obtain the trace index for this scope.
            List <Variable> variableList = new List <Variable>();

            // Obtain our local variables at this point in execution
            VariableValuePair[] variablePairs = Array.Empty <VariableValuePair>();
            if (isLocalVariableScope)
            {
                variablePairs = threadState.ExecutionTraceAnalysis.GetLocalVariables(traceIndex);
            }
            else if (isStateVariableScope)
            {
                variablePairs = threadState.ExecutionTraceAnalysis.GetStateVariables(traceIndex);
            }
            else if (isParentVariableScope)
            {
                // We're loading sub-variables for a variable.
                switch (parentVariableValuePair.Variable.GenericType)
                {
                case VarGenericType.Struct:
                {
                    // Cast our to an enumerable type.
                    variablePairs = ((IEnumerable <VariableValuePair>)parentVariableValuePair.Value).ToArray();
                    break;
                }

                case VarGenericType.Array:
                {
                    // Cast our variable
                    var arrayVariable = ((VarArray)parentVariableValuePair.Variable);

                    // Cast to an object array.
                    var arrayValue = (object[])parentVariableValuePair.Value;

                    // Loop for each element
                    for (int i = 0; i < arrayValue.Length; i++)
                    {
                        // Create an underlying variable value pair for this element
                        var underlyingVariableValuePair = new UnderlyingVariableValuePair(arrayVariable.ElementObject, arrayValue[i]);

                        // Check if this is a nested variable type
                        bool nestedType = IsNestedVariableType(arrayVariable.ElementObject.GenericType);
                        int  variablePairReferenceId = 0;
                        if (nestedType)
                        {
                            // Create a new reference id for this variable if it's a nested type.
                            variablePairReferenceId = ReferenceContainer.GetUniqueId();

                            // Link our reference for any nested types.
                            ReferenceContainer.LinkSubVariableReference(responder.Arguments.VariablesReference, variablePairReferenceId, threadId, underlyingVariableValuePair);
                        }

                        // Obtain the value string for this variable and add it to our list.
                        string variableValueString = GetVariableValueString(underlyingVariableValuePair);
                        variableList.Add(new Variable($"[{i}]", variableValueString, variablePairReferenceId));
                    }


                    break;
                }

                case VarGenericType.ByteArrayDynamic:
                case VarGenericType.ByteArrayFixed:
                {
                    // Cast our to an enumerable type.
                    var bytes = (Memory <byte>)parentVariableValuePair.Value;
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        variableList.Add(new Variable($"[{i}]", bytes.Span[i].ToString(CultureInfo.InvariantCulture), 0));
                    }

                    break;
                }
                }
            }

            // Loop for each local variables
            foreach (VariableValuePair variablePair in variablePairs)
            {
                // Create an underlying variable value pair for this pair.
                var underlyingVariableValuePair = new UnderlyingVariableValuePair(variablePair);

                // Check if this is a nested variable type
                bool nestedType = IsNestedVariableType(variablePair.Variable.GenericType);
                int  variablePairReferenceId = 0;
                if (nestedType)
                {
                    // Create a new reference id for this variable if it's a nested type.
                    variablePairReferenceId = ReferenceContainer.GetUniqueId();

                    // Link our reference for any nested types.
                    ReferenceContainer.LinkSubVariableReference(responder.Arguments.VariablesReference, variablePairReferenceId, threadId, underlyingVariableValuePair);
                }

                // Obtain the value string for this variable and add it to our list.
                string variableValueString = GetVariableValueString(underlyingVariableValuePair);
                variableList.Add(new Variable(variablePair.Variable.Name, variableValueString, variablePairReferenceId));
            }

            // Respond with our variable list.
            responder.SetResponse(new VariablesResponse(variableList));
        }
        protected override void HandleStackTraceRequestAsync(IRequestResponder <StackTraceArguments, StackTraceResponse> responder)
        {
            // Create a list of stack frames or try to get cached ones.
            List <StackFrame> stackFrames;
            bool cachedStackFrames = ReferenceContainer.TryGetStackFrames(responder.Arguments.ThreadId, out stackFrames);

            // Verify we have a thread state for this thread, and a valid step to represent in it.
            if (!cachedStackFrames && ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState) && threadState.CurrentStepIndex.HasValue)
            {
                // Initialize our stack frame list
                stackFrames = new List <StackFrame>();

                // Obtain the callstack
                var callstack = threadState.ExecutionTraceAnalysis.GetCallStack(threadState.CurrentStepIndex.Value);

                // Loop through our scopes.
                for (int i = 0; i < callstack.Length; i++)
                {
                    // Grab our current call frame
                    var currentStackFrame = callstack[i];

                    // If the scope could not be resolved within a function, and no lines could be resolved, skip to the next frame.
                    // as this is not a code section we can describe in any meaningful way.
                    if (!currentStackFrame.ResolvedFunction && currentStackFrame.CurrentPositionLines.Length == 0)
                    {
                        continue;
                    }

                    // If we couldn't resolve the current position or there were no lines representing it
                    if (currentStackFrame.Error || currentStackFrame.CurrentPositionLines.Length == 0)
                    {
                        continue;
                    }

                    // Obtain the method name we are executing in.
                    string frameName = currentStackFrame.FunctionName;
                    if (string.IsNullOrEmpty(frameName))
                    {
                        frameName = "<undefined>";
                    }

                    // Determine the bounds of our stack frame.
                    int startLine   = 0;
                    int startColumn = 0;
                    int endLine     = 0;
                    int endColumn   = 0;

                    // Loop through all of our lines for this position.
                    for (int x = 0; x < currentStackFrame.CurrentPositionLines.Length; x++)
                    {
                        // Obtain our indexed line.
                        SourceFileLine line = currentStackFrame.CurrentPositionLines[x];

                        // Set our start position if relevant.
                        if (x == 0 || line.LineNumber <= startLine)
                        {
                            // Set our starting line number.
                            startLine = line.LineNumber;

                            // TODO: Determine our column start
                        }

                        // Set our end position if relevant.
                        if (x == 0 || line.LineNumber >= endLine)
                        {
                            // Set our ending line number.
                            endLine = line.LineNumber;

                            // TODO: Determine our column
                            endColumn = line.Length;
                        }
                    }

                    // Format agnostic path to platform specific path
                    var sourceFilePath = currentStackFrame.CurrentPositionLines[0].SourceFileMapParent.SourceFilePath;
                    if (Path.DirectorySeparatorChar == '\\')
                    {
                        sourceFilePath = sourceFilePath.Replace('/', Path.DirectorySeparatorChar);
                    }

                    // Create our source object
                    Source stackFrameSource = new Source()
                    {
                        Name = currentStackFrame.CurrentPositionLines[0].SourceFileMapParent.SourceFileName,
                        Path = Path.Join(ConfigurationProperties.WorkspaceDirectory, _contractsDirectory, sourceFilePath)
                    };

                    var stackFrame = new StackFrame()
                    {
                        Id        = ReferenceContainer.GetUniqueId(),
                        Name      = frameName,
                        Line      = startLine,
                        Column    = startColumn,
                        Source    = stackFrameSource,
                        EndLine   = endLine,
                        EndColumn = endColumn
                    };

                    // Add the stack frame to our reference list
                    ReferenceContainer.LinkStackFrame(threadState.ThreadId, stackFrame, currentStackFrame.CurrentPositionTraceIndex);

                    // Add our stack frame to the result list
                    stackFrames.Add(stackFrame);
                }
            }

            // Return our stack frames in our response.
            responder.SetResponse(new StackTraceResponse(stackFrames));
        }
예제 #25
0
        void HandleInlineVariable(IRequestResponder <InlineVariableArguments> handler)
        {
            List <InlineVaiable> res = new List <InlineVaiable>();
            var DocumentName         = handler.Arguments.DocumentName;

            try
            {
                if (File.Exists(DocumentName))
                {
                    using (var stream = File.OpenRead(DocumentName))
                    {
                        SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(SourceText.From(stream), path: DocumentName);
                        TextLine   textLine   = syntaxTree.GetText().Lines[handler.Arguments.Line];
                        Location   location   = syntaxTree.GetLocation(textLine.Span);
                        SyntaxTree sourceTree = location.SourceTree;
                        SyntaxNode node       = location.SourceTree.GetRoot().FindNode(location.SourceSpan, true, true);

                        bool isLambda = GetParentMethod <LambdaExpressionSyntax>(node.Parent) != null;
                        BaseMethodDeclarationSyntax method = GetParentMethod <MethodDeclarationSyntax>(node.Parent);
                        if (method == null)
                        {
                            method = GetParentMethod <ConstructorDeclarationSyntax>(node.Parent);
                        }

                        foreach (var i in method.ParameterList.Parameters)
                        {
                            var span = syntaxTree.GetLineSpan(i.Identifier.Span);
                            if (span.StartLinePosition.Line > handler.Arguments.Line)
                            {
                                continue;
                            }
                            res.Add(InlineVaiable.FromIdentifier(i.Identifier));
                        }

                        foreach (var i in method.Body.Statements)
                        {
                            if (i is LocalDeclarationStatementSyntax local)
                            {
                                foreach (var j in local.Declaration.Variables)
                                {
                                    var span = syntaxTree.GetLineSpan(j.Identifier.Span);
                                    if (span.StartLinePosition.Line > handler.Arguments.Line)
                                    {
                                        continue;
                                    }
                                    res.Add(InlineVaiable.FromIdentifier(j.Identifier));
                                }
                            }
                            if (i is ForStatementSyntax fore)
                            {
                                foreach (var j in fore.Declaration.Variables)
                                {
                                    var span = syntaxTree.GetLineSpan(j.Identifier.Span);
                                    if (span.StartLinePosition.Line > handler.Arguments.Line)
                                    {
                                        continue;
                                    }

                                    res.Add(InlineVaiable.FromIdentifier(j.Identifier));
                                }
                            }
                            if (i is ForEachStatementSyntax fore2)
                            {
                            }
                        }
                    }
                }
                handler.SetResponse(new InlineVariableResponse()
                {
                    Variables = res
                });
            }
            catch (Exception ex)
            {
                handler.SetError(new ProtocolException(ex.ToString()));
            }
        }
 protected override void HandlePauseRequestAsync(IRequestResponder <PauseArguments> responder)
 {
     responder.SetResponse(new PauseResponse());
 }
 protected override void HandleStepInTargetsRequestAsync(IRequestResponder <StepInTargetsArguments, StepInTargetsResponse> responder)
 {
     responder.SetResponse(new StepInTargetsResponse());
 }
 protected override void HandleStepOutRequestAsync(IRequestResponder <StepOutArguments> responder)
 {
     responder.SetResponse(new StepOutResponse());
 }