Add a library unit for comparing two TFormFile ASTs and producing a
structured diff. Useful for tools that show form-level changes between
commits, migration auditing, and CI pipelines that need to detect
component additions/removals/renames.
Design
TPropertyChange = record
ComponentPath: string; // e.g. 'Form1.Panel1.Button1'
PropertyName: string;
OldValue: string; // preview text from FormValuePreview
NewValue: string;
end;
TComponentChange = record
Path: string; // dot-separated path to the component
ClassName: string;
ObjectKind: TObjectKind;
end;
TFormDiff = record
AddedComponents: TArray<TComponentChange>;
RemovedComponents: TArray<TComponentChange>;
ChangedProperties: TArray<TPropertyChange>;
Identical: Boolean;
end;
class function CompareForms(A, B: TFormFile): TFormDiff;
Matching strategy
Components are matched by name path (e.g. Form1.Panel1.Button1).
A component present in B but not A is "added"; present in A but not B
is "removed". Matched components have their properties compared by name
-- differing values produce a TPropertyChange entry.
This name-based matching works for the common case (same form, different
versions). It does not handle component renames -- that would require
heuristic matching and is out of scope for the initial implementation.
Deliverables
Acceptance criteria
Add a library unit for comparing two
TFormFileASTs and producing astructured diff. Useful for tools that show form-level changes between
commits, migration auditing, and CI pipelines that need to detect
component additions/removals/renames.
Design
Matching strategy
Components are matched by name path (e.g.
Form1.Panel1.Button1).A component present in B but not A is "added"; present in A but not B
is "removed". Matched components have their properties compared by name
-- differing values produce a
TPropertyChangeentry.This name-based matching works for the common case (same form, different
versions). It does not handle component renames -- that would require
heuristic matching and is out of scope for the initial implementation.
Deliverables
source/Delphi.Forms.Diff.paswithCompareFormsfunctionFormValuePreviewfor value textproperties, nested component changes, empty forms
Acceptance criteria
Identical = Trueand empty arrays