private void HandleScopesRequest(DAPRequest request, DAPScopesRequest msg) { var threadId = msg.frameId >> 16; var frameIndex = msg.frameId & 0xffff; var state = GetThread(threadId); if (!state.Stopped) { throw new RequestFailedException("Cannot get scopes when thread is not stopped"); } if (frameIndex < 0 || frameIndex >= state.Stack.Count) { throw new RequestFailedException("Requested scopes for unknown frame"); } var frame = state.Stack[frameIndex]; var stackScope = new DAPScope { name = "Locals", variablesReference = Evaluator.MakeStackRef(threadId, frameIndex, 0), namedVariables = 0, // TODO - get hinted named/indexed variable count, indexedVariables = 0, expensive = false }; SetScopeRange(stackScope, frame); var upvalueScope = new DAPScope { name = "Upvalues", variablesReference = Evaluator.MakeStackRef(threadId, frameIndex, 1), namedVariables = 0, indexedVariables = 0, expensive = false }; SetScopeRange(upvalueScope, frame); var scopes = new List <DAPScope> { stackScope, upvalueScope }; var reply = new DAPScopesResponse { scopes = scopes }; Stream.SendReply(request, reply); }
private void SetScopeRange(DAPScope scope, StackFrame frame) { // Send location information for rule-local scopes. // If the scope location is missing, the value of local variables will be displayed in // every rule that has variables with the same name. // This restricts them so they're only displayed in the rule that the stack frame belongs to. if (frame.ScopeFirstLine != 0) { scope.source = new DAPSource { name = frame.Source, path = (frame.Path ?? frame.Source).Replace("/", "\\") }; scope.line = frame.ScopeFirstLine; scope.column = 1; scope.endLine = frame.ScopeLastLine; scope.endColumn = 1; } }