mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-26 17:21:05 +02:00
Debugger: Inspect/Evaluate windows, when opened from watches or each-other transfer settings for eval-flags and converter
This commit is contained in:
parent
f3bf79fa35
commit
847436a56f
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user