codetools: directorycache: invalidate directory when a codebuffer is marked deleted

This commit is contained in:
mattias 2025-02-04 16:45:03 +01:00
parent de11537070
commit 116b91b184
13 changed files with 459 additions and 348 deletions

View File

@ -53,6 +53,7 @@ type
TCodeBuffer = class(TSourceLog) TCodeBuffer = class(TSourceLog)
private private
FFilename: string; FFilename: string;
FOnDeleted: TNotifyEvent;
FReferenceCount: integer; FReferenceCount: integer;
FScanner: TLinkScanner; FScanner: TLinkScanner;
FOnSetScanner: TNotifyEvent; FOnSetScanner: TNotifyEvent;
@ -114,6 +115,7 @@ type
property FileChangeStep: integer read FFileChangeStep; // last loaded/saved changestep, only valid if LoadDateValid=true property FileChangeStep: integer read FFileChangeStep; // last loaded/saved changestep, only valid if LoadDateValid=true
property OnSetFilename: TNotifyEvent read FOnSetFilename write FOnSetFilename; property OnSetFilename: TNotifyEvent read FOnSetFilename write FOnSetFilename;
property OnSetScanner: TNotifyEvent read FOnSetScanner write FOnSetScanner; property OnSetScanner: TNotifyEvent read FOnSetScanner write FOnSetScanner;
property OnDeleted: TNotifyEvent read FOnDeleted write FOnDeleted;
property Scanner: TLinkScanner read FScanner write SetScanner; property Scanner: TLinkScanner read FScanner write SetScanner;
property ReferenceCount: integer read FReferenceCount; property ReferenceCount: integer read FReferenceCount;
end; end;
@ -153,11 +155,13 @@ type
fLastIncludeLinkFileValid: boolean; fLastIncludeLinkFileValid: boolean;
fLastIncludeLinkFileChangeStep: integer; fLastIncludeLinkFileChangeStep: integer;
fChangeStep: integer; fChangeStep: integer;
FOnCodeDeleted: TNotifyEvent;
FOnDecodeLoaded: TOnCodeCacheDecodeLoaded; FOnDecodeLoaded: TOnCodeCacheDecodeLoaded;
FOnEncodeSaving: TOnCodeCacheEncodeSaving; FOnEncodeSaving: TOnCodeCacheEncodeSaving;
function FindIncludeLink(const IncludeFilename: string): string; function FindIncludeLink(const IncludeFilename: string): string;
function FindIncludeLinkNode(const IncludeFilename: string): TIncludedByLink; function FindIncludeLinkNode(const IncludeFilename: string): TIncludedByLink;
function FindIncludeLinkAVLNode(const IncludeFilename: string): TAVLTreeNode; function FindIncludeLinkAVLNode(const IncludeFilename: string): TAVLTreeNode;
procedure OnCodeDeleted(Sender: TObject);
function OnScannerCheckFileOnDisk(Code: TSourceLog): boolean; // true if code changed function OnScannerCheckFileOnDisk(Code: TSourceLog): boolean; // true if code changed
function OnScannerGetFileName(Sender: TObject; Code: TSourceLog): string; function OnScannerGetFileName(Sender: TObject; Code: TSourceLog): string;
function OnScannerLoadSource(Sender: TObject; const AFilename: string; function OnScannerLoadSource(Sender: TObject; const AFilename: string;
@ -216,6 +220,7 @@ type
write FOnDecodeLoaded; write FOnDecodeLoaded;
property OnEncodeSaving: TOnCodeCacheEncodeSaving read FOnEncodeSaving property OnEncodeSaving: TOnCodeCacheEncodeSaving read FOnEncodeSaving
write FOnEncodeSaving; write FOnEncodeSaving;
property OnFileDeleted: TNotifyEvent read FOnCodeDeleted write FOnCodeDeleted;
property DefaultEncoding: string read FDefaultEncoding write FDefaultEncoding; property DefaultEncoding: string read FDefaultEncoding write FDefaultEncoding;
property ChangeStamp: int64 read FChangeStamp; property ChangeStamp: int64 read FChangeStamp;
property DirectoryCachePool: TCTDirectoryCachePool read FDirectoryCachePool property DirectoryCachePool: TCTDirectoryCachePool read FDirectoryCachePool
@ -760,6 +765,7 @@ begin
FItems.Add(Result); FItems.Add(Result);
Result.FCodeCache:=Self;// must be called after FileName:= Result.FCodeCache:=Self;// must be called after FileName:=
Result.LastIncludedByFile:=FindIncludeLink(Result.Filename); Result.LastIncludedByFile:=FindIncludeLink(Result.Filename);
Result.OnDeleted:=@OnCodeDeleted;
end; end;
Result.DiskEncoding:=DefaultEncoding; Result.DiskEncoding:=DefaultEncoding;
Result.MemEncoding:=Result.DiskEncoding; Result.MemEncoding:=Result.DiskEncoding;
@ -998,6 +1004,27 @@ begin
@CompareAnsiStringWithIncludedByLink); @CompareAnsiStringWithIncludedByLink);
end; end;
procedure TCodeCache.OnCodeDeleted(Sender: TObject);
var
Code: TCodeBuffer;
Dir: String;
Cache: TCTDirectoryCache;
begin
if DirectoryCachePool<>nil then begin
Code:=TCodeBuffer(Sender);
if Code.IsVirtual then
Cache:=DirectoryCachePool.GetCache('',false,false)
else begin
Dir:=ExtractFilePath(Code.Filename);
Cache:=DirectoryCachePool.GetCache(Dir,false,false);
end;
if Cache<>nil then
Cache.Invalidate;
end;
if Assigned(OnFileDeleted) then
OnFileDeleted(Sender);
end;
function TCodeCache.FindIncludeLink(const IncludeFilename: string): string; function TCodeCache.FindIncludeLink(const IncludeFilename: string): string;
var Link: TIncludedByLink; var Link: TIncludedByLink;
begin begin
@ -1391,6 +1418,8 @@ begin
if FIsDeleted then begin if FIsDeleted then begin
Clear; Clear;
FIsDeleted:=true; FIsDeleted:=true;
if Assigned(OnDeleted) then
OnDeleted(Self);
//DebugLn(['TCodeBuffer.SetIsDeleted ',Filename,' ',FileNeedsUpdate]); //DebugLn(['TCodeBuffer.SetIsDeleted ',Filename,' ',FileNeedsUpdate]);
end; end;
end; end;

View File

@ -6946,7 +6946,7 @@ begin
if (Filename='') or (System.Pos(PathDelim,Filename)>0) then if (Filename='') or (System.Pos(PathDelim,Filename)>0) then
exit; exit;
Code:=FindFile(Filename); Code:=FindFile(Filename);
if Code<>nil then if (Code<>nil) and not Code.IsDeleted then
Result:=Code.Filename; Result:=Code.Filename;
end; end;

View File

@ -43,24 +43,28 @@ procedure TTestChangeDeclaration.TestCTAddProcedureModifier;
+'implementation'+sLineBreak +'implementation'+sLineBreak
+'end.'; +'end.';
Code:=CodeToolBoss.CreateFile(FDefFilename); Code:=CodeToolBoss.CreateFile(FDefFilename);
Code.Source:=Src; try
if not CodeToolBoss.AddProcModifier(Code,3,3,aModifier) then Code.Source:=Src;
begin if not CodeToolBoss.AddProcModifier(Code,3,3,aModifier) then
Fail('AddProcModifier failed: '+CodeToolBoss.ErrorMessage); begin
end else begin Fail('AddProcModifier failed: '+CodeToolBoss.ErrorMessage);
if not CodeToolBoss.ExtractProcedureHeader(Code,3,3, end else begin
[phpWithStart,phpWithResultType,phpWithOfObject,phpWithProcModifiers,phpWithComments,phpDoNotAddSemicolon], if not CodeToolBoss.ExtractProcedureHeader(Code,3,3,
ProcHead) [phpWithStart,phpWithResultType,phpWithOfObject,phpWithProcModifiers,phpWithComments,phpDoNotAddSemicolon],
then ProcHead)
Fail('ExtractProcedureHeader failed: '+CodeToolBoss.ErrorMessage); then
if ProcHead<>Expected then begin Fail('ExtractProcedureHeader failed: '+CodeToolBoss.ErrorMessage);
writeln('Test ProcCode="',ProcCode,'"'); if ProcHead<>Expected then begin
Src:=Code.Source; writeln('Test ProcCode="',ProcCode,'"');
writeln('SrcSTART:======================'); Src:=Code.Source;
writeln(Src); writeln('SrcSTART:======================');
writeln('SrcEND:========================'); writeln(Src);
AssertEquals('ProcHead',Expected,ProcHead); writeln('SrcEND:========================');
AssertEquals('ProcHead',Expected,ProcHead);
end;
end; end;
finally
Code.IsDeleted:=true;
end; end;
end; end;

View File

@ -78,30 +78,34 @@ var
NewCode, Code: TCodeBuffer; NewCode, Code: TCodeBuffer;
begin begin
Code:=CodeToolBoss.CreateFile('test1.pas'); Code:=CodeToolBoss.CreateFile('test1.pas');
s:=''; try
for i:=Low(Src) to High(Src) do s:='';
s+=Src[i]+LineEnding; for i:=Low(Src) to High(Src) do
Code.Source:=s; s+=Src[i]+LineEnding;
Code.Source:=s;
if not CodeToolBoss.CompleteCode(Code,Col,Line,Line,NewCode,NewX,NewY,NewTopLine, if not CodeToolBoss.CompleteCode(Code,Col,Line,Line,NewCode,NewX,NewY,NewTopLine,
BlockTopLine,BlockBottomLine,false) BlockTopLine,BlockBottomLine,false)
and (CodeToolBoss.ErrorDbgMsg<>'') then and (CodeToolBoss.ErrorDbgMsg<>'') then
begin begin
NewCode:=Code; NewCode:=Code;
NewY:=Line; NewY:=Line;
NewX:=Col; NewX:=Col;
if (CodeToolBoss.ErrorCode<>nil) and (CodeToolBoss.ErrorLine>0) then begin if (CodeToolBoss.ErrorCode<>nil) and (CodeToolBoss.ErrorLine>0) then begin
NewY:=CodeToolBoss.ErrorLine; NewY:=CodeToolBoss.ErrorLine;
NewX:=CodeToolBoss.ErrorColumn; NewX:=CodeToolBoss.ErrorColumn;
NewCode:=CodeToolBoss.ErrorCode; NewCode:=CodeToolBoss.ErrorCode;
end;
WriteSource(NewCode.Filename,NewY,NewX);
Fail(Title+': call CompleteCode failed: "'+CodeToolBoss.ErrorDbgMsg+'"');
end; end;
WriteSource(NewCode.Filename,NewY,NewX); s:='';
Fail(Title+': call CompleteCode failed: "'+CodeToolBoss.ErrorDbgMsg+'"'); for i:=Low(Expected) to High(Expected) do
s+=Expected[i]+LineEnding;
CheckDiff(Title,s,Code.Source);
finally
Code.IsDeleted:=true;
end; end;
s:='';
for i:=Low(Expected) to High(Expected) do
s+=Expected[i]+LineEnding;
CheckDiff(Title,s,Code.Source);
end; end;
procedure TTestCodeCompletion.TestIntfProcUpdateArgName; procedure TTestCodeCompletion.TestIntfProcUpdateArgName;

View File

@ -111,6 +111,7 @@ begin
AssertEquals('Src is empty',Trim(Src)<>'',true); AssertEquals('Src is empty',Trim(Src)<>'',true);
AssertEquals('ExpectedSrc is empty',Trim(ExpectedSrc)<>'',true); AssertEquals('ExpectedSrc is empty',Trim(ExpectedSrc)<>'',true);
Code:=nil;
ExpectedCode:=TCodeBuffer.Create; ExpectedCode:=TCodeBuffer.Create;
try try
// replace cursor | marker in Src // replace cursor | marker in Src
@ -146,6 +147,7 @@ begin
AssertEquals('CompleteBlock did no or the wrong completion: ',TrimExpected,TrimResult); AssertEquals('CompleteBlock did no or the wrong completion: ',TrimExpected,TrimResult);
finally finally
if Code<>nil then Code.IsDeleted:=true;
ExpectedCode.Free; ExpectedCode.Free;
end; end;
end; end;
@ -173,17 +175,21 @@ begin
// replace cursor | marker in Src // replace cursor | marker in Src
Code:=CodeToolBoss.CreateFile('TestCompleteBlock.pas'); Code:=CodeToolBoss.CreateFile('TestCompleteBlock.pas');
FullSrc:=CreateFullSrc(Src,p); try
if p<1 then FullSrc:=CreateFullSrc(Src,p);
AssertEquals('missing cursor | in test source: "'+dbgstr(Src)+'"',true,false); if p<1 then
Code.Source:=FullSrc; AssertEquals('missing cursor | in test source: "'+dbgstr(Src)+'"',true,false);
Code.AbsoluteToLineCol(p,Y,X); Code.Source:=FullSrc;
Code.AbsoluteToLineCol(p,Y,X);
if CodeToolBoss.CompleteBlock(Code,X,Y,OnlyIfCursorBlockIndented, if CodeToolBoss.CompleteBlock(Code,X,Y,OnlyIfCursorBlockIndented,
NewCode,NewX,NewY,NewTopLine) NewCode,NewX,NewY,NewTopLine)
then begin then begin
debugln(['TTestCodetoolsCompleteBlock.CompleteBlockFail completion: ',dbgstr(Code.Source)]); debugln(['TTestCodetoolsCompleteBlock.CompleteBlockFail completion: ',dbgstr(Code.Source)]);
AssertEquals('CodeToolBoss.CompleteBlock returned true for incompletable src="'+dbgstr(Src)+'"',true,false); AssertEquals('CodeToolBoss.CompleteBlock returned true for incompletable src="'+dbgstr(Src)+'"',true,false);
end;
finally
Code.IsDeleted:=true;
end; end;
end; end;

View File

@ -119,6 +119,8 @@ begin
AssertEquals('start comment header1.h in front of header2.h',true,Header1Start<Header2Start); AssertEquals('start comment header1.h in front of header2.h',true,Header1Start<Header2Start);
AssertEquals('start comment header2.h in front of end of header1.h',true,Header2Start<Header1End); AssertEquals('start comment header2.h in front of end of header1.h',true,Header2Start<Header1End);
finally finally
Header1.IsDeleted:=true;
Header2.IsDeleted:=true;
Merger.Free; Merger.Free;
Filenames.Free; Filenames.Free;
end; end;
@ -163,6 +165,7 @@ begin
Check('do not replace macros in #ifdef','#ifdef macro1','#ifdef macro1'); Check('do not replace macros in #ifdef','#ifdef macro1','#ifdef macro1');
Check('do not replace macros in #ifndef','#ifndef macro1','#ifndef macro1'); Check('do not replace macros in #ifndef','#ifndef macro1','#ifndef macro1');
finally finally
Header1.IsDeleted:=true;
Buffers.Free; Buffers.Free;
Merger.Free; Merger.Free;
end; end;

View File

@ -123,7 +123,6 @@ begin
PascalCompilerNames[pcPas2js], PascalCompilerNames[pcPas2js],
PascalCompilerNames[CodeToolBoss.GetPascalCompilerForDirectory('')]); PascalCompilerNames[CodeToolBoss.GetPascalCompilerForDirectory('')]);
end; end;
FCode:=CodeToolBoss.CreateFile('test1.pas'); FCode:=CodeToolBoss.CreateFile('test1.pas');
end; end;

View File

@ -164,39 +164,43 @@ var
TreeChangeStep: LongInt; TreeChangeStep: LongInt;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source // scan source
Code.Source:=GetSource([]); Code.Source:=GetSource([]);
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRange INITIAL SCAN']); debugln(['TTestCodetoolsRangeScan.TestCTScanRange INITIAL SCAN']);
{$ENDIF} {$ENDIF}
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
RootNode:=Tool.Tree.Root; RootNode:=Tool.Tree.Root;
TreeChangeStep:=Tool.TreeChangeStep; TreeChangeStep:=Tool.TreeChangeStep;
AssertEquals('Step1: RootNode<>nil',true,RootNode<>nil); AssertEquals('Step1: RootNode<>nil',true,RootNode<>nil);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
// append a comment at end and scan again => this should result in no tree change // append a comment at end and scan again => this should result in no tree change
Code.Source:=GetSource([crsfWithCommentAtEnd]); Code.Source:=GetSource([crsfWithCommentAtEnd]);
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRange SCAN with comment at end']); debugln(['TTestCodetoolsRangeScan.TestCTScanRange SCAN with comment at end']);
{$ENDIF} {$ENDIF}
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('Step2: RootNode=Tree.Root',true,RootNode=Tool.Tree.Root); AssertEquals('Step2: RootNode=Tree.Root',true,RootNode=Tool.Tree.Root);
AssertEquals('Step2: TreeChangeStep=Tool.TreeChangeStep',true,TreeChangeStep=Tool.TreeChangeStep); AssertEquals('Step2: TreeChangeStep=Tool.TreeChangeStep',true,TreeChangeStep=Tool.TreeChangeStep);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
// insert a procedure in the implementation and scan again // insert a procedure in the implementation and scan again
// => this should result in a tree change, but the root node should be kept // => this should result in a tree change, but the root node should be kept
Code.Source:=GetSource([crsfWithProc1]); Code.Source:=GetSource([crsfWithProc1]);
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRange SCAN with new proc in implementation']); debugln(['TTestCodetoolsRangeScan.TestCTScanRange SCAN with new proc in implementation']);
{$ENDIF} {$ENDIF}
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('Step3: RootNode=Tree.Root',true,RootNode=Tool.Tree.Root); AssertEquals('Step3: RootNode=Tree.Root',true,RootNode=Tool.Tree.Root);
AssertEquals('Step3: TreeChangeStep<>Tool.TreeChangeStep',true,TreeChangeStep<>Tool.TreeChangeStep); AssertEquals('Step3: TreeChangeStep<>Tool.TreeChangeStep',true,TreeChangeStep<>Tool.TreeChangeStep);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeAscending; procedure TTestCodetoolsRangeScan.TestCTScanRangeAscending;
@ -209,56 +213,60 @@ var
MaxRange: TLinkScannerRange; MaxRange: TLinkScannerRange;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// empty tool // empty tool
Code.Source:=''; Code.Source:='';
Tool.BuildTree(lsrInit); Tool.BuildTree(lsrInit);
// scan source // scan source
Code.Source:=GetSource([crsfWithInitialization,crsfWithFinalization]); Code.Source:=GetSource([crsfWithInitialization,crsfWithFinalization]);
RootNode:=nil; RootNode:=nil;
MinRange:=low(TLinkScannerRange); MinRange:=low(TLinkScannerRange);
MaxRange:=high(TLinkScannerRange); MaxRange:=high(TLinkScannerRange);
for r:=MinRange to MaxRange do begin for r:=MinRange to MaxRange do begin
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRangeAscending Range=',dbgs(r)]); debugln(['TTestCodetoolsRangeScan.TestCTScanRangeAscending Range=',dbgs(r)]);
{$ENDIF} {$ENDIF}
Tool.BuildTree(r); Tool.BuildTree(r);
if RootNode<>nil then begin if RootNode<>nil then begin
AssertEquals('RootNode must stay for ascending range '+dbgs(r),true,RootNode=Tool.Tree.Root); AssertEquals('RootNode must stay for ascending range '+dbgs(r),true,RootNode=Tool.Tree.Root);
end; end;
RootNode:=Tool.Tree.Root; RootNode:=Tool.Tree.Root;
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
case r of case r of
lsrNone: ; lsrNone: ;
lsrInit: ; lsrInit: ;
lsrSourceType: lsrSourceType:
AssertEquals('source type scanned',true,RootNode<>nil); AssertEquals('source type scanned',true,RootNode<>nil);
lsrSourceName: lsrSourceName:
begin begin
AssertEquals('source name scanned',true,RootNode.FirstChild<>nil); AssertEquals('source name scanned',true,RootNode.FirstChild<>nil);
AssertEquals('source name found',true,RootNode.FirstChild.Desc=ctnSrcName); AssertEquals('source name found',true,RootNode.FirstChild.Desc=ctnSrcName);
end;
lsrInterfaceStart:
AssertEquals('interface start scanned',true,Tool.FindInterfaceNode<>nil);
lsrMainUsesSectionStart:
AssertEquals('main uses section start scanned',true,Tool.FindMainUsesNode<>nil);
lsrMainUsesSectionEnd:
AssertEquals('main uses section end scanned',true,Tool.FindMainUsesNode.FirstChild<>nil);
lsrImplementationStart:
AssertEquals('implementation start scanned',true,Tool.FindImplementationNode<>nil);
lsrImplementationUsesSectionStart:
AssertEquals('implementation uses section start scanned',true,Tool.FindImplementationUsesNode<>nil);
lsrImplementationUsesSectionEnd:
AssertEquals('implementation uses section end scanned',true,Tool.FindImplementationUsesNode.FirstChild<>nil);
lsrInitializationStart:
AssertEquals('initialization section start scanned',true,Tool.FindInitializationNode<>nil);
lsrFinalizationStart:
AssertEquals('finalization section start scanned',true,Tool.FindFinalizationNode<>nil);
lsrEnd:
AssertEquals('end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
end; end;
lsrInterfaceStart:
AssertEquals('interface start scanned',true,Tool.FindInterfaceNode<>nil);
lsrMainUsesSectionStart:
AssertEquals('main uses section start scanned',true,Tool.FindMainUsesNode<>nil);
lsrMainUsesSectionEnd:
AssertEquals('main uses section end scanned',true,Tool.FindMainUsesNode.FirstChild<>nil);
lsrImplementationStart:
AssertEquals('implementation start scanned',true,Tool.FindImplementationNode<>nil);
lsrImplementationUsesSectionStart:
AssertEquals('implementation uses section start scanned',true,Tool.FindImplementationUsesNode<>nil);
lsrImplementationUsesSectionEnd:
AssertEquals('implementation uses section end scanned',true,Tool.FindImplementationUsesNode.FirstChild<>nil);
lsrInitializationStart:
AssertEquals('initialization section start scanned',true,Tool.FindInitializationNode<>nil);
lsrFinalizationStart:
AssertEquals('finalization section start scanned',true,Tool.FindFinalizationNode<>nil);
lsrEnd:
AssertEquals('end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
end; end;
finally
Code.IsDeleted:=true;
end; end;
end; end;
@ -271,21 +279,25 @@ var
r: TLinkScannerRange; r: TLinkScannerRange;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source // scan source
Code.Source:='begin end.'; Code.Source:='begin end.';
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
Code.Source:=GetSource([]); Code.Source:=GetSource([]);
MinRange:=low(TLinkScannerRange); MinRange:=low(TLinkScannerRange);
MaxRange:=high(TLinkScannerRange); MaxRange:=high(TLinkScannerRange);
for r:=MaxRange downto MinRange do begin for r:=MaxRange downto MinRange do begin
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRangeDescending Range=',dbgs(r)]); debugln(['TTestCodetoolsRangeScan.TestCTScanRangeDescending Range=',dbgs(r)]);
{$ENDIF} {$ENDIF}
Tool.BuildTree(r); Tool.BuildTree(r);
AssertEquals('RootNode must stay for descending range '+dbgs(r),true,Tool.Tree.Root<>nil); AssertEquals('RootNode must stay for descending range '+dbgs(r),true,Tool.Tree.Root<>nil);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
end;
finally
Code.IsDeleted:=true;
end; end;
end; end;
@ -295,20 +307,24 @@ var
Tool: TEventsCodeTool; Tool: TEventsCodeTool;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source // scan source
Code.Source:=GetSource([crsfWithProc1]); Code.Source:=GetSource([crsfWithProc1]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
AssertEquals('step1: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step1: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
Code.Source:=GetSource([crsfWithProc1Modified]); Code.Source:=GetSource([crsfWithProc1Modified]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
CheckTree(Tool); CheckTree(Tool);
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeImplementationToEnd; procedure TTestCodetoolsRangeScan.TestCTScanRangeImplementationToEnd;
@ -317,22 +333,26 @@ var
Tool: TEventsCodeTool; Tool: TEventsCodeTool;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
Code.Source:=''; Code.Source:='';
Tool.BuildTree(lsrInit); Tool.BuildTree(lsrInit);
// scan source // scan source
Code.Source:=GetSource([crsfWithProc1]); Code.Source:=GetSource([crsfWithProc1]);
Tool.BuildTree(lsrImplementationStart); Tool.BuildTree(lsrImplementationStart);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
AssertEquals('step1: implementation found',true,Tool.FindImplementationNode<>nil); AssertEquals('step1: implementation found',true,Tool.FindImplementationNode<>nil);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step2: end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
CheckTree(Tool); CheckTree(Tool);
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeInitializationModified; procedure TTestCodetoolsRangeScan.TestCTScanRangeInitializationModified;
@ -341,20 +361,24 @@ var
Tool: TCodeTool; Tool: TCodeTool;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source with initialization // scan source with initialization
Code.Source:=GetSource([crsfWithInitialization,crsfWithInitializationStatement1]); Code.Source:=GetSource([crsfWithInitialization,crsfWithInitializationStatement1]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('step1: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step1: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
// scan source with a modified initialization // scan source with a modified initialization
Code.Source:=GetSource([crsfWithInitialization,crsfWithInitializationStatement2]); Code.Source:=GetSource([crsfWithInitialization,crsfWithInitializationStatement2]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('step2: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step2: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
CheckTree(Tool); CheckTree(Tool);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeLibraryInitializationModified; procedure TTestCodetoolsRangeScan.TestCTScanRangeLibraryInitializationModified;
@ -363,20 +387,24 @@ var
Tool: TCodeTool; Tool: TCodeTool;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source with initialization // scan source with initialization
Code.Source:=GetSource([crsfLibrary,crsfWithInitialization,crsfWithInitializationStatement1]); Code.Source:=GetSource([crsfLibrary,crsfWithInitialization,crsfWithInitializationStatement1]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('step1: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step1: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
// scan source with a modified initialization // scan source with a modified initialization
Code.Source:=GetSource([crsfLibrary,crsfWithInitialization,crsfWithInitializationStatement2]); Code.Source:=GetSource([crsfLibrary,crsfWithInitialization,crsfWithInitializationStatement2]);
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
AssertEquals('step2: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); AssertEquals('step2: end found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
CheckTree(Tool); CheckTree(Tool);
//Tool.WriteDebugTreeReport; //Tool.WriteDebugTreeReport;
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeScannerAtEnd; procedure TTestCodetoolsRangeScan.TestCTScanRangeScannerAtEnd;
@ -387,24 +415,28 @@ var
CleanCursorPos: integer; CleanCursorPos: integer;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
// scan source til implementation uses end // scan source til implementation uses end
Code.Source:=GetSource([crsfWithProc1Modified]); Code.Source:=GetSource([crsfWithProc1Modified]);
Tool.BuildTree(lsrImplementationUsesSectionEnd); Tool.BuildTree(lsrImplementationUsesSectionEnd);
// let LinkScanner scan til end // let LinkScanner scan til end
Tool.Scanner.Scan(lsrEnd,false); Tool.Scanner.Scan(lsrEnd,false);
AssertEquals('scanner at end, tool at impl uses end',true,Tool.ScannedRange=lsrImplementationUsesSectionEnd); AssertEquals('scanner at end, tool at impl uses end',true,Tool.ScannedRange=lsrImplementationUsesSectionEnd);
AssertEquals('scanner at end, tool at impl uses end',true,Tool.Scanner.ScannedRange=lsrEnd); AssertEquals('scanner at end, tool at impl uses end',true,Tool.Scanner.ScannedRange=lsrEnd);
// test BuildTreeAndGetCleanPos in implementation section // test BuildTreeAndGetCleanPos in implementation section
CursorPos.Code:=Code; CursorPos.Code:=Code;
FindPos(Code,ctrsCommentOfProc1,CursorPos.Y,CursorPos.X); FindPos(Code,ctrsCommentOfProc1,CursorPos.Y,CursorPos.X);
Tool.BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos, Tool.BuildTreeAndGetCleanPos(trTillCursor,lsrEnd,CursorPos,CleanCursorPos,
[btSetIgnoreErrorPos]); [btSetIgnoreErrorPos]);
AssertEquals('scanner and tool at end',true,Tool.ScannedRange=lsrEnd); AssertEquals('scanner and tool at end',true,Tool.ScannedRange=lsrEnd);
AssertEquals('scanner and tool at end',true,Tool.Scanner.ScannedRange=lsrEnd); AssertEquals('scanner and tool at end',true,Tool.Scanner.ScannedRange=lsrEnd);
finally
Code.IsDeleted:=true;
end;
end; end;
procedure TTestCodetoolsRangeScan.TestCTScanRangeProgramNoName; procedure TTestCodetoolsRangeScan.TestCTScanRangeProgramNoName;
@ -415,41 +447,45 @@ var
RootNode: TCodeTreeNode; RootNode: TCodeTreeNode;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool.BuildTree(lsrInit); Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
Code.Source:=GetSource([crsfProgram,crsfNoSrcName]); Tool.BuildTree(lsrInit);
Tool.BuildTree(lsrImplementationUsesSectionEnd); Code.Source:=GetSource([crsfProgram,crsfNoSrcName]);
RootNode:=nil; Tool.BuildTree(lsrImplementationUsesSectionEnd);
for r in TLinkScannerRange do begin RootNode:=nil;
{$IFDEF VerboseTestCTRangeScan} for r in TLinkScannerRange do begin
debugln(['TTestCodetoolsRangeScan.TestCTScanRangeProgramNoName Range=',dbgs(r)]); {$IFDEF VerboseTestCTRangeScan}
{$ENDIF} debugln(['TTestCodetoolsRangeScan.TestCTScanRangeProgramNoName Range=',dbgs(r)]);
Tool.BuildTree(r); {$ENDIF}
if RootNode<>nil then begin Tool.BuildTree(r);
AssertEquals('RootNode must stay for ascending range '+dbgs(r),true,RootNode=Tool.Tree.Root); if RootNode<>nil then begin
end; AssertEquals('RootNode must stay for ascending range '+dbgs(r),true,RootNode=Tool.Tree.Root);
RootNode:=Tool.Tree.Root; end;
//Tool.WriteDebugTreeReport; RootNode:=Tool.Tree.Root;
case r of //Tool.WriteDebugTreeReport;
lsrNone: ; case r of
lsrInit: ; lsrNone: ;
lsrSourceType: lsrInit: ;
AssertEquals('source type scanned',true,RootNode<>nil); lsrSourceType:
lsrSourceName: AssertEquals('source type scanned',true,RootNode<>nil);
AssertEquals('source name scanned',true,RootNode<>nil); lsrSourceName:
lsrInterfaceStart: ; AssertEquals('source name scanned',true,RootNode<>nil);
lsrMainUsesSectionStart: lsrInterfaceStart: ;
AssertEquals('main uses section start scanned',true,Tool.FindMainUsesNode<>nil); lsrMainUsesSectionStart:
lsrMainUsesSectionEnd: AssertEquals('main uses section start scanned',true,Tool.FindMainUsesNode<>nil);
AssertEquals('main uses section end scanned',true,Tool.FindMainUsesNode.FirstChild<>nil); lsrMainUsesSectionEnd:
lsrImplementationStart: ; AssertEquals('main uses section end scanned',true,Tool.FindMainUsesNode.FirstChild<>nil);
lsrImplementationUsesSectionStart: ; lsrImplementationStart: ;
lsrImplementationUsesSectionEnd: ; lsrImplementationUsesSectionStart: ;
lsrInitializationStart: ; lsrImplementationUsesSectionEnd: ;
lsrFinalizationStart: ; lsrInitializationStart: ;
lsrEnd: lsrFinalizationStart: ;
AssertEquals('end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil); lsrEnd:
AssertEquals('end. found',true,Tool.Tree.FindRootNode(ctnEndPoint)<>nil);
end;
end; end;
finally
Code.IsDeleted:=true;
end; end;
end; end;
@ -463,40 +499,44 @@ var
Src: String; Src: String;
begin begin
Code:=CodeToolBoss.CreateFile('TestRangeScan.pas'); Code:=CodeToolBoss.CreateFile('TestRangeScan.pas');
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool; try
Tool:=CodeToolBoss.GetCodeToolForSource(Code,false,true) as TCodeTool;
Src:= Src:=
'unit testrangescan;'+LineEnding 'unit testrangescan;'+LineEnding
+'interface'+LineEnding +'interface'+LineEnding
+'uses sysutils;'+LineEnding +'uses sysutils;'+LineEnding
+'implementation'+LineEnding +'implementation'+LineEnding
+'initialization'+LineEnding +'initialization'+LineEnding
+'write;'+LineEnding +'write;'+LineEnding
+'finalization'+LineEnding +'finalization'+LineEnding
+'writeln;'+LineEnding +'writeln;'+LineEnding
+'end.'+LineEnding; +'end.'+LineEnding;
Code.Source:=Src; Code.Source:=Src;
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
p:=1; p:=1;
repeat repeat
ReadRawNextPascalAtom(Src,p,AtomStart); ReadRawNextPascalAtom(Src,p,AtomStart);
if p>=length(Src) then break; if p>=length(Src) then break;
if Src[AtomStart] in ['a'..'z'] then begin if Src[AtomStart] in ['a'..'z'] then begin
try try
{$IFDEF VerboseTestCTRangeScan} {$IFDEF VerboseTestCTRangeScan}
debugln(['TTestCodetoolsRangeScan.TestCTScanRangeAscending Word="',GetIdentifier(@Src[AtomStart]),'"']); debugln(['TTestCodetoolsRangeScan.TestCTScanRangeAscending Word="',GetIdentifier(@Src[AtomStart]),'"']);
{$ENDIF} {$ENDIF}
Src[AtomStart]:=upcase(Src[AtomStart]); Src[AtomStart]:=upcase(Src[AtomStart]);
Code.Source:=Src; Code.Source:=Src;
Tool.BuildTree(lsrEnd); Tool.BuildTree(lsrEnd);
except except
on E: Exception do begin on E: Exception do begin
debugln(['TTestCodetoolsRangeScan.TestCTScanRangeUnitModified word="'+GetIdentifier(@Src[AtomStart])+'" ',E.ClassName,' Msg=',E.Message]); debugln(['TTestCodetoolsRangeScan.TestCTScanRangeUnitModified word="'+GetIdentifier(@Src[AtomStart])+'" ',E.ClassName,' Msg=',E.Message]);
Fail(E.Message); Fail(E.Message);
end;
end; end;
end; end;
end; until false;
until false; finally
Code.IsDeleted:=true;
end;
end; end;
initialization initialization

View File

@ -79,6 +79,7 @@ begin
s+=Expected[i]+LineEnding; s+=Expected[i]+LineEnding;
CheckDiff(Title,s,Code.Source); CheckDiff(Title,s,Code.Source);
finally finally
Code.IsDeleted:=true;
CodeToolBoss.DefineTree.RemoveDefineTemplate(DefTemp); CodeToolBoss.DefineTree.RemoveDefineTemplate(DefTemp);
end; end;
end; end;
@ -135,6 +136,7 @@ begin
Fail('VarNameToToType differ'); Fail('VarNameToToType differ');
end; end;
finally finally
Code.IsDeleted:=true;
VarNameToToType.Free; VarNameToToType.Free;
CodeToolBoss.DefineTree.RemoveDefineTemplate(DefTemp); CodeToolBoss.DefineTree.RemoveDefineTemplate(DefTemp);
end; end;

View File

@ -1510,20 +1510,24 @@ var
UnitType: TCodeBuffer; UnitType: TCodeBuffer;
begin begin
UnitType:=CodeToolBoss.CreateFile('type.pas'); UnitType:=CodeToolBoss.CreateFile('type.pas');
UnitType.Source:= try
'unit &Type;'+sLineBreak UnitType.Source:=
+'interface'+sLineBreak 'unit &Type;'+sLineBreak
+'var r: word;'+sLineBreak +'interface'+sLineBreak
+'implementation'+sLineBreak +'var r: word;'+sLineBreak
+'end.'; +'implementation'+sLineBreak
+'end.';
StartProgram; StartProgram;
Add([ Add([
'uses &Type;', 'uses &Type;',
'begin', 'begin',
' r{declaration:&type.r}:=3;', ' r{declaration:&type.r}:=3;',
'end.']); 'end.']);
FindDeclarations(Code); FindDeclarations(Code);
finally
UnitType.IsDeleted:=true;
end;
end; end;
procedure TTestFindDeclaration.TestFindDeclaration_AmpersandArray; procedure TTestFindDeclaration.TestFindDeclaration_AmpersandArray;

View File

@ -146,22 +146,26 @@ begin
+'{$I TestMethodJumpTool2.inc}'+LineEnding +'{$I TestMethodJumpTool2.inc}'+LineEnding
+'end.'+LineEnding; +'end.'+LineEnding;
IncCode:=CodeToolBoss.CreateFile('TestMethodJumpTool2.inc'); IncCode:=CodeToolBoss.CreateFile('TestMethodJumpTool2.inc');
IncCode.Source:='' try
+'{%MainUnit test1.pas}'+LineEnding IncCode.Source:=''
+'{$IFDEF UseInterface}'+LineEnding +'{%MainUnit test1.pas}'+LineEnding
+'procedure {ProcHeader}DoSomething;'+LineEnding +'{$IFDEF UseInterface}'+LineEnding
+'{$ENDIF}'+LineEnding +'procedure {ProcHeader}DoSomething;'+LineEnding
+'{$IFDEF UseImplementation}'+LineEnding +'{$ENDIF}'+LineEnding
+'procedure DoSomething;'+LineEnding +'{$IFDEF UseImplementation}'+LineEnding
+'begin'+LineEnding +'procedure DoSomething;'+LineEnding
+' {ProcBody}writeln;'+LineEnding +'begin'+LineEnding
+'end;'+LineEnding +' {ProcBody}writeln;'+LineEnding
+'{$ENDIF}'+LineEnding; +'end;'+LineEnding
+'{$ENDIF}'+LineEnding;
Test('Method jump from interface to implementation in one include file', Test('Method jump from interface to implementation in one include file',
IncCode,'ProcHeader',false,'ProcBody',true); IncCode,'ProcHeader',false,'ProcBody',true);
Test('Method jump from implementation to interface in one include file', Test('Method jump from implementation to interface in one include file',
IncCode,'ProcBody',false,'ProcHeader',false); IncCode,'ProcBody',false,'ProcHeader',false);
finally
IncCode.IsDeleted:=true;
end;
end; end;
procedure TTestMethodJumpTool.TestMethodJump_IntfToImplSingleProc; procedure TTestMethodJumpTool.TestMethodJump_IntfToImplSingleProc;

View File

@ -73,7 +73,6 @@ type
procedure TestRenameUsedUnit_Impl; procedure TestRenameUsedUnit_Impl;
procedure TestRenameUsedUnit_FN_KeepShort; procedure TestRenameUsedUnit_FN_KeepShort;
procedure TestRenameUsedUnit_InFilename; procedure TestRenameUsedUnit_InFilename;
// todo: rename uses Bar in 'bar.pas'
end; end;
implementation implementation
@ -1486,7 +1485,7 @@ var
begin begin
UsedUnit:=nil; UsedUnit:=nil;
try try
UsedUnit:=CodeToolBoss.CreateFile('type.pp'); UsedUnit:=CodeToolBoss.CreateFile('type.pas');
UsedUnit.Source:='unit &Type;'+LineEnding UsedUnit.Source:='unit &Type;'+LineEnding
+'interface'+LineEnding +'interface'+LineEnding
+'type'+LineEnding +'type'+LineEnding

View File

@ -223,21 +223,25 @@ var
i: Integer; i: Integer;
begin begin
Code:=CodeToolBoss.CreateFile('test1.pas'); Code:=CodeToolBoss.CreateFile('test1.pas');
s:=''; try
for i:=Low(Src) to High(Src) do s:='';
s+=Src[i]+LineEnding; for i:=Low(Src) to High(Src) do
Code.Source:=s; s+=Src[i]+LineEnding;
Code.Source:=s;
if not CodeToolBoss.AddUnitWarnDirective(Code,WarnID,Comment,TurnOn) then begin if not CodeToolBoss.AddUnitWarnDirective(Code,WarnID,Comment,TurnOn) then begin
WriteSource(Code.Filename,1,1); WriteSource(Code.Filename,1,1);
Fail(Title+'call AddUnitWarnDirective failed: '+CodeToolBoss.ErrorDbgMsg); Fail(Title+'call AddUnitWarnDirective failed: '+CodeToolBoss.ErrorDbgMsg);
end;
//debugln(['TTestCTStdCodetools.DoTestAddUnitWarn NewSrc=',Code.Source]);
s:='';
for i:=Low(Expected) to High(Expected) do
s+=Expected[i]+LineEnding;
CheckDiff(Title,s,Code.Source);
finally
Code.IsDeleted:=true;
end; end;
//debugln(['TTestCTStdCodetools.DoTestAddUnitWarn NewSrc=',Code.Source]);
s:='';
for i:=Low(Expected) to High(Expected) do
s+=Expected[i]+LineEnding;
CheckDiff(Title,s,Code.Source);
end; end;
procedure TTestCTStdCodetools.DoTestAddUnitToMainUses(NewUnitName, NewUnitInFilename, UsesSrc, ExpectedUsesSrc: string; procedure TTestCTStdCodetools.DoTestAddUnitToMainUses(NewUnitName, NewUnitInFilename, UsesSrc, ExpectedUsesSrc: string;
@ -253,19 +257,23 @@ begin
+'begin'+LineEnding +'begin'+LineEnding
+'end.'+LineEnding; +'end.'+LineEnding;
Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas'); Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas');
Code.Source:=Header+UsesSrc+Footer; try
if not CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(Code,NewUnitName,NewUnitInFilename,Flags) then Code.Source:=Header+UsesSrc+Footer;
begin if not CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(Code,NewUnitName,NewUnitInFilename,Flags) then
AssertEquals('AddUnitToMainUsesSectionIfNeeded failed: '+CodeToolBoss.ErrorMessage,true,false); begin
end else begin AssertEquals('AddUnitToMainUsesSectionIfNeeded failed: '+CodeToolBoss.ErrorMessage,true,false);
Src:=Code.Source; end else begin
AssertEquals('AddUnitToMainUsesSectionIfNeeded altered header: ',Header,LeftStr(Src,length(Header))); Src:=Code.Source;
System.Delete(Src,1,length(Header)); AssertEquals('AddUnitToMainUsesSectionIfNeeded altered header: ',Header,LeftStr(Src,length(Header)));
AssertEquals('AddUnitToMainUsesSectionIfNeeded altered footer: ',Footer,RightStr(Src,length(Footer))); System.Delete(Src,1,length(Header));
System.Delete(Src,length(Src)-length(Footer)+1,length(Footer)); AssertEquals('AddUnitToMainUsesSectionIfNeeded altered footer: ',Footer,RightStr(Src,length(Footer)));
if ExpectedUsesSrc<>Src then System.Delete(Src,length(Src)-length(Footer)+1,length(Footer));
debugln(Code.Source); if ExpectedUsesSrc<>Src then
AssertEquals('AddUnitToMainUsesSectionIfNeeded: ',ExpectedUsesSrc,Src); debugln(Code.Source);
AssertEquals('AddUnitToMainUsesSectionIfNeeded: ',ExpectedUsesSrc,Src);
end;
finally
Code.IsDeleted:=true;
end; end;
end; end;
@ -323,6 +331,7 @@ begin
Test('begin,try,finally,end|end','begin1','begin1end'); Test('begin,try,finally,end|end','begin1','begin1end');
Test('begin,try,finally,|end,end','try1finally','try1end'); Test('begin,try,finally,|end,end','try1finally','try1end');
Test('begin,try,finally,|end,end','try1','try1finally'); Test('begin,try,finally,|end,end','try1','try1finally');
Code.IsDeleted:=true;
end; end;
procedure TTestCTStdCodetools.TestCTUses_AddUses_Start; procedure TTestCTStdCodetools.TestCTUses_AddUses_Start;
@ -405,17 +414,21 @@ procedure TTestCTStdCodetools.TestCTUses_RemoveFromAllUsesSections;
+'begin'+LineEnding +'begin'+LineEnding
+'end.'+LineEnding; +'end.'+LineEnding;
Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas'); Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas');
Code.Source:=Header+UsesSrc+Footer; try
if not CodeToolBoss.RemoveUnitFromAllUsesSections(Code,RemoveUnit) then Code.Source:=Header+UsesSrc+Footer;
begin if not CodeToolBoss.RemoveUnitFromAllUsesSections(Code,RemoveUnit) then
AssertEquals('RemoveUnitFromAllUsesSections failed: '+CodeToolBoss.ErrorMessage,true,false); begin
end else begin AssertEquals('RemoveUnitFromAllUsesSections failed: '+CodeToolBoss.ErrorMessage,true,false);
Src:=Code.Source; end else begin
AssertEquals('RemoveUnitFromAllUsesSections altered header: ',Header,LeftStr(Src,length(Header))); Src:=Code.Source;
System.Delete(Src,1,length(Header)); AssertEquals('RemoveUnitFromAllUsesSections altered header: ',Header,LeftStr(Src,length(Header)));
AssertEquals('RemoveUnitFromAllUsesSections altered footer: ',Footer,RightStr(Src,length(Footer))); System.Delete(Src,1,length(Header));
System.Delete(Src,length(Src)-length(Footer)+1,length(Footer)); AssertEquals('RemoveUnitFromAllUsesSections altered footer: ',Footer,RightStr(Src,length(Footer)));
AssertEquals('RemoveUnitFromAllUsesSections: ',ExpectedUsesSrc,Src); System.Delete(Src,length(Src)-length(Footer)+1,length(Footer));
AssertEquals('RemoveUnitFromAllUsesSections: ',ExpectedUsesSrc,Src);
end;
finally
Code.IsDeleted:=true;
end; end;
end; end;
@ -524,22 +537,26 @@ procedure TTestCTStdCodetools.TestCTSetApplicationTitleStatement;
OldSrc:=Header+OldBeginEnd; OldSrc:=Header+OldBeginEnd;
ExpectedSrc:=Header+NewBeginEnd; ExpectedSrc:=Header+NewBeginEnd;
Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas'); Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas');
Code.Source:=OldSrc; try
if not CodeToolBoss.SetApplicationTitleStatement(Code,NewTitle) then Code.Source:=OldSrc;
begin if not CodeToolBoss.SetApplicationTitleStatement(Code,NewTitle) then
writeln('Src=['); begin
writeln(OldSrc,']'); writeln('Src=[');
AssertEquals('SetApplicationTitleStatement failed: '+CodeToolBoss.ErrorMessage,true,false); writeln(OldSrc,']');
end else begin AssertEquals('SetApplicationTitleStatement failed: '+CodeToolBoss.ErrorMessage,true,false);
ActualSrc:=Code.Source; end else begin
if ActualSrc=ExpectedSrc then exit; ActualSrc:=Code.Source;
writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement OldSrc:'); if ActualSrc=ExpectedSrc then exit;
writeln(OldSrc); writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement OldSrc:');
writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement NewTitle="',NewTitle,'" ExpectedSrc:'); writeln(OldSrc);
writeln(ExpectedSrc); writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement NewTitle="',NewTitle,'" ExpectedSrc:');
writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement But found NewSrc:'); writeln(ExpectedSrc);
writeln(ActualSrc); writeln('TTestCTStdCodetools.TestCTSetApplicationTitleStatement But found NewSrc:');
Fail('SetApplicationTitleStatement with Title="'+NewTitle+'"'); writeln(ActualSrc);
Fail('SetApplicationTitleStatement with Title="'+NewTitle+'"');
end;
finally
Code.IsDeleted:=true;
end; end;
end; end;