IdeDebugger: improve unfolding of watches. Allow Pointer to object/array to be unfolded (and dereference them for this)

This commit is contained in:
Martin 2023-06-11 14:30:46 +02:00
parent 9a0e268738
commit ea1e68ed26
3 changed files with 66 additions and 42 deletions

View File

@ -155,6 +155,9 @@ begin
end;
ResData := AWatchAbleResult.ResultData;
while (ResData <> nil) and (ResData.ValueKind = rdkPointerVal) do
ResData := ResData.DerefData;
if (ResData <> nil) and
(ResData.FieldCount > 0) and
(ResData.ValueKind <> rdkConvertRes)
@ -180,7 +183,7 @@ procedure TDbgTreeViewWatchDataMgr.DoUpdateArraySubItems(AWatchAble: TObject;
ChildCount: LongWord);
var
NewWatchAble: TObject;
i, TotalCount: Integer;
i, TotalCount, DerefCount: Integer;
ResData: TWatchResultData;
ExistingNode, nd: PVirtualNode;
Nav: TArrayNavigationBar;
@ -188,6 +191,11 @@ var
begin
ChildCount := 0;
ResData := AWatchAbleResult.ResultData;
DerefCount := 0;
while (ResData <> nil) and (ResData.ValueKind = rdkPointerVal) do begin
ResData := ResData.DerefData;
inc(DerefCount);
end;
if (ResData = nil) then
exit;
@ -226,7 +234,7 @@ begin
Offs := Nav.Index;
for i := 0 to ChildCount - 1 do begin
NewWatchAble := AWatchAbleResult.ChildrenByNameAsArrayEntry[Offs + i];
NewWatchAble := AWatchAbleResult.ChildrenByNameAsArrayEntry[Offs + i, DerefCount];
if NewWatchAble = nil then begin
dec(ChildCount);
continue;
@ -265,9 +273,18 @@ var
AnchClass: String;
NewWatchAble: TObject;
ChildInfo: TWatchResultDataFieldInfo;
DerefCount: Integer;
begin
ChildCount := 0;
ResData := AWatchAbleResult.ResultData;
DerefCount := 0;
while (ResData <> nil) and (ResData.ValueKind = rdkPointerVal) do begin
ResData := ResData.DerefData;
inc(DerefCount);
end;
if ResData = nil then
exit;
ExistingNode := FTreeView.GetFirstChildNoInit(AVNode);
if ExistingNode <> nil then
FTreeView.NodeControl[ExistingNode].Free;
@ -276,7 +293,7 @@ begin
if ResData.StructType <> dstRecord then
AnchClass := ResData.TypeName;
for ChildInfo in ResData do begin
NewWatchAble := AWatchAbleResult.ChildrenByNameAsField[ChildInfo.FieldName, AnchClass];
NewWatchAble := AWatchAbleResult.ChildrenByNameAsField[ChildInfo.FieldName, AnchClass, DerefCount];
if NewWatchAble = nil then begin
continue;
end;
@ -318,9 +335,9 @@ begin
AnchClass := TypInfo.TypeName;
for i := 0 to TypInfo.Fields.Count-1 do begin
if IsGdbmiArray then
NewWatchAble := AWatchAbleResult.ChildrenByNameAsArrayEntry[StrToInt64Def(TypInfo.Fields[i].Name, 0)]
NewWatchAble := AWatchAbleResult.ChildrenByNameAsArrayEntry[StrToInt64Def(TypInfo.Fields[i].Name, 0), 0]
else
NewWatchAble := AWatchAbleResult.ChildrenByNameAsField[TypInfo.Fields[i].Name, AnchClass];
NewWatchAble := AWatchAbleResult.ChildrenByNameAsField[TypInfo.Fields[i].Name, AnchClass, 0];
if NewWatchAble = nil then begin
dec(ChildCount);
continue;
@ -422,6 +439,7 @@ procedure TDbgTreeViewWatchDataMgr.UpdateWatchData(AWatchAble: TObject;
AnIgnoreNodeVisible: Boolean);
var
TypInfo: TDBGType;
ResData: TWatchResultData;
HasChildren: Boolean;
c: LongWord;
begin
@ -450,12 +468,15 @@ begin
((DebugBoss = nil) or (DebugBoss.State <> dsRun))
then begin
TypInfo := AWatchAbleResult.TypeInfo;
ResData := AWatchAbleResult.ResultData;
while (ResData <> nil) and (ResData.ValueKind = rdkPointerVal) do
ResData := ResData.DerefData;
HasChildren := ( (TypInfo <> nil) and (TypInfo.Fields <> nil) and (TypInfo.Fields.Count > 0) ) or
( (AWatchAbleResult.ResultData <> nil) and
( ( (AWatchAbleResult.ResultData.FieldCount > 0) and (AWatchAbleResult.ResultData.ValueKind <> rdkConvertRes) )
( (ResData <> nil) and
( ( (ResData.FieldCount > 0) and (ResData.ValueKind <> rdkConvertRes) )
or
//( (AWatchAbleResult.ResultData.ValueKind = rdkArray) and (AWatchAbleResult.ResultData.ArrayLength > 0) )
(AWatchAbleResult.ResultData.ArrayLength > 0)
//( (ResData.ValueKind = rdkArray) and (ResData.ArrayLength > 0) )
(ResData.ArrayLength > 0)
) );
FTreeView.HasChildren[AVNode] := HasChildren;

View File

@ -534,8 +534,8 @@ type
TIdeWatchValue = class(TWatchValue, IWatchAbleResultIntf)
private
function GetChildrenByNameAsArrayEntry(AName: Int64): TObject; // TIdeWatch;
function GetChildrenByNameAsField(AName, AClassName: String): TObject; // TIdeWatch;
function GetChildrenByNameAsArrayEntry(AName: Int64; DerefCount: Integer): TObject; // TIdeWatch;
function GetChildrenByNameAsField(AName, AClassName: String; DerefCount: Integer): TObject; // TIdeWatch;
function GetWatch: TIdeWatch;
function GetEnabled: Boolean;
protected
@ -566,8 +566,8 @@ type
function MaybeCopyResult(ASourceWatch: TIdeWatch): boolean;
property ChildrenByNameAsField[AName, AClassName: String]: TObject read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64]: TObject read GetChildrenByNameAsArrayEntry;
property ChildrenByNameAsField[AName, AClassName: String; DerefCount: Integer]: TObject read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64; DerefCount: Integer]: TObject read GetChildrenByNameAsArrayEntry;
end;
TIdeTempWatchValue = class(TIdeWatchValue)
@ -604,8 +604,8 @@ type
FParentWatch: TIdeWatch;
function GetChildWatch(ADispName, AnExpr: String): TIdeWatch;
function GetChildrenByNameAsArrayEntry(AName: Int64): TIdeWatch;
function GetChildrenByNameAsField(AName, AClassName: String): TIdeWatch;
function GetChildrenByNameAsArrayEntry(AName: Int64; DerefCount: Integer): TIdeWatch;
function GetChildrenByNameAsField(AName, AClassName: String; DerefCount: Integer): TIdeWatch;
function GetTopParentWatch: TIdeWatch;
function GetValue(const AThreadId: Integer; const AStackFrame: Integer): TIdeWatchValue;
function GetAnyValidParentWatchValue(AThreadId: Integer; AStackFrame: Integer): TIdeWatchValue;
@ -636,8 +636,8 @@ type
procedure BeginChildUpdate;
procedure EndChildUpdate;
procedure LimitChildWatchCount(AMaxCnt: Integer; AKeepIndexEntriesBelow: Int64 = low(Int64));
property ChildrenByNameAsField[AName, AClassName: String]: TIdeWatch read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64]: TIdeWatch read GetChildrenByNameAsArrayEntry;
property ChildrenByNameAsField[AName, AClassName: String; DerefCount: Integer]: TIdeWatch read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64; DerefCount: Integer]: TIdeWatch read GetChildrenByNameAsArrayEntry;
function HasAllValidParents(AThreadId: Integer; AStackFrame: Integer): boolean;
property ParentWatch: TIdeWatch read FParentWatch;
property TopParentWatch: TIdeWatch read GetTopParentWatch;
@ -949,8 +949,8 @@ type
function GetDisplayFormat: TWatchDisplayFormat;
function GetTypeInfo: TDBGType; deprecated;
function GetChildrenByNameAsArrayEntry(AName: Int64): TObject;
function GetChildrenByNameAsField(AName, AClassName: String): TObject;
function GetChildrenByNameAsArrayEntry(AName: Int64; DerefCount: Integer): TObject;
function GetChildrenByNameAsField(AName, AClassName: String; DerefCount: Integer): TObject;
protected
function FindParentValue: TIdeLocalsValue; virtual;
@ -4378,7 +4378,8 @@ begin
Result := ddsEvaluating; // ddsWaitForParent;
end;
function TIdeWatchValue.GetChildrenByNameAsArrayEntry(AName: Int64): TObject;
function TIdeWatchValue.GetChildrenByNameAsArrayEntry(AName: Int64;
DerefCount: Integer): TObject;
begin
Result := nil;
if FWatch = nil then
@ -4389,11 +4390,11 @@ begin
exit;
end;
Result := Watch.ChildrenByNameAsArrayEntry[AName];
Result := Watch.ChildrenByNameAsArrayEntry[AName, DerefCount];
end;
function TIdeWatchValue.GetChildrenByNameAsField(AName, AClassName: String
): TObject;
function TIdeWatchValue.GetChildrenByNameAsField(AName, AClassName: String;
DerefCount: Integer): TObject;
begin
Result := nil;
if FWatch = nil then
@ -4404,7 +4405,7 @@ begin
exit;
end;
Result := Watch.ChildrenByNameAsField[AName, AClassName];
Result := Watch.ChildrenByNameAsField[AName, AClassName, DerefCount];
end;
function TIdeWatchValue.GetWatch: TIdeWatch;
@ -6807,23 +6808,24 @@ begin
EndChildUpdate;
end;
function TIdeWatch.GetChildrenByNameAsArrayEntry(AName: Int64): TIdeWatch;
function TIdeWatch.GetChildrenByNameAsArrayEntry(AName: Int64;
DerefCount: Integer): TIdeWatch;
begin
Result := GetChildWatch(IntToStr(AName),
GetExpressionForArrayElement(Expression, AName)
Result := GetChildWatch(StringOfChar('^', DerefCount) + IntToStr(AName),
GetExpressionForArrayElement(Expression + StringOfChar('^', DerefCount), AName)
);
end;
function TIdeWatch.GetChildrenByNameAsField(AName, AClassName: String
): TIdeWatch;
function TIdeWatch.GetChildrenByNameAsField(AName, AClassName: String;
DerefCount: Integer): TIdeWatch;
var
Expr: String;
begin
Expr := Expression;
Expr := Expression + StringOfChar('^', DerefCount);
if AClassName <> '' then
Expr := AClassName + '(' + Expr + ')';
Expr := Expr + '.' + AName;
Result := GetChildWatch(AName, Expr);
Result := GetChildWatch(StringOfChar('^', DerefCount) + AName, Expr);
end;
function TIdeWatch.CreateChildWatches: TIdeWatches;
@ -7343,24 +7345,25 @@ begin
Result := nil;
end;
function TIdeLocalsValue.GetChildrenByNameAsArrayEntry(AName: Int64): TObject;
function TIdeLocalsValue.GetChildrenByNameAsArrayEntry(AName: Int64;
DerefCount: Integer): TObject;
begin
Result := GetSubLocal(IntToStr(AName),
GetExpressionForArrayElement(Name, AName)
Result := GetSubLocal(StringOfChar('^', DerefCount) + IntToStr(AName),
GetExpressionForArrayElement(Name + StringOfChar('^', DerefCount), AName)
);
end;
function TIdeLocalsValue.GetChildrenByNameAsField(AName, AClassName: String
): TObject;
function TIdeLocalsValue.GetChildrenByNameAsField(AName, AClassName: String;
DerefCount: Integer): TObject;
var
Expr: String;
begin
Expr := Name;
Expr := Name + StringOfChar('^', DerefCount);
// no defClassAutoCast for locals // if changed also update FindParentValue
//if AClassName <> '' then
// Expr := AClassName + '(' + Expr + ')';
Expr := Expr + '.' + AName;
Result := GetSubLocal(AName, Expr);
Result := GetSubLocal(StringOfChar('^', DerefCount) + AName, Expr);
end;
function TIdeLocalsValue.FindParentValue: TIdeLocalsValue;

View File

@ -34,8 +34,8 @@ type
end;
IWatchAbleResultIntf = interface ['wdr']
function GetChildrenByNameAsArrayEntry(AName: Int64): TObject;
function GetChildrenByNameAsField(AName, AClassName: String): TObject;
function GetChildrenByNameAsArrayEntry(AName: Int64; DerefCount: Integer): TObject;
function GetChildrenByNameAsField(AName, AClassName: String; DerefCount: Integer): TObject;
function GetEnabled: Boolean;
function GetValidity: TDebuggerDataState;
@ -44,8 +44,8 @@ type
function GetValue: string;
function GetResultData: TWatchResultData;
property ChildrenByNameAsField[AName, AClassName: String]: TObject read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64]: TObject read GetChildrenByNameAsArrayEntry;
property ChildrenByNameAsField[AName, AClassName: String; DerefCount: Integer]: TObject read GetChildrenByNameAsField;
property ChildrenByNameAsArrayEntry[AName: Int64; DerefCount: Integer]: TObject read GetChildrenByNameAsArrayEntry;
property Enabled: Boolean read GetEnabled;
property Validity: TDebuggerDataState read GetValidity;