codetools: find overloads: add parent-child edges

git-svn-id: trunk@19752 -
This commit is contained in:
mattias 2009-05-01 22:53:22 +00:00
parent a927537fcb
commit 21ad29c287
4 changed files with 101 additions and 16 deletions

View File

@ -2133,6 +2133,7 @@ begin
if not InitCurCodeTool(Code) then exit; if not InitCurCodeTool(Code) then exit;
try try
Graph:=TDeclarationOverloadsGraph.Create; Graph:=TDeclarationOverloadsGraph.Create;
Graph.OnGetCodeToolForBuffer:=@OnGetCodeToolForBuffer;
Result:=Graph.Init(NewCode,NewX,NewY); Result:=Graph.Init(NewCode,NewX,NewY);
except except
on e: Exception do Result:=HandleException(e); on e: Exception do Result:=HandleException(e);
@ -4886,9 +4887,10 @@ function TCodeToolManager.OnGetCodeToolForBuffer(Sender: TObject;
Code: TCodeBuffer; GoToMainCode: boolean): TFindDeclarationTool; Code: TCodeBuffer; GoToMainCode: boolean): TFindDeclarationTool;
begin begin
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
DebugLn('[TCodeToolManager.OnGetCodeToolForBuffer]' DbgOut('[TCodeToolManager.OnGetCodeToolForBuffer]');
,' Sender=',TCustomCodeTool(Sender).MainFilename if Sender is TCustomCodeTool then
,' Code=',Code.Filename); DbgOut(' Sender=',TCustomCodeTool(Sender).MainFilename);
debugln(' Code=',Code.Filename);
{$ENDIF} {$ENDIF}
Result:=TFindDeclarationTool(GetCodeToolForSource(Code,GoToMainCode,true)); Result:=TFindDeclarationTool(GetCodeToolForSource(Code,GoToMainCode,true));
end; end;

View File

@ -142,9 +142,12 @@ const
// combined values // combined values
AllCodeSections = AllSourceTypes =
[ctnProgram, ctnPackage, ctnLibrary, ctnUnit, ctnInterface, [ctnProgram,ctnPackage,ctnLibrary,ctnUnit];
ctnImplementation, ctnInitialization, ctnFinalization]; AllUsableSourceTypes =
[ctnUnit];
AllCodeSections = AllSourceTypes
+ [ctnInterface, ctnImplementation, ctnInitialization, ctnFinalization];
AllClassBaseSections = AllClassBaseSections =
[ctnClassPublic,ctnClassPublished,ctnClassPrivate,ctnClassProtected]; [ctnClassPublic,ctnClassPublished,ctnClassPrivate,ctnClassProtected];
AllClassTypeSections = AllClassTypeSections =
@ -173,10 +176,6 @@ const
ctnClassOfType,ctnVariantType,ctnConstant]; ctnClassOfType,ctnVariantType,ctnConstant];
AllPascalStatements = [ctnBeginBlock,ctnWithStatement,ctnWithVariable, AllPascalStatements = [ctnBeginBlock,ctnWithStatement,ctnWithVariable,
ctnOnBlock,ctnOnIdentifier,ctnOnStatement]; ctnOnBlock,ctnOnIdentifier,ctnOnStatement];
AllSourceTypes =
[ctnProgram,ctnPackage,ctnLibrary,ctnUnit];
AllUsableSourceTypes =
[ctnUnit];
AllFindContextDescs = AllIdentifierDefinitions + AllCodeSections + AllFindContextDescs = AllIdentifierDefinitions + AllCodeSections +
[ctnClass,ctnClassInterface,ctnProcedure]; [ctnClass,ctnClassInterface,ctnProcedure];

View File

@ -30,19 +30,22 @@ unit FindOverloads;
interface interface
uses uses
Classes, SysUtils, CodeGraph, CodeCache; Classes, SysUtils, FileProcs, CodeAtom, CodeTree, CodeGraph, CodeCache,
FindDeclarationTool;
type type
TOverloadsGraphNode = class(TCodeGraphNode) TOverloadsGraphNode = class(TCodeGraphNode)
public public
Identifier: string; Identifier: string;
Tool: TFindDeclarationTool;
end; end;
TOverloadsGraphEdgeType = ( TOverloadsGraphEdgeType = (
ogetParent, ogetParentChild,
ogetAncestor, ogetAncestorInherited,
ogetInterface ogetInterfaceInherited
); );
TOverloadsGraphEdgeTypes = set of TOverloadsGraphEdgeType;
TOverloadsGraphEdge = class(TCodeGraphEdge) TOverloadsGraphEdge = class(TCodeGraphEdge)
public public
@ -55,9 +58,14 @@ type
private private
FGraph: TCodeGraph; FGraph: TCodeGraph;
FIdentifier: string; FIdentifier: string;
FOnGetCodeToolForBuffer: TOnGetCodeToolForBuffer;
FStartCode: TCodeBuffer; FStartCode: TCodeBuffer;
FStartX: integer; FStartX: integer;
FStartY: integer; FStartY: integer;
function AddContext(Tool: TFindDeclarationTool;
CodeNode: TCodeTreeNode): TOverloadsGraphNode;
function AddEdge(Typ: TOverloadsGraphEdgeType;
FromNode, ToNode: TCodeTreeNode): TOverloadsGraphEdge;
public public
constructor Create; constructor Create;
destructor Destroy; override; destructor Destroy; override;
@ -68,12 +76,75 @@ type
property StartCode: TCodeBuffer read FStartCode; property StartCode: TCodeBuffer read FStartCode;
property StartX: integer read FStartX; property StartX: integer read FStartX;
property StartY: integer read FStartY; property StartY: integer read FStartY;
property OnGetCodeToolForBuffer: TOnGetCodeToolForBuffer
read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer;
end; end;
const
OverloadsGraphEdgeTypeNames: array[TOverloadsGraphEdgeType] of string = (
'Parent-Child',
'Ancestor-Inherited',
'Interface-Inherited'
);
implementation implementation
{ TDeclarationOverloadsGraph } { TDeclarationOverloadsGraph }
function TDeclarationOverloadsGraph.AddContext(Tool: TFindDeclarationTool;
CodeNode: TCodeTreeNode): TOverloadsGraphNode;
var
ParentCodeNode: TCodeTreeNode;
ParentGraphNode: TOverloadsGraphNode;
begin
Result:=TOverloadsGraphNode(Graph.GetGraphNode(CodeNode,false));
if Result<>nil then exit;
// add new node
DebugLn(['TDeclarationOverloadsGraph.AddContext ',Tool.MainFilename,' ',CodeNode.DescAsString,' "',dbgstr(copy(Tool.Src,CodeNode.StartPos,20)),'"']);
Result:=TOverloadsGraphNode(Graph.GetGraphNode(CodeNode,true));
Result.Tool:=Tool;
// add parent nodes to graph
ParentCodeNode:=CodeNode.Parent;
while ParentCodeNode<>nil do begin
DebugLn(['TDeclarationOverloadsGraph.AddContext ',ParentCodeNode.DescAsString]);
if ParentCodeNode.Desc in
AllSourceTypes+[ctnClass,ctnClassInterface,ctnRecordType]
then begin
DebugLn(['TDeclarationOverloadsGraph.AddContext ADD parent']);
ParentGraphNode:=AddContext(Tool,ParentCodeNode);
AddEdge(ogetParentChild,ParentGraphNode.Node,Result.Node);
break;
end;
if ParentCodeNode.Parent<>nil then
ParentCodeNode:=ParentCodeNode.Parent
else
ParentCodeNode:=ParentCodeNode.PriorBrother;
end;
// ToDo: add ancestors, interfaces
// ToDo: add alias
end;
function TDeclarationOverloadsGraph.AddEdge(Typ: TOverloadsGraphEdgeType;
FromNode, ToNode: TCodeTreeNode): TOverloadsGraphEdge;
begin
Result:=TOverloadsGraphEdge(Graph.GetEdge(FromNode,ToNode,false));
if (Result<>nil) then begin
if Result.Typ<>Typ then
RaiseCatchableException('TDeclarationOverloadsGraph.AddEdge Typ conflict');
exit;
end;
// create new edge
Result:=TOverloadsGraphEdge(Graph.GetEdge(FromNode,ToNode,true));
Result.Typ:=Typ;
DebugLn(['TDeclarationOverloadsGraph.AddEdge ',OverloadsGraphEdgeTypeNames[Typ]]);
end;
constructor TDeclarationOverloadsGraph.Create; constructor TDeclarationOverloadsGraph.Create;
begin begin
FGraph:=TCodeGraph.Create(TOverloadsGraphNode,TOverloadsGraphEdge); FGraph:=TCodeGraph.Create(TOverloadsGraphNode,TOverloadsGraphEdge);
@ -93,13 +164,24 @@ end;
function TDeclarationOverloadsGraph.Init(Code: TCodeBuffer; X, Y: integer function TDeclarationOverloadsGraph.Init(Code: TCodeBuffer; X, Y: integer
): Boolean; ): Boolean;
var
Tool: TFindDeclarationTool;
CleanPos: integer;
CodeNode: TCodeTreeNode;
begin begin
Result:=false; Result:=false;
FStartCode:=Code; FStartCode:=Code;
FStartX:=X; FStartX:=X;
FStartY:=Y; FStartY:=Y;
Tool:=OnGetCodeToolForBuffer(Self,Code,true);
if Tool.CaretToCleanPos(CodeXYPosition(X,Y,Code),CleanPos)<>0 then begin
DebugLn(['TDeclarationOverloadsGraph.Init Tool.CaretToCleanPos failed']);
exit(false);
end;
CodeNode:=Tool.FindDeepestNodeAtPos(CleanPos,true);
DebugLn(['TDeclarationOverloadsGraph.Init Add start context']);
AddContext(Tool,CodeNode);
Result:=true; Result:=true;
end; end;

View File

@ -157,16 +157,18 @@ var
begin begin
Graph:=nil; Graph:=nil;
FindOverloadsDialog:=nil; FindOverloadsDialog:=nil;
CodeToolBoss.ActivateWriteLock;
try try
if not CodeToolBoss.GatherOverloads(Code,X,Y,Graph) then begin if not CodeToolBoss.GatherOverloads(Code,X,Y,Graph) then begin
LazarusIDE.DoJumpToCodeToolBossError; LazarusIDE.DoJumpToCodeToolBossError;
exit(mrCancel); exit(mrCancel);
end; end;
DebugLn(['ShowFindOverloadsDialog ',Graph.StartCode.Filename,' ',Graph.StartX,',',Graph.StartY]); //DebugLn(['ShowFindOverloadsDialog ',Graph.StartCode.Filename,' ',Graph.StartX,',',Graph.StartY]);
FindOverloadsDialog:=TFindOverloadsDialog.Create(nil); FindOverloadsDialog:=TFindOverloadsDialog.Create(nil);
FindOverloadsDialog.Worker.Graph:=Graph; FindOverloadsDialog.Worker.Graph:=Graph;
Result:=FindOverloadsDialog.ShowModal; Result:=FindOverloadsDialog.ShowModal;
finally finally
CodeToolBoss.DeactivateWriteLock;
FindOverloadsDialog.Free; FindOverloadsDialog.Free;
Graph.Free; Graph.Free;
end; end;