mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 14:29:36 +02:00
codetools: FindSourceNameReferences: elimnate duplicates
This commit is contained in:
parent
4ce84e7af4
commit
287832a0e8
@ -573,7 +573,7 @@ type
|
||||
|
||||
function FindSourceNameReferences(TargetFilename: string;
|
||||
Files: TStringList; SkipComments: boolean;
|
||||
out ListOfSrcNameRefs: TObjectList): boolean;
|
||||
out ListOfSrcNameRefs: TObjectList; WithDuplicates: boolean = false): boolean;
|
||||
function RenameSourceNameReferences(OldFilename, NewFilename, NewSrcname: string;
|
||||
ListOfSrcNameRefs: TObjectList): boolean;
|
||||
// todo: deprecate FindUnitReferences
|
||||
@ -3048,7 +3048,7 @@ begin
|
||||
end;
|
||||
|
||||
function TCodeToolManager.FindSourceNameReferences(TargetFilename: string; Files: TStringList;
|
||||
SkipComments: boolean; out ListOfSrcNameRefs: TObjectList): boolean;
|
||||
SkipComments: boolean; out ListOfSrcNameRefs: TObjectList; WithDuplicates: boolean): boolean;
|
||||
var
|
||||
i, j, InFilenameCleanPos: Integer;
|
||||
Filename, Dir, TargetUnitName, InFilename, LocalSrcName: String;
|
||||
@ -3057,6 +3057,8 @@ var
|
||||
DirCache: TCTDirectoryCache;
|
||||
TreeOfPCodeXYPosition: TAVLTree;
|
||||
Param: TSrcNameRefs;
|
||||
Node, NextNode: TAVLTreeNode;
|
||||
CodeXYPos: PCodeXYPosition;
|
||||
begin
|
||||
{$IFDEF VerboseFindSourceNameReferences}
|
||||
debugln(['TCodeToolManager.FindReferencesInFiles TargetFile="',TargetFilename,'" FileCount=',Files.Count,' SkipComments=',SkipComments]);
|
||||
@ -3074,7 +3076,7 @@ begin
|
||||
'','.','..': continue; // invalid filename
|
||||
end;
|
||||
{$IFDEF VerboseFindSourceNameReferences}
|
||||
debugln(['TCodeToolManager.FindReferencesInFiles File ',Filename]);
|
||||
debugln(['TCodeToolManager.FindReferencesInFiles File ',i,'/',Files.Count,' ',Filename]);
|
||||
{$ENDIF}
|
||||
j:=i-1;
|
||||
while (j>=0) and (CompareFilenames(Filename,Files[j])<>0) do dec(j);
|
||||
@ -3137,6 +3139,22 @@ begin
|
||||
FreeTreeOfPCodeXYPosition(TreeOfPCodeXYPosition);
|
||||
continue;
|
||||
end;
|
||||
if (not WithDuplicates) and (ListOfSrcNameRefs<>nil) then begin
|
||||
// elimnate duplicates
|
||||
for j:=0 to ListOfSrcNameRefs.Count-1 do begin
|
||||
Param:=TSrcNameRefs(ListOfSrcNameRefs[j]);
|
||||
if Param.TreeOfPCodeXYPosition=nil then continue;
|
||||
Node:=TreeOfPCodeXYPosition.FindLowest;
|
||||
while Node<>nil do begin
|
||||
NextNode:=TreeOfPCodeXYPosition.FindSuccessor(Node);
|
||||
CodeXYPos:=PCodeXYPosition(Node.Data);
|
||||
if Param.TreeOfPCodeXYPosition.Find(CodeXYPos)<>nil then
|
||||
TreeOfPCodeXYPosition.Delete(Node);
|
||||
Node:=NextNode;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{$IFDEF VerboseFindSourceNameReferences}
|
||||
debugln(['TCodeToolManager.FindSourceNameReferences SrcName="',LocalSrcName,'" Count=',TreeOfPCodeXYPosition.Count]);
|
||||
{$ENDIF}
|
||||
|
@ -10,9 +10,11 @@ unit TestRefactoring;
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, CodeToolManager, CodeCache, CodeTree, BasicCodeTools, CTUnitGraph,
|
||||
FindDeclarationTool, ChangeDeclarationTool, LazLogger, LazFileUtils, AVL_Tree, Contnrs, fpcunit,
|
||||
testregistry, TestFinddeclaration;
|
||||
Classes, SysUtils, Contnrs, fpcunit, AVL_Tree,
|
||||
LazLogger, LazFileUtils, testregistry,
|
||||
CodeToolManager, CodeCache, CodeTree, BasicCodeTools, CTUnitGraph,
|
||||
FindDeclarationTool, ChangeDeclarationTool, TestGlobals,
|
||||
TestFinddeclaration;
|
||||
|
||||
const
|
||||
ExplodeWithMarker = 'explodewith:';
|
||||
@ -24,7 +26,9 @@ type
|
||||
protected
|
||||
procedure RenameReferences(NewIdentifier: string; const Flags: TFindRefsFlags = []);
|
||||
procedure RenameSourceName(NewName, NewFilename: string);
|
||||
procedure RenameUsedUnitRefs(UsedUnit: TCodeBuffer; NewName, NewFilename: string);
|
||||
procedure RenameSourceName(NewName, NewFilename: string; const AddFiles: array of string);
|
||||
procedure RenameUsedUnitRefs(UsedUnit: TCodeBuffer; NewName, NewFilename: string); // only in Code, not in UsedUnit
|
||||
procedure RenameUsedUnitRefs(UsedUnit: TCodeBuffer; NewName, NewFilename: string; const AddFiles: array of string);
|
||||
procedure CheckDiff(CurCode: TCodeBuffer; const ExpLines: array of string);
|
||||
end;
|
||||
|
||||
@ -68,6 +72,10 @@ type
|
||||
procedure TestRenameProgramName_DottedShortenEnd;
|
||||
procedure TestRenameProgramName_ToraToraTora;
|
||||
|
||||
// rename unit
|
||||
procedure TestRenameUnitName_IncludeUsedTwiceInOneUnit;
|
||||
procedure TestRenameUnitName_IncludeUsedInTwoUnits;
|
||||
|
||||
// rename uses
|
||||
procedure TestUseOmittedNamespace;
|
||||
procedure TestRenameUsedUnit_Amp;
|
||||
@ -171,9 +179,16 @@ begin
|
||||
end;
|
||||
|
||||
procedure TCustomTestRefactoring.RenameSourceName(NewName, NewFilename: string);
|
||||
begin
|
||||
RenameSourceName(NewName,NewFilename,[]);
|
||||
end;
|
||||
|
||||
procedure TCustomTestRefactoring.RenameSourceName(NewName, NewFilename: string;
|
||||
const AddFiles: array of string);
|
||||
var
|
||||
Files: TStringList;
|
||||
ListOfSrcNameRefs: TObjectList;
|
||||
i: Integer;
|
||||
begin
|
||||
// create the file list
|
||||
ListOfSrcNameRefs:=nil;
|
||||
@ -181,6 +196,9 @@ begin
|
||||
try
|
||||
// search pascal source references in Code
|
||||
Files.Add(Code.Filename);
|
||||
for i:=0 to length(AddFiles)-1 do
|
||||
Files.Add(AddFiles[i]);
|
||||
|
||||
if not CodeToolBoss.FindSourceNameReferences(Code.Filename,Files,false,ListOfSrcNameRefs) then
|
||||
begin
|
||||
Fail('CodeToolBoss.FindSourceNameReferences failed File='+Code.Filename);
|
||||
@ -221,6 +239,36 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomTestRefactoring.RenameUsedUnitRefs(UsedUnit: TCodeBuffer; NewName,
|
||||
NewFilename: string; const AddFiles: array of string);
|
||||
var
|
||||
Files: TStringList;
|
||||
ListOfSrcNameRefs: TObjectList;
|
||||
i: Integer;
|
||||
begin
|
||||
// create the file list
|
||||
ListOfSrcNameRefs:=nil;
|
||||
Files:=TStringList.Create;
|
||||
try
|
||||
// search pascal source references in Code
|
||||
Files.Add(UsedUnit.Filename);
|
||||
Files.Add(Code.Filename);
|
||||
for i:=0 to length(AddFiles)-1 do
|
||||
Files.Add(AddFiles[i]);
|
||||
if not CodeToolBoss.FindSourceNameReferences(UsedUnit.Filename,Files,false,ListOfSrcNameRefs) then
|
||||
begin
|
||||
Fail('CodeToolBoss.FindSourceNameReferences failed File='+Code.Filename);
|
||||
end;
|
||||
// rename
|
||||
if not CodeToolBoss.RenameSourceNameReferences(UsedUnit.Filename,NewFilename,NewName,ListOfSrcNameRefs)
|
||||
then
|
||||
Fail('CodeToolBoss.RenameSourceNameReferences failed');
|
||||
finally
|
||||
ListOfSrcNameRefs.Free;
|
||||
Files.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TCustomTestRefactoring.CheckDiff(CurCode: TCodeBuffer;
|
||||
const ExpLines: array of string);
|
||||
var
|
||||
@ -1481,6 +1529,137 @@ begin
|
||||
'']);
|
||||
end;
|
||||
|
||||
procedure TTestRefactoring.TestRenameUnitName_IncludeUsedTwiceInOneUnit;
|
||||
var
|
||||
RedInc: TCodeBuffer;
|
||||
begin
|
||||
RedInc:=CodeToolBoss.CreateFile('red.inc');
|
||||
try
|
||||
RedInc.Source:=
|
||||
'{$IFDEF EnableIntf}'+LineEnding
|
||||
+'function Fly: Test1.TBird;'+LineEnding
|
||||
+'{$ENDIF}'+LineEnding
|
||||
+'{$IFDEF EnableImpl}'+LineEnding
|
||||
+'function Fly: Test1.TBird;'+LineEnding
|
||||
+'begin'+LineEnding
|
||||
+' Test1.Ant:=test1.ant;'+LineEnding
|
||||
+'end;'+LineEnding
|
||||
+'{$ENDIF}'+LineEnding;
|
||||
|
||||
Add([
|
||||
'unit test1;',
|
||||
'{$mode objfpc}{$H+}',
|
||||
'interface',
|
||||
'type TAnt = word;',
|
||||
'{$define EnableIntf}',
|
||||
'{$i red.inc}',
|
||||
'{$undefine EnableIntf}',
|
||||
'implementation',
|
||||
'{$define EnableImpl}',
|
||||
'{$i red.inc}',
|
||||
'{$undefine EnableIntf}',
|
||||
'end.',
|
||||
'']);
|
||||
RenameSourceName('&End','End.pas');
|
||||
CheckDiff(Code,[
|
||||
'unit &End;',
|
||||
'{$mode objfpc}{$H+}',
|
||||
'interface',
|
||||
'type TAnt = word;',
|
||||
'{$define EnableIntf}',
|
||||
'{$i red.inc}',
|
||||
'{$undefine EnableIntf}',
|
||||
'implementation',
|
||||
'{$define EnableImpl}',
|
||||
'{$i red.inc}',
|
||||
'{$undefine EnableIntf}',
|
||||
'end.',
|
||||
'']);
|
||||
CheckDiff(RedInc,[
|
||||
'{$IFDEF EnableIntf}',
|
||||
'function Fly: &End.TBird;',
|
||||
'{$ENDIF}',
|
||||
'{$IFDEF EnableImpl}',
|
||||
'function Fly: &End.TBird;',
|
||||
'begin',
|
||||
' &End.Ant:=&End.ant;',
|
||||
'end;',
|
||||
'{$ENDIF}']);
|
||||
|
||||
finally
|
||||
RedInc.IsDeleted:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestRefactoring.TestRenameUnitName_IncludeUsedInTwoUnits;
|
||||
var
|
||||
RedInc, RedGreenUnit: TCodeBuffer;
|
||||
begin
|
||||
RedInc:=CodeToolBoss.CreateFile('red.inc');
|
||||
RedGreenUnit:=CodeToolBoss.CreateFile('red.green.pas');
|
||||
try
|
||||
RedInc.Source:=LinesToStr([
|
||||
'function Fly: Red.Green.TAnt;',
|
||||
'begin',
|
||||
' red.green.Ant:=3;',
|
||||
'end;']);
|
||||
|
||||
RedGreenUnit.Source:=LinesToStr([
|
||||
'unit Red.Green;',
|
||||
'interface',
|
||||
'type TAnt = word;',
|
||||
'var Ant: TAnt;',
|
||||
'implementation',
|
||||
'{$I red.inc}',
|
||||
'var Hop: red.green.TAnt;',
|
||||
'end.']);
|
||||
|
||||
Add([
|
||||
'unit test1;',
|
||||
'{$mode objfpc}{$H+}',
|
||||
'interface',
|
||||
'uses Red.Green;',
|
||||
'implementation',
|
||||
'{$I red.inc}',
|
||||
'begin',
|
||||
' red.green.ant:=2;',
|
||||
'end.',
|
||||
'']);
|
||||
RenameUsedUnitRefs(RedGreenUnit,'&End','end.pas',[]);
|
||||
CheckDiff(Code,[
|
||||
'unit test1;',
|
||||
'{$mode objfpc}{$H+}',
|
||||
'interface',
|
||||
'uses &End;',
|
||||
'implementation',
|
||||
'{$I red.inc}',
|
||||
'begin',
|
||||
' &End.ant:=2;',
|
||||
'end.',
|
||||
'']);
|
||||
|
||||
CheckDiff(RedGreenUnit,[
|
||||
'unit &End;',
|
||||
'interface',
|
||||
'type TAnt = word;',
|
||||
'var Ant: TAnt;',
|
||||
'implementation',
|
||||
'{$I red.inc}',
|
||||
'var Hop: &End.TAnt;',
|
||||
'end.']);
|
||||
|
||||
CheckDiff(RedInc,[
|
||||
'function Fly: &End.TAnt;',
|
||||
'begin',
|
||||
' &End.Ant:=3;',
|
||||
'end;']);
|
||||
|
||||
finally
|
||||
RedInc.IsDeleted:=true;
|
||||
RedGreenUnit.IsDeleted:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestRefactoring.TestUseOmittedNamespace;
|
||||
|
||||
procedure t(const OldShort, OldFull, NewFull, Expected: string);
|
||||
|
Loading…
Reference in New Issue
Block a user