codetools: fixed method jump to delphi generic class method body, issue #33615

git-svn-id: trunk@57732 -
This commit is contained in:
mattias 2018-04-27 17:35:45 +00:00
parent b8ff72cec9
commit 4e7156c071
3 changed files with 53 additions and 16 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;