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()); }
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)); }
protected override void HandleDisconnectRequestAsync(IRequestResponder <DisconnectArguments> responder) { responder.SetResponse(new DisconnectResponse()); Protocol.SendEvent(new TerminatedEvent()); Protocol.SendEvent(new ExitedEvent(0)); _terminatedTcs.TrySetResult(null); }
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); }
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); } }
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()); }
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); } }
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); }
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); }
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)); }
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)); }
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()); }