mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-31 05:20:31 +02:00
codetools: class completion: copy one method changes to body
git-svn-id: trunk@18045 -
This commit is contained in:
parent
ff31b3a753
commit
ad86924500
@ -5478,10 +5478,10 @@ end;
|
||||
|
||||
function TCodeCompletionCodeTool.CreateMissingProcBodies: boolean;
|
||||
var
|
||||
Indent, InsertPos: integer;
|
||||
TheClassName: string;
|
||||
|
||||
procedure InsertProcBody(ANodeExt: TCodeTreeNodeExtension);
|
||||
procedure InsertProcBody(ANodeExt: TCodeTreeNodeExtension;
|
||||
InsertPos, Indent: integer);
|
||||
var ProcCode: string;
|
||||
begin
|
||||
if ANodeExt.ExtTxt3<>'' then
|
||||
@ -5508,7 +5508,8 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CreateCodeForMissingProcBody(TheNodeExt: TCodeTreeNodeExtension);
|
||||
procedure CreateCodeForMissingProcBody(TheNodeExt: TCodeTreeNodeExtension;
|
||||
Indent: integer);
|
||||
var
|
||||
ANode: TCodeTreeNode;
|
||||
ProcCode: string;
|
||||
@ -5597,7 +5598,7 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CheckForChangedProcs;
|
||||
function CheckForChangedProcs: boolean;
|
||||
var
|
||||
BodyAVLNode: TAVLTreeNode;
|
||||
BodyNodeExt: TCodeTreeNodeExtension;
|
||||
@ -5605,7 +5606,13 @@ var
|
||||
DefsWithoutBodies: TAVLTree;
|
||||
DefAVLNode: TAVLTreeNode;
|
||||
DefNodeExt: TCodeTreeNodeExtension;
|
||||
InsertPos: LongInt;
|
||||
Indent: LongInt;
|
||||
BodyProcHeadNode: TCodeTreeNode;
|
||||
InsertEndPos: LongInt;
|
||||
ProcCode: String;
|
||||
begin
|
||||
Result:=false;
|
||||
BodiesWithoutDefs:=nil;
|
||||
DefsWithoutBodies:=nil;
|
||||
try
|
||||
@ -5624,24 +5631,57 @@ var
|
||||
DefAVLNode:=ClassProcs.FindLowest;
|
||||
while DefAVLNode<>nil do begin
|
||||
DefNodeExt:=TCodeTreeNodeExtension(DefAVLNode.Data);
|
||||
DefAVLNode:=ClassProcs.FindSuccessor(DefAVLNode);
|
||||
if ProcBodyNodes.Find(DefNodeExt)=nil then begin
|
||||
// move proc definition from ClassProcs to DefsWithoutBodies
|
||||
DefsWithoutBodies:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||
DefsWithoutBodies.Add(DefNodeExt);
|
||||
end;
|
||||
DefAVLNode:=ClassProcs.FindSuccessor(DefAVLNode);
|
||||
end;
|
||||
if DefsWithoutBodies=nil then exit;
|
||||
if BodiesWithoutDefs.Count<>DefsWithoutBodies.Count then exit;
|
||||
|
||||
// there is the same amount of bodies without a def and defs without bodies
|
||||
// => try to create a mapping
|
||||
|
||||
|
||||
// => try to create a mapping from defs to bodies
|
||||
if DefsWithoutBodies.Count=1 then begin
|
||||
// only one method def changed
|
||||
BodyNodeExt:=TCodeTreeNodeExtension(BodiesWithoutDefs.FindLowest.Data);
|
||||
DefNodeExt:=TCodeTreeNodeExtension(DefsWithoutBodies.FindLowest.Data);
|
||||
DefNodeExt.Data:=BodyNodeExt;
|
||||
end else begin
|
||||
// no mapping found
|
||||
// => warn user
|
||||
ANode:=TCodeTreeNodeExtension(BodiesWithoutDefs.FindLowest.Data).Node;
|
||||
MoveCursorToNodeStart(ANode.FirstChild);
|
||||
RaiseException('procedure has no definition in the class');
|
||||
end;
|
||||
|
||||
// replace body proc head(s) with class proc head(s)
|
||||
DefAVLNode:=DefsWithoutBodies.FindLowest;
|
||||
while DefAVLNode<>nil do begin
|
||||
DefNodeExt:=TCodeTreeNodeExtension(DefAVLNode.Data);
|
||||
BodyNodeExt:=TCodeTreeNodeExtension(DefNodeExt.Data);
|
||||
BodyNodeExt.Txt:=DefNodeExt.Txt;
|
||||
BodyProcHeadNode:=BodyNodeExt.Node.FirstChild;
|
||||
InsertPos:=BodyNodeExt.Node.StartPos;
|
||||
InsertEndPos:=BodyProcHeadNode.EndPos;
|
||||
Indent:=GetLineIndent(Src,InsertPos);
|
||||
ProcCode:=ExtractProcHead(DefNodeExt.Node,[phpWithStart,
|
||||
phpAddClassname,phpWithVarModifiers,
|
||||
phpWithParameterNames,phpWithResultType,phpWithCallingSpecs,
|
||||
phpWithoutSemicolon]);
|
||||
ProcCode:=ASourceChangeCache.BeautifyCodeOptions.BeautifyProc(
|
||||
ProcCode,Indent,false);
|
||||
//debugln(['CheckForChangedProcs OLD=',copy(Src,InsertPos,InsertEndPos-InsertPos),' New=',ProcCode]);
|
||||
if not ASourceChangeCache.Replace(gtNone,gtNone,InsertPos,InsertEndPos,ProcCode) then
|
||||
exit;
|
||||
DefAVLNode:=DefsWithoutBodies.FindSuccessor(DefAVLNode);
|
||||
end;
|
||||
finally
|
||||
BodiesWithoutDefs.Free;
|
||||
DefsWithoutBodies.Free;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure RemoveAbstractMethods;
|
||||
@ -5660,8 +5700,10 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure FindInsertPointForNewClass;
|
||||
procedure FindInsertPointForNewClass(out InsertPos, Indent: LongInt);
|
||||
begin
|
||||
InsertPos:=0;
|
||||
Indent:=0;
|
||||
if NodeHasParentOfType(FCodeCompleteClassNode,ctnInterface) then begin
|
||||
// class is in interface section
|
||||
// -> insert at the end of the implementation section
|
||||
@ -5692,7 +5734,7 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure InsertClassMethodsComment;
|
||||
procedure InsertClassMethodsComment(InsertPos, Indent: integer);
|
||||
var
|
||||
CommentStart, CommentEnd: TCodeXYPosition;
|
||||
begin
|
||||
@ -5713,6 +5755,9 @@ var
|
||||
ClassStartComment);
|
||||
end;
|
||||
|
||||
var
|
||||
InsertPos: integer;
|
||||
Indent: integer;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeCompletionCodeTool.CreateMissingProcBodies Gather existing method bodies ... ');
|
||||
@ -5744,7 +5789,7 @@ begin
|
||||
CheckForDoubleDefinedMethods;
|
||||
|
||||
// check for changed procs (existing proc bodies without definitions in the class)
|
||||
CheckForChangedProcs;
|
||||
if not CheckForChangedProcs then exit;
|
||||
|
||||
// remove abstract methods
|
||||
RemoveAbstractMethods;
|
||||
@ -5806,15 +5851,15 @@ begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TCodeCompletionCodeTool.CreateMissingProcBodies Starting class in implementation ');
|
||||
{$ENDIF}
|
||||
FindInsertPointForNewClass;
|
||||
InsertClassMethodsComment;
|
||||
FindInsertPointForNewClass(InsertPos,Indent);
|
||||
InsertClassMethodsComment(InsertPos,Indent);
|
||||
|
||||
// insert all proc bodies
|
||||
MissingNode:=ClassProcs.FindHighest;
|
||||
while (MissingNode<>nil) do begin
|
||||
ANodeExt:=TCodeTreeNodeExtension(MissingNode.Data);
|
||||
CreateCodeForMissingProcBody(ANodeExt);
|
||||
InsertProcBody(ANodeExt);
|
||||
CreateCodeForMissingProcBody(ANodeExt,Indent);
|
||||
InsertProcBody(ANodeExt,InsertPos,Indent);
|
||||
MissingNode:=ClassProcs.FindPrecessor(MissingNode);
|
||||
end;
|
||||
|
||||
@ -5838,6 +5883,7 @@ begin
|
||||
ExistingNode:=ProcBodyNodes.Find(MissingNode.Data);
|
||||
//DebugLn(['TCodeCompletionCodeTool.CreateMissingProcBodies ANodeExt.Txt=',ANodeExt.Txt,' ExistingNode=',ExistingNode<>nil]);
|
||||
if ExistingNode=nil then begin
|
||||
//DebugLn(['TCodeCompletionCodeTool.CreateMissingProcBodies ANodeExt.Txt=',ANodeExt.Txt,' ExistingNode=',TCodeTreeNodeExtension(ExistingNode.Data).Txt]);
|
||||
// MissingNode does not have a body -> insert proc body
|
||||
case MethodInsertPolicy of
|
||||
mipAlphabetically:
|
||||
@ -5902,8 +5948,8 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
CreateCodeForMissingProcBody(ANodeExt);
|
||||
InsertProcBody(ANodeExt);
|
||||
CreateCodeForMissingProcBody(ANodeExt,Indent);
|
||||
InsertProcBody(ANodeExt,InsertPos,Indent);
|
||||
end;
|
||||
MissingNode:=ClassProcs.FindPrecessor(MissingNode);
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user