codetools: find references: search simple function Result references

This commit is contained in:
mattias 2025-06-25 17:51:56 +02:00
parent 977f3e8331
commit 2504c0fce0
4 changed files with 6457 additions and 8 deletions

View File

@ -2064,6 +2064,54 @@ var
CleanCursorPos: integer;
CursorNode, ClassNode: TCodeTreeNode;
DirectSearch, SkipChecks, SearchForward: boolean;
function IsPredefinedResult: boolean;
var
ANode: TCodeTreeNode;
p: Integer;
begin
Result:=false;
p:=GetIdentStartPosition(Src,CleanCursorPos);
if p<1 then exit;
if CompareIdentifiers('Result',@Src[p])<>0 then exit;
if CursorNode.Desc<>ctnBeginBlock then exit;
if not CursorNode.HasParentOfType(ctnProcedure) then exit;
if not (cmsResult in Scanner.CompilerModeSwitches) then begin
debugln('Predefined "Result" inside a function body is not allowed');
exit;
end;
ANode:=CursorNode.Parent;
while ANode<>nil do begin
if (ANode.Desc = ctnProcedure) then begin
if CompareIdentifiers('function',@Src[ANode.StartPos])=0 then
break;
end;
ANode:=ANode.Parent
end;
if ANode=nil then exit;
CursorNode:=ANode;
MoveCursorToCleanPos(CleanCursorPos);
Result:=true;
end;
function FindFunctionResultTypeNode: TCodeTreeNode;
var ANode: TCodeTreeNode;
begin
Result:=nil;
if CursorNode.Desc<>ctnProcedure then exit;
ANode:=CursorNode.FirstChild;
if ANode.Desc<>ctnProcedureHead then exit;
ANode:=ANode.FirstChild;
while ANode<>nil do begin
if ANode.Desc=ctnIdentifier then break;
ANode:=Anode.NextBrother;
end;
if (ANode<>nil) and (ANode.Desc=ctnIdentifier) then
Result:=ANode;
end;
function CheckIfNodeIsForwardDefinedClass(ANode: TCodeTreeNode;
ATool: TFindDeclarationTool): Boolean;
var
@ -2272,7 +2320,6 @@ var
BlockBottomLine := NewSkipBlockBottomLine;
end;
end;
var
CleanPosInFront: integer;
CursorAtIdentifier: boolean;
@ -2321,8 +2368,8 @@ begin
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then begin
CursorNode:=BuildSubTreeAndFindDeepestNodeAtPos(CleanCursorPos,true);
if (fsfFindMainDeclaration in SearchSmartFlags)
and CleanPosIsDeclarationIdentifier(CleanCursorPos,CursorNode)
then begin
and CleanPosIsDeclarationIdentifier(CleanCursorPos,CursorNode) then
begin
//DebugLn(['TFindDeclarationTool.FindDeclaration CleanPosIsDeclarationIdentifier ',CursorNode.DescAsString]);
NewExprType.Desc:=xtContext;
NewExprType.Context.Tool:=Self;
@ -2427,6 +2474,23 @@ begin
{$ENDIF}
end;
exit;
end else if IsPredefinedResult then begin
// "Result" is allowed
Result:=false;
CleanCursorPos:=GetIdentStartPosition(Src,CleanCursorPos);
NewExprType.Desc:=xtContext;
NewExprType.Context.Tool:=Self;
NewExprType.Context.Node:=FindFunctionResultTypeNode();
if (NewExprType.Context.Node<>nil) and (NewExprType.Context.Node.StartPos<CleanCursorPos)
then begin
CleanPosToCaret(CleanCursorPos, NewPos);
NewTopLine := NewPos.Y;
BlockTopLine := NewTopLine;
BlockBottomLine := NewPos.Y;
Result:=true;
end else
NewExprType.Context.Node:=CursorNode;
exit;
end;
DirectSearch:=false;
@ -3697,7 +3761,7 @@ begin
Result += lowercase(Node.Parent.DescAsString)+' ';
MoveCursorToNodeStart(Node);
Result := Result + ReadIdentifierWithDots+' ';
end
end;
else
DebugLn('ToDo: TFindDeclarationTool.GetSmartHint ',Node.DescAsString);
end;
@ -6573,6 +6637,8 @@ var
var
p: LongInt;
begin
if Node.Desc=ctnBeginBlock then
exit; // e.g. Result in function
p:=Node.StartPos;
if Node.Desc in [ctnProcedure,ctnProcedureHead] then begin
MoveCursorToProcName(Node,true);
@ -6748,7 +6814,7 @@ var
then begin
// declaration itself found
//debugln(['ReadIdentifier declaration itself found, adding ...']);
AddReference(IdentStartPos)
AddReference(IdentStartPos);
end
else if CleanPosIsDeclarationIdentifier(IdentStartPos,CursorNode) then begin
// this identifier is another declaration with the same name

View File

@ -240,8 +240,7 @@ const
DefaultCompilerModeSwitches: array[TCompilerMode] of TCompilerModeSwitches = (
// cmFPC
[cmsString_pchar,cmsNested_comment,cmsRepeat_forward,cmsCvar_support,
cmsInitfinal,cmsHintdirective,cmsProperty,cmsDefault_inline,
cmsResult],
cmsInitfinal,cmsHintdirective,cmsProperty,cmsDefault_inline],
// cmDELPHI
[cmsClass,cmsObjpas,cmsResult,cmsString_pchar,
cmsPointer_2_procedure,cmsAutoderef,cmsTp_procvar,cmsInitfinal,cmsDefault_ansistring,
@ -260,7 +259,7 @@ const
// cmGPC
[cmsTp_procvar],
// cmTP
[cmsResult,cmsTp_procvar,cmsDuplicate_names],
[cmsTp_procvar,cmsDuplicate_names],
// cmOBJFPC
[cmsClass,cmsObjpas,cmsResult,cmsString_pchar,cmsNested_comment,
cmsRepeat_forward,cmsCvar_support,cmsInitfinal,cmsOut,cmsDefault_para,

View File

@ -1354,6 +1354,16 @@ begin
Err:=Format(lisIdentifierCannotBeDotted,[FNewIdentifier]);
end;
if ok
and (FNode.Desc=ctnBeginBlock) // 'Result'
and (CompareIdentifiers(PChar(FNewIdentifier),
PChar(FOldIdentifier))<>0) // only case change allowed
then begin
// Result inside function
ok:=false;
Err:=Format(lisIdentifierIsReservedWord,['Result']);
end;
if ok and (FTool<>nil) then begin
i:=1;
while ok and (i<=length(FNewIdentifier)) do begin

File diff suppressed because it is too large Load Diff