mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 11:39:19 +02:00
codetools: fixed class completion for new public methods without context
git-svn-id: trunk@23312 -
This commit is contained in:
parent
a35c06eeb7
commit
20f8159dce
@ -2498,7 +2498,7 @@ begin
|
|||||||
AVLNode:=TreeOfCodeTreeNodeExt.FindLowest;
|
AVLNode:=TreeOfCodeTreeNodeExt.FindLowest;
|
||||||
while AVLNode<>nil do begin
|
while AVLNode<>nil do begin
|
||||||
Node:=TCodeTreeNodeExtension(AVLNode.Data).Node;
|
Node:=TCodeTreeNodeExtension(AVLNode.Data).Node;
|
||||||
DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions AAA1 ',GetRedefinitionNodeText(Node)]);
|
//DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions add to NodesToDo ',GetRedefinitionNodeText(Node)]);
|
||||||
NodesToDo.Add(Node);
|
NodesToDo.Add(Node);
|
||||||
AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
|
AVLNode:=TreeOfCodeTreeNodeExt.FindSuccessor(AVLNode);
|
||||||
end;
|
end;
|
||||||
@ -2507,7 +2507,7 @@ begin
|
|||||||
while NodesToDo.Count>0 do begin
|
while NodesToDo.Count>0 do begin
|
||||||
// find a block of redefinitions
|
// find a block of redefinitions
|
||||||
StartNode:=TCodeTreeNode(NodesToDo.Root.Data);
|
StartNode:=TCodeTreeNode(NodesToDo.Root.Data);
|
||||||
DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions ',StartNode.StartPos,' ',GetRedefinitionNodeText(StartNode)]);
|
//DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions StartNode=',StartNode.StartPos,' ',GetRedefinitionNodeText(StartNode)]);
|
||||||
EndNode:=StartNode;
|
EndNode:=StartNode;
|
||||||
while (StartNode.PriorBrother<>nil)
|
while (StartNode.PriorBrother<>nil)
|
||||||
and (NodesToDo.Find(StartNode.PriorBrother)<>nil) do
|
and (NodesToDo.Find(StartNode.PriorBrother)<>nil) do
|
||||||
@ -2515,7 +2515,7 @@ begin
|
|||||||
while (EndNode.NextBrother<>nil)
|
while (EndNode.NextBrother<>nil)
|
||||||
and (NodesToDo.Find(EndNode.NextBrother)<>nil) do
|
and (NodesToDo.Find(EndNode.NextBrother)<>nil) do
|
||||||
EndNode:=EndNode.NextBrother;
|
EndNode:=EndNode.NextBrother;
|
||||||
DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions Start=',StartNode.StartPos,' ',GetRedefinitionNodeText(StartNode),' End=',EndNode.StartPos,' ',GetRedefinitionNodeText(EndNode)]);
|
//DebugLn(['TCodeCompletionCodeTool.RemoveRedefinitions Start=',StartNode.StartPos,' ',GetRedefinitionNodeText(StartNode),' End=',EndNode.StartPos,' ',GetRedefinitionNodeText(EndNode)]);
|
||||||
|
|
||||||
// check if a whole section is deleted
|
// check if a whole section is deleted
|
||||||
if (StartNode.PriorBrother=nil) and (EndNode.NextBrother=nil)
|
if (StartNode.PriorBrother=nil) and (EndNode.NextBrother=nil)
|
||||||
@ -4796,7 +4796,7 @@ var
|
|||||||
PublishedMethods:=nil;
|
PublishedMethods:=nil;
|
||||||
try
|
try
|
||||||
{$IFDEF EnableInheritedEmptyMethods}
|
{$IFDEF EnableInheritedEmptyMethods}
|
||||||
DebugLn(['GatherClassProcs AAA1']);
|
DebugLn(['GatherClassProcs EnableInheritedEmptyMethods']);
|
||||||
GatherPublishedMethods(FCompletingStartNode,PublishedMethods);
|
GatherPublishedMethods(FCompletingStartNode,PublishedMethods);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
finally
|
finally
|
||||||
@ -5673,6 +5673,7 @@ begin
|
|||||||
IsVariable:=NodeExtIsVariable(ANodeExt);
|
IsVariable:=NodeExtIsVariable(ANodeExt);
|
||||||
if (cardinal(ord(PartType))=ANodeExt.Flags) then begin
|
if (cardinal(ord(PartType))=ANodeExt.Flags) then begin
|
||||||
// search a destination section
|
// search a destination section
|
||||||
|
ClassSectionNode:=nil;
|
||||||
if Visibility=pcsPublished then begin
|
if Visibility=pcsPublished then begin
|
||||||
// insert into first published section
|
// insert into first published section
|
||||||
ClassSectionNode:=FCodeCompleteClassNode.FirstChild;
|
ClassSectionNode:=FCodeCompleteClassNode.FirstChild;
|
||||||
@ -5698,6 +5699,17 @@ begin
|
|||||||
end else begin
|
end else begin
|
||||||
ClassSectionNode:=FCodeCompleteClassNode;
|
ClassSectionNode:=FCodeCompleteClassNode;
|
||||||
end;
|
end;
|
||||||
|
end else begin
|
||||||
|
// search a section of the same Visibility
|
||||||
|
if FCodeCompleteClassNode.Desc in AllClassObjects then
|
||||||
|
begin
|
||||||
|
ClassSectionNode:=FCodeCompleteClassNode.FirstChild;
|
||||||
|
while (ClassSectionNode<>nil)
|
||||||
|
and (ClassSectionNode.Desc<>ClassSectionNodeType[Visibility]) do
|
||||||
|
ClassSectionNode:=ClassSectionNode.NextBrother;
|
||||||
|
end else begin
|
||||||
|
ClassSectionNode:=FCodeCompleteClassNode;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
if ClassSectionNode=nil then begin
|
if ClassSectionNode=nil then begin
|
||||||
// there is no existing class section node
|
// there is no existing class section node
|
||||||
@ -5705,6 +5717,8 @@ begin
|
|||||||
Indent:=NewClassSectionIndent[Visibility]
|
Indent:=NewClassSectionIndent[Visibility]
|
||||||
+ASourceChangeCache.BeautifyCodeOptions.Indent;
|
+ASourceChangeCache.BeautifyCodeOptions.Indent;
|
||||||
InsertPos:=NewClassSectionInsertPos[Visibility];
|
InsertPos:=NewClassSectionInsertPos[Visibility];
|
||||||
|
if InsertPos<1 then
|
||||||
|
raise Exception.Create('TCodeCompletionCodeTool.InsertNewClassParts inconsistency: missing section: please create a bug report');
|
||||||
end else begin
|
end else begin
|
||||||
// there is an existing class section to insert into
|
// there is an existing class section to insert into
|
||||||
|
|
||||||
@ -5891,9 +5905,9 @@ var
|
|||||||
Result:=nil;
|
Result:=nil;
|
||||||
ANodeExt:=FirstInsert;
|
ANodeExt:=FirstInsert;
|
||||||
while ANodeExt<>nil do begin
|
while ANodeExt<>nil do begin
|
||||||
if ((Result=nil)
|
if (ANodeExt.Node<>nil)
|
||||||
or (Result.StartPos>ANodeExt.Node.StartPos))
|
and ((Result=nil) or (Result.StartPos>ANodeExt.Node.StartPos))
|
||||||
and (NodeExtHasVisibilty(ANodeExt,Visibility))
|
and (NodeExtHasVisibilty(ANodeExt,Visibility))
|
||||||
then
|
then
|
||||||
Result:=ANodeExt.Node;
|
Result:=ANodeExt.Node;
|
||||||
ANodeExt:=ANodeExt.Next;
|
ANodeExt:=ANodeExt.Next;
|
||||||
@ -5930,27 +5944,33 @@ var
|
|||||||
ANode: TCodeTreeNode;
|
ANode: TCodeTreeNode;
|
||||||
FirstVisibilitySection: TCodeTreeNode;
|
FirstVisibilitySection: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
|
NewClassSectionInsertPos[Visibility]:=-1;
|
||||||
|
NewClassSectionIndent[Visibility]:=0;
|
||||||
if FCodeCompleteClassNode.Desc in AllClassInterfaces then begin
|
if FCodeCompleteClassNode.Desc in AllClassInterfaces then begin
|
||||||
// a class interface has no sections
|
// a class interface has no sections
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
NewClassSectionInsertPos[Visibility]:=-1;
|
|
||||||
NewClassSectionIndent[Visibility]:=0;
|
|
||||||
// check if section is needed
|
// check if section is needed
|
||||||
if GetFirstNodeExtWithVisibility(Visibility)=nil then exit;
|
if GetFirstNodeExtWithVisibility(Visibility)=nil then exit;
|
||||||
// search topmost position node for this Visibility
|
// search topmost position node for this Visibility
|
||||||
TopMostPositionNode:=GetTopMostPositionNode(Visibility);
|
TopMostPositionNode:=GetTopMostPositionNode(Visibility);
|
||||||
SectionNode:=nil;
|
SectionNode:=nil;
|
||||||
// search a Visibility section in front of topmost position node
|
// search a Visibility section in front of topmost position node
|
||||||
if TopMostPositionNode<>nil then
|
if TopMostPositionNode<>nil then begin
|
||||||
SectionNode:=TopMostPositionNode.Parent.PriorBrother
|
SectionNode:=TopMostPositionNode;
|
||||||
else
|
while (SectionNode<>nil) and (SectionNode.Parent<>FCodeCompleteClassNode)
|
||||||
|
do
|
||||||
|
SectionNode:=SectionNode.Parent;
|
||||||
|
if SectionNode<>nil then
|
||||||
|
SectionNode:=SectionNode.PriorBrother;
|
||||||
|
end else
|
||||||
SectionNode:=FCodeCompleteClassNode.LastChild;
|
SectionNode:=FCodeCompleteClassNode.LastChild;
|
||||||
while (SectionNode<>nil)
|
while (SectionNode<>nil)
|
||||||
and (SectionNode.Desc<>ClassSectionNodeType[Visibility]) do
|
and (SectionNode.Desc<>ClassSectionNodeType[Visibility]) do
|
||||||
SectionNode:=SectionNode.PriorBrother;
|
SectionNode:=SectionNode.PriorBrother;
|
||||||
if (SectionNode<>nil) then begin
|
if (SectionNode<>nil) then begin
|
||||||
|
//DebugLn(['AddClassSection section exists for ',NodeDescriptionAsString(ClassSectionNodeType[Visibility])]);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
{ There is no section of this Visibility in front (or at all)
|
{ There is no section of this Visibility in front (or at all)
|
||||||
@ -7035,68 +7055,73 @@ begin
|
|||||||
Beautifier:=SourceChangeCache.BeautifyCodeOptions;
|
Beautifier:=SourceChangeCache.BeautifyCodeOptions;
|
||||||
NewMethods:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
NewMethods:=TAVLTree.Create(@CompareCodeTreeNodeExt);
|
||||||
try
|
try
|
||||||
|
ActivateGlobalWriteLock;
|
||||||
// collect all methods
|
try
|
||||||
for i:=0 to ListOfPCodeXYPosition.Count-1 do begin
|
// collect all methods
|
||||||
//get next code position
|
for i:=0 to ListOfPCodeXYPosition.Count-1 do begin
|
||||||
CodeXYPos:=PCodeXYPosition(ListOfPCodeXYPosition[i])^;
|
//get next code position
|
||||||
// get codetool for this position
|
CodeXYPos:=PCodeXYPosition(ListOfPCodeXYPosition[i])^;
|
||||||
NewCodeTool:=OnGetCodeToolForBuffer(Self,CodeXYPos.Code,true);
|
// get codetool for this position
|
||||||
if NewCodeTool=nil then begin
|
NewCodeTool:=OnGetCodeToolForBuffer(Self,CodeXYPos.Code,true);
|
||||||
DebugLn(['TCodeCompletionCodeTool.AddMethods unit not found for source ',CodeXYPos.Code.Filename,'(',CodeXYPos.Y,',',CodeXYPos.X,')']);
|
if NewCodeTool=nil then begin
|
||||||
exit;
|
DebugLn(['TCodeCompletionCodeTool.AddMethods unit not found for source ',CodeXYPos.Code.Filename,'(',CodeXYPos.Y,',',CodeXYPos.X,')']);
|
||||||
end;
|
exit;
|
||||||
// parse unit
|
|
||||||
NewCodeTool.BuildTreeAndGetCleanPos(trAll,CodeXYPos,CleanCursorPos,[]);
|
|
||||||
// find node at position
|
|
||||||
ProcNode:=NewCodeTool.BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
|
|
||||||
if (ProcNode.Desc<>ctnProcedure)
|
|
||||||
or (ProcNode.Parent=nil) then begin
|
|
||||||
NewCodeTool.MoveCursorToNodeStart(ProcNode);
|
|
||||||
RaiseException('TCodeCompletionCodeTool.AddMethods source position not a procedure');
|
|
||||||
end;
|
|
||||||
// find visibility
|
|
||||||
VisibilityDesc:=ctnClassPublic;
|
|
||||||
if ProcNode.Parent.Desc in AllClassBaseSections then
|
|
||||||
VisibilityDesc:=ProcNode.Parent.Desc;
|
|
||||||
// extract proc
|
|
||||||
ProcName:=NewCodeTool.ExtractProcName(ProcNode,[phpWithoutClassName,phpInUpperCase]);
|
|
||||||
CleanProcCode:=NewCodeTool.ExtractProcHead(ProcNode,[phpWithoutClassName]);
|
|
||||||
FullProcCode:=NewCodeTool.ExtractProcHead(ProcNode,
|
|
||||||
[phpWithStart,phpWithoutClassName,phpWithVarModifiers,
|
|
||||||
phpWithParameterNames,phpWithDefaultValues,phpWithResultType,
|
|
||||||
phpWithCallingSpecs,phpWithProcModifiers]);
|
|
||||||
if VirtualToOverride then begin
|
|
||||||
VirtualStartPos:=SearchProcSpecifier(FullProcCode,'virtual',
|
|
||||||
VirtualEndPos,NewCodeTool.Scanner.NestedComments);
|
|
||||||
if VirtualStartPos>=1 then begin
|
|
||||||
// replace virtual with override
|
|
||||||
FullProcCode:=copy(FullProcCode,1,VirtualStartPos-1)
|
|
||||||
+'override;'
|
|
||||||
+copy(FullProcCode,VirtualEndPos,length(FullProcCode));
|
|
||||||
end;
|
end;
|
||||||
// remove abstract
|
// parse unit
|
||||||
FullProcCode:=RemoveProcSpecifier(FullProcCode,'abstract',
|
NewCodeTool.BuildTreeAndGetCleanPos(trAll,CodeXYPos,CleanCursorPos,[]);
|
||||||
NewCodeTool.Scanner.NestedComments);
|
// find node at position
|
||||||
|
ProcNode:=NewCodeTool.BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
|
||||||
|
if (ProcNode.Desc<>ctnProcedure)
|
||||||
|
or (ProcNode.Parent=nil) then begin
|
||||||
|
NewCodeTool.MoveCursorToNodeStart(ProcNode);
|
||||||
|
RaiseException('TCodeCompletionCodeTool.AddMethods source position not a procedure');
|
||||||
|
end;
|
||||||
|
// find visibility
|
||||||
|
VisibilityDesc:=ctnClassPublic;
|
||||||
|
if ProcNode.Parent.Desc in AllClassBaseSections then
|
||||||
|
VisibilityDesc:=ProcNode.Parent.Desc;
|
||||||
|
// extract proc
|
||||||
|
ProcName:=NewCodeTool.ExtractProcName(ProcNode,[phpWithoutClassName,phpInUpperCase]);
|
||||||
|
CleanProcCode:=NewCodeTool.ExtractProcHead(ProcNode,[phpWithoutClassName]);
|
||||||
|
FullProcCode:=NewCodeTool.ExtractProcHead(ProcNode,
|
||||||
|
[phpWithStart,phpWithoutClassName,phpWithVarModifiers,
|
||||||
|
phpWithParameterNames,phpWithDefaultValues,phpWithResultType,
|
||||||
|
phpWithCallingSpecs,phpWithProcModifiers]);
|
||||||
|
if VirtualToOverride then begin
|
||||||
|
VirtualStartPos:=SearchProcSpecifier(FullProcCode,'virtual',
|
||||||
|
VirtualEndPos,NewCodeTool.Scanner.NestedComments);
|
||||||
|
if VirtualStartPos>=1 then begin
|
||||||
|
// replace virtual with override
|
||||||
|
FullProcCode:=copy(FullProcCode,1,VirtualStartPos-1)
|
||||||
|
+'override;'
|
||||||
|
+copy(FullProcCode,VirtualEndPos,length(FullProcCode));
|
||||||
|
end;
|
||||||
|
// remove abstract
|
||||||
|
FullProcCode:=RemoveProcSpecifier(FullProcCode,'abstract',
|
||||||
|
NewCodeTool.Scanner.NestedComments);
|
||||||
|
end;
|
||||||
|
|
||||||
|
ProcCode:=NewCodeTool.ExtractProcHead(ProcNode,[phpWithStart,
|
||||||
|
phpWithoutClassName,phpWithVarModifiers,phpWithParameterNames,
|
||||||
|
phpWithResultType,phpWithCallingSpecs]);
|
||||||
|
ProcCode:=ProcCode+Beautifier.LineEnd
|
||||||
|
+'begin'+Beautifier.LineEnd
|
||||||
|
+GetIndentStr(Beautifier.Indent)+Beautifier.LineEnd
|
||||||
|
+'end;';
|
||||||
|
|
||||||
|
// add method data
|
||||||
|
NodeExt:=NodeExtMemManager.NewNode;
|
||||||
|
NodeExt.Txt:=CleanProcCode;
|
||||||
|
NodeExt.ExtTxt1:=FullProcCode;
|
||||||
|
NodeExt.ExtTxt2:=ProcName;
|
||||||
|
NodeExt.ExtTxt3:=ProcCode;
|
||||||
|
NodeExt.Flags:=VisibilityDesc;
|
||||||
|
NewMethods.Add(NodeExt);
|
||||||
|
//DebugLn(['TCodeCompletionCodeTool.AddMethods ',i,' CleanProcTxt=',CleanProcCode,' FullProcTxt=',FullProcCode]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ProcCode:=NewCodeTool.ExtractProcHead(ProcNode,[phpWithStart,
|
finally
|
||||||
phpWithoutClassName,phpWithVarModifiers,phpWithParameterNames,
|
DeactivateGlobalWriteLock;
|
||||||
phpWithResultType,phpWithCallingSpecs]);
|
|
||||||
ProcCode:=ProcCode+Beautifier.LineEnd
|
|
||||||
+'begin'+Beautifier.LineEnd
|
|
||||||
+GetIndentStr(Beautifier.Indent)+Beautifier.LineEnd
|
|
||||||
+'end;';
|
|
||||||
|
|
||||||
// add method data
|
|
||||||
NodeExt:=NodeExtMemManager.NewNode;
|
|
||||||
NodeExt.Txt:=CleanProcCode;
|
|
||||||
NodeExt.ExtTxt1:=FullProcCode;
|
|
||||||
NodeExt.ExtTxt2:=ProcName;
|
|
||||||
NodeExt.ExtTxt3:=ProcCode;
|
|
||||||
NodeExt.Flags:=VisibilityDesc;
|
|
||||||
NewMethods.Add(NodeExt);
|
|
||||||
DebugLn(['TCodeCompletionCodeTool.AddMethods ',i,' CleanProcTxt=',CleanProcCode,' FullProcTxt=',FullProcCode]);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
BuildTreeAndGetCleanPos(trAll,CursorPos,CleanCursorPos,[]);
|
BuildTreeAndGetCleanPos(trAll,CursorPos,CleanCursorPos,[]);
|
||||||
@ -7115,6 +7140,7 @@ begin
|
|||||||
DebugLn(['TIdentCompletionTool.AddMethods cursor not in a class']);
|
DebugLn(['TIdentCompletionTool.AddMethods cursor not in a class']);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
//DebugLn(['TCodeCompletionCodeTool.AddMethods CursorNode=',CursorNode.DescAsString]);
|
||||||
|
|
||||||
CodeCompleteSrcChgCache:=SourceChangeCache;
|
CodeCompleteSrcChgCache:=SourceChangeCache;
|
||||||
CodeCompleteClassNode:=CursorNode;
|
CodeCompleteClassNode:=CursorNode;
|
||||||
|
Loading…
Reference in New Issue
Block a user