Debugger: Inspect/Evaluate windows, when opened from watches or each-other transfer settings for eval-flags and converter

This commit is contained in:
Martin 2022-08-05 16:51:58 +02:00
parent f3bf79fa35
commit 847436a56f
6 changed files with 140 additions and 43 deletions

View File

@ -49,7 +49,7 @@ uses
LazarusIDEStrConsts, BaseDebugManager, InputHistory, IDEProcs, Debugger,
IdeDebuggerWatchResPrinter, IdeDebuggerWatchResult, IdeDebuggerOpts,
IdeDebuggerFpDbgValueConv, WatchInspectToolbar, DebuggerDlg, DebuggerStrConst,
IdeDebuggerStringConstants, EnvironmentOpts;
IdeDebuggerStringConstants, IdeDebuggerBase, EnvironmentOpts;
type
@ -87,7 +87,7 @@ type
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure Execute(const AExpression: String);
procedure Execute(const AExpression: String; AWatch: TWatch = nil);
property EvalExpression: string read GetEvalExpression write SetEvalExpression;
end;
@ -161,9 +161,12 @@ begin
inherited Destroy;
end;
procedure TEvaluateDlg.Execute(const AExpression: String);
procedure TEvaluateDlg.Execute(const AExpression: String; AWatch: TWatch);
begin
SetEvalExpression(AExpression);
if AWatch <> nil then
WatchInspectNav1.ReadFromWatch(AWatch, AExpression)
else
SetEvalExpression(AExpression);
end;
procedure TEvaluateDlg.DoAddWatch(Sender: TObject);
@ -288,8 +291,13 @@ begin
end;
procedure TEvaluateDlg.DoAddInspect(Sender: TObject);
var
w: TIdeWatch;
begin
DebugBoss.Inspect(WatchInspectNav1.Expression);
w := nil;
if WatchInspectNav1.CurrentWatchValue <> nil then
w := WatchInspectNav1.CurrentWatchValue.Watch;
DebugBoss.Inspect(WatchInspectNav1.Expression, w);
end;
procedure TEvaluateDlg.SetEvalExpression(const NewExpression: string);

View File

@ -127,7 +127,7 @@ type
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Execute(const AExpression: ansistring);
procedure Execute(const AExpression: ansistring; AWatch: TWatch = nil);
end;
implementation
@ -1164,9 +1164,12 @@ begin
end;
procedure TIDEInspectDlg.Execute(const AExpression: ansistring);
procedure TIDEInspectDlg.Execute(const AExpression: ansistring; AWatch: TWatch);
begin
WatchInspectNav1.Execute(AExpression);
if AWatch <> nil then
WatchInspectNav1.ReadFromWatch(AWatch, AExpression)
else
WatchInspectNav1.Execute(AExpression);
end;
procedure TIDEInspectDlg.DoWatchUpdated(const ASender: TIdeWatches;
@ -1318,8 +1321,13 @@ begin
end;
procedure TIDEInspectDlg.DoAddEval(Sender: TObject);
var
w: TIdeWatch;
begin
DebugBoss.EvaluateModify(WatchInspectNav1.Expression);
w := nil;
if WatchInspectNav1.CurrentWatchValue <> nil then
w := WatchInspectNav1.CurrentWatchValue.Watch;
DebugBoss.EvaluateModify(WatchInspectNav1.Expression, w);
end;
procedure TIDEInspectDlg.DoAddWatch(Sender: TObject);

View File

@ -750,7 +750,7 @@ var
begin
CurWatch := GetSelected;
if CurWatch <> nil then
DebugBoss.EvaluateModify(CurWatch.Expression);
DebugBoss.EvaluateModify(CurWatch.Expression, CurWatch);
end;
procedure TWatchesDlg.actInspectExecute(Sender: TObject);
@ -759,7 +759,7 @@ var
begin
CurWatch := GetSelected;
if CurWatch <> nil then
DebugBoss.Inspect(CurWatch.Expression);
DebugBoss.Inspect(CurWatch.Expression, CurWatch);
end;
procedure TWatchesDlg.actDisableSelectedExecute(Sender: TObject);

View File

@ -52,7 +52,8 @@ uses
LazDebuggerIntf,
IdeDebuggerOpts,
// IDE
Debugger, SourceMarks, Project, ProjectDefs, LazarusIDEStrConsts;
Debugger, IdeDebuggerBase, SourceMarks, Project, ProjectDefs,
LazarusIDEStrConsts;
type
TDebugDialogType = (
@ -188,8 +189,8 @@ type
out Filename: string; AskUserIfNotFound: Boolean): Boolean; virtual; abstract;
function GetFullFilename(var Filename: string; AskUserIfNotFound: Boolean): Boolean; virtual; abstract;
procedure EvaluateModify(const AExpression: String); virtual; abstract;
procedure Inspect(const AExpression: String); virtual; abstract;
procedure EvaluateModify(const AExpression: String; AWatch: TWatch = nil); virtual; abstract;
procedure Inspect(const AExpression: String; AWatch: TWatch = nil); virtual; abstract;
function DoCreateBreakPoint(const AFilename: string; ALine: integer;
WarnIfNoDebugger: boolean): TModalResult; virtual; abstract;
@ -213,8 +214,11 @@ type
procedure CreateDebugDialog(Sender: TObject; aFormName: string;
var AForm: TCustomForm; DoDisableAutoSizing: boolean); virtual; abstract;
procedure ViewDebugDialog(const ADialogType: TDebugDialogType;
BringToFront: Boolean = True; Show: Boolean = true;
DoDisableAutoSizing: boolean = false); virtual; abstract;
BringToFront: Boolean = true;
Show: Boolean = true;
DoDisableAutoSizing: boolean = false;
InitFromSourceEdit: boolean = True
); virtual; abstract;
procedure ViewDisassembler(AnAddr: TDBGPtr;
BringToFront: Boolean = True; Show: Boolean = true;
DoDisableAutoSizing: boolean = false); virtual; abstract;

View File

@ -58,9 +58,9 @@ uses
BreakPointsdlg, BreakPropertyDlg, LocalsDlg, WatchPropertyDlg, CallStackDlg,
EvaluateDlg, RegistersDlg, AssemblerDlg, DebugOutputForm, ExceptionDlg,
InspectDlg, DebugEventsForm, PseudoTerminalDlg, FeedbackDlg, ThreadDlg,
HistoryDlg, ProcessDebugger, DbgIntfBaseTypes, DbgIntfDebuggerBase,
DbgIntfMiscClasses, DbgIntfPseudoTerminal, LazDebuggerIntf,
LazDebuggerIntfBaseTypes, BaseDebugManager;
HistoryDlg, ProcessDebugger, IdeDebuggerBase, DbgIntfBaseTypes,
DbgIntfDebuggerBase, DbgIntfMiscClasses, DbgIntfPseudoTerminal,
LazDebuggerIntf, LazDebuggerIntfBaseTypes, BaseDebugManager;
type
@ -253,8 +253,8 @@ type
EvalFlags: TWatcheEvaluateFlags = []): Boolean; override;
function Modify(const AExpression, ANewValue: String): Boolean; override;
procedure EvaluateModify(const AExpression: String); override;
procedure Inspect(const AExpression: String); override;
procedure EvaluateModify(const AExpression: String; AWatch: TWatch = nil); override;
procedure Inspect(const AExpression: String; AWatch: TWatch = nil); override;
function GetFullFilename(const AUnitinfo: TDebuggerUnitInfo; out Filename: string;
AskUserIfNotFound: Boolean): Boolean; override;
@ -282,7 +282,12 @@ type
// Dialog routines
procedure CreateDebugDialog(Sender: TObject; aFormName: string;
var AForm: TCustomForm; DoDisableAutoSizing: boolean); override;
procedure ViewDebugDialog(const ADialogType: TDebugDialogType; BringToFront: Boolean = true; Show: Boolean = true; DoDisableAutoSizing: boolean = false); override;
procedure ViewDebugDialog(const ADialogType: TDebugDialogType;
BringToFront: Boolean = true;
Show: Boolean = true;
DoDisableAutoSizing: boolean = false;
InitFromSourceEdit: boolean = True
); override;
procedure ViewDisassembler(AnAddr: TDBGPtr;
BringToFront: Boolean = True; Show: Boolean = true;
DoDisableAutoSizing: boolean = false); override;
@ -1658,7 +1663,8 @@ begin
end;
procedure TDebugManager.ViewDebugDialog(const ADialogType: TDebugDialogType;
BringToFront: Boolean; Show: Boolean; DoDisableAutoSizing: boolean);
BringToFront: Boolean; Show: Boolean; DoDisableAutoSizing: boolean;
InitFromSourceEdit: boolean);
const
DEBUGDIALOGCLASS: array[TDebugDialogType] of TDebuggerDlgClass = (
TDbgOutputForm, TDbgEventsForm, TBreakPointsDlg, TWatchesDlg, TLocalsDlg,
@ -1711,19 +1717,21 @@ begin
then begin
TAssemblerDlg(CurDialog).SetLocation(FDebugger, FCurrentLocation.Address);
end;
if (CurDialog is TIDEInspectDlg) and (SourceEditorManager.GetActiveSE <> nil)
then begin
if SourceEditorManager.GetActiveSE.SelectionAvailable then
TIDEInspectDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.Selection)
else
TIDEInspectDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.GetOperandAtCurrentCaret);
end;
if (CurDialog is TEvaluateDlg) and (SourceEditorManager.GetActiveSE <> nil)
then begin
if SourceEditorManager.GetActiveSE.SelectionAvailable then
TEvaluateDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.Selection)
else
TEvaluateDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.GetOperandAtCurrentCaret);
if InitFromSourceEdit then begin
if (CurDialog is TIDEInspectDlg) and (SourceEditorManager.GetActiveSE <> nil)
then begin
if SourceEditorManager.GetActiveSE.SelectionAvailable then
TIDEInspectDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.Selection)
else
TIDEInspectDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.GetOperandAtCurrentCaret);
end;
if (CurDialog is TEvaluateDlg) and (SourceEditorManager.GetActiveSE <> nil)
then begin
if SourceEditorManager.GetActiveSE.SelectionAvailable then
TEvaluateDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.Selection)
else
TEvaluateDlg(CurDialog).Execute(SourceEditorManager.GetActiveSE.GetOperandAtCurrentCaret);
end;
end;
end;
if not DoDisableAutoSizing then
@ -3011,21 +3019,22 @@ begin
and FDebugger.Modify(AExpression, ANewValue);
end;
procedure TDebugManager.EvaluateModify(const AExpression: String);
procedure TDebugManager.EvaluateModify(const AExpression: String; AWatch: TWatch
);
begin
if Destroying then Exit;
ViewDebugDialog(ddtEvaluate);
ViewDebugDialog(ddtEvaluate, True, True, False, False);
if FDialogs[ddtEvaluate] <> nil then
TEvaluateDlg(FDialogs[ddtEvaluate]).EvalExpression := AExpression;
TEvaluateDlg(FDialogs[ddtEvaluate]).Execute(AExpression, AWatch);
end;
procedure TDebugManager.Inspect(const AExpression: String);
procedure TDebugManager.Inspect(const AExpression: String; AWatch: TWatch);
begin
if Destroying then Exit;
ViewDebugDialog(ddtInspect); // TODO: If not yet open, this will get Expression from SourceEdit, and trigger uneeded eval.
ViewDebugDialog(ddtInspect, True, True, False, False);
if FDialogs[ddtInspect] <> nil then
begin
TIDEInspectDlg(FDialogs[ddtInspect]).Execute(AExpression);
TIDEInspectDlg(FDialogs[ddtInspect]).Execute(AExpression, AWatch);
end;
end;

View File

@ -8,7 +8,7 @@ uses
Classes, SysUtils, Forms, Controls, ComCtrls, Buttons, StdCtrls, ExtCtrls,
Menus, LCLType, SpinEx, IDEImagesIntf, LazUTF8, LazClasses, LazDebuggerIntf,
IdeDebuggerStringConstants, ArrayNavigationFrame, IdeDebuggerOpts, Debugger,
IdeDebuggerFpDbgValueConv;
IdeDebuggerFpDbgValueConv, IdeDebuggerBase;
type
@ -92,6 +92,8 @@ type
FThreadsMonitor: TIdeThreadsMonitor;
FCallStackMonitor: TIdeCallStackMonitor;
FInspectWatches: TCurrentWatches;
FUpdateCount: Integer;
FExecAfterUpdate: Boolean;
procedure ArrayNavSizeChanged(Sender: TObject);
procedure DoDbpConvMenuClicked(Sender: TObject);
@ -124,7 +126,12 @@ type
ADefaultEvalOpts: TWatcheEvaluateFlags
);
procedure BeginUpdate;
procedure EndUpdate;
procedure InitWatch(AWatch: TIdeWatch);
procedure ReadFromWatch(AWatch: TWatch; AlternateExpression: String = '');
procedure Execute(const AnExpression: ansistring; ASkipHistory: Boolean = False);
procedure UpdateData(AForceClear: Boolean = False);// context changed instead
procedure DoContextChanged;
@ -616,6 +623,21 @@ begin
FDefaultEvalOpts := ADefaultEvalOpts;
end;
procedure TWatchInspectNav.BeginUpdate;
begin
if FUpdateCount = 0 then
FExecAfterUpdate := False;
inc(FUpdateCount);
end;
procedure TWatchInspectNav.EndUpdate;
begin
if FUpdateCount > 0 then
dec(FUpdateCount);
if (FUpdateCount = 0) and FExecAfterUpdate then
UpdateData(True);
end;
procedure TWatchInspectNav.InitWatch(AWatch: TIdeWatch);
var
Opts: TWatcheEvaluateFlags;
@ -640,6 +662,46 @@ begin
AWatch.FpDbgConverter := Conv;
end;
procedure TWatchInspectNav.ReadFromWatch(AWatch: TWatch;
AlternateExpression: String);
var
i: Integer;
begin
BeginUpdate;
try
btnUseInstance.Down := defClassAutoCast in AWatch.EvaluateFlags;
btnFunctionEval.Down := defAllowFunctionCall in AWatch.EvaluateFlags;
if defSkipValConv in AWatch.EvaluateFlags then begin
if popConverter.Items.Count > 1 then
popConverter.Items[1].Click;
end
else if AWatch.FpDbgConverter = nil then begin
if popConverter.Items.Count > 0 then
popConverter.Items[0].Click;
end
else begin
i := DebuggerOptions.FpDbgConverterConfig.Count - 1;
while i >= 0 do begin
if DebuggerOptions.FpDbgConverterConfig.IdeItems[i] = AWatch.FpDbgConverter then begin
if popConverter.Items.Count > i+2 then
popConverter.Items[i+2].Click;
break;
end;
dec(i);
end;
end;
if AlternateExpression <> '' then
Execute(AlternateExpression)
else
Execute(AWatch.Expression);
finally
EndUpdate;
end;
end;
procedure TWatchInspectNav.Execute(const AnExpression: ansistring;
ASkipHistory: Boolean);
begin
@ -709,6 +771,12 @@ var
expr: String;
Conv: TIdeFpDbgConverterConfig;
begin
if FUpdateCount > 0 then begin
FExecAfterUpdate := True;
exit;
end;
FExecAfterUpdate := False;
if AForceClear then
FInspectWatches.Clear;