mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-04 04:18:22 +01:00
codetools: fixed method jump to delphi generic class method body, issue #33615
git-svn-id: trunk@57732 -
This commit is contained in:
parent
b8ff72cec9
commit
4e7156c071
@ -73,7 +73,7 @@ interface
|
||||
{$DEFINE VerboseCompletionAdds}
|
||||
{off $DEFINE VerboseUpdateProcBodySignatures}
|
||||
{off $DEFINE VerboseCompleteMethod}
|
||||
{off $DEFINE VerboseCreateMissingClassProcBodies}
|
||||
{$DEFINE VerboseCreateMissingClassProcBodies}
|
||||
{off $DEFINE VerboseCompleteLocalVarAssign}
|
||||
{off $DEFINE VerboseCompleteEventAssign}
|
||||
{off $DEFINE EnableCodeCompleteTemplates}
|
||||
@ -8679,6 +8679,14 @@ procedure TCodeCompletionCodeTool.GuessProcDefBodyMapping(ProcDefNodes,
|
||||
end;
|
||||
|
||||
begin
|
||||
{$IFDEF VerboseUpdateProcBodySignatures}
|
||||
debugln(['TCodeCompletionCodeTool.GuessProcDefBodyMapping',
|
||||
' ProcDefNodes=',ProcDefNodes.Count,
|
||||
' ProcBodyNodes=',ProcBodyNodes.Count,
|
||||
' MapByNameOnly=',MapByNameOnly,
|
||||
' MapLastOne=',MapLastOne
|
||||
]);
|
||||
{$ENDIF}
|
||||
ClearNodeExtData(ProcBodyNodes);
|
||||
ClearNodeExtData(ProcDefNodes);
|
||||
MapBodiesAndDefsByNameAndParams; // first: map all exact matches between bodies and defs
|
||||
@ -8722,7 +8730,7 @@ begin
|
||||
TypeSectionNode:=ClassNode.GetTopMostNodeOfType(ctnTypeSection);
|
||||
Result:=GatherProcNodes(TypeSectionNode,
|
||||
[phpInUpperCase,phpIgnoreForwards,phpOnlyWithClassname],
|
||||
ExtractClassName(ClassNode,true,true,Scanner.CompilerMode in [cmDELPHI,cmDELPHIUNICODE]));
|
||||
ExtractClassName(ClassNode,true,true,false));
|
||||
end;
|
||||
|
||||
function TCodeCompletionCodeTool.CreateMissingClassProcBodies(
|
||||
@ -9026,11 +9034,13 @@ begin
|
||||
ProcBodyNodes:=GatherClassProcBodies(CodeCompleteClassNode);
|
||||
|
||||
{$IFDEF VerboseCreateMissingClassProcBodies}
|
||||
debugln(['TCodeCompletionCodeTool.CreateMissingClassProcBodies ClassProcs=',ClassProcs.Count]);
|
||||
AnAVLNode:=ClassProcs.FindLowest;
|
||||
while AnAVLNode<>nil do begin
|
||||
DebugLn(' Gathered ProcDef ',TCodeTreeNodeExtension(AnAVLNode.Data).Txt);
|
||||
AnAVLNode:=ClassProcs.FindSuccessor(AnAVLNode);
|
||||
end;
|
||||
debugln(['TCodeCompletionCodeTool.CreateMissingClassProcBodies ProcBodyNodes=',ProcBodyNodes.Count]);
|
||||
AnAVLNode:=ProcBodyNodes.FindLowest;
|
||||
while AnAVLNode<>nil do begin
|
||||
DebugLn(' Gathered ProcBody ',TCodeTreeNodeExtension(AnAVLNode.Data).Txt);
|
||||
|
||||
@ -218,6 +218,8 @@ const
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint.JumpToProc A ',dbgs(FromProcNode<>nil),' ',dbgs(ToProcNode<>nil));
|
||||
debugln([' JumpToProc FromProcAttr=[',dbgs(FromProcAttr),']']);
|
||||
debugln([' JumpToProc ToProcAttr=[',dbgs(ToProcAttr),']']);
|
||||
{$ENDIF}
|
||||
FromProcHead:=ExtractProcHead(FromProcNode,FromProcAttr);
|
||||
ToProcHead:=ExtractProcHead(ToProcNode,ToProcAttr);
|
||||
@ -275,9 +277,9 @@ const
|
||||
StartNode: TCodeTreeNode; SearchInProcAttr: TProcHeadAttributes;
|
||||
SearchAlsoDifferentParamList: boolean): boolean;
|
||||
// search first for proc node with same name and param list and jump,
|
||||
// if this fails
|
||||
// search for a proc node with same name and jump to difference in param list
|
||||
// returns true on jumped, false if no target proc found
|
||||
// if this fails:
|
||||
// search for a proc node with same name and jump to difference in param list
|
||||
// returns true if jumped, false if no target proc found
|
||||
var
|
||||
SearchedProcHead: TPascalMethodHeader;
|
||||
ProcNode: TCodeTreeNode;
|
||||
@ -383,7 +385,7 @@ begin
|
||||
CursorNode:=FindDeepestNodeAtPos(CleanCursorPos,true).
|
||||
GetNodeOfType(ctnProcedure);
|
||||
if (CursorNode=nil) then exit;
|
||||
// search corresponding proc node
|
||||
// search corresponding proc node with same name
|
||||
Result:=FindBestProcNode(CursorNode,[phpAddClassName,phpInUpperCase],
|
||||
TypeSectionNode,[phpIgnoreForwards,phpInUpperCase],
|
||||
false);
|
||||
@ -412,10 +414,13 @@ begin
|
||||
[phpInUpperCase,phpIgnoreForwards,phpOnlyWithClassname],
|
||||
ExtractClassName(ClassNode,true,true));
|
||||
try
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn(['TMethodJumpingCodeTool.FindJumpPoint J Gather SearchForNodes=',SearchForNodes.Count,' SearchInNodes=',SearchInNodes.Count]);
|
||||
{$ENDIF}
|
||||
// remove all corresponding methods
|
||||
RemoveCorrespondingProcNodes(SearchInNodes,SearchForNodes,false);
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint J DiffMethods found = ',dbgs(SearchInNodes.Count));
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint K DiffMethods found = ',dbgs(SearchInNodes.Count));
|
||||
{$ENDIF}
|
||||
if SearchInNodes.Count=0 then exit;
|
||||
// SearchForNodes now contains all method bodies, which do not have any
|
||||
@ -424,7 +429,7 @@ begin
|
||||
ProcNode:=FindProcNodeInTreeWithName(SearchInNodes,
|
||||
ExtractProcName(CursorNode,[phpWithoutClassName,phpInUpperCase]));
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint J DiffMethod with same name found = ',dbgs(ProcNode<>nil));
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint H DiffMethod with same name found = ',dbgs(ProcNode<>nil));
|
||||
{$ENDIF}
|
||||
if (ProcNode=nil) then begin
|
||||
// no method body with same name
|
||||
@ -432,7 +437,7 @@ begin
|
||||
ProcNode:=TCodeTreeNodeExtension(SearchInNodes.FindLowest.Data).Node;
|
||||
end;
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint K jump ...');
|
||||
DebugLn('TMethodJumpingCodeTool.FindJumpPoint L jump ...');
|
||||
{$ENDIF}
|
||||
Result:=JumpToProc(CursorNode,JumpToProcAttr,
|
||||
ProcNode,JumpToProcAttr);
|
||||
@ -794,7 +799,7 @@ var CurProcName: string;
|
||||
cmp: boolean;
|
||||
CurClassName: String;
|
||||
begin
|
||||
//debugln(['TMethodJumpingCodeTool.GatherProcNodes START']);
|
||||
//debugln(['TMethodJumpingCodeTool.GatherProcNodes START FilterClassName="',FilterClassName,'" Attr=[',dbgs(Attr),']']);
|
||||
Result:=TAVLTree.Create(@CompareCodeTreeNodeExtMethodHeaders);
|
||||
if (StartNode=nil) or (StartNode.Parent=nil) then exit;
|
||||
ANode:=StartNode;
|
||||
|
||||
@ -62,7 +62,12 @@ type
|
||||
|
||||
//the scope groups of pascal methods.
|
||||
//please note that Destructor is principally a method and thus is not listed here -> you cannot define "procedure Destroy;" and "destructor Destroy" in one class
|
||||
TPascalMethodGroup = (mgMethod, mgConstructor, mgClassConstructor, mgClassDestructor, mgClassOperator);
|
||||
TPascalMethodGroup = (
|
||||
mgMethod,
|
||||
mgConstructor,
|
||||
mgClassConstructor,
|
||||
mgClassDestructor,
|
||||
mgClassOperator);
|
||||
|
||||
TPascalMethodHeader = record
|
||||
Name, ResultType: string;
|
||||
@ -144,7 +149,7 @@ type
|
||||
function ExtractProcedureHeader(CursorPos: TCodeXYPosition;
|
||||
Attributes: TProcHeadAttributes; var ProcHead: string): boolean;
|
||||
function ExtractClassNameOfProcNode(ProcNode: TCodeTreeNode;
|
||||
AddParentClasses: boolean = true): string;
|
||||
AddParentClasses: boolean = true; KeepGeneric: boolean = false): string;
|
||||
function ProcNodeHasSpecifier(ProcNode: TCodeTreeNode;
|
||||
ProcSpec: TProcedureSpecifier): boolean;
|
||||
function GetProcNameIdentifier(ProcNode: TCodeTreeNode): PChar;
|
||||
@ -704,8 +709,9 @@ begin
|
||||
ReadNextAtom;
|
||||
if (Scanner.CompilerMode in [cmDELPHI,cmDELPHIUNICODE]) and AtomIsChar('<') then
|
||||
begin
|
||||
while not AtomIsChar('>') and (CurPos.EndPos < SrcLen) do
|
||||
repeat
|
||||
ReadNextAtom;
|
||||
until AtomIsChar('>') or (CurPos.EndPos > SrcLen);
|
||||
ReadNextAtom;
|
||||
end;
|
||||
IsClassName:=(CurPos.Flag=cafPoint);
|
||||
@ -713,6 +719,13 @@ begin
|
||||
if IsClassName then begin
|
||||
// read class name
|
||||
ExtractNextAtom(not (phpWithoutClassName in Attr),Attr);
|
||||
if (Scanner.CompilerMode in [cmDELPHI,cmDELPHIUNICODE]) and AtomIsChar('<') then
|
||||
begin
|
||||
repeat
|
||||
ExtractNextAtom(false,Attr);
|
||||
until AtomIsChar('>') or (CurPos.EndPos > SrcLen);
|
||||
ExtractNextAtom(false,Attr);
|
||||
end;
|
||||
// read '.'
|
||||
ExtractNextAtom(not (phpWithoutClassName in Attr),Attr);
|
||||
if ((not IsOperator)
|
||||
@ -721,6 +734,13 @@ begin
|
||||
end else begin
|
||||
// read name
|
||||
ExtractNextAtom(not (phpWithoutName in Attr),Attr);
|
||||
if (Scanner.CompilerMode in [cmDELPHI,cmDELPHIUNICODE]) and AtomIsChar('<') then
|
||||
begin
|
||||
repeat
|
||||
ExtractNextAtom(false,Attr);
|
||||
until AtomIsChar('>') or (CurPos.EndPos > SrcLen);
|
||||
ExtractNextAtom(false,Attr);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
until false;
|
||||
@ -943,7 +963,7 @@ begin
|
||||
end;
|
||||
|
||||
function TPascalReaderTool.ExtractClassNameOfProcNode(ProcNode: TCodeTreeNode;
|
||||
AddParentClasses: boolean): string;
|
||||
AddParentClasses: boolean; KeepGeneric: boolean): string;
|
||||
var
|
||||
Part: String;
|
||||
begin
|
||||
@ -959,10 +979,12 @@ begin
|
||||
ReadNextAtom;
|
||||
if (Scanner.CompilerMode in [cmDELPHI,cmDELPHIUNICODE]) and AtomIsChar('<') then
|
||||
begin { delphi generics }
|
||||
Part := Part + GetAtom;
|
||||
if KeepGeneric then
|
||||
Part := Part + GetAtom;
|
||||
repeat
|
||||
ReadNextAtom;
|
||||
Part := Part + GetAtom;
|
||||
if KeepGeneric then
|
||||
Part := Part + GetAtom;
|
||||
until (CurPos.StartPos > SrcLen) or AtomIsChar('>');
|
||||
ReadNextAtom;
|
||||
end;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user