From a3bd018a8653b9bd5c37a210e9f9474cf8f7e1df Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 29 May 2021 22:51:13 +0000 Subject: [PATCH] Debugger, IDE: Watches, add "Allow function calls" option to IDE / Add "Auto set class from instance" git-svn-id: trunk@65152 - --- .../debuggerintf/dbgintfdebuggerbase.pp | 23 ++++++ .../lazdebuggerfp/fpdebugdebugger.pas | 6 ++ .../fpdebugdebuggerworkthreads.pas | 4 +- debugger/debugger.pp | 8 +++ debugger/evaluatedlg.pp | 2 + debugger/frames/debugger_general_options.pas | 22 +++--- debugger/inspectdlg.pas | 5 ++ debugger/localsdlg.pp | 4 +- debugger/watchesdlg.pp | 8 ++- debugger/watchpropertydlg.lfm | 71 +++++++++---------- debugger/watchpropertydlg.pp | 22 +++--- ide/basedebugmanager.pas | 1 + ide/debugmanager.pas | 13 ++++ ide/environmentopts.pp | 10 +++ ide/lazarusidestrconsts.pas | 2 + ide/main.pp | 4 ++ 16 files changed, 147 insertions(+), 58 deletions(-) diff --git a/components/debuggerintf/dbgintfdebuggerbase.pp b/components/debuggerintf/dbgintfdebuggerbase.pp index c3ec7c5f14..26e81c8fb6 100644 --- a/components/debuggerintf/dbgintfdebuggerbase.pp +++ b/components/debuggerintf/dbgintfdebuggerbase.pp @@ -59,6 +59,11 @@ type EDebuggerException = class(Exception); EDBGExceptions = class(EDebuggerException); + TDBGFeature = ( + dfEvalFunctionCalls // The debugger supports calling functions in watches/expressions. defAllowFunctionCall in TDBGEvaluateFlag + ); + TDBGFeatures = set of TDBGFeature; + TDBGCommand = ( dcRun, dcPause, @@ -1832,6 +1837,7 @@ type FDebuggerEnvironment: TStrings; FCurEnvironment: TStrings; FDisassembler: TDBGDisassembler; + FEnabledFeatures: TDBGFeatures; FEnvironment: TStrings; FErrorStateInfo: String; FErrorStateMessage: String; @@ -1877,6 +1883,7 @@ type const AParams: array of const; const ACallback: TMethod): Boolean; procedure SetDebuggerEnvironment (const AValue: TStrings ); overload; + procedure SetEnabledFeatures(AValue: TDBGFeatures); procedure SetEnvironment(const AValue: TStrings); procedure SetFileName(const AValue: String); protected @@ -1929,6 +1936,7 @@ type class function HasExePath: boolean; virtual; deprecated; // use NeedsExePath instead class function NeedsExePath: boolean; virtual; // If the debugger needs to have an exe path class function RequiredCompilerOpts(ATargetCPU, ATargetOS: String): TDebugCompilerRequirements; virtual; + class function SupportedFeatures: TDBGFeatures; virtual; // debugger properties class function CreateProperties: TDebuggerProperties; virtual; // Creates debuggerproperties @@ -2012,6 +2020,7 @@ type property ErrorStateMessage: String read FErrorStateMessage; property ErrorStateInfo: String read FErrorStateInfo; property SkipStopMessage: Boolean read FSkipStopMessage; + property EnabledFeatures: TDBGFeatures read FEnabledFeatures write SetEnabledFeatures; //property UnitInfoProvider: TDebuggerUnitInfoProvider // Provided by DebugBoss, to map files to packages or project // read GetUnitInfoProvider write FUnitInfoProvider; // Events @@ -5824,6 +5833,8 @@ var nr: TDebuggerNotifyReason; begin inherited Create; + FEnabledFeatures := SupportedFeatures; + for nr := low(TDebuggerNotifyReason) to high(TDebuggerNotifyReason) do FDestroyNotificationList[nr] := TMethodList.Create; FOnState := nil; @@ -6234,6 +6245,11 @@ begin Result := []; end; +class function TDebuggerIntf.SupportedFeatures: TDBGFeatures; +begin + Result := []; +end; + function TDebuggerIntf.GetCommands: TDBGCommands; begin Result := COMMANDMAP[State] * GetSupportedCommands; @@ -6363,6 +6379,13 @@ begin FDebuggerEnvironment.Assign(AValue); end; +procedure TDebuggerIntf.SetEnabledFeatures(AValue: TDBGFeatures); +begin + AValue := AValue * SupportedFeatures; + if FEnabledFeatures = AValue then Exit; + FEnabledFeatures := AValue; +end; + procedure TDebuggerIntf.SetEnvironment(const AValue: TStrings); begin FEnvironment.Assign(AValue); diff --git a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas index c5e0dd2ad5..3b25fe0be7 100644 --- a/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas +++ b/components/lazdebuggers/lazdebuggerfp/fpdebugdebugger.pas @@ -392,6 +392,7 @@ type class function CreateProperties: TDebuggerProperties; override; class function GetSupportedCommands: TDBGCommands; override; class function SupportedCommandsFor(AState: TDBGState): TDBGCommands; override; + class function SupportedFeatures: TDBGFeatures; override; end; { TFpLineInfo } @@ -3808,6 +3809,11 @@ begin Result := Result - [dcStepInto, dcStepOver, dcStepOut, dcStepIntoInstr, dcStepOverInstr]; end; +class function TFpDebugDebugger.SupportedFeatures: TDBGFeatures; +begin + Result := [dfEvalFunctionCalls]; +end; + initialization DBG_VERBOSE := DebugLogger.FindOrRegisterLogGroup('DBG_VERBOSE' {$IFDEF DBG_VERBOSE} , True {$ENDIF} ); DBG_WARNINGS := DebugLogger.FindOrRegisterLogGroup('DBG_WARNINGS' {$IFDEF DBG_WARNINGS} , True {$ENDIF} ); diff --git a/components/lazdebuggers/lazdebuggerfp/fpdebugdebuggerworkthreads.pas b/components/lazdebuggers/lazdebuggerfp/fpdebugdebuggerworkthreads.pas index d31d703f1c..ba7e8a5e58 100644 --- a/components/lazdebuggers/lazdebuggerfp/fpdebugdebuggerworkthreads.pas +++ b/components/lazdebuggers/lazdebuggerfp/fpdebugdebuggerworkthreads.pas @@ -883,7 +883,7 @@ begin PrettyPrinter := nil; APasExpr := TFpPascalExpression.Create(AnExpression, FExpressionScope); try - if FAllowFunctions then + if FAllowFunctions and (dfEvalFunctionCalls in FDebugger.EnabledFeatures) then APasExpr.OnFunctionCall := @DoWatchFunctionCall; APasExpr.ResultValue; // trigger full validation if not APasExpr.Valid then begin @@ -975,7 +975,7 @@ begin FDispFormat := ADispFormat; FRepeatCnt := ARepeatCnt; FEvalFlags := AnEvalFlags; - if defAllowFunctionCall in AnEvalFlags then + if (defAllowFunctionCall in AnEvalFlags) then FAllowFunctions := True; FRes := False; end; diff --git a/debugger/debugger.pp b/debugger/debugger.pp index ec6348c5fd..4cfbd94f15 100644 --- a/debugger/debugger.pp +++ b/debugger/debugger.pp @@ -5449,6 +5449,9 @@ begin if AConfig.GetValue(APath + 'ClassAutoCast', False) then Include(FEvaluateFlags, defClassAutoCast) else Exclude(FEvaluateFlags, defClassAutoCast); + if AConfig.GetValue(APath + 'AllowFunctionCall', False) + then Include(FEvaluateFlags, defAllowFunctionCall) + else Exclude(FEvaluateFlags, defAllowFunctionCall); try ReadStr(AConfig.GetValue(APath + 'DisplayFormat', 'wdfDefault'), FDisplayFormat); except FDisplayFormat := wdfDefault; end; FRepeatCount := AConfig.GetValue(APath + 'RepeatCount', 0); @@ -5465,6 +5468,7 @@ begin WriteStr(s{%H-}, FDisplayFormat); AConfig.SetDeleteValue(APath + 'DisplayFormat', s, 'wdfDefault'); AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False); + AConfig.SetDeleteValue(APath + 'AllowFunctionCall', defAllowFunctionCall in FEvaluateFlags, False); AConfig.SetDeleteValue(APath + 'RepeatCount', FRepeatCount, 0); TIdeWatchValueList(FValueList).SaveDataToXMLConfig(AConfig, APath + 'ValueList/'); @@ -5533,6 +5537,9 @@ begin if AConfig.GetValue(APath + 'ClassAutoCast', False) then Include(FEvaluateFlags, defClassAutoCast) else Exclude(FEvaluateFlags, defClassAutoCast); + if AConfig.GetValue(APath + 'AllowFunctionCall', False) + then Include(FEvaluateFlags, defAllowFunctionCall) + else Exclude(FEvaluateFlags, defAllowFunctionCall); i := StringCase (AConfig.GetValue(APath + 'DisplayStyle/Value', TWatchDisplayFormatNames[wdfDefault]), TWatchDisplayFormatNames); @@ -5549,6 +5556,7 @@ begin AConfig.SetDeleteValue(APath + 'DisplayStyle/Value', TWatchDisplayFormatNames[DisplayFormat], TWatchDisplayFormatNames[wdfDefault]); AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False); + AConfig.SetDeleteValue(APath + 'AllowFunctionCall', defAllowFunctionCall in FEvaluateFlags, False); AConfig.SetDeleteValue(APath + 'RepeatCount', FRepeatCount, 0); end; diff --git a/debugger/evaluatedlg.pp b/debugger/evaluatedlg.pp index 9cfc9feb35..29ba9869fb 100644 --- a/debugger/evaluatedlg.pp +++ b/debugger/evaluatedlg.pp @@ -386,6 +386,8 @@ begin try Watch := DebugBoss.Watches.CurrentWatches.Add(S); Watch.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass then + Watch.EvaluateFlags := Watch.EvaluateFlags + [defClassAutoCast]; finally DebugBoss.Watches.CurrentWatches.EndUpdate; end; diff --git a/debugger/frames/debugger_general_options.pas b/debugger/frames/debugger_general_options.pas index 70bb6027de..07a0813bc9 100644 --- a/debugger/frames/debugger_general_options.pas +++ b/debugger/frames/debugger_general_options.pas @@ -86,6 +86,8 @@ begin gcbDebuggerGeneralOptions.Checked[1] := EnvironmentOptions.DebuggerShowExitCodeMessage; gcbDebuggerGeneralOptions.Checked[2] := EnvironmentOptions.DebuggerResetAfterRun; gcbDebuggerGeneralOptions.Checked[3] := EnvironmentOptions.DebuggerAutoCloseAsm; + gcbDebuggerGeneralOptions.Checked[4] := EnvironmentOptions.DebuggerAutoSetInstanceFromClass; + gcbDebuggerGeneralOptions.Checked[5] := EnvironmentOptions.DebuggerAllowFunctionCalls; txtAdditionalPath.Text:=EnvironmentOptions.GetParsedDebuggerSearchPath; end; @@ -103,10 +105,12 @@ procedure TDebuggerGeneralOptionsFrame.Setup(ADialog: TAbstractOptionsEditorDial begin gbAdditionalSearchPath.Caption := lisDebugOptionsFrmAdditionalSearchPath; gcbDebuggerGeneralOptions.Caption := lisDebugOptionsFrmDebuggerGeneralOptions; - gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmShowMessageOnStop); - gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmShowExitCodeOnStop); - gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmResetDebuggerOnEachRun); - gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmAutoCloseAsm); + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmShowMessageOnStop); // 0 Message on stop + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmShowExitCodeOnStop); // 1 Exit-code on stop + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmResetDebuggerOnEachRun); // 2 reset dbg after each run + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmAutoCloseAsm); // 3 auto close asm + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmAutoInstanceClass); // 4 auto set class-from-instance + gcbDebuggerGeneralOptions.Items.Add(lisDebugOptionsFrmAllowFunctionCalls); // 5 allow function calls end; procedure TDebuggerGeneralOptionsFrame.ReadSettings(AOptions: TAbstractIDEOptions); @@ -125,10 +129,12 @@ begin begin DebuggerSearchPath := TrimSearchPath(txtAdditionalPath.Text,''); // IMPORTANT if more items are added the indexes must be updated here! - DebuggerShowStopMessage := gcbDebuggerGeneralOptions.Checked[0]; - DebuggerShowExitCodeMessage := gcbDebuggerGeneralOptions.Checked[1]; - DebuggerResetAfterRun := gcbDebuggerGeneralOptions.Checked[2]; - DebuggerAutoCloseAsm := gcbDebuggerGeneralOptions.Checked[3]; + DebuggerShowStopMessage := gcbDebuggerGeneralOptions.Checked[0]; + DebuggerShowExitCodeMessage := gcbDebuggerGeneralOptions.Checked[1]; + DebuggerResetAfterRun := gcbDebuggerGeneralOptions.Checked[2]; + DebuggerAutoCloseAsm := gcbDebuggerGeneralOptions.Checked[3]; + DebuggerAutoSetInstanceFromClass := gcbDebuggerGeneralOptions.Checked[4]; + DebuggerAllowFunctionCalls := gcbDebuggerGeneralOptions.Checked[5]; end; end; diff --git a/debugger/inspectdlg.pas b/debugger/inspectdlg.pas index 54d0cddda3..8522604dae 100644 --- a/debugger/inspectdlg.pas +++ b/debugger/inspectdlg.pas @@ -316,6 +316,10 @@ begin w := DebugBoss.Watches.CurrentWatches.Add(FExpression); if (w <> nil) then begin w.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass or + btnUseInstance.Down + then + w.EvaluateFlags := w.EvaluateFlags + [defClassAutoCast]; DebugBoss.ViewDebugDialog(ddtWatches, False); end; finally @@ -824,6 +828,7 @@ begin BtnAddWatch.Caption:=lisInspectAddWatch; btnUseInstance.Enabled := False; + btnUseInstance.Down := EnvironmentOptions.DebuggerAutoSetInstanceFromClass; btnColClass.Enabled := False; btnColType.Enabled := False; btnColVisibility.Enabled := False; diff --git a/debugger/localsdlg.pp b/debugger/localsdlg.pp index a8affff637..b6c37b31df 100644 --- a/debugger/localsdlg.pp +++ b/debugger/localsdlg.pp @@ -46,7 +46,7 @@ uses // DebuggerIntf DbgIntfDebuggerBase, // IDE - DebuggerStrConst, BaseDebugManager, Debugger, DebuggerDlg; + DebuggerStrConst, BaseDebugManager, EnvironmentOpts, Debugger, DebuggerDlg; type @@ -324,6 +324,8 @@ begin try Watch := DebugBoss.Watches.CurrentWatches.Add(S); Watch.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass then + Watch.EvaluateFlags := Watch.EvaluateFlags + [defClassAutoCast]; finally DebugBoss.Watches.CurrentWatches.EndUpdate; end; diff --git a/debugger/watchesdlg.pp b/debugger/watchesdlg.pp index 5f3c7a4140..274d580a9c 100644 --- a/debugger/watchesdlg.pp +++ b/debugger/watchesdlg.pp @@ -42,7 +42,7 @@ uses IDEWindowIntf, Menus, ComCtrls, ActnList, ExtCtrls, StdCtrls, LCLType, IDEImagesIntf, LazarusIDEStrConsts, DebuggerStrConst, Debugger, DebuggerDlg, DbgIntfBaseTypes, DbgIntfDebuggerBase, DbgIntfMiscClasses, SynEdit, - BaseDebugManager; + BaseDebugManager, EnvironmentOpts; type @@ -431,8 +431,9 @@ begin try NewWatch := DebugBoss.Watches.CurrentWatches.Add(s); NewWatch.DisplayFormat := wdfDefault; - NewWatch.EvaluateFlags := [defClassAutoCast]; NewWatch.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass then + NewWatch.EvaluateFlags := [defClassAutoCast]; finally DebugBoss.Watches.CurrentWatches.EndUpdate; end; @@ -465,8 +466,9 @@ begin try NewWatch := DebugBoss.Watches.CurrentWatches.Add(s); NewWatch.DisplayFormat := wdfDefault; - NewWatch.EvaluateFlags := [defClassAutoCast]; NewWatch.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass then + NewWatch.EvaluateFlags := [defClassAutoCast]; finally DebugBoss.Watches.CurrentWatches.EndUpdate; end; diff --git a/debugger/watchpropertydlg.lfm b/debugger/watchpropertydlg.lfm index 34d647b413..285659e1bb 100644 --- a/debugger/watchpropertydlg.lfm +++ b/debugger/watchpropertydlg.lfm @@ -14,8 +14,8 @@ object WatchPropertyDlg: TWatchPropertyDlg LCLVersion = '2.1.0.0' object rgStyle: TRadioGroup Left = 6 - Height = 104 - Top = 138 + Height = 119 + Top = 124 Width = 416 Align = alClient AutoFill = True @@ -31,7 +31,7 @@ object WatchPropertyDlg: TWatchPropertyDlg ChildSizing.ShrinkVertical = crsScaleChilds ChildSizing.Layout = cclLeftToRightThenTopToBottom ChildSizing.ControlsPerLine = 3 - ClientHeight = 85 + ClientHeight = 99 ClientWidth = 412 Columns = 3 ItemIndex = 7 @@ -51,8 +51,8 @@ object WatchPropertyDlg: TWatchPropertyDlg end object ButtonPanel: TButtonPanel Left = 6 - Height = 27 - Top = 248 + Height = 26 + Top = 249 Width = 416 OKButton.Name = 'OKButton' OKButton.DefaultCaption = True @@ -71,13 +71,13 @@ object WatchPropertyDlg: TWatchPropertyDlg end object PanelTop: TPanel Left = 0 - Height = 138 + Height = 124 Top = 0 Width = 428 Align = alTop AutoSize = True BevelOuter = bvNone - ClientHeight = 138 + ClientHeight = 124 ClientWidth = 428 TabOrder = 0 object lblExpression: TLabel @@ -85,9 +85,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideTop.Control = txtExpression AnchorSideTop.Side = asrCenter Left = 6 - Height = 17 - Top = 11 - Width = 64 + Height = 15 + Top = 10 + Width = 59 BorderSpacing.Left = 6 Caption = 'Expression:' ParentColor = False @@ -97,10 +97,10 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideLeft.Side = asrBottom AnchorSideRight.Control = PanelTop AnchorSideRight.Side = asrBottom - Left = 76 - Height = 27 + Left = 71 + Height = 23 Top = 6 - Width = 346 + Width = 351 Anchors = [akTop, akLeft, akRight] BorderSpacing.Left = 6 BorderSpacing.Top = 6 @@ -113,9 +113,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideTop.Control = txtRepCount AnchorSideTop.Side = asrCenter Left = 6 - Height = 17 - Top = 44 - Width = 78 + Height = 15 + Top = 39 + Width = 75 BorderSpacing.Left = 6 Caption = 'Repeat Count:' ParentColor = False @@ -125,9 +125,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = txtExpression AnchorSideTop.Side = asrBottom - Left = 90 - Height = 27 - Top = 39 + Left = 87 + Height = 23 + Top = 35 Width = 60 BorderSpacing.Left = 6 BorderSpacing.Top = 6 @@ -139,9 +139,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = txtRepCount AnchorSideTop.Side = asrCenter - Left = 203 - Height = 27 - Top = 39 + Left = 198 + Height = 23 + Top = 35 Width = 60 BorderSpacing.Left = 6 BorderSpacing.Top = 6 @@ -153,10 +153,10 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = lblRepCount AnchorSideTop.Side = asrCenter - Left = 162 - Height = 17 - Top = 44 - Width = 35 + Left = 159 + Height = 15 + Top = 39 + Width = 33 BorderSpacing.Left = 12 Caption = 'Digits:' ParentColor = False @@ -165,9 +165,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideTop.Control = txtRepCount AnchorSideTop.Side = asrBottom Left = 6 - Height = 21 - Top = 69 - Width = 68 + Height = 19 + Top = 61 + Width = 62 BorderSpacing.Left = 6 BorderSpacing.Top = 3 Caption = 'Enabled' @@ -178,10 +178,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideTop.Control = chkEnabled AnchorSideTop.Side = asrBottom Left = 6 - Height = 21 - Top = 90 - Width = 133 - AllowGrayed = True + Height = 19 + Top = 80 + Width = 128 Caption = 'Allow Function Calls' TabOrder = 4 end @@ -190,9 +189,9 @@ object WatchPropertyDlg: TWatchPropertyDlg AnchorSideTop.Control = chkAllowFunc AnchorSideTop.Side = asrBottom Left = 6 - Height = 21 - Top = 111 - Width = 142 + Height = 19 + Top = 99 + Width = 129 BorderSpacing.Bottom = 6 Caption = 'chkUseInstanceClass' TabOrder = 5 diff --git a/debugger/watchpropertydlg.pp b/debugger/watchpropertydlg.pp index d596025af8..1ba86a428d 100644 --- a/debugger/watchpropertydlg.pp +++ b/debugger/watchpropertydlg.pp @@ -39,8 +39,9 @@ unit WatchPropertyDlg; interface uses - Classes, SysUtils, Forms, StdCtrls, Extctrls, ButtonPanel, LazarusIDEStrConsts, - IDEHelpIntf, DbgIntfDebuggerBase, Debugger, BaseDebugManager, DebuggerStrConst; + Classes, SysUtils, Forms, StdCtrls, Extctrls, ButtonPanel, + LazarusIDEStrConsts, IDEHelpIntf, DbgIntfDebuggerBase, Debugger, + BaseDebugManager, EnvironmentOpts, DebuggerStrConst; type @@ -103,6 +104,9 @@ begin if chkUseInstanceClass.Checked then FWatch.EvaluateFlags := [defClassAutoCast] else FWatch.EvaluateFlags := []; + if chkAllowFunc.Checked + then FWatch.EvaluateFlags := FWatch.EvaluateFlags + [defAllowFunctionCall] + else FWatch.EvaluateFlags := []; FWatch.RepeatCount := StrToIntDef(txtRepCount.Text, 0); FWatch.Enabled := chkEnabled.Checked; @@ -140,21 +144,23 @@ begin chkEnabled.Checked := True; txtExpression.Text := AWatchExpression; rgStyle.ItemIndex := 7; - chkUseInstanceClass.Checked := False; + chkUseInstanceClass.Checked := EnvironmentOptions.DebuggerAutoSetInstanceFromClass; txtRepCount.Text := '0'; end else begin - txtExpression.Text := FWatch.Expression; - chkEnabled.Checked := FWatch.Enabled; - rgStyle.ItemIndex := DispFormatToStyle[FWatch.DisplayFormat]; + txtExpression.Text := FWatch.Expression; + chkEnabled.Checked := FWatch.Enabled; + rgStyle.ItemIndex := DispFormatToStyle[FWatch.DisplayFormat]; chkUseInstanceClass.Checked := defClassAutoCast in FWatch.EvaluateFlags; - txtRepCount.Text := IntToStr(FWatch.RepeatCount); + chkAllowFunc.Checked := defAllowFunctionCall in FWatch.EvaluateFlags; + txtRepCount.Text := IntToStr(FWatch.RepeatCount); end; txtExpressionChange(nil); lblDigits.Enabled := False; txtDigits.Enabled := False; - chkAllowFunc.Enabled := False; + chkAllowFunc.Enabled := EnvironmentOptions.DebuggerAllowFunctionCalls and + (dfEvalFunctionCalls in DebugBoss.DebuggerClass.SupportedFeatures); Caption:= lisWatchPropert; lblExpression.Caption:= lisExpression; diff --git a/ide/basedebugmanager.pas b/ide/basedebugmanager.pas index 889a31cf66..c84ec97417 100644 --- a/ide/basedebugmanager.pas +++ b/ide/basedebugmanager.pas @@ -145,6 +145,7 @@ type procedure SetupSourceMenuShortCuts; virtual; abstract; procedure UpdateButtonsAndMenuItems; virtual; abstract; procedure UpdateToolStatus; virtual; abstract; + procedure EnvironmentOptsChanged; virtual; abstract; procedure LoadProjectSpecificInfo(XMLConfig: TXMLConfig; Merge: boolean); virtual; abstract; diff --git a/ide/debugmanager.pas b/ide/debugmanager.pas index 1b11835495..f528de797c 100644 --- a/ide/debugmanager.pas +++ b/ide/debugmanager.pas @@ -202,6 +202,7 @@ type procedure SetupSourceMenuShortCuts; override; procedure UpdateButtonsAndMenuItems; override; procedure UpdateToolStatus; override; + procedure EnvironmentOptsChanged; override; procedure LoadProjectSpecificInfo(XMLConfig: TXMLConfig; Merge: boolean); override; @@ -1145,6 +1146,8 @@ begin if (w <> nil) then begin w.Enabled := True; + if EnvironmentOptions.DebuggerAutoSetInstanceFromClass then + w.EvaluateFlags := w.EvaluateFlags + [defClassAutoCast]; ViewDebugDialog(ddtWatches, False); Exit; end; @@ -2185,6 +2188,16 @@ begin end; end; +procedure TDebugManager.EnvironmentOptsChanged; +begin + if FDebugger <> nil then begin + if EnvironmentOptions.DebuggerAllowFunctionCalls then + FDebugger.EnabledFeatures := FDebugger.EnabledFeatures + [dfEvalFunctionCalls] + else + FDebugger.EnabledFeatures := FDebugger.EnabledFeatures - [dfEvalFunctionCalls]; + end; +end; + {------------------------------------------------------------------------------ procedure TDebugManager.LoadProjectSpecificInfo(XMLConfig: TXMLConfig; Merge: boolean); diff --git a/ide/environmentopts.pp b/ide/environmentopts.pp index 9c25edb581..1429976608 100644 --- a/ide/environmentopts.pp +++ b/ide/environmentopts.pp @@ -543,6 +543,8 @@ type XML_PATH_DEBUGGER_CONF_OLD = 'EnvironmentOptions/Debugger/Class%s/%s/'; private FCurrentDebuggerPropertiesConfig: TDebuggerPropertiesConfig; + FDebuggerAllowFunctionCalls: boolean; + FDebuggerAutoSetInstanceFromClass: boolean; FDebuggerShowExitCodeMessage: boolean; FHasActiveDebuggerEntry: Boolean; fRegisteredSubConfig: TObjectList; @@ -911,6 +913,8 @@ type property DebuggerShowExitCodeMessage: boolean read FDebuggerShowExitCodeMessage write FDebuggerShowExitCodeMessage; property DebuggerResetAfterRun: boolean read FDebuggerResetAfterRun write FDebuggerResetAfterRun; property DebuggerAutoCloseAsm: boolean read FDebuggerAutoCloseAsm write FDebuggerAutoCloseAsm; + property DebuggerAutoSetInstanceFromClass: boolean read FDebuggerAutoSetInstanceFromClass write FDebuggerAutoSetInstanceFromClass; + property DebuggerAllowFunctionCalls: boolean read FDebuggerAllowFunctionCalls write FDebuggerAllowFunctionCalls; property FppkgConfigFile: string read GetFppkgConfigFile write SetFppkgConfigFile; property FppkgConfigFileHistory: TStringList read FFppkgConfigFileHistory write FFppkgConfigFileHistory; // ShowCompileDialog and AutoCloseCompileDialog are currently not used. @@ -2492,6 +2496,8 @@ begin DebuggerShowExitCodeMessage:=FXMLCfg.GetValue(Path+'DebuggerOptions/DebuggerShowExitCodeMessage/Value', True); DebuggerResetAfterRun :=FXMLCfg.GetValue(Path+'DebuggerOptions/DebuggerResetAfterRun/Value', False); FDebuggerAutoCloseAsm :=FXMLCfg.GetValue(Path+'DebuggerOptions/DebuggerAutoCloseAsm/Value', False); + FDebuggerAutoSetInstanceFromClass :=FXMLCfg.GetValue(Path+'DebuggerOptions/DebuggerAutoSetInstanceFromClass/Value', False); + FDebuggerAllowFunctionCalls :=FXMLCfg.GetValue(Path+'DebuggerOptions/DebuggerAllowFunctionCalls/Value', False); FDebuggerEventLogClearOnRun := FXMLCfg.GetValue(Path+'Debugger/EventLogClearOnRun', True); FDebuggerEventLogCheckLineLimit := FXMLCfg.GetValue(Path+'Debugger/EventLogCheckLineLimit', False); FDebuggerEventLogLineLimit := FXMLCfg.GetValue(Path+'Debugger/EventLogLineLimit', 1000); @@ -2889,6 +2895,10 @@ begin FDebuggerResetAfterRun, False); FXMLCfg.SetDeleteValue(Path+'DebuggerOptions/DebuggerAutoCloseAsm/Value', FDebuggerAutoCloseAsm, False); + FXMLCfg.SetDeleteValue(Path+'DebuggerOptions/DebuggerAutoSetInstanceFromClass/Value', + FDebuggerAutoSetInstanceFromClass, False); + FXMLCfg.SetDeleteValue(Path+'DebuggerOptions/DebuggerAllowFunctionCalls/Value', + FDebuggerAllowFunctionCalls, False); for i := 0 to FDebuggerFileHistory.Count -1 do if FDebuggerFileHistory[i] = '' then SaveRecentList(FXMLCfg,TStrings(FDebuggerFileHistory.Objects[i]),Path+'DebuggerFilename/History/') diff --git a/ide/lazarusidestrconsts.pas b/ide/lazarusidestrconsts.pas index 36c6fe94d7..1ce5d9c42f 100644 --- a/ide/lazarusidestrconsts.pas +++ b/ide/lazarusidestrconsts.pas @@ -5408,6 +5408,8 @@ resourcestring lisDebugOptionsFrmShowExitCodeOnStop = 'Show message on stop with Error (Exit-code <> 0)'; lisDebugOptionsFrmResetDebuggerOnEachRun = 'Reset Debugger after each run'; lisDebugOptionsFrmAutoCloseAsm = 'Automatically close the assembler window, after source not found'; + lisDebugOptionsFrmAutoInstanceClass = 'Automatically set "use instance class" for new watches'; + lisDebugOptionsFrmAllowFunctionCalls = 'BETA: Allow function calls in watches (if supported by backend)'; lisDebugOptionsFrmDebuggerSpecific = 'Debugger specific options (depends on ' +'type of debugger)'; lisDebugOptionsFrmEventLog = 'Event Log'; diff --git a/ide/main.pp b/ide/main.pp index ec35e42600..58c6b3397e 100644 --- a/ide/main.pp +++ b/ide/main.pp @@ -5129,6 +5129,10 @@ begin // reload lazarus packages if LazarusSrcDirChanged then PkgBoss.LazarusSrcDirChanged; + + if DebugBoss <> nil then + DebugBoss.EnvironmentOptsChanged; + UpdateCaption; end;