mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-11 05:00:24 +02:00
codetools: AddUnitToSpecificUsesSection for implementation, patch #18028
git-svn-id: trunk@28435 -
This commit is contained in:
parent
253ceab16b
commit
496151f6f8
@ -55,6 +55,8 @@ uses
|
||||
CustomCodeTool, CodeToolsStructs;
|
||||
|
||||
type
|
||||
TUsesSection = (usMain, usImplementation);
|
||||
|
||||
TOnFindDefinePropertyForContext = procedure(Sender: TObject;
|
||||
const ClassContext, AncestorClassContext: TFindContext;
|
||||
LFMNode: TLFMTreeNode;
|
||||
@ -88,9 +90,23 @@ type
|
||||
const NewUnitName, NewUnitInFile: string;
|
||||
SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
||||
function AddUnitToSpecificUsesSection(UsesSection: TUsesSection;
|
||||
const NewUnitName, NewUnitInFile: string;
|
||||
SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
||||
function AddUnitToMainUsesSection(const NewUnitName, NewUnitInFile: string;
|
||||
SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
||||
function AddUnitToImplementationUsesSection(const NewUnitName,
|
||||
NewUnitInFile: string;
|
||||
SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
||||
function UnitExistsInUsesSection(UsesSection: TUsesSection;
|
||||
const UpperUnitName: string;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
function UnitExistsInUsesSection(UsesNode: TCodeTreeNode;
|
||||
const UpperUnitName: string;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
function RemoveUnitFromUsesSection(UsesNode: TCodeTreeNode;
|
||||
const UpperUnitName: string;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
@ -890,16 +906,36 @@ end;
|
||||
function TStandardCodeTool.AddUnitToMainUsesSection(const NewUnitName,
|
||||
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
|
||||
var UsesNode, SectionNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=AddUnitToSpecificUsesSection(usMain, NewUnitName, NewUnitInFile, SourceChangeCache,
|
||||
AsLast, CheckSpecialUnits);
|
||||
end;
|
||||
|
||||
function TStandardCodeTool.AddUnitToImplementationUsesSection(const NewUnitName,
|
||||
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
|
||||
begin
|
||||
Result:=AddUnitToSpecificUsesSection(usImplementation, NewUnitName, NewUnitInFile, SourceChangeCache,
|
||||
AsLast, CheckSpecialUnits);
|
||||
end;
|
||||
|
||||
function TStandardCodeTool.AddUnitToSpecificUsesSection(UsesSection: TUsesSection;
|
||||
const NewUnitName, NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
|
||||
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
|
||||
var
|
||||
UsesNode, SectionNode: TCodeTreeNode;
|
||||
NewUsesTerm: string;
|
||||
InsertPos: integer;
|
||||
Junk : TAtomPosition;
|
||||
begin
|
||||
Result:=false;
|
||||
if (NewUnitName='') or (length(NewUnitName)>255) then exit;
|
||||
BuildTree(true);
|
||||
BuildTree(UsesSection=usMain);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
UsesNode:=FindMainUsesSection;
|
||||
case UsesSection Of
|
||||
usMain: UsesNode:=FindMainUsesSection;
|
||||
usImplementation: UsesNode:=FindImplementationUsesSection;
|
||||
end;
|
||||
if UsesNode<>nil then begin
|
||||
// add unit to existing uses section
|
||||
if not (FindUnitInUsesSection(UsesNode,UpperCaseStr(NewUnitName),Junk,Junk))
|
||||
@ -917,31 +953,48 @@ begin
|
||||
NewUsesTerm:='';
|
||||
if SectionNode.Desc=ctnUnit then begin
|
||||
// unit
|
||||
SectionNode:=FindInterfaceNode;
|
||||
if SectionNode=nil then begin
|
||||
// unit without interface section
|
||||
NewUsesTerm:=SourceChangeCache.BeautifyCodeOptions.BeautifyKeyWord('interface')
|
||||
+SourceChangeCache.BeautifyCodeOptions.LineEnd;
|
||||
case UsesSection of
|
||||
usMain: SectionNode:=FindInterfaceNode;
|
||||
usImplementation: SectionNode:=FindImplementationNode;
|
||||
end;
|
||||
if SectionNode<>nil then begin
|
||||
// add uses to existing interface/implementation behind title and directives
|
||||
if SectionNode.FirstChild<>nil then begin
|
||||
// section not empty => add in front of first node
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.FirstChild.StartPos,
|
||||
true);
|
||||
end else begin
|
||||
// section empty => add at end of interface section
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.EndPos,true);
|
||||
end;
|
||||
end else begin
|
||||
// insert behind interface keyword
|
||||
MoveCursorToNodeStart(SectionNode);
|
||||
ReadNextAtom;
|
||||
InsertPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos,false);
|
||||
// section is missing => add it
|
||||
SectionNode:=Tree.Root;
|
||||
case UsesSection of
|
||||
usMain: NewUsesTerm:='interface';
|
||||
usImplementation: NewUsesTerm:='implementation';
|
||||
end;
|
||||
NewUsesTerm:=SourceChangeCache.BeautifyCodeOptions.BeautifyKeyWord(NewUsesTerm)
|
||||
+SourceChangeCache.BeautifyCodeOptions.LineEnd;
|
||||
if SectionNode.FirstChild<>nil then begin
|
||||
// unit not empty => add in front of first node
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.FirstChild.StartPos,
|
||||
true);
|
||||
end else begin
|
||||
// unit empty => add at end
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.EndPos,true);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if InsertPos<1 then begin
|
||||
// insert after title and directives
|
||||
// not a unit (i.e. program)
|
||||
// => insert after title and directives
|
||||
if SectionNode.Next<>nil then begin
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.Next.StartPos,
|
||||
true);
|
||||
end else begin
|
||||
MoveCursorToNodeStart(SectionNode);
|
||||
ReadNextAtom; // read keyword
|
||||
ReadNextAtom; // read name
|
||||
ReadNextAtom; // read semicolon
|
||||
if CurPos.Flag<>cafSemicolon then
|
||||
RaiseCharExpectedButAtomFound(';');
|
||||
InsertPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos,true);
|
||||
// program empty => add at end
|
||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.EndPos,true);
|
||||
end;
|
||||
end;
|
||||
NewUsesTerm:=NewUsesTerm
|
||||
@ -958,6 +1011,53 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TStandardCodeTool.UnitExistsInUsesSection(UsesSection: TUsesSection;
|
||||
const UpperUnitName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var
|
||||
UsesNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
if (UpperUnitName='') or (length(UpperUnitName)>255) then
|
||||
exit;
|
||||
BuildTree(UsesSection=usMain);
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
case UsesSection Of
|
||||
usMain: UsesNode:=FindMainUsesSection;
|
||||
usImplementation: UsesNode:=FindImplementationUsesSection;
|
||||
end;
|
||||
Result:=UnitExistsInUsesSection(UsesNode,UpperUnitName,SourceChangeCache);
|
||||
end;
|
||||
|
||||
function TStandardCodeTool.UnitExistsInUsesSection(UsesNode: TCodeTreeNode;
|
||||
const UpperUnitName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var
|
||||
UnitCount: integer;
|
||||
begin
|
||||
Result:=false;
|
||||
if (UsesNode=nil) or (UpperUnitName='') or (length(UpperUnitName)>255) then
|
||||
exit;
|
||||
MoveCursorToNodeStart(UsesNode);
|
||||
ReadNextAtom; // read 'uses'
|
||||
UnitCount:=0;
|
||||
repeat
|
||||
ReadNextAtom; // read name
|
||||
if not AtomIsIdentifier(false) then exit;
|
||||
inc(UnitCount);
|
||||
if UpAtomIs(UpperUnitName) then begin
|
||||
// unit found
|
||||
Result:=true;
|
||||
exit;
|
||||
end;
|
||||
ReadNextAtom;
|
||||
if UpAtomIs('IN') then begin
|
||||
ReadNextAtom;
|
||||
ReadNextAtom;
|
||||
end;
|
||||
if AtomIsChar(';') then break;
|
||||
if not AtomIsChar(',') then break;
|
||||
until (CurPos.StartPos>UsesNode.EndPos) or (CurPos.StartPos>SrcLen);
|
||||
end;
|
||||
|
||||
function TStandardCodeTool.RemoveUnitFromUsesSection(UsesNode: TCodeTreeNode;
|
||||
const UpperUnitName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var UnitCount, StartPos, EndPos: integer;
|
||||
|
Loading…
Reference in New Issue
Block a user