mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-14 09:01:01 +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;
|
CustomCodeTool, CodeToolsStructs;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
TUsesSection = (usMain, usImplementation);
|
||||||
|
|
||||||
TOnFindDefinePropertyForContext = procedure(Sender: TObject;
|
TOnFindDefinePropertyForContext = procedure(Sender: TObject;
|
||||||
const ClassContext, AncestorClassContext: TFindContext;
|
const ClassContext, AncestorClassContext: TFindContext;
|
||||||
LFMNode: TLFMTreeNode;
|
LFMNode: TLFMTreeNode;
|
||||||
@ -88,9 +90,23 @@ type
|
|||||||
const NewUnitName, NewUnitInFile: string;
|
const NewUnitName, NewUnitInFile: string;
|
||||||
SourceChangeCache: TSourceChangeCache;
|
SourceChangeCache: TSourceChangeCache;
|
||||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
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;
|
function AddUnitToMainUsesSection(const NewUnitName, NewUnitInFile: string;
|
||||||
SourceChangeCache: TSourceChangeCache;
|
SourceChangeCache: TSourceChangeCache;
|
||||||
AsLast: boolean = false; CheckSpecialUnits: boolean = true): boolean;
|
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;
|
function RemoveUnitFromUsesSection(UsesNode: TCodeTreeNode;
|
||||||
const UpperUnitName: string;
|
const UpperUnitName: string;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
@ -890,16 +906,36 @@ end;
|
|||||||
function TStandardCodeTool.AddUnitToMainUsesSection(const NewUnitName,
|
function TStandardCodeTool.AddUnitToMainUsesSection(const NewUnitName,
|
||||||
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
|
NewUnitInFile: string; SourceChangeCache: TSourceChangeCache;
|
||||||
AsLast: boolean; CheckSpecialUnits: boolean): boolean;
|
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;
|
NewUsesTerm: string;
|
||||||
InsertPos: integer;
|
InsertPos: integer;
|
||||||
Junk : TAtomPosition;
|
Junk : TAtomPosition;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if (NewUnitName='') or (length(NewUnitName)>255) then exit;
|
if (NewUnitName='') or (length(NewUnitName)>255) then exit;
|
||||||
BuildTree(true);
|
BuildTree(UsesSection=usMain);
|
||||||
SourceChangeCache.MainScanner:=Scanner;
|
SourceChangeCache.MainScanner:=Scanner;
|
||||||
UsesNode:=FindMainUsesSection;
|
case UsesSection Of
|
||||||
|
usMain: UsesNode:=FindMainUsesSection;
|
||||||
|
usImplementation: UsesNode:=FindImplementationUsesSection;
|
||||||
|
end;
|
||||||
if UsesNode<>nil then begin
|
if UsesNode<>nil then begin
|
||||||
// add unit to existing uses section
|
// add unit to existing uses section
|
||||||
if not (FindUnitInUsesSection(UsesNode,UpperCaseStr(NewUnitName),Junk,Junk))
|
if not (FindUnitInUsesSection(UsesNode,UpperCaseStr(NewUnitName),Junk,Junk))
|
||||||
@ -917,31 +953,48 @@ begin
|
|||||||
NewUsesTerm:='';
|
NewUsesTerm:='';
|
||||||
if SectionNode.Desc=ctnUnit then begin
|
if SectionNode.Desc=ctnUnit then begin
|
||||||
// unit
|
// unit
|
||||||
SectionNode:=FindInterfaceNode;
|
case UsesSection of
|
||||||
if SectionNode=nil then begin
|
usMain: SectionNode:=FindInterfaceNode;
|
||||||
// unit without interface section
|
usImplementation: SectionNode:=FindImplementationNode;
|
||||||
NewUsesTerm:=SourceChangeCache.BeautifyCodeOptions.BeautifyKeyWord('interface')
|
end;
|
||||||
+SourceChangeCache.BeautifyCodeOptions.LineEnd;
|
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
|
end else begin
|
||||||
// insert behind interface keyword
|
// section is missing => add it
|
||||||
MoveCursorToNodeStart(SectionNode);
|
SectionNode:=Tree.Root;
|
||||||
ReadNextAtom;
|
case UsesSection of
|
||||||
InsertPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos,false);
|
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;
|
||||||
end;
|
end;
|
||||||
if InsertPos<1 then begin
|
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
|
if SectionNode.Next<>nil then begin
|
||||||
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.Next.StartPos,
|
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.Next.StartPos,
|
||||||
true);
|
true);
|
||||||
end else begin
|
end else begin
|
||||||
MoveCursorToNodeStart(SectionNode);
|
// program empty => add at end
|
||||||
ReadNextAtom; // read keyword
|
InsertPos:=FindLineEndOrCodeInFrontOfPosition(SectionNode.EndPos,true);
|
||||||
ReadNextAtom; // read name
|
|
||||||
ReadNextAtom; // read semicolon
|
|
||||||
if CurPos.Flag<>cafSemicolon then
|
|
||||||
RaiseCharExpectedButAtomFound(';');
|
|
||||||
InsertPos:=FindLineEndOrCodeAfterPosition(CurPos.EndPos,true);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
NewUsesTerm:=NewUsesTerm
|
NewUsesTerm:=NewUsesTerm
|
||||||
@ -958,6 +1011,53 @@ begin
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
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;
|
function TStandardCodeTool.RemoveUnitFromUsesSection(UsesNode: TCodeTreeNode;
|
||||||
const UpperUnitName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
const UpperUnitName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var UnitCount, StartPos, EndPos: integer;
|
var UnitCount, StartPos, EndPos: integer;
|
||||||
|
Loading…
Reference in New Issue
Block a user