mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-14 11:14:23 +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(
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
const
|
||||
NodeMovedFlag = 1;
|
||||
var
|
||||
NodeMoves: TCodeGraph;// an edge means, move the FromNode in front of the ToNode
|
||||
|
||||
@ -2093,30 +2095,64 @@ var
|
||||
NodeMoves.AddEdge(Node,InsertInFrontOf);
|
||||
end;
|
||||
|
||||
function ApplyNodeMove(GraphEdge: TCodeGraphEdge): boolean;
|
||||
function WholeSectionIsMoved(SectionNode: TCodeTreeNode): boolean;
|
||||
var
|
||||
MoveNode: TCodeTreeNode;
|
||||
ToNode: TCodeTreeNode;
|
||||
Node: TCodeTreeNode;
|
||||
GraphNode: TCodeGraphNode;
|
||||
begin
|
||||
Result:=false;
|
||||
MoveNode:=GraphEdge.FromNode.Node;
|
||||
ToNode:=GraphEdge.ToNode.Node;
|
||||
DebugLn(['ApplyNodeMove Node=',ExtractNode(MoveNode,[]),' To=',ExtractNode(ToNode,[])]);
|
||||
|
||||
Node:=SectionNode.FirstChild;
|
||||
while Node<>nil do begin
|
||||
GraphNode:=NodeMoves.GetGraphNode(Node,false);
|
||||
if (GraphNode=nil) or (GraphNode.OutTreeCount=0) then
|
||||
exit(false);
|
||||
Node:=Node.NextBrother;
|
||||
end;
|
||||
Result:=true;
|
||||
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
|
||||
AVLNode: TAVLTreeNode;
|
||||
GraphEdge: TCodeGraphEdge;
|
||||
Node: TCodeTreeNode;
|
||||
FromPos: LongInt;
|
||||
ToPos: LongInt;
|
||||
NodeSrc: String;
|
||||
begin
|
||||
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
|
||||
AVLNode:=GraphNode.InTree.FindLowest;
|
||||
while AVLNode<>nil do begin
|
||||
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);
|
||||
end;
|
||||
end;
|
||||
@ -2129,10 +2165,19 @@ var
|
||||
ListOfGraphNodes: TFPList;
|
||||
i: Integer;
|
||||
GraphNode: TCodeGraphNode;
|
||||
InsertPos: LongInt;
|
||||
Indent: LongInt;
|
||||
begin
|
||||
Result:=false;
|
||||
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
|
||||
repeat
|
||||
GraphEdge:=NodeMoves.GetTopologicalSortedList(ListOfGraphNodes);
|
||||
@ -2145,9 +2190,14 @@ var
|
||||
// apply changes
|
||||
// the ListOfGraphNodes is sorted topologically with nodes at end must be
|
||||
// moved first
|
||||
NodeMoves.ClearNodeFlags;
|
||||
for i:=ListOfGraphNodes.Count-1 downto 0 do begin
|
||||
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;
|
||||
Result:=SourceChangeCache.Apply;
|
||||
end;
|
||||
@ -2169,6 +2219,7 @@ var
|
||||
try
|
||||
// move the pointer types to the same type sections
|
||||
if not BuildUnitDefinitionGraph(Definitions,Graph,false) then exit;
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
if Definitions=nil then exit(true);
|
||||
InitNodeMoves;
|
||||
|
||||
|
@ -43,7 +43,10 @@ type
|
||||
Node: TCodeTreeNode;
|
||||
InTree: TAVLTree;// tree of TCodeGraphEdge sorted for FromNode (ToNode = 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;
|
||||
|
||||
PCodeGraphEdgeKey = ^TCodeGraphEdgeKey;
|
||||
@ -57,7 +60,8 @@ type
|
||||
TCodeGraphEdge = class
|
||||
FromNode: TCodeGraphNode;
|
||||
ToNode: TCodeGraphNode;
|
||||
Data: Pointer;
|
||||
Data: Pointer; // custom data
|
||||
Flags: cardinal;// custom flags
|
||||
end;
|
||||
|
||||
{ TCodeGraph }
|
||||
@ -69,12 +73,19 @@ type
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
procedure Clear;
|
||||
procedure ClearNodeFlags;
|
||||
procedure ClearEdgeFlags;
|
||||
procedure Assign(Source: TCodeGraph);
|
||||
function CreateCopy: TCodeGraph;
|
||||
function AddGraphNode(Node: TCodeTreeNode): TCodeGraphNode;
|
||||
function GetGraphNode(Node: TCodeTreeNode; CreateIfNotExists: boolean
|
||||
): TCodeGraphNode;
|
||||
procedure DeleteGraphNode(Node: TCodeTreeNode);
|
||||
function FindGraphNodeWithNumberOfOutEdges(MinNumber, MaxNumber: integer
|
||||
): TCodeGraphNode;
|
||||
function FindGraphNodeWithNumberOfInEdges(MinNumber, MaxNumber: integer
|
||||
): TCodeGraphNode;
|
||||
|
||||
function AddEdge(FromNode, ToNode: TCodeTreeNode): TCodeGraphEdge;
|
||||
function GetEdge(FromNode, ToNode: TCodeTreeNode;
|
||||
CreateIfNotExists: boolean): TCodeGraphEdge;
|
||||
@ -269,6 +280,28 @@ begin
|
||||
Edges.Clear;
|
||||
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);
|
||||
var
|
||||
AVLNode: TAVLTreeNode;
|
||||
@ -367,6 +400,42 @@ begin
|
||||
GraphNode.Free;
|
||||
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;
|
||||
begin
|
||||
Result:=GetEdge(FromNode,ToNode,true);
|
||||
@ -543,5 +612,23 @@ begin
|
||||
Result:=Edges.FindKey(@EdgeKey,@CompareEdgeKeyWithGraphEdge);
|
||||
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.
|
||||
|
||||
|
@ -26,10 +26,10 @@
|
||||
</RunParams>
|
||||
<RequiredPackages Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="LCL"/>
|
||||
<PackageName Value="CodeTools"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="CodeTools"/>
|
||||
<PackageName Value="LCL"/>
|
||||
</Item2>
|
||||
</RequiredPackages>
|
||||
<Units Count="3">
|
||||
@ -57,7 +57,6 @@
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<Generate Value="Faster"/>
|
||||
<TargetCPU Value="arm"/>
|
||||
</CodeGeneration>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
|
@ -31,8 +31,8 @@ program FixDefinitionOrder;
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
System, Classes, SysUtils, CodeCache, CodeToolManager, FileProcs,
|
||||
CodeTree, DirectivesTree;
|
||||
Classes, SysUtils, CodeCache, CodeToolManager, FileProcs, CodeTree,
|
||||
DirectivesTree;
|
||||
|
||||
var
|
||||
Filename: string;
|
||||
|
Loading…
Reference in New Issue
Block a user