fpc/rtl/objpas/classes/resref.inc
michael 93400f276c Merged revisions 9263-10571 via svnmerge from
svn+ssh://svn.freepascal.org/FPC/svn/fpc/branches/cleanroom

................
  r9269 | michael | 2007-11-17 13:58:31 +0100 (Sat, 17 Nov 2007) | 1 line
  
  * Cleaned initial list of tained routines
................
  r9270 | michael | 2007-11-17 14:00:25 +0100 (Sat, 17 Nov 2007) | 1 line
  
  * Test routines for cleanroom implementation
................
  r9271 | michael | 2007-11-17 14:04:43 +0100 (Sat, 17 Nov 2007) | 1 line
  
  DoVarClearArray also tainted
................
  r9272 | michael | 2007-11-17 15:25:04 +0100 (Sat, 17 Nov 2007) | 1 line
  
  * Removed possibly tainted code
................
  r9276 | Almindor | 2007-11-17 21:29:16 +0100 (Sat, 17 Nov 2007) | 2 lines
  
  * initial cleanroom implementation of TStringList.Find
................
  r9277 | Almindor | 2007-11-17 21:32:44 +0100 (Sat, 17 Nov 2007) | 2 lines
  
  * also commit forgotten part for "where would it instert" in case of sorted stringlist
................
  r9295 | michael | 2007-11-19 21:07:10 +0100 (Mon, 19 Nov 2007) | 1 line
  
  * More tests
................
  r9307 | michael | 2007-11-21 08:43:56 +0100 (Wed, 21 Nov 2007) | 1 line
  
  * More tests and reorganization per unit
................
  r9308 | michael | 2007-11-21 08:47:58 +0100 (Wed, 21 Nov 2007) | 1 line
  
  * More reorganization of files
................
  r9310 | michael | 2007-11-21 21:05:40 +0100 (Wed, 21 Nov 2007) | 1 line
  
  * Completed tccollection tests
................
  r9322 | marco | 2007-11-24 15:40:18 +0100 (Sat, 24 Nov 2007) | 1 line
  
   * getnamepath first version. Tests not run yet (fpcunit)
................
  r9337 | michael | 2007-11-27 09:21:31 +0100 (Tue, 27 Nov 2007) | 1 line
  
  * Removed TFPlist.Assign and TFPList.Extract
................
  r9340 | michael | 2007-11-27 22:33:07 +0100 (Tue, 27 Nov 2007) | 1 line
  
  Removed HandleSafeCallException 
................
  r9343 | Almindor | 2007-11-28 11:23:00 +0100 (Wed, 28 Nov 2007) | 2 lines
  
  * add cleanroom quicksort implementation [tested very little]
................
  r9344 | Almindor | 2007-11-28 11:25:54 +0100 (Wed, 28 Nov 2007) | 2 lines
  
  * update quicksort to use ExchangeItems instead of manual swap
................
  r9359 | vincents | 2007-11-30 20:10:03 +0100 (Fri, 30 Nov 2007) | 1 line
  
  + clean room implementation of HandleSafeCallException; compiles, but not tested.
................
  r9387 | michael | 2007-12-03 14:24:32 +0100 (Mon, 03 Dec 2007) | 1 line
  
  * Clean-room implementation of TParser by Giulio Bernardi
................
  r9396 | michael | 2007-12-05 21:36:41 +0100 (Wed, 05 Dec 2007) | 5 lines
  
  * Patch from Giulio Bernardi:
   - Fixes token positioning after HexToBinary 
   - Support for certain malformed negative integer values
................
  r9399 | michael | 2007-12-06 16:53:41 +0100 (Thu, 06 Dec 2007) | 1 line
  
  * More tests for classes unit
................
  r9401 | michael | 2007-12-06 21:58:16 +0100 (Thu, 06 Dec 2007) | 1 line
  
  * Added additional tests for collection streaming. Restructured
................
  r9402 | michael | 2007-12-06 22:35:56 +0100 (Thu, 06 Dec 2007) | 1 line
  
  * All compiles again, resolving references not quite yet done
................
  r9434 | michael | 2007-12-12 21:24:57 +0100 (Wed, 12 Dec 2007) | 1 line
  
  * New FindNestedComponent routine
................
  r9466 | michael | 2007-12-15 23:44:41 +0100 (Sat, 15 Dec 2007) | 1 line
  
  * Fixed all tests
................
  r9468 | michael | 2007-12-16 01:00:01 +0100 (Sun, 16 Dec 2007) | 1 line
  
  * Fixed reader fixup of references
................
  r9491 | joost | 2007-12-18 21:46:54 +0100 (Tue, 18 Dec 2007) | 3 lines
  
   * Implemented TWriter.WriteComponent
   * Implemented TWriter.WriteComponentData
   * Implemented TWriter.WriteDescendent
................
  r9492 | joost | 2007-12-18 21:56:32 +0100 (Tue, 18 Dec 2007) | 1 line
  
   * The BinaryObjectWriter of fpc stores TValueTypes as a byte, fixed the test for that
................
  r9566 | michael | 2007-12-29 15:53:32 +0100 (Sat, 29 Dec 2007) | 1 line
  
  * Clean (and complete) implementation of T(FP)List.Assign
................
  r9567 | michael | 2007-12-29 16:02:19 +0100 (Sat, 29 Dec 2007) | 1 line
  
  * Additional tests for reference resolving and TList.Assign
................
  r9568 | michael | 2007-12-29 16:12:33 +0100 (Sat, 29 Dec 2007) | 1 line
  
  * Cleanroom implementation of extract
................
  r9750 | yury | 2008-01-14 13:07:17 +0100 (Mon, 14 Jan 2008) | 1 line
  
  * My cleanroom implementation of DoVarClearArray.
................
  r10271 | michael | 2008-02-10 15:52:37 +0100 (Sun, 10 Feb 2008) | 1 line
  
  * Correct implementation committed
................
  r10273 | michael | 2008-02-10 17:08:59 +0100 (Sun, 10 Feb 2008) | 1 line
  
  * Added DecodeSoundexInt
................
  r10352 | vincents | 2008-02-18 08:23:18 +0100 (Mon, 18 Feb 2008) | 1 line
  
  + TStringList.Grow, used algorithm from TFPList.Expand
................
  r10353 | vincents | 2008-02-18 10:21:58 +0100 (Mon, 18 Feb 2008) | 1 line
  
  * use new TStringList.Grow implementation from trunk
................
  r10354 | vincents | 2008-02-18 10:23:07 +0100 (Mon, 18 Feb 2008) | 1 line
  
  * fixed TList tests
................
  r10355 | vincents | 2008-02-18 16:43:35 +0100 (Mon, 18 Feb 2008) | 1 line
  
  * fixed hint in test and removed session information from lpi
................
  r10356 | vincents | 2008-02-18 21:58:29 +0100 (Mon, 18 Feb 2008) | 1 line
  
  + implemented TStringList.Find
................
  r10358 | vincents | 2008-02-19 15:02:17 +0100 (Tue, 19 Feb 2008) | 1 line
  
  * fixed TTestTComponentNotifies test
................
  r10359 | vincents | 2008-02-19 15:48:43 +0100 (Tue, 19 Feb 2008) | 1 line
  
  * fixed memleak in TWriter.WriteProperties
................
  r10360 | vincents | 2008-02-19 15:49:20 +0100 (Tue, 19 Feb 2008) | 1 line
  
  + initial implementation of TReader.ReadCollection (needs further testing)
................
  r10364 | vincents | 2008-02-19 23:05:49 +0100 (Tue, 19 Feb 2008) | 1 line
  
  + TDataset.SetFieldValues (untested)
................
  r10365 | vincents | 2008-02-20 09:03:16 +0100 (Wed, 20 Feb 2008) | 1 line
  
  * initilize critical section used by resolving references
................
  r10366 | vincents | 2008-02-20 09:38:03 +0100 (Wed, 20 Feb 2008) | 2 lines
  
  * fixed resolve references test
  * removed unused variable
................
  r10369 | vincents | 2008-02-20 17:04:51 +0100 (Wed, 20 Feb 2008) | 1 line
  
  + initial version of TReader.FindComponentClass, works with a simple LCL application
................
  r10370 | michael | 2008-02-20 20:48:36 +0100 (Wed, 20 Feb 2008) | 1 line
  
  * Added tcollection stream read tests
................
  r10373 | vincents | 2008-02-21 00:33:10 +0100 (Thu, 21 Feb 2008) | 1 line
  
  * TReader.FindComponentClass: also search in FieldTables of parent classes.
................
  r10374 | michael | 2008-02-21 11:00:04 +0100 (Thu, 21 Feb 2008) | 1 line
  
  * Fix voor ResolveReferences
................
  r10376 | vincents | 2008-02-21 19:37:55 +0100 (Thu, 21 Feb 2008) | 1 line
  
  * reduced hints
................
  r10377 | vincents | 2008-02-22 14:56:22 +0100 (Fri, 22 Feb 2008) | 1 line
  
  * add check for valid NewIndex in TFPList.Move, so that an invalid NewIndex doesn't lead to memleak
................
  r10378 | vincents | 2008-02-22 15:16:56 +0100 (Fri, 22 Feb 2008) | 1 line
  
  * fixed TReader.ReadCollection in case more than one property was streamed
................
  r10379 | vincents | 2008-02-22 15:35:44 +0100 (Fri, 22 Feb 2008) | 3 lines
  
  + added another test for writing collections (shows how it should be written and thus read
  + added a test for a writing an enum with default value 
................
  r10380 | vincents | 2008-02-22 15:36:14 +0100 (Fri, 22 Feb 2008) | 1 line
  
  * fixed memleak
................
  r10381 | vincents | 2008-02-23 20:03:00 +0100 (Sat, 23 Feb 2008) | 1 line
  
  * fixed AV when streaming a component without published properties
................
  r10390 | michael | 2008-02-25 21:34:10 +0100 (Mon, 25 Feb 2008) | 1 line
  
  * Clean version of searchbuf inserted
................
  r10393 | vincents | 2008-02-26 23:06:14 +0100 (Tue, 26 Feb 2008) | 1 line
  
  * fixed TDataset.SetFieldValues
................
  r10398 | michael | 2008-02-27 21:58:49 +0100 (Wed, 27 Feb 2008) | 1 line
  
  * Added test for streaming 2 components
................
  r10400 | vincents | 2008-02-28 00:51:08 +0100 (Thu, 28 Feb 2008) | 1 line
  
  * improved tests for streaming components with owned subcomponents
................
  r10403 | vincents | 2008-02-28 22:19:32 +0100 (Thu, 28 Feb 2008) | 1 line
  
  * fixed writing child components
................
  r10441 | florian | 2008-03-04 20:11:46 +0100 (Tue, 04 Mar 2008) | 3 lines
  
  Initialized merge tracking via "svnmerge" with revisions "1-9261" from 
  http://svn.freepascal.org/svn/fpc/trunk
................
  r10444 | joost | 2008-03-05 11:31:07 +0100 (Wed, 05 Mar 2008) | 30 lines
  
  Merged revisions 9783,9786,9788,9814,9822,9825,9837-9850,9852,9854-9856,9863-9864,9867,9885,9895 via svnmerge from 
  svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk
  
  ........
    r9783 | joost | 2008-01-18 23:52:13 +0100 (Fri, 18 Jan 2008) | 1 line
    
     * DigestTestREport makes it possible to write the unittest results to a testsuite-digest
  ........
    r9786 | joost | 2008-01-19 00:40:44 +0100 (Sat, 19 Jan 2008) | 1 line
    
     * Added dependency on paszlib to fcl-fpcunit
  ........
    r9788 | jonas | 2008-01-19 01:20:49 +0100 (Sat, 19 Jan 2008) | 2 lines
    
      + also add fpc-unit dependency on paszlib to build dependencies
  ........
    r9854 | joost | 2008-01-21 17:26:20 +0100 (Mon, 21 Jan 2008) | 2 lines
    
     * Added Comment and Category properties to TDigestResultsWriter
     * Write Comment and Category to digest.cfg
  ........
    r9885 | joost | 2008-01-23 22:56:34 +0100 (Wed, 23 Jan 2008) | 1 line
    
     * Write RelSrcDir to digest.cfg
  ........
    r9895 | joost | 2008-01-24 18:02:47 +0100 (Thu, 24 Jan 2008) | 1 line
    
     * Add dash between hostname and date in digest-tarfile
  ........
................
  r10445 | joost | 2008-03-05 11:47:26 +0100 (Wed, 05 Mar 2008) | 9 lines
  
  Merged revisions 10431 via svnmerge from 
  svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk
  
  ........
    r10431 | joost | 2008-03-02 18:08:16 +0100 (Sun, 02 Mar 2008) | 1 line
    
     * Set Modified to false when te state of a dataset changes
  ........
................
  r10446 | joost | 2008-03-05 15:34:38 +0100 (Wed, 05 Mar 2008) | 9 lines
  
  Merged revisions 10350 via svnmerge from 
  svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk
  
  ........
    r10350 | joost | 2008-02-17 22:14:26 +0100 (Sun, 17 Feb 2008) | 1 line
    
     * Fixed bug #8464
  ........
................
  r10490 | Almindor | 2008-03-15 11:18:42 +0100 (Sat, 15 Mar 2008) | 3 lines
  
  * add TDataLink.CalcFirstRecord cleanroom implementation (blind)
  * add TField.RefreshLookupList cleanroom implementation (blind)
................
  r10491 | Almindor | 2008-03-15 11:29:54 +0100 (Sat, 15 Mar 2008) | 2 lines
  
  * fix compilation of the TField.RefreshLookuplist;
................
  r10510 | Almindor | 2008-03-20 18:57:22 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * implement cleanroom TDataset.CalculateFields
................
  r10511 | Almindor | 2008-03-20 19:16:55 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * add TDataSet.EnableControls cleanroom implementation
................
  r10512 | Almindor | 2008-03-20 19:27:27 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * add TField.CalcLookupValue cleanroom implementation
................
  r10513 | Almindor | 2008-03-20 19:30:23 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * fix potential bug in cleanroom TField.RefreshLookupList
................
  r10514 | Almindor | 2008-03-20 19:33:13 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * add forgotten function call in TDataset.CalculateFields
................
  r10515 | Almindor | 2008-03-20 19:37:19 +0100 (Thu, 20 Mar 2008) | 2 lines
  
  * fix potential bug in cleanroom TDataLink.CalcFirstRecord
................
  r10531 | Almindor | 2008-03-22 10:57:40 +0100 (Sat, 22 Mar 2008) | 2 lines
  
  * implement cleanroom TDataSet.DataEvent
................
  r10534 | Almindor | 2008-03-22 21:30:02 +0100 (Sat, 22 Mar 2008) | 2 lines
  
  * fix cleanroom TDataset.DataEvent, make it call all connected datasources
................
  r10537 | michael | 2008-03-23 11:19:05 +0100 (Sun, 23 Mar 2008) | 6 lines
  
  * Fixed some issues:
    - Memleak in TReader.ReadPropValue. FFixups was re-allocated in beginreferences !
    - FPC behaves different from Delphi if no Default value is declared, it assumes a
      default of ord(TEnum)=0, same for sets.
    - Fixed MemLeak when a reference was resolved, Removed item was not freed.
................
  r10547 | Almindor | 2008-03-24 10:57:28 +0100 (Mon, 24 Mar 2008) | 2 lines
  
  * first fix to cleanroom TDataSet.DataEvent only 6 tests fail now :)
................
  r10553 | joost | 2008-03-24 19:58:33 +0100 (Mon, 24 Mar 2008) | 9 lines
  
  Merged revisions 10470 via svnmerge from 
  svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk
  
  ........
    r10470 | joost | 2008-03-09 21:11:17 +0100 (Sun, 09 Mar 2008) | 1 line
    
     * Set TDataSet.InternalCalcFields if there are InternalCalcFields
  ........
................
  r10555 | joost | 2008-03-25 12:06:12 +0100 (Tue, 25 Mar 2008) | 9 lines
  
  Merged revisions 10519 via svnmerge from 
  svn+ssh://joost@svn.freepascal.org/FPC/svn/fpc/trunk
  
  ........
    r10519 | joost | 2008-03-21 14:38:44 +0100 (Fri, 21 Mar 2008) | 1 line
    
     * Fix for ValueOfKey for multiple-fields keys
  ........
................
  r10565 | Almindor | 2008-03-25 18:28:58 +0100 (Tue, 25 Mar 2008) | 2 lines
  
  * fix cleanroom TDataLink.CalcFirstRecord (passes tests now)
................

git-svn-id: trunk@10572 -
2008-03-27 20:15:57 +00:00

454 lines
11 KiB
PHP

type
// Quadruple representing an unresolved component property.
{ TUnresolvedReference }
TUnresolvedReference = class(TlinkedListItem)
Private
FRoot: TComponent; // Root component when streaming
FPropInfo: PPropInfo; // Property to set.
FGlobal, // Global component.
FRelative : string; // Path relative to global component.
Function Resolve(Instance : TPersistent) : Boolean; // Resolve this reference
Function RootMatches(ARoot : TComponent) : Boolean; Inline; // True if Froot matches or ARoot is nil.
Function NextRef : TUnresolvedReference; inline;
end;
TLocalUnResolvedReference = class(TUnresolvedReference)
Finstance : TPersistent;
end;
// Linked list of TPersistent items that have unresolved properties.
{ TUnResolvedInstance }
TUnResolvedInstance = Class(TLinkedListItem)
Instance : TPersistent; // Instance we're handling unresolveds for
FUnresolved : TLinkedList; // The list
Destructor Destroy; override;
Function AddReference(ARoot : TComponent; APropInfo : PPropInfo; AGlobal,ARelative : String) : TUnresolvedReference;
Function RootUnresolved : TUnresolvedReference; inline; // Return root element in list.
Function ResolveReferences : Boolean; // Return true if all unresolveds were resolved.
end;
// Builds a list of TUnResolvedInstances, removes them from global list on free.
TBuildListVisitor = Class(TLinkedListVisitor)
List : TFPList;
Procedure Add(Item : TlinkedListItem); // Add TUnResolvedInstance item to list. Create list if needed
Destructor Destroy; override; // All elements in list (if any) are removed from the global list.
end;
// Visitor used to try and resolve instances in the global list
TResolveReferenceVisitor = Class(TBuildListVisitor)
Function Visit(Item : TLinkedListItem) : Boolean; override;
end;
// Visitor used to remove all references to a certain component.
TRemoveReferenceVisitor = Class(TBuildListVisitor)
FRef : String;
FRoot : TComponent;
Constructor Create(ARoot : TComponent;Const ARef : String);
Function Visit(Item : TLinkedListItem) : Boolean; override;
end;
// Visitor used to collect reference names.
TReferenceNamesVisitor = Class(TLinkedListVisitor)
FList : TStrings;
FRoot : TComponent;
Function Visit(Item : TLinkedListItem) : Boolean; override;
Constructor Create(ARoot : TComponent;AList : TStrings);
end;
// Visitor used to collect instance names.
TReferenceInstancesVisitor = Class(TLinkedListVisitor)
FList : TStrings;
FRef : String;
FRoot : TComponent;
Function Visit(Item : TLinkedListItem) : Boolean; override;
Constructor Create(ARoot : TComponent;Const ARef : String; AList : TStrings);
end;
// Visitor used to redirect links to another root component.
TRedirectReferenceVisitor = Class(TLinkedListVisitor)
FOld,
FNew : String;
FRoot : TComponent;
Function Visit(Item : TLinkedListItem) : Boolean; override;
Constructor Create(ARoot : TComponent;Const AOld,ANew : String);
end;
var
NeedResolving : TLinkedList;
ResolveSection : TRTLCriticalSection;
LastAddInstance : TUnresolvedInstance;
// Add an instance to the global list of instances which need resolving.
Function FindUnresolvedInstance(AInstance: TPersistent) : TUnResolvedInstance;
begin
Result:=Nil;
EnterCriticalSection(ResolveSection);
Try
If Assigned(NeedResolving) then
begin
Result:=TUnResolvedInstance(NeedResolving.Root);
While (Result<>Nil) and (Result.Instance<>AInstance) do
Result:=TUnResolvedInstance(Result.Next);
end;
finally
LeaveCriticalSection(ResolveSection);
end;
end;
Function AddtoResolveList(AInstance: TPersistent) : TUnResolvedInstance;
begin
Result:=FindUnresolvedInstance(AInstance);
If (Result=Nil) then
begin
EnterCriticalSection(ResolveSection);
Try
If not Assigned(NeedResolving) then
NeedResolving:=TLinkedList.Create(TUnResolvedInstance);
Result:=NeedResolving.Add as TUnResolvedInstance;
Result.Instance:=AInstance;
finally
LeaveCriticalSection(ResolveSection);
end;
end;
end;
// Walk through the global list of instances to be resolved.
Procedure VisitResolveList(V : TLinkedListVisitor);
begin
EnterCriticalSection(ResolveSection);
Try
try
NeedResolving.Foreach(V);
Finally
FreeAndNil(V);
end;
Finally
LeaveCriticalSection(ResolveSection);
end;
end;
procedure GlobalFixupReferences;
var
V : TResolveReferenceVisitor;
I : Integer;
begin
If (NeedResolving=Nil) then
Exit;
GlobalNameSpace.BeginWrite;
try
VisitResolveList(TResolveReferenceVisitor.Create);
finally
GlobalNameSpace.EndWrite;
end;
end;
procedure GetFixupReferenceNames(Root: TComponent; Names: TStrings);
begin
If (NeedResolving=Nil) then
Exit;
VisitResolveList(TReferenceNamesVisitor.Create(Root,Names));
end;
procedure GetFixupInstanceNames(Root: TComponent; const ReferenceRootName: string; Names: TStrings);
begin
If (NeedResolving=Nil) then
Exit;
VisitResolveList(TReferenceInstancesVisitor.Create(Root,ReferenceRootName,Names));
end;
procedure RedirectFixupReferences(Root: TComponent; const OldRootName, NewRootName: string);
begin
If (NeedResolving=Nil) then
Exit;
VisitResolveList(TRedirectReferenceVisitor.Create(Root,OldRootName,NewRootName));
end;
procedure RemoveFixupReferences(Root: TComponent; const RootName: string);
begin
If (NeedResolving=Nil) then
Exit;
VisitResolveList(TRemoveReferenceVisitor.Create(Root,RootName));
end;
procedure RemoveFixups(Instance: TPersistent);
begin
// This needs work.
{
if not Assigned(GlobalFixupList) then
exit;
with GlobalFixupList.LockList do
try
for i := Count - 1 downto 0 do
begin
CurFixup := TPropFixup(Items[i]);
if (CurFixup.FInstance = Instance) then
begin
Delete(i);
CurFixup.Free;
end;
end;
finally
GlobalFixupList.UnlockList;
end;
}
end;
{ TUnresolvedReference }
Function TUnresolvedReference.Resolve(Instance : TPersistent) : Boolean;
Var
C : TComponent;
begin
C:=FindGlobalComponent(FGlobal);
Result:=(C<>Nil);
If Result then
begin
C:=FindNestedComponent(C,FRelative);
Result:=C<>Nil;
If Result then
SetObjectProp(Instance, FPropInfo,C);
end;
end;
Function TUnresolvedReference.RootMatches(ARoot : TComponent) : Boolean; Inline;
begin
Result:=(ARoot=Nil) or (ARoot=FRoot);
end;
Function TUnResolvedReference.NextRef : TUnresolvedReference;
begin
Result:=TUnresolvedReference(Next);
end;
{ TUnResolvedInstance }
destructor TUnResolvedInstance.Destroy;
begin
FUnresolved.Free;
inherited Destroy;
end;
function TUnResolvedInstance.AddReference(ARoot: TComponent;
APropInfo: PPropInfo; AGlobal, ARelative: String): TUnresolvedReference;
begin
If (FUnResolved=Nil) then
FUnResolved:=TLinkedList.Create(TUnresolvedReference);
Result:=FUnResolved.Add as TUnresolvedReference;
Result.FGlobal:=AGLobal;
Result.FRelative:=ARelative;
Result.FPropInfo:=APropInfo;
Result.FRoot:=ARoot;
end;
Function TUnResolvedInstance.RootUnresolved : TUnresolvedReference;
begin
Result:=Nil;
If Assigned(FUnResolved) then
Result:=TUnresolvedReference(FUnResolved.Root);
end;
Function TUnResolvedInstance.ResolveReferences:Boolean;
Var
R,RN : TUnresolvedReference;
begin
R:=RootUnResolved;
While (R<>Nil) do
begin
RN:=R.NextRef;
If R.Resolve(Self.Instance) then
FUnresolved.RemoveItem(R,True);
R:=RN;
end;
Result:=RootUnResolved=Nil;
end;
{ TReferenceNamesVisitor }
Constructor TReferenceNamesVisitor.Create(ARoot : TComponent;AList : TStrings);
begin
FRoot:=ARoot;
FList:=AList;
end;
Function TReferenceNamesVisitor.Visit(Item : TLinkedListItem) : Boolean;
Var
R : TUnresolvedReference;
begin
R:=TUnResolvedInstance(Item).RootUnresolved;
While (R<>Nil) do
begin
If R.RootMatches(FRoot) then
If (FList.IndexOf(R.FGlobal)=-1) then
FList.Add(R.FGlobal);
R:=R.NextRef;
end;
Result:=True;
end;
{ TReferenceInstancesVisitor }
Constructor TReferenceInstancesVisitor.Create(ARoot : TComponent; Const ARef : String;AList : TStrings);
begin
FRoot:=ARoot;
FRef:=UpperCase(ARef);
FList:=AList;
end;
Function TReferenceInstancesVisitor.Visit(Item : TLinkedListItem) : Boolean;
Var
R : TUnresolvedReference;
begin
R:=TUnResolvedInstance(Item).RootUnresolved;
While (R<>Nil) do
begin
If (FRoot=R.FRoot) and (FRef=UpperCase(R.FGLobal)) Then
If Flist.IndexOf(R.FRelative)=-1 then
Flist.Add(R.FRelative);
R:=R.NextRef;
end;
Result:=True;
end;
{ TRedirectReferenceVisitor }
Constructor TRedirectReferenceVisitor.Create(ARoot : TComponent; Const AOld,ANew : String);
begin
FRoot:=ARoot;
FOld:=UpperCase(AOld);
FNew:=ANew;
end;
Function TRedirectReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean;
Var
R : TUnresolvedReference;
begin
R:=TUnResolvedInstance(Item).RootUnresolved;
While (R<>Nil) do
begin
If R.RootMatches(FRoot) and (FOld=UpperCase(R.FGLobal)) Then
R.FGlobal:=FNew;
R:=R.NextRef;
end;
Result:=True;
end;
{ TRemoveReferenceVisitor }
Constructor TRemoveReferenceVisitor.Create(ARoot : TComponent; Const ARef : String);
begin
FRoot:=ARoot;
FRef:=UpperCase(ARef);
end;
Function TRemoveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean;
Var
I : Integer;
UI : TUnResolvedInstance;
R : TUnresolvedReference;
L : TFPList;
begin
UI:=TUnResolvedInstance(Item);
R:=UI.RootUnresolved;
L:=Nil;
Try
// Collect all matches.
While (R<>Nil) do
begin
If R.RootMatches(FRoot) and (FRef=UpperCase(R.FGLobal)) Then
begin
If Not Assigned(L) then
L:=TFPList.Create;
L.Add(R);
end;
R:=R.NextRef;
end;
// Remove all matches.
IF Assigned(L) then
begin
For I:=0 to L.Count-1 do
UI.FUnresolved.RemoveItem(TLinkedListitem(L[i]),True);
end;
// If any references are left, leave them.
If UI.FUnResolved.Root=Nil then
begin
If List=Nil then
List:=TFPList.Create;
List.Add(UI);
end;
Finally
L.Free;
end;
Result:=True;
end;
{ TBuildListVisitor }
Procedure TBuildListVisitor.Add(Item : TlinkedListItem);
begin
If (List=Nil) then
List:=TFPList.Create;
List.Add(Item);
end;
Destructor TBuildListVisitor.Destroy;
Var
I : Integer;
begin
If Assigned(List) then
For I:=0 to List.Count-1 do
NeedResolving.RemoveItem(TLinkedListItem(List[I]),True);
FreeAndNil(List);
Inherited;
end;
{ TResolveReferenceVisitor }
Function TResolveReferenceVisitor.Visit(Item : TLinkedListItem) : Boolean;
begin
If TUnResolvedInstance(Item).ResolveReferences then
Add(Item);
Result:=True;
end;