How to get a link to an object or its data from an external visualizer of the external view debugger?

I am trying to write a debugger visualizer for a TJSONObject or TJSONValue. Most of the visualizer works for me well. The problem I am facing is getting a reference to a TJSONObject, or at least the tostring () value for a TJSONObject.

According to the samples I saw, as well as a good post by Jeremy Sever at http://edn.embarcadero.com/article/40268 , I should get what I need the Show method of my implementation of IOTADebuggerVisualizerExternalViewer. In particular, from the string parameters Expression, TypeName and EvalResult.

From what I understand, an expression is the name of the variable to be checked (rendered), TypeName is the name of the variable's class, and EvalResult is the default string representation of the variable.

For a simple test, I placed TMemo on a TFrame descendant. From the IOTADebuggerVisualizerExternalViewer.Show method, I call the ShowJSONObject method of my TFrame, to which I pass Expression, TypeName and EvalResult. The corresponding code is displayed here:

function TDebuggerJSONVisualizer.Show(const Expression, TypeName, EvalResult: string; SuggestedLeft, SuggestedTop: Integer): IOTADebuggerVisualizerExternalViewerUpdater; var AForm: TCustomForm; AFrame: TJSONViewerFrame; VisDockForm: INTACustomDockableForm; begin VisDockForm := TJSONVisualizerForm.Create(Expression) as INTACustomDockableForm; AForm := (BorlandIDEServices as INTAServices).CreateDockableForm(VisDockForm); AForm.Left := SuggestedLeft; AForm.Top := SuggestedTop; (VisDockForm as IFrameFormHelper).SetForm(AForm); AFrame := (VisDockForm as IFrameFormHelper).GetFrame as TJSONViewerFrame; AFrame.ShowJSONObject(Expression, TypeName, EvalResult); Result := AFrame as IOTADebuggerVisualizerExternalViewerUpdater; end; { TStringListViewerFrame } procedure TJSONViewerFrame.ShowJSONObject(const Expression, TypeName, EvalResult: string); begin Memo1.Lines.Add(Expression); Memo1.Lines.Add(TypeName); Memo1.Lines.Add(EvalResult); end; 

As you can see, at this moment I am only trying to display the values โ€‹โ€‹of these three parameters from my ShowJSONObject method.

Here is a simple TJSONObject that I tried to render using the visualizer:

 var jo: TJSONObject; begin jo := TJSONObject.Create; jo.AddPair('one', 'one'); jo.AddPair('two', TJSONNumber.Create(1)); //a breakpoint here 

The result is as follows:

A debugger visualizer under development

I was hoping EvalResult would return a tostring TJSONObject view, but it returned uninformative (), which is the same as what you see by default in the local variables window.

How to get either the tostring representation of the TJSONObject for which the visualizer was called, or the handle of the actual object, so I can deconstruct and display its value?

+4
source share
1 answer

You must evaluate your expression (including calling ToString) with this procedure (just copied from my own visualizer source so that it can use some local variables that are not declared here):

 function TJSONViewerFrame.Evaluate(Expression: string): string; var CurProcess: IOTAProcess; CurThread: IOTAThread; ResultStr: array[0..4095] of Char; CanModify: Boolean; ResultAddr, ResultSize, ResultVal: LongWord; EvalRes: TOTAEvaluateResult; DebugSvcs: IOTADebuggerServices; begin begin Result := ''; if Supports(BorlandIDEServices, IOTADebuggerServices, DebugSvcs) then CurProcess := DebugSvcs.CurrentProcess; if CurProcess <> nil then begin CurThread := CurProcess.CurrentThread; if CurThread <> nil then begin EvalRes := CurThread.Evaluate(Expression, @ResultStr, Length(ResultStr), CanModify, eseAll, '', ResultAddr, ResultSize, ResultVal, '', 0); case EvalRes of erOK: Result := ResultStr; erDeferred: begin FCompleted := False; FDeferredResult := ''; FDeferredError := False; FNotifierIndex := CurThread.AddNotifier(Self); while not FCompleted do DebugSvcs.ProcessDebugEvents; CurThread.RemoveNotifier(FNotifierIndex); FNotifierIndex := -1; if not FDeferredError then begin if FDeferredResult <> '' then Result := FDeferredResult else Result := ResultStr; end; end; erBusy: begin DebugSvcs.ProcessDebugEvents; Result := Evaluate(Expression); end; end; end; end; end; end; 

So now you can replace your Show function as follows:

 AFrame.ShowJSONObject(Expression, TypeName, Evaluate(Expression + '.ToString')); 
+3
source

Source: https://habr.com/ru/post/1380959/


All Articles