codetools: improved fixing definition order and fixing alias defs

git-svn-id: trunk@12315 -
This commit is contained in:
mattias 2007-10-04 17:14:19 +00:00
parent f6fe5420e0
commit dc1e321f46
5 changed files with 162 additions and 54 deletions

View File

@ -1384,7 +1384,8 @@ var
begin
// check if definition is an alias
// Example: const A = B; or const A = B();
// Example: const A = B; or const A = B();
if (Node.Parent=nil) then exit;
if not (Node.Parent.Desc in [ctnConstSection,ctnTypeSection]) then exit;
// this is a const or type
@ -1427,34 +1428,27 @@ var
end;
end;
if NeededType=ctnNone then exit;
if (NeededType<>Node.Desc) or (not OnlyWrongType) then begin
// add alias
if NeededType<>Node.Desc then begin
DebugLn(['TCodeCompletionCodeTool.FindAliasDefinitions Wrong: ',Node.DescAsString,' ',ExtractNode(Node,[]),' ',Node.DescAsString,'<>',NodeDescToStr(NeededType)]);
end;
if TreeOfCodeTreeNodeExt=nil then
TreeOfCodeTreeNodeExt:=TAVLTree.Create(@CompareCodeTreeNodeExt);
NodeExt:=NodeExtMemManager.NewNode;
NodeExt.Node:=Node;
NodeExt.Txt:=GetRedefinitionNodeText(Node);
NodeExt.Data:=ReferingNode;
NodeExt.Flags:=NeededType;
TreeOfCodeTreeNodeExt.Add(NodeExt);
// add alias
if NeededType<>Node.Desc then begin
DebugLn(['TCodeCompletionCodeTool.FindAliasDefinitions Wrong: ',Node.DescAsString,' ',ExtractNode(Node,[]),' ',Node.DescAsString,'<>',NodeDescToStr(NeededType)]);
end;
if TreeOfCodeTreeNodeExt=nil then
TreeOfCodeTreeNodeExt:=TAVLTree.Create(@CompareCodeTreeNodeExt);
NodeExt:=NodeExtMemManager.NewNode;
NodeExt.Node:=Node;
NodeExt.Txt:=GetRedefinitionNodeText(Node);
NodeExt.Data:=ReferingNode;
NodeExt.Flags:=NeededType;
TreeOfCodeTreeNodeExt.Add(NodeExt);
end;
var
NodeExt: TCodeTreeNodeExtension;
Node: TCodeTreeNode;
NodeText: String;
AVLNode: TAVLTreeNode;
begin
Result:=false;
TreeOfCodeTreeNodeExt:=nil;
BuildTree(true);
AllNodes:=TAVLTree.Create(@CompareCodeTreeNodeExt);
try
procedure CollectAllDefinitions;
var
Node: TCodeTreeNode;
NodeText: String;
AVLNode: TAVLTreeNode;
NodeExt: TCodeTreeNodeExtension;
begin
Node:=Tree.Root;
while Node<>nil do begin
case Node.Desc of
@ -1489,7 +1483,12 @@ begin
Node:=Node.Next;
end;
end;
end;
procedure CollectAllAliasDefinitions;
var
Node: TCodeTreeNode;
begin
Node:=Tree.Root;
while Node<>nil do begin
case Node.Desc of
@ -1508,7 +1507,101 @@ begin
Node:=Node.Next;
end;
end;
end;
procedure ResolveAliases;
function FindAliasRoot(Node: TCodeTreeNode;
out NeededRootDesc: TCodeTreeNodeDesc): TCodeTreeNode;
var
AliasText: String;
AVLNode: TAVLTreeNode;
ReferingNode: TCodeTreeNode;
OldDesc: TCodeTreeNodeDesc;
NodeExt: TCodeTreeNodeExtension;
begin
Result:=Node;
NeededRootDesc:=Node.Desc;
AliasText:=GetRedefinitionNodeText(Node);
if AliasText='' then exit;
AVLNode:=FindCodeTreeNodeExtAVLNode(TreeOfCodeTreeNodeExt,AliasText);
if AVLNode=nil then exit;
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
NeededRootDesc:=TCodeTreeNodeDesc(NodeExt.Flags);
ReferingNode:=TCodeTreeNode(NodeExt.Data);
if ReferingNode=nil then exit;
// this is an alias => search further
if ReferingNode.Desc=ctnNone then begin
// circle
exit;
end;
// mark node as visited
OldDesc:=Node.Desc;
Node.Desc:=ctnNone;
Result:=FindAliasRoot(ReferingNode,NeededRootDesc);
// unmark node as visited
Node.Desc:=OldDesc;
if NeededRootDesc=ctnNone then
NeededRootDesc:=Node.Desc;
end;
var
AVLNode: TAVLTreeNode;
NodeExt: TCodeTreeNodeExtension;
ReferingNode: TCodeTreeNode;
NeededType: TCodeTreeNodeDesc;
begin
if TreeOfCodeTreeNodeExt=nil then exit;
AVLNode:=TreeOfCodeTreeNodeExt.FindLowest;
while AVLNode<>nil do begin
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
ReferingNode:=TCodeTreeNode(NodeExt.Data);
if ReferingNode<>nil then begin
// this node is an alias.
// => find the root alias
ReferingNode:=FindAliasRoot(ReferingNode,NeededType);
NodeExt.Data:=ReferingNode;
NodeExt.Flags:=NeededType;
end;
AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
end;
end;
procedure RemoveGoodAliases;
var
AVLNode: TAVLTreeNode;
NodeExt: TCodeTreeNodeExtension;
NeededType: TCodeTreeNodeDesc;
NextAVLNode: TAVLTreeNode;
begin
AVLNode:=TreeOfCodeTreeNodeExt.FindLowest;
while AVLNode<>nil do begin
NextAVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
NeededType:=TCodeTreeNodeDesc(NodeExt.Flags);
if NodeExt.Node.Desc=NeededType then begin
TreeOfCodeTreeNodeExt.RemovePointer(NodeExt);
NodeExtMemManager.DisposeNode(NodeExt);
end;
AVLNode:=NextAVLNode;
end;
end;
begin
Result:=false;
TreeOfCodeTreeNodeExt:=nil;
BuildTree(true);
AllNodes:=TAVLTree.Create(@CompareCodeTreeNodeExt);
try
if OnlyWrongType then
CollectAllDefinitions;
CollectAllAliasDefinitions;
if OnlyWrongType then begin
ResolveAliases;
RemoveGoodAliases;
end;
finally
NodeExtMemManager.DisposeAVLTree(AllNodes);
end;
@ -1522,7 +1615,7 @@ function TCodeCompletionCodeTool.FixAliasDefinitions(
The function body will be removed.
See the function FindAliasDefinitions.
}
function FindReferingNode(DefNode: TCodeTreeNode): TCodeTreeNode;
function FindReferingNodeExt(DefNode: TCodeTreeNode): TCodeTreeNodeExtension;
var
AVLNode: TAVLTreeNode;
NodeExt: TCodeTreeNodeExtension;
@ -1531,7 +1624,7 @@ function TCodeCompletionCodeTool.FixAliasDefinitions(
while AVLNode<>nil do begin
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
if NodeExt.Node=DefNode then begin
Result:=TCodeTreeNode(NodeExt.Data);
Result:=NodeExt;
exit;
end;
AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
@ -1544,8 +1637,8 @@ var
NodeExt: TCodeTreeNodeExtension;
DefNode: TCodeTreeNode;
NextAVLNode: TAVLTreeNode;
ReferingNodeInFront: TCodeTreeNode;
ReferingNodeBehind: TCodeTreeNode;
ReferingNodeInFront: TCodeTreeNodeExtension;
ReferingNodeBehind: TCodeTreeNodeExtension;
NewSrc: String;
FromPos: LongInt;
ReferingType: TCodeTreeNodeDesc;
@ -1577,8 +1670,9 @@ begin
NodeExt:=TCodeTreeNodeExtension(AVLNode.Data);
DefNode:=NodeExt.Node;
ReferingType:=TCodeTreeNodeDesc(NodeExt.Flags);
ReferingType:=TCodeTreeNodeDesc(NodeExt.Flags);
DebugLn(['TCodeCompletionCodeTool.FixAliasDefinitions Old=',DefNode.DescAsString,' New=',NodeDescToStr(ReferingType)]);
//DebugLn(['TCodeCompletionCodeTool.FixAliasDefinitions Old=',DefNode.DescAsString,' New=',NodeDescToStr(ReferingType)]);
case ReferingType of
ctnTypeDefinition: NewSrc:='type';
@ -1595,9 +1689,10 @@ begin
CurPos.StartPos,CurPos.EndPos,NewSrc) then exit;
end else begin
// this is not the start of the section
ReferingNodeInFront:=FindReferingNode(DefNode.PriorBrother);
ReferingNodeInFront:=FindReferingNodeExt(DefNode.PriorBrother);
if (ReferingNodeInFront=nil)
or (ReferingNodeInFront.Desc<>ReferingType) then begin
or (TCodeTreeNodeDesc(ReferingNodeInFront.Flags)<>ReferingType) then
begin
// the node in front has a different section
FromPos:=FindLineEndOrCodeInFrontOfPosition(DefNode.StartPos);
if not SourceChangeCache.Replace(gtEmptyLine,gtNewLine,
@ -1610,7 +1705,7 @@ begin
// this is the end of the section
end else begin
// this is not the end of the section
ReferingNodeBehind:=FindReferingNode(DefNode.NextBrother);
ReferingNodeBehind:=FindReferingNodeExt(DefNode.NextBrother);
if ReferingNodeBehind<>nil then begin
// the next node will change the section
end else begin
@ -2893,12 +2988,14 @@ function TCodeCompletionCodeTool.FixForwardDefinitions(
// restore destination section if needed
if not NextInsertAtSamePos then begin
// this was the last insertion at this destination
if (NeedSection<>DestSection)
DebugLn(['MoveNodes this was the last insertion at this dest NeedSection=',NodeDescToStr(NeedSection),' DestSection=',NodeDescToStr(DestSection)]);
if (DestNode.Desc in AllIdentifierDefinitions)
and (NeedSection<>DestSection)
and (DestSection in AllDefinitionSections) then begin
// restore the section of destination
case DestSection of
ctnVarDefinition: NewTxt:='var';
ctnConstDefinition: NewTxt:='const';
ctnVarSection: NewTxt:='var';
ctnConstSection: NewTxt:='const';
ctnResStrSection: NewTxt:='resourcestring';
ctnTypeSection: NewTxt:='type';
ctnLabelSection: NewTxt:='label';

View File

@ -32,22 +32,12 @@
<PackageName Value="CodeTools"/>
</Item2>
</RequiredPackages>
<Units Count="3">
<Units Count="1">
<Unit0>
<Filename Value="fixdefinitionorder.lpr"/>
<IsPartOfProject Value="True"/>
<UnitName Value="FixDefinitionOrder"/>
</Unit0>
<Unit1>
<Filename Value="scanexamples/simplefunctions.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="SimpleFunctions"/>
</Unit1>
<Unit2>
<Filename Value="scanexamples/wrongforwarddefinitions.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="WrongForwardDefinitions"/>
</Unit2>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -47,16 +47,16 @@ begin
if Code=nil then
raise Exception.Create('loading failed '+Filename);
if not CodeToolBoss.FixAllAliasDefinitions(Code) then begin
{if not CodeToolBoss.FixAllAliasDefinitions(Code) then begin
writeln('FixAllAliasDefinitions failed');
exit;
end;
end;}
// fix constants
{if not CodeToolBoss.FixForwardDefinitions(Code) then begin
if not CodeToolBoss.FixForwardDefinitions(Code) then begin
writeln('FixForwardDefinitions failed');
exit;
end;}
end;
// write the new source:
writeln('-----------------------------------');

View File

@ -31,6 +31,10 @@ type
Func2 = MyNilFunc;
Func3 = Func2;
type
MPI_Delete_function = function (_para1:MPI_Comm; _para2:longint; _para3:pointer; _para4:pointer):longint;cdecl;
MPI_NULL_DELETE_FN = MPI_Delete_function(0);
implementation
end.

View File

@ -2267,12 +2267,29 @@ begin
i:=0;
while i<=Lines.Count-1 do begin
Line:=Lines[i];
// example: #define MPI_ARGV_NULL (char **)0
if REMatches(Line,'^#define\s+([a-zA-Z0-9_]+)\s+(\(.*\*\)0)\s*($|//|/\*)')
then begin
REVarPos(2,MacroStart,MacroLen);
Line:=copy(Line,1,MacroStart-1)+'NULL'
+copy(Line,MacroStart+MacroLen,length(Line));
Lines[i]:=Line;
end
else // example: #define MPI_NULL_COPY_FN ((MPI_Copy_function *)0)
if REMatches(Line,'^#define\s+([a-zA-Z0-9_]+)\s+(\(\(.*\*\)0\))\s*($|//|/\*)')
then begin
REVarPos(2,MacroStart,MacroLen);
Line:=copy(Line,1,MacroStart-1)+'NULL'
+copy(Line,MacroStart+MacroLen,length(Line));
Lines[i]:=Line;
end
else // example: *)0)
if REMatches(Line,'\*\)(0)\)')
then begin
REVarPos(1,MacroStart,MacroLen);
Line:=copy(Line,1,MacroStart-1)+'NULL'
+copy(Line,MacroStart+MacroLen,length(Line));
Lines[i]:=Line;
end;
inc(i);
end;