codetools: clean up and simplified

This commit is contained in:
mattias 2024-12-31 11:39:21 +01:00
parent 43d02af738
commit f4094028d4
2 changed files with 50 additions and 109 deletions

View File

@ -107,15 +107,15 @@ procedure GetIdentStartEndAtPosition(const Source:string; Position:integer;
out IdentStart,IdentEnd:integer); out IdentStart,IdentEnd:integer);
function GetIdentStartPosition(const Source:string; Position:integer): integer; function GetIdentStartPosition(const Source:string; Position:integer): integer;
function GetIdentLen(Identifier: PChar): integer; function GetIdentLen(Identifier: PChar): integer;
function GetIdentifier(Identifier: PChar; const aSkipAmp: Boolean = True; function GetIdentifier(Identifier: PChar; aSkipAmp: Boolean = True;
const IsDottedIdent: Boolean = False): string; IsDottedIdent: Boolean = False): string;
function FindNextIdentifier(const Source: string; StartPos, MaxPos: integer): integer; function FindNextIdentifier(const Source: string; StartPos, MaxPos: integer): integer;
function FindNextIdentifierSkipStrings(const Source: string; function FindNextIdentifierSkipStrings(const Source: string;
StartPos, MaxPos: integer): integer; StartPos, MaxPos: integer): integer;
function IsValidDottedIdent(const Ident: string; AllowDots: Boolean = True): Boolean; // as sysutils.IsValidIdent, but faster and supports & function IsValidDottedIdent(const Ident: string; AllowDots: Boolean = True): Boolean; // as sysutils.IsValidIdent, but faster and supports &
function IsValidIdentPair(const NamePair: string): boolean; // true if exactly two identifiers separated by a dot function IsValidIdentPair(const NamePair: string): boolean; // true if exactly two identifiers separated by a dot
function IsValidIdentPair(const NamePair: string; out First, Second: string): boolean; function IsValidIdentPair(const NamePair: string; out First, Second: string): boolean;
function ExtractPasIdentifier(const Ident: string; AllowDots: Boolean): string; function ExtractPasIdentifier(const Ident: string; AllowDots: Boolean): string; // removes non identifier chars
// line/code ends // line/code ends
function SrcPosToLineCol(const s: string; Position: integer; function SrcPosToLineCol(const s: string; Position: integer;
@ -4848,8 +4848,7 @@ begin
Result:='Expected: '+dbgstr(Expected,1,d-1)+'|'+dbgstr(Expected,d,length(Expected))+LineEnding Result:='Expected: '+dbgstr(Expected,1,d-1)+'|'+dbgstr(Expected,d,length(Expected))+LineEnding
+'Actual: '+dbgstr(Actual,1,d-1)+'|'+dbgstr(Actual,d,length(Actual)); +'Actual: '+dbgstr(Actual,1,d-1)+'|'+dbgstr(Actual,d,length(Actual));
end; end;
function GetIdentifier(Identifier: PChar; const aSkipAmp: Boolean; function GetIdentifier(Identifier: PChar; aSkipAmp: Boolean; IsDottedIdent: Boolean): string;
const IsDottedIdent: Boolean): string;
var len: integer; var len: integer;
begin begin
if (Identifier=nil) then begin if (Identifier=nil) then begin

View File

@ -545,7 +545,7 @@ type
function GetIdentifierAt(Code: TCodeBuffer; var X,Y: integer; function GetIdentifierAt(Code: TCodeBuffer; var X,Y: integer;
out Identifier: string): boolean; out Identifier: string): boolean;
function GetIdentifierAt(Code: TCodeBuffer; var X,Y: integer; function GetIdentifierAt(Code: TCodeBuffer; var X,Y: integer;
out Identifier: string; var ANode: TCodeTreeNode): boolean; out Identifier: string; out ANode: TCodeTreeNode): boolean;
function IdentItemCheckHasChilds(IdentItem: TIdentifierListItem): boolean; function IdentItemCheckHasChilds(IdentItem: TIdentifierListItem): boolean;
function FindAbstractMethods(Code: TCodeBuffer; X,Y: integer; function FindAbstractMethods(Code: TCodeBuffer; X,Y: integer;
out ListOfPCodeXYPosition: TFPList; out ListOfPCodeXYPosition: TFPList;
@ -2666,70 +2666,17 @@ end;
function TCodeToolManager.GetIdentifierAt(Code: TCodeBuffer; var X, Y: integer; function TCodeToolManager.GetIdentifierAt(Code: TCodeBuffer; var X, Y: integer;
out Identifier: string): boolean; out Identifier: string): boolean;
var var
CleanPos,CleanPosAmd: integer; aNode: TCodeTreeNode;
CodeTool: TCodeTool;
CaretXY: TCodeXYPosition;
CodeNode: TCodeTreeNode;
CanBeDotted: boolean;
begin begin
Result:=false; Result:=GetIdentifierAt(Code,X,Y,Identifier,aNode);
Identifier:='';
{$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.GetIdentifierAt A ',Code.Filename,' x=',dbgs(x),' y=',dbgs(y));
{$ENDIF}
Code.LineColToPosition(Y,X,CleanPos);
if (CleanPos>0) and (CleanPos<=Code.SourceLength) then begin
CodeTool:=nil;
CaretXY:=CleanCodeXYPosition;
CaretXY.Code:=Code;
CaretXY.X:=X;
CaretXY.Y:=Y;
CodeNode:=nil;
if CodeToolBoss.Explore(Code,CodeTool,true) then
if CodeTool<>nil then begin
CodeTool.CaretToCleanPos(CaretXY,CleanPosAmd);
CodeNode:=CodeTool.FindDeepestNodeAtPos(CleanPosAmd,false);
end;
if (CodeNode<>nil) and (CodeNode.Parent<>nil) then begin
CanBeDotted := (CodeNode.Desc = ctnUseUnit) or
(CodeNode.Desc = ctnUseUnitNamespace) or
(CodeNode.Desc = ctnUseUnitClearName) or
((CodeNode.Parent.Desc = ctnSrcName) and
(CodeNode.Desc = ctnIdentifier));
if CanBeDotted then begin
if CodeNode.Desc in [ctnIdentifier,ctnUseUnitNamespace, ctnUseUnitClearName]
then
CleanPosAmd:= CodeNode.Parent.StartPos
else
CleanPosAmd:= CodeNode.StartPos;
Code.AbsoluteToLineCol(CleanPosAmd,Y,X); //does anybody want to know it?
CodeTool.MoveCursorToCleanPos(CleanPosAmd);
CodeTool.ReadNextAtom;
repeat
if CodeTool.CurPos.Flag<>cafWord then
break;
Identifier:=Identifier+CodeTool.GetAtom;
CodeTool.ReadNextAtom;
if CodeTool.CurPos.Flag=cafPoint then begin
Identifier:=Identifier+CodeTool.GetAtom;
end else
break;
CodeTool.ReadNextAtom;
until CodeTool.CurPos.StartPos>=CodeTool.SrcLen;
end else
Identifier:=GetIdentifier(@Code.Source[CleanPos],False);
Result:=true;
exit;
end;
end;
end; end;
function TCodeToolManager.GetIdentifierAt(Code: TCodeBuffer; var X, Y: integer; function TCodeToolManager.GetIdentifierAt(Code: TCodeBuffer; var X, Y: integer; out
out Identifier: string; var ANode: TCodeTreeNode): boolean; Identifier: string; out ANode: TCodeTreeNode): boolean;
var var
CleanPos,CleanPosAmd: integer; p,CleanPos, IdentStartPos: integer;
CodePos: TCodePosition;
CodeTool: TCodeTool; CodeTool: TCodeTool;
CaretXY: TCodeXYPosition;
CodeNode: TCodeTreeNode; CodeNode: TCodeTreeNode;
CanBeDotted: boolean; CanBeDotted: boolean;
begin begin
@ -2739,56 +2686,51 @@ begin
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.GetIdentifierAt A ',Code.Filename,' x=',dbgs(x),' y=',dbgs(y)); DebugLn('TCodeToolManager.GetIdentifierAt A ',Code.Filename,' x=',dbgs(x),' y=',dbgs(y));
{$ENDIF} {$ENDIF}
Code.LineColToPosition(Y,X,CleanPos); Code.LineColToPosition(Y,X,p);
if (CleanPos>0) and (CleanPos<=Code.SourceLength) then begin if (p<0) or (p>Code.SourceLength) then
CodeTool:=nil; exit;
CaretXY:=CleanCodeXYPosition; if CodeToolBoss.Explore(Code,CodeTool,true) then begin
CaretXY.Code:=Code; CodePos.Code:=Code;
CaretXY.X:=X; CodePos.P:=p;
CaretXY.Y:=Y;
CodeNode:=nil; CodeNode:=nil;
if CodeToolBoss.Explore(Code,CodeTool,true) then if CodeTool.CodePosToCleanPos(CodePos,CleanPos)=0 then begin
if CodeTool<>nil then begin CodeNode:=CodeTool.FindDeepestNodeAtPos(CleanPos,false);
CodeTool.CaretToCleanPos(CaretXY,CleanPosAmd);
CodeNode:=CodeTool.FindDeepestNodeAtPos(CleanPosAmd,false);
ANode:=CodeNode; ANode:=CodeNode;
end; if (CodeNode<>nil) and (CodeNode.Parent<>nil) then begin
if (CodeNode<>nil) and (CodeNode.Parent<>nil) then begin CanBeDotted := (CodeNode.Desc in [ctnUseUnit,ctnUseUnitNamespace,ctnUseUnitClearName])
CanBeDotted := (CodeNode.Desc = ctnUseUnit) or or ((CodeNode.Desc = ctnIdentifier) and (CodeNode.Parent.Desc = ctnSrcName));
(CodeNode.Desc = ctnUseUnitNamespace) or if CanBeDotted then begin
(CodeNode.Desc = ctnUseUnitClearName) or if CodeNode.Parent.Desc = ctnSrcName then
((CodeNode.Parent.Desc = ctnSrcName) and ANode:= CodeNode.Parent.Parent; //ctnProgram..ctnUnit
(CodeNode.Desc = ctnIdentifier)); if CodeNode.Desc in [ctnIdentifier,ctnUseUnitNamespace, ctnUseUnitClearName]
if CanBeDotted then begin then
if CodeNode.Parent.Desc = ctnSrcName then CleanPos:= CodeNode.Parent.StartPos
ANode:= CodeNode.Parent.Parent; //ctnProgram..ctnUnit else
CleanPos:= CodeNode.StartPos;
if CodeNode.Desc in [ctnIdentifier,ctnUseUnitNamespace, ctnUseUnitClearName] Code.AbsoluteToLineCol(CleanPos,Y,X);
then CodeTool.MoveCursorToCleanPos(CleanPos);
CleanPosAmd:= CodeNode.Parent.StartPos
else
CleanPosAmd:= CodeNode.StartPos;
Code.AbsoluteToLineCol(CleanPosAmd,Y,X);
CodeTool.MoveCursorToCleanPos(CleanPosAmd);
CodeTool.ReadNextAtom;
repeat
if CodeTool.CurPos.Flag<>cafWord then
break;
Identifier:=Identifier+CodeTool.GetAtom;
CodeTool.ReadNextAtom; CodeTool.ReadNextAtom;
if CodeTool.CurPos.Flag=cafPoint then begin repeat
if CodeTool.CurPos.Flag<>cafWord then
break;
Identifier:=Identifier+CodeTool.GetAtom; Identifier:=Identifier+CodeTool.GetAtom;
end else CodeTool.ReadNextAtom;
break; if CodeTool.CurPos.Flag=cafPoint then begin
CodeTool.ReadNextAtom; Identifier:=Identifier+CodeTool.GetAtom;
until CodeTool.CurPos.StartPos>=CodeTool.SrcLen; end else
end else break;
Identifier:=GetIdentifier(@Code.Source[CleanPos],False); CodeTool.ReadNextAtom;
Result:=true; until CodeTool.CurPos.StartPos>=CodeTool.SrcLen;
exit; exit(true);
end;
end;
end; end;
end; end;
// fallback: extract from source
IdentStartPos:=GetIdentStartPosition(Code.Source,p);
Identifier:=GetIdentifier(@Code.Source[IdentStartPos],false);
Code.AbsoluteToLineCol(IdentStartPos,Y,X);
Result:=Identifier<>'';
end; end;
function TCodeToolManager.IdentItemCheckHasChilds(IdentItem: TIdentifierListItem function TCodeToolManager.IdentItemCheckHasChilds(IdentItem: TIdentifierListItem