mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-09 12:35:55 +02:00
codetools: TUsesGraph.FindShortestPath
git-svn-id: trunk@42725 -
This commit is contained in:
parent
79670c113d
commit
15838492b6
@ -32,7 +32,7 @@ interface
|
||||
uses
|
||||
Classes, SysUtils, AVL_Tree, FileProcs, FindDeclarationTool, CodeBeautifier,
|
||||
CodeGraph, CodeCache, StdCodeTools, DirectoryCacher, LinkScanner,
|
||||
CustomCodeTool, CodeTree, CodeAtom;
|
||||
CustomCodeTool, CodeTree, CodeAtom, CodeToolsStructs;
|
||||
|
||||
type
|
||||
|
||||
@ -115,6 +115,7 @@ type
|
||||
procedure Clear;
|
||||
procedure ConsistencyCheck;
|
||||
function GetUnit(const ExpFilename: string; CreateIfNotExists: boolean): TUGUnit;
|
||||
function FindUnit(const AnUnitName: string): TUGUnit; // slow
|
||||
|
||||
procedure AddStartUnit(ExpFilename: string);
|
||||
procedure AddTargetUnit(ExpFilename: string);
|
||||
@ -126,6 +127,8 @@ type
|
||||
function UnitCanFindTarget(ExpFilename: string): boolean;
|
||||
function IsTargetDir(ExpDir: string): boolean;
|
||||
|
||||
function FindShortestPath(StartUnit, EndUnit: TUGUnit): TFPList; // list of TUGUnit, nil if no path exists
|
||||
|
||||
property FilesTree: TAVLTree read FFiles; // tree of TUGUnit sorted for Filename (all parsed)
|
||||
property QueuedFilesTree: TAVLTree read FQueuedFiles; // tree of TUGUnit sorted for Filename
|
||||
property TargetFilesTree: TAVLTree read FTargetFiles; // tree of TUGUnit sorted for Filename
|
||||
@ -300,6 +303,19 @@ begin
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
function TUsesGraph.FindUnit(const AnUnitName: string): TUGUnit;
|
||||
var
|
||||
AVLNode: TAVLTreeNode;
|
||||
begin
|
||||
AVLNode:=FFiles.FindLowest;
|
||||
while AVLNode<>nil do begin
|
||||
Result:=TUGUnit(AVLNode.Data);
|
||||
if CompareText(ExtractFileNameOnly(Result.Filename),AnUnitName)=0 then
|
||||
exit;
|
||||
AVLNode:=FFiles.FindSuccessor(AVLNode);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TUsesGraph.AddStartUnit(ExpFilename: string);
|
||||
var
|
||||
NewUnit: TUGUnit;
|
||||
@ -591,5 +607,56 @@ begin
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
function TUsesGraph.FindShortestPath(StartUnit, EndUnit: TUGUnit): TFPList;
|
||||
// broad search first
|
||||
var
|
||||
Queue: TFPList;
|
||||
NodeToPrevNode: TPointerToPointerTree;
|
||||
CurUnit: TUGUnit;
|
||||
i: Integer;
|
||||
CurUses: TUGUses;
|
||||
UsesUnit: TUGUnit;
|
||||
PrevUnit: TUGUnit;
|
||||
begin
|
||||
Result:=nil;
|
||||
if (StartUnit=nil) or (EndUnit=nil) then exit;
|
||||
Queue:=TFPList.Create;
|
||||
NodeToPrevNode:=TPointerToPointerTree.Create;
|
||||
try
|
||||
Queue.Add(EndUnit);
|
||||
NodeToPrevNode[EndUnit]:=EndUnit; // set end marker
|
||||
while Queue.Count>0 do begin
|
||||
CurUnit:=TUGUnit(Queue[0]);
|
||||
Queue.Delete(0);
|
||||
if CurUnit.UsedByUnits=nil then continue;
|
||||
for i:=0 to CurUnit.UsesUnits.Count-1 do begin
|
||||
CurUses:=TUGUses(CurUnit.UsedByUnits[i]);
|
||||
if CurUses.InImplementation then continue;
|
||||
UsesUnit:=CurUses.UsesUnit;
|
||||
if NodeToPrevNode.Contains(UsesUnit) then
|
||||
continue; // already visited
|
||||
NodeToPrevNode[UsesUnit]:=CurUnit;
|
||||
if UsesUnit=StartUnit then begin
|
||||
// target found
|
||||
// => create list from StartUnit to EndUnit
|
||||
Result:=TFPList.Create;
|
||||
CurUnit:=StartUnit;
|
||||
repeat
|
||||
Result.Add(CurUnit);
|
||||
PrevUnit:=TUGUnit(NodeToPrevNode[CurUnit]);
|
||||
if PrevUnit=CurUnit then exit; // end marker found
|
||||
CurUnit:=PrevUnit;
|
||||
until false;
|
||||
exit;
|
||||
end;
|
||||
Queue.Add(UsesUnit);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
NodeToPrevNode.Free;
|
||||
Queue.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user