codetools: AddUnitToMainUsesSection using flags, test

git-svn-id: trunk@63404 -
This commit is contained in:
mattias 2020-06-20 15:52:42 +00:00
parent 5bb7d9bdd1
commit 665ab3cba6
4 changed files with 187 additions and 48 deletions

View File

@ -708,13 +708,22 @@ type
UnitNamePairs: TStringToStringTree): boolean;
function AddUnitToMainUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
const Flags: TAddUsesFlags = []): boolean; overload;
function AddUnitToMainUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean; CheckSpecialUnits: boolean = true): boolean; overload; deprecated;
function AddUnitToMainUsesSectionIfNeeded(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
const Flags: TAddUsesFlags = []): boolean;
function AddUnitToMainUsesSectionIfNeeded(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean; CheckSpecialUnits: boolean = true): boolean; overload; deprecated;
function AddUnitToImplementationUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
const Flags: TAddUsesFlags = []): boolean;
function AddUnitToImplementationUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string;
AsLast: boolean; CheckSpecialUnits: boolean = true): boolean; overload; deprecated;
function RemoveUnitFromAllUsesSections(Code: TCodeBuffer;
const AnUnitName: string): boolean;
function FindUsedUnitFiles(Code: TCodeBuffer; var MainUsesSection: TStrings
@ -5056,8 +5065,8 @@ begin
end;
function TCodeToolManager.AddUnitToMainUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; AsLast: boolean;
CheckSpecialUnits: boolean = true): boolean;
const NewUnitName, NewUnitInFile: string; const Flags: TAddUsesFlags
): boolean;
begin
Result:=false;
{$IFDEF CTDEBUG}
@ -5066,15 +5075,27 @@ begin
if not InitCurCodeTool(Code) then exit;
try
Result:=FCurCodeTool.AddUnitToMainUsesSection(NewUnitName, NewUnitInFile,
SourceChangeCache,AsLast,CheckSpecialUnits);
SourceChangeCache,Flags);
except
on e: Exception do Result:=HandleException(e);
end;
end;
function TCodeToolManager.AddUnitToMainUsesSectionIfNeeded(Code: TCodeBuffer;
function TCodeToolManager.AddUnitToMainUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; AsLast: boolean;
CheckSpecialUnits: boolean): boolean;
CheckSpecialUnits: boolean = true): boolean;
var
Flags: TAddUsesFlags;
begin
Flags:=[];
if AsLast then Include(Flags,aufLast);
if not CheckSpecialUnits then Include(Flags,aufNotCheckSpecialUnit);
Result:=AddUnitToMainUsesSection(Code,NewUnitName,NewUnitInFile,Flags);
end;
function TCodeToolManager.AddUnitToMainUsesSectionIfNeeded(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; const Flags: TAddUsesFlags
): boolean;
var
NamePos, InPos: TAtomPosition;
begin
@ -5086,15 +5107,27 @@ begin
try
if not FCurCodeTool.FindUnitInAllUsesSections(NewUnitName,NamePos,InPos) then
Result:=FCurCodeTool.AddUnitToMainUsesSection(NewUnitName, NewUnitInFile,
SourceChangeCache,AsLast,CheckSpecialUnits);
SourceChangeCache,Flags);
except
on e: Exception do Result:=HandleException(e);
end;
end;
function TCodeToolManager.AddUnitToImplementationUsesSection(Code: TCodeBuffer;
function TCodeToolManager.AddUnitToMainUsesSectionIfNeeded(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; AsLast: boolean;
CheckSpecialUnits: boolean): boolean;
var
Flags: TAddUsesFlags;
begin
Flags:=[];
if AsLast then Include(Flags,aufLast);
if not CheckSpecialUnits then Include(Flags,aufNotCheckSpecialUnit);
Result:=AddUnitToMainUsesSectionIfNeeded(Code,NewUnitName,NewUnitInFile,Flags);
end;
function TCodeToolManager.AddUnitToImplementationUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; const Flags: TAddUsesFlags
): boolean;
begin
Result:=false;
{$IFDEF CTDEBUG}
@ -5104,12 +5137,24 @@ begin
try
Result:=FCurCodeTool.AddUnitToImplementationUsesSection(
NewUnitName, NewUnitInFile,
SourceChangeCache,AsLast,CheckSpecialUnits);
SourceChangeCache,Flags);
except
on e: Exception do Result:=HandleException(e);
end;
end;
function TCodeToolManager.AddUnitToImplementationUsesSection(Code: TCodeBuffer;
const NewUnitName, NewUnitInFile: string; AsLast: boolean;
CheckSpecialUnits: boolean): boolean;
var
Flags: TAddUsesFlags;
begin
Flags:=[];
if AsLast then Include(Flags,aufLast);
if not CheckSpecialUnits then Include(Flags,aufNotCheckSpecialUnit);
Result:=AddUnitToImplementationUsesSection(Code,NewUnitName,NewUnitInFile,Flags);
end;
function TCodeToolManager.RemoveUnitFromAllUsesSections(Code: TCodeBuffer;
const AnUnitName: string): boolean;
begin

View File

@ -72,6 +72,11 @@ type
end;
TUsesSection = (usMain, usImplementation);
TAddUsesFlag = (
aufLast,
aufNotCheckSpecialUnit
);
TAddUsesFlags = set of TAddUsesFlag;
TOnFindDefinePropertyForContext = procedure(Sender: TObject;
const ClassContext, AncestorClassContext: TFindContext;
@ -112,18 +117,14 @@ type
SourceChangeCache: TSourceChangeCache): boolean;
function AddUnitToUsesSection(UsesNode: TCodeTreeNode;
const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags = []): boolean;
function AddUnitToSpecificUsesSection(UsesSection: TUsesSection;
const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags = []): boolean;
function AddUnitToMainUsesSection(const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags = []): boolean;
function AddUnitToImplementationUsesSection(const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache;
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags = []): boolean;
function UnitExistsInUsesSection(UsesSection: TUsesSection;
const AnUnitName: string): boolean;
function UnitExistsInUsesSection(UsesNode: TCodeTreeNode;
@ -632,8 +633,7 @@ end;
function TStandardCodeTool.AddUnitToUsesSection(UsesNode: TCodeTreeNode;
const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache; AsLast: boolean;
CheckSpecialUnits: boolean): boolean;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags): boolean;
const
SpecialUnits: array[1..5] of string = (
'cmem',
@ -732,7 +732,7 @@ var
UsesInsertPolicy: TUsesInsertPolicy;
Prio: LongInt;
FirstNormalUsesNode: TCodeTreeNode;
InsertPosFound: Boolean;
InsertPosFound, CheckSpecialUnits: Boolean;
begin
Result:=false;
if (UsesNode=nil) or (UsesNode.Desc<>ctnUsesSection)
@ -746,9 +746,10 @@ begin
Prio:=SpecialUnitPriority(PChar(NewUnitName));
UsesInsertPolicy:=Beauty.UsesInsertPolicy;
if AsLast then
if aufLast in Flags then
UsesInsertPolicy:=uipLast;
InsertPosFound:=false;
CheckSpecialUnits:=not (aufNotCheckSpecialUnit in Flags);
if CheckSpecialUnits and (Prio<=High(SpecialUnits)) then begin
// this is a special unit, insert at the beginning
InsertBehind:=false;
@ -940,23 +941,23 @@ end;
function TStandardCodeTool.AddUnitToMainUsesSection(const NewUnitName,
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
const Flags: TAddUsesFlags): boolean;
begin
Result:=AddUnitToSpecificUsesSection(usMain, NewUnitName, NewUnitInFile, SourceChangeCache,
AsLast, CheckSpecialUnits);
Result:=AddUnitToSpecificUsesSection(usMain, NewUnitName, NewUnitInFile,
SourceChangeCache, Flags);
end;
function TStandardCodeTool.AddUnitToImplementationUsesSection(const NewUnitName,
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
function TStandardCodeTool.AddUnitToImplementationUsesSection(
const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags): boolean;
begin
Result:=AddUnitToSpecificUsesSection(usImplementation, NewUnitName, NewUnitInFile, SourceChangeCache,
AsLast, CheckSpecialUnits);
Result:=AddUnitToSpecificUsesSection(usImplementation,
NewUnitName, NewUnitInFile, SourceChangeCache, Flags);
end;
function TStandardCodeTool.AddUnitToSpecificUsesSection(UsesSection: TUsesSection;
const NewUnitName, NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
function TStandardCodeTool.AddUnitToSpecificUsesSection(
UsesSection: TUsesSection; const NewUnitName, NewUnitInFile: string;
SourceChangeCache: TSourceChangeCache; const Flags: TAddUsesFlags): boolean;
var
UsesNode, OtherUsesNode, SectionNode, Node: TCodeTreeNode;
NewUsesTerm: string;
@ -1001,7 +1002,7 @@ begin
if not (FindUnitInUsesSection(UsesNode,NewUnitName,Junk,Junk))
then begin
if not AddUnitToUsesSection(UsesNode,NewUnitName,NewUnitInFile,
SourceChangeCache,AsLast,CheckSpecialUnits)
SourceChangeCache,Flags)
then
exit;
end;

View File

@ -12,7 +12,7 @@ interface
uses
Classes, SysUtils, LazLoggerBase, fpcunit, testregistry,
CodeToolManager, StdCodeTools, CodeCache, LinkScanner;
CodeToolManager, StdCodeTools, CodeCache, LinkScanner, SourceChanger;
type
@ -32,12 +32,19 @@ type
private
procedure DoTestAddUnitWarn(Title: string; Src, Expected: array of string;
WarnID, Comment: string; TurnOn: boolean);
procedure DoTestAddUnitToMainUses(NewUnitName, NewUnitInFilename,
UsesSrc, ExpectedUsesSrc: string; const Flags: TAddUsesFlags);
published
procedure TestCTStdFindBlockStart;
procedure TestCTRemoveUnitFromAllUsesSections;
procedure TestCTAddUnitWarnProgram;
procedure TestCTAddUnitWarnProgramNoName;
procedure TestCTAddUnitWarnUnit;
procedure TestCTUses_AddUses_Start;
procedure TestCTUses_AddUses_Append;
procedure TestCTUses_AddUses_AppendKeepSpaces;
procedure TestCTUses_AddUses_AppendKeepComment; // ToDo
procedure TestCTUses_AddUses_Append_DottedNoBreak;
procedure TestCTUses_RemoveFromAllUsesSections;
procedure TestCTAddWarn5025_Program;
procedure TestCTAddWarn5025_ProgramNoName;
procedure TestCTAddWarn5025_Unit;
end;
implementation
@ -222,6 +229,35 @@ begin
CheckDiff(Title,s,Code.Source);
end;
procedure TTestCTStdCodetools.DoTestAddUnitToMainUses(NewUnitName, NewUnitInFilename, UsesSrc, ExpectedUsesSrc: string;
const Flags: TAddUsesFlags);
var
Header: String;
Footer: String;
Code: TCodeBuffer;
Src: String;
begin
Header:='program TestStdCodeTools;'+LineEnding;
Footer:=LineEnding
+'begin'+LineEnding
+'end.'+LineEnding;
Code:=CodeToolBoss.CreateFile('TestStdCodeTools.pas');
Code.Source:=Header+UsesSrc+Footer;
if not CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(Code,NewUnitName,NewUnitInFilename,Flags) then
begin
AssertEquals('AddUnitToMainUsesSectionIfNeeded failed: '+CodeToolBoss.ErrorMessage,true,false);
end else begin
Src:=Code.Source;
AssertEquals('AddUnitToMainUsesSectionIfNeeded altered header: ',Header,LeftStr(Src,length(Header)));
System.Delete(Src,1,length(Header));
AssertEquals('AddUnitToMainUsesSectionIfNeeded altered footer: ',Footer,RightStr(Src,length(Footer)));
System.Delete(Src,length(Src)-length(Footer)+1,length(Footer));
if ExpectedUsesSrc<>Src then
debugln(Code.Source);
AssertEquals('AddUnitToMainUsesSectionIfNeeded: ',ExpectedUsesSrc,Src);
end;
end;
procedure TTestCTStdCodetools.TestCTStdFindBlockStart;
var
Code: TCodeBuffer;
@ -278,12 +314,69 @@ begin
Test('begin,try,finally,|end,end','try1','try1finally');
end;
procedure TTestCTStdCodetools.TestCTRemoveUnitFromAllUsesSections;
procedure TTestCTStdCodetools.TestCTUses_AddUses_Start;
begin
DoTestAddUnitToMainUses('Foo','',
'',
LineEnding+'uses Foo;'+LineEnding,
[]);
end;
procedure TTestCTStdCodetools.TestCTUses_AddUses_Append;
begin
DoTestAddUnitToMainUses('Foo','',
'uses Abc;'+LineEnding,
'uses Abc, Foo;'+LineEnding,
[]);
end;
procedure TTestCTStdCodetools.TestCTUses_AddUses_AppendKeepSpaces;
begin
DoTestAddUnitToMainUses('Foo','',
'uses Go, Bla;'+LineEnding,
'uses Go, Bla, Foo;'+LineEnding,
[]);
end;
procedure TTestCTStdCodetools.TestCTUses_AddUses_AppendKeepComment;
begin
exit;
DoTestAddUnitToMainUses('Foo','',
'uses Go, {Comment} Bla;'+LineEnding,
'uses Go, {Comment} Bla, Foo;'+LineEnding,
[]);
end;
procedure TTestCTStdCodetools.TestCTUses_AddUses_Append_DottedNoBreak;
var
Beauty: TBeautifyCodeOptions;
OldLineLength: Integer;
OldDoNotSplitLineInFront: TAtomTypes;
begin
Beauty:=CodeToolBoss.SourceChangeCache.BeautifyCodeOptions;
OldLineLength:=Beauty.LineLength;
OldDoNotSplitLineInFront:=Beauty.DoNotSplitLineInFront;
try
Beauty.LineLength:=35;
Beauty.DoNotSplitLineInFront:=Beauty.DoNotSplitLineInFront+[atPoint];// test that atPoint has no effect
DoTestAddUnitToMainUses('System.SysUtils','',
'uses System.Classes;'+LineEnding,
'uses System.Classes,'+LineEnding
+' System.SysUtils;'+LineEnding,
[]);
finally
Beauty.LineLength:=OldLineLength;
Beauty.DoNotSplitLineInFront:=OldDoNotSplitLineInFront;
end;
end;
procedure TTestCTStdCodetools.TestCTUses_RemoveFromAllUsesSections;
function GetSource(UsesSrc: string): string;
begin
Result:='program TestStdCodeTools;'+LineEnding
+UsesSrc
+UsesSrc;
end;
procedure Test(RemoveUnit, UsesSrc, ExpectedUsesSrc: string);
@ -293,7 +386,7 @@ procedure TTestCTStdCodetools.TestCTRemoveUnitFromAllUsesSections;
Code: TCodeBuffer;
Src: String;
begin
Header:='program TestStdCodeTools;'+LineEnding;
Header:=GetSource('');
Footer:=LineEnding
+'begin'+LineEnding
+'end.'+LineEnding;
@ -369,7 +462,7 @@ begin
);
end;
procedure TTestCTStdCodetools.TestCTAddUnitWarnProgram;
procedure TTestCTStdCodetools.TestCTAddWarn5025_Program;
begin
DoTestAddUnitWarn(
'TestCTAddUnitWarn',
@ -382,7 +475,7 @@ begin
,'end.'],'5025','',false);
end;
procedure TTestCTStdCodetools.TestCTAddUnitWarnProgramNoName;
procedure TTestCTStdCodetools.TestCTAddWarn5025_ProgramNoName;
begin
DoTestAddUnitWarn(
'TestCTAddUnitWarn',
@ -393,7 +486,7 @@ begin
,'end.'],'5025','',false);
end;
procedure TTestCTStdCodetools.TestCTAddUnitWarnUnit;
procedure TTestCTStdCodetools.TestCTAddWarn5025_Unit;
begin
DoTestAddUnitWarn(
'TestCTAddUnitWarn',

View File

@ -52,7 +52,7 @@ uses
LCLProc, Forms, Controls, Dialogs,
// CodeTools
CodeToolsConfig, ExprEval, DefineTemplates, BasicCodeTools, CodeToolsCfgScript,
LinkScanner, CodeToolManager, CodeCache, CodeTree, FileProcs,
LinkScanner, CodeToolManager, CodeCache, CodeTree, FileProcs, StdCodeTools,
// LazUtils
FPCAdds, LazUtilities, FileUtil, LazFileUtils, LazFileCache, LazMethodList,
LazLoggerBase, LazUTF8, Laz2_XMLCfg, Maps,
@ -3622,7 +3622,7 @@ begin
begin
s:=AnUnit.GetUsesUnitName;
if s<>'' then // add unit to uses section
CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(MainUnitInfo.Source,s,'',true);
CodeToolBoss.AddUnitToMainUsesSectionIfNeeded(MainUnitInfo.Source,s,'',[aufLast]);
end;
EndUpdate;
UnitModified(AnUnit);