mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 03:39:48 +01:00 
			
		
		
		
	codetools: find overloads: add parent-child edges
git-svn-id: trunk@19752 -
This commit is contained in:
		
							parent
							
								
									a927537fcb
								
							
						
					
					
						commit
						21ad29c287
					
				@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user