mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 20:59:08 +02:00
codetools: added function to move pointer types to there refering types
git-svn-id: trunk@11841 -
This commit is contained in:
parent
898efab50a
commit
ce4bd7e89a
@ -2072,6 +2072,8 @@ end;
|
|||||||
|
|
||||||
function TCodeCompletionCodeTool.FixForwardDefinitions(
|
function TCodeCompletionCodeTool.FixForwardDefinitions(
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
|
const
|
||||||
|
NodeMovedFlag = 1;
|
||||||
var
|
var
|
||||||
NodeMoves: TCodeGraph;// an edge means, move the FromNode in front of the ToNode
|
NodeMoves: TCodeGraph;// an edge means, move the FromNode in front of the ToNode
|
||||||
|
|
||||||
@ -2093,30 +2095,64 @@ var
|
|||||||
NodeMoves.AddEdge(Node,InsertInFrontOf);
|
NodeMoves.AddEdge(Node,InsertInFrontOf);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ApplyNodeMove(GraphEdge: TCodeGraphEdge): boolean;
|
function WholeSectionIsMoved(SectionNode: TCodeTreeNode): boolean;
|
||||||
var
|
var
|
||||||
MoveNode: TCodeTreeNode;
|
Node: TCodeTreeNode;
|
||||||
ToNode: TCodeTreeNode;
|
GraphNode: TCodeGraphNode;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Node:=SectionNode.FirstChild;
|
||||||
MoveNode:=GraphEdge.FromNode.Node;
|
while Node<>nil do begin
|
||||||
ToNode:=GraphEdge.ToNode.Node;
|
GraphNode:=NodeMoves.GetGraphNode(Node,false);
|
||||||
DebugLn(['ApplyNodeMove Node=',ExtractNode(MoveNode,[]),' To=',ExtractNode(ToNode,[])]);
|
if (GraphNode=nil) or (GraphNode.OutTreeCount=0) then
|
||||||
|
exit(false);
|
||||||
|
Node:=Node.NextBrother;
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ApplyNodeMoves(GraphNode: TCodeGraphNode): boolean;
|
function ApplyNodeMove(GraphNode: TCodeGraphNode; MoveNode: boolean;
|
||||||
|
InsertPos, Indent: integer): boolean;
|
||||||
|
// if MoveNode=true then move code of GraphNode.Node to InsertPos
|
||||||
|
// Always: recursively all nodes that should be moved to GraphNode too
|
||||||
var
|
var
|
||||||
AVLNode: TAVLTreeNode;
|
AVLNode: TAVLTreeNode;
|
||||||
GraphEdge: TCodeGraphEdge;
|
GraphEdge: TCodeGraphEdge;
|
||||||
|
Node: TCodeTreeNode;
|
||||||
|
FromPos: LongInt;
|
||||||
|
ToPos: LongInt;
|
||||||
|
NodeSrc: String;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
DebugLn(['ApplyNodeMoves ',ExtractNode(GraphNode.Node,[])]);
|
Node:=GraphNode.Node;
|
||||||
|
// marked as moved
|
||||||
|
GraphNode.Flags:=NodeMovedFlag;
|
||||||
|
DebugLn(['ApplyNodeMoves ',ExtractNode(Node,[])]);
|
||||||
|
if MoveNode then begin
|
||||||
|
FromPos:=FindLineEndOrCodeInFrontOfPosition(Node.StartPos);
|
||||||
|
ToPos:=FindLineEndOrCodeAfterPosition(Node.EndPos);
|
||||||
|
NodeSrc:=GetIndentStr(Indent)+Trim(copy(Src,FromPos,ToPos-FromPos));
|
||||||
|
// remove
|
||||||
|
if (Node.PriorBrother=nil)
|
||||||
|
and (Node.Parent<>nil) and (Node.Parent.Desc in AllDefinitionSections)
|
||||||
|
and WholeSectionIsMoved(Node.Parent)
|
||||||
|
then begin
|
||||||
|
// the whole section is moved and this is the first node of the section
|
||||||
|
// remove the section header too
|
||||||
|
FromPos:=FindLineEndOrCodeInFrontOfPosition(Node.Parent.StartPos);
|
||||||
|
end;
|
||||||
|
DebugLn(['ApplyNodeMove Remove: "',copy(Src,FromPos,ToPos-FromPos),'"']);
|
||||||
|
if not SourceChangeCache.Replace(gtNone,gtNone,FromPos,ToPos,'') then exit;
|
||||||
|
// insert
|
||||||
|
DebugLn(['ApplyNodeMove Insert: "',NodeSrc,'"']);
|
||||||
|
if not SourceChangeCache.Replace(gtNewLine,gtNewLine,
|
||||||
|
InsertPos,InsertPos,NodeSrc) then exit;
|
||||||
|
end;
|
||||||
|
// move dependent nodes
|
||||||
if GraphNode.InTree<>nil then begin
|
if GraphNode.InTree<>nil then begin
|
||||||
AVLNode:=GraphNode.InTree.FindLowest;
|
AVLNode:=GraphNode.InTree.FindLowest;
|
||||||
while AVLNode<>nil do begin
|
while AVLNode<>nil do begin
|
||||||
GraphEdge:=TCodeGraphEdge(AVLNode.Data);
|
GraphEdge:=TCodeGraphEdge(AVLNode.Data);
|
||||||
if not ApplyNodeMove(GraphEdge) then exit;
|
if not ApplyNodeMove(GraphEdge.FromNode,true,InsertPos,Indent) then exit;
|
||||||
AVLNode:=GraphNode.InTree.FindSuccessor(AVLNode);
|
AVLNode:=GraphNode.InTree.FindSuccessor(AVLNode);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2129,10 +2165,19 @@ var
|
|||||||
ListOfGraphNodes: TFPList;
|
ListOfGraphNodes: TFPList;
|
||||||
i: Integer;
|
i: Integer;
|
||||||
GraphNode: TCodeGraphNode;
|
GraphNode: TCodeGraphNode;
|
||||||
|
InsertPos: LongInt;
|
||||||
|
Indent: LongInt;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if NodeMoves.Edges.Count=0 then exit(true);
|
if NodeMoves.Edges.Count=0 then exit(true);
|
||||||
|
|
||||||
|
// check that every node has at most one destination
|
||||||
|
GraphNode:=NodeMoves.FindGraphNodeWithNumberOfOutEdges(2,-1);
|
||||||
|
if GraphNode<>nil then begin
|
||||||
|
DebugLn(['TCodeCompletionCodeTool.FixForwardDefinitions.ApplyNodeMoves inconsistency: node should be moved to several places: ',ExtractNode(GraphNode.Node,[])]);
|
||||||
|
raise Exception.Create('TCodeCompletionCodeTool.FixForwardDefinitions.ApplyNodeMoves node should be moved to several places');
|
||||||
|
end;
|
||||||
|
|
||||||
// sort topologically and break all circles
|
// sort topologically and break all circles
|
||||||
repeat
|
repeat
|
||||||
GraphEdge:=NodeMoves.GetTopologicalSortedList(ListOfGraphNodes);
|
GraphEdge:=NodeMoves.GetTopologicalSortedList(ListOfGraphNodes);
|
||||||
@ -2145,9 +2190,14 @@ var
|
|||||||
// apply changes
|
// apply changes
|
||||||
// the ListOfGraphNodes is sorted topologically with nodes at end must be
|
// the ListOfGraphNodes is sorted topologically with nodes at end must be
|
||||||
// moved first
|
// moved first
|
||||||
|
NodeMoves.ClearNodeFlags;
|
||||||
for i:=ListOfGraphNodes.Count-1 downto 0 do begin
|
for i:=ListOfGraphNodes.Count-1 downto 0 do begin
|
||||||
GraphNode:=TCodeGraphNode(ListOfGraphNodes[i]);
|
GraphNode:=TCodeGraphNode(ListOfGraphNodes[i]);
|
||||||
if not ApplyNodeMoves(GraphNode) then exit;
|
if GraphNode.Flags=0 then begin
|
||||||
|
InsertPos:=FindLineEndOrCodeInFrontOfPosition(GraphNode.Node.StartPos);
|
||||||
|
Indent:=GetLineIndent(Src,GraphNode.Node.StartPos);
|
||||||
|
if not ApplyNodeMove(GraphNode,false,InsertPos,Indent) then exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
Result:=SourceChangeCache.Apply;
|
Result:=SourceChangeCache.Apply;
|
||||||
end;
|
end;
|
||||||
@ -2169,6 +2219,7 @@ var
|
|||||||
try
|
try
|
||||||
// move the pointer types to the same type sections
|
// move the pointer types to the same type sections
|
||||||
if not BuildUnitDefinitionGraph(Definitions,Graph,false) then exit;
|
if not BuildUnitDefinitionGraph(Definitions,Graph,false) then exit;
|
||||||
|
SourceChangeCache.MainScanner:=Scanner;
|
||||||
if Definitions=nil then exit(true);
|
if Definitions=nil then exit(true);
|
||||||
InitNodeMoves;
|
InitNodeMoves;
|
||||||
|
|
||||||
|
@ -43,7 +43,10 @@ type
|
|||||||
Node: TCodeTreeNode;
|
Node: TCodeTreeNode;
|
||||||
InTree: TAVLTree;// tree of TCodeGraphEdge sorted for FromNode (ToNode = Self)
|
InTree: TAVLTree;// tree of TCodeGraphEdge sorted for FromNode (ToNode = Self)
|
||||||
OutTree: TAVLTree;// tree of TCodeGraphEdge sorted for ToNode (FromNode = Self)
|
OutTree: TAVLTree;// tree of TCodeGraphEdge sorted for ToNode (FromNode = Self)
|
||||||
Data: Pointer;
|
Data: Pointer; // custom data
|
||||||
|
Flags: cardinal;// custom flags
|
||||||
|
function OutTreeCount: integer;
|
||||||
|
function InTreeCount: integer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
PCodeGraphEdgeKey = ^TCodeGraphEdgeKey;
|
PCodeGraphEdgeKey = ^TCodeGraphEdgeKey;
|
||||||
@ -57,7 +60,8 @@ type
|
|||||||
TCodeGraphEdge = class
|
TCodeGraphEdge = class
|
||||||
FromNode: TCodeGraphNode;
|
FromNode: TCodeGraphNode;
|
||||||
ToNode: TCodeGraphNode;
|
ToNode: TCodeGraphNode;
|
||||||
Data: Pointer;
|
Data: Pointer; // custom data
|
||||||
|
Flags: cardinal;// custom flags
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TCodeGraph }
|
{ TCodeGraph }
|
||||||
@ -69,12 +73,19 @@ type
|
|||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
|
procedure ClearNodeFlags;
|
||||||
|
procedure ClearEdgeFlags;
|
||||||
procedure Assign(Source: TCodeGraph);
|
procedure Assign(Source: TCodeGraph);
|
||||||
function CreateCopy: TCodeGraph;
|
function CreateCopy: TCodeGraph;
|
||||||
function AddGraphNode(Node: TCodeTreeNode): TCodeGraphNode;
|
function AddGraphNode(Node: TCodeTreeNode): TCodeGraphNode;
|
||||||
function GetGraphNode(Node: TCodeTreeNode; CreateIfNotExists: boolean
|
function GetGraphNode(Node: TCodeTreeNode; CreateIfNotExists: boolean
|
||||||
): TCodeGraphNode;
|
): TCodeGraphNode;
|
||||||
procedure DeleteGraphNode(Node: TCodeTreeNode);
|
procedure DeleteGraphNode(Node: TCodeTreeNode);
|
||||||
|
function FindGraphNodeWithNumberOfOutEdges(MinNumber, MaxNumber: integer
|
||||||
|
): TCodeGraphNode;
|
||||||
|
function FindGraphNodeWithNumberOfInEdges(MinNumber, MaxNumber: integer
|
||||||
|
): TCodeGraphNode;
|
||||||
|
|
||||||
function AddEdge(FromNode, ToNode: TCodeTreeNode): TCodeGraphEdge;
|
function AddEdge(FromNode, ToNode: TCodeTreeNode): TCodeGraphEdge;
|
||||||
function GetEdge(FromNode, ToNode: TCodeTreeNode;
|
function GetEdge(FromNode, ToNode: TCodeTreeNode;
|
||||||
CreateIfNotExists: boolean): TCodeGraphEdge;
|
CreateIfNotExists: boolean): TCodeGraphEdge;
|
||||||
@ -269,6 +280,28 @@ begin
|
|||||||
Edges.Clear;
|
Edges.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCodeGraph.ClearNodeFlags;
|
||||||
|
var
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
AVLNode:=Nodes.FindLowest;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
TCodeGraphNode(AVLNode.Data).Flags:=0;
|
||||||
|
AVLNode:=Nodes.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCodeGraph.ClearEdgeFlags;
|
||||||
|
var
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
AVLNode:=Edges.FindLowest;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
TCodeGraphEdge(AVLNode.Data).Flags:=0;
|
||||||
|
AVLNode:=Edges.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCodeGraph.Assign(Source: TCodeGraph);
|
procedure TCodeGraph.Assign(Source: TCodeGraph);
|
||||||
var
|
var
|
||||||
AVLNode: TAVLTreeNode;
|
AVLNode: TAVLTreeNode;
|
||||||
@ -367,6 +400,42 @@ begin
|
|||||||
GraphNode.Free;
|
GraphNode.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCodeGraph.FindGraphNodeWithNumberOfOutEdges(MinNumber,
|
||||||
|
MaxNumber: integer): TCodeGraphNode;
|
||||||
|
var
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
Cnt: LongInt;
|
||||||
|
begin
|
||||||
|
AVLNode:=Nodes.FindLowest;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
Result:=TCodeGraphNode(AVLNode.Data);
|
||||||
|
Cnt:=Result.OutTreeCount;
|
||||||
|
if ((MinNumber<0) or (MinNumber<=Cnt))
|
||||||
|
and ((MaxNumber<0) or (MaxNumber>=Cnt)) then
|
||||||
|
exit;
|
||||||
|
AVLNode:=Nodes.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCodeGraph.FindGraphNodeWithNumberOfInEdges(MinNumber,
|
||||||
|
MaxNumber: integer): TCodeGraphNode;
|
||||||
|
var
|
||||||
|
AVLNode: TAVLTreeNode;
|
||||||
|
Cnt: LongInt;
|
||||||
|
begin
|
||||||
|
AVLNode:=Nodes.FindLowest;
|
||||||
|
while AVLNode<>nil do begin
|
||||||
|
Result:=TCodeGraphNode(AVLNode.Data);
|
||||||
|
Cnt:=Result.InTreeCount;
|
||||||
|
if ((MinNumber<0) or (MinNumber<=Cnt))
|
||||||
|
and ((MaxNumber<0) or (MaxNumber>=Cnt)) then
|
||||||
|
exit;
|
||||||
|
AVLNode:=Nodes.FindSuccessor(AVLNode);
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCodeGraph.AddEdge(FromNode, ToNode: TCodeTreeNode): TCodeGraphEdge;
|
function TCodeGraph.AddEdge(FromNode, ToNode: TCodeTreeNode): TCodeGraphEdge;
|
||||||
begin
|
begin
|
||||||
Result:=GetEdge(FromNode,ToNode,true);
|
Result:=GetEdge(FromNode,ToNode,true);
|
||||||
@ -543,5 +612,23 @@ begin
|
|||||||
Result:=Edges.FindKey(@EdgeKey,@CompareEdgeKeyWithGraphEdge);
|
Result:=Edges.FindKey(@EdgeKey,@CompareEdgeKeyWithGraphEdge);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TCodeGraphNode }
|
||||||
|
|
||||||
|
function TCodeGraphNode.OutTreeCount: integer;
|
||||||
|
begin
|
||||||
|
if OutTree<>nil then
|
||||||
|
Result:=OutTree.Count
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCodeGraphNode.InTreeCount: integer;
|
||||||
|
begin
|
||||||
|
if InTree<>nil then
|
||||||
|
Result:=InTree.Count
|
||||||
|
else
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
</RunParams>
|
</RunParams>
|
||||||
<RequiredPackages Count="2">
|
<RequiredPackages Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="CodeTools"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
<Item2>
|
<Item2>
|
||||||
<PackageName Value="CodeTools"/>
|
<PackageName Value="LCL"/>
|
||||||
</Item2>
|
</Item2>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="3">
|
<Units Count="3">
|
||||||
@ -57,7 +57,6 @@
|
|||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<CodeGeneration>
|
<CodeGeneration>
|
||||||
<Generate Value="Faster"/>
|
<Generate Value="Faster"/>
|
||||||
<TargetCPU Value="arm"/>
|
|
||||||
</CodeGeneration>
|
</CodeGeneration>
|
||||||
<Other>
|
<Other>
|
||||||
<CompilerPath Value="$(CompPath)"/>
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
@ -31,8 +31,8 @@ program FixDefinitionOrder;
|
|||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
System, Classes, SysUtils, CodeCache, CodeToolManager, FileProcs,
|
Classes, SysUtils, CodeCache, CodeToolManager, FileProcs, CodeTree,
|
||||||
CodeTree, DirectivesTree;
|
DirectivesTree;
|
||||||
|
|
||||||
var
|
var
|
||||||
Filename: string;
|
Filename: string;
|
||||||
|
Loading…
Reference in New Issue
Block a user