mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-23 09:19:40 +02:00
codetools: find declaratuion: added flag to skip forward class
git-svn-id: trunk@19814 -
This commit is contained in:
parent
ed6ba36741
commit
3e5a744e2d
@ -364,7 +364,8 @@ type
|
||||
// find declaration
|
||||
function FindDeclaration(Code: TCodeBuffer; X,Y: integer;
|
||||
out NewCode: TCodeBuffer;
|
||||
out NewX, NewY, NewTopLine: integer): boolean;
|
||||
out NewX, NewY, NewTopLine: integer;
|
||||
Flags: TFindSmartFlags = DefaultFindSmartFlags): boolean;
|
||||
function FindDeclarationOfIdentifier(Code: TCodeBuffer; X,Y: integer;
|
||||
Identifier: PChar;
|
||||
out NewCode: TCodeBuffer;
|
||||
@ -1708,10 +1709,13 @@ end;
|
||||
|
||||
function TCodeToolManager.FindDeclaration(Code: TCodeBuffer; X,Y: integer;
|
||||
out NewCode: TCodeBuffer;
|
||||
out NewX, NewY, NewTopLine: integer): boolean;
|
||||
out NewX, NewY, NewTopLine: integer;
|
||||
Flags: TFindSmartFlags): boolean;
|
||||
var
|
||||
CursorPos: TCodeXYPosition;
|
||||
NewPos: TCodeXYPosition;
|
||||
NewTool: TFindDeclarationTool;
|
||||
NewNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
{$IFDEF CTDEBUG}
|
||||
@ -1729,11 +1733,13 @@ begin
|
||||
DebugLn('TCodeToolManager.FindDeclaration NOT HANDLING EXCEPTIONS');
|
||||
RaiseUnhandableExceptions:=true;
|
||||
{$ENDIF}
|
||||
Result:=FCurCodeTool.FindDeclaration(CursorPos,NewPos,NewTopLine);
|
||||
Result:=FCurCodeTool.FindDeclaration(CursorPos,Flags,NewTool,NewNode,
|
||||
NewPos,NewTopLine);
|
||||
if Result then begin
|
||||
NewX:=NewPos.X;
|
||||
NewY:=NewPos.Y;
|
||||
NewCode:=NewPos.Code;
|
||||
if (NewTool=nil) and (NewNode<>nil) then ;
|
||||
{$IFDEF CTDEBUG}
|
||||
debugln(['TCodeToolManager.FindDeclaration ',DbgsCXY(NewPos)]);
|
||||
{$ENDIF}
|
||||
|
@ -277,8 +277,6 @@ type
|
||||
const AnUpperIdent: string): integer;
|
||||
function CompareSrcIdentifiers(
|
||||
CleanStartPos1, CleanStartPos2: integer): boolean;
|
||||
function CompareSrcIdentifier(CleanStartPos: integer;
|
||||
const Identifier: string): boolean;
|
||||
function CompareSrcIdentifiers(Identifier1, Identifier2: PChar): boolean;
|
||||
function CompareSrcIdentifiers(CleanStartPos: integer;
|
||||
AnIdentifier: PChar): boolean;
|
||||
@ -2453,25 +2451,6 @@ begin
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.CompareSrcIdentifier(CleanStartPos: integer;
|
||||
const Identifier: string): boolean;
|
||||
var IdentPos, Len: integer;
|
||||
begin
|
||||
Result:=false;
|
||||
Len:=length(Identifier);
|
||||
if (CleanStartPos<1) or (CleanStartPos>SrcLen-Len+1) or (Identifier='') then
|
||||
exit;
|
||||
IdentPos:=1;
|
||||
while (IdentPos<=Len) and (IsIdentChar[Src[CleanStartPos]]) do begin
|
||||
if UpChars[Identifier[IdentPos]]<>UpperSrc[CleanStartPos] then
|
||||
exit;
|
||||
inc(IdentPos);
|
||||
inc(CleanStartPos);
|
||||
end;
|
||||
Result:=(IdentPos>Len)
|
||||
and ((CleanStartPos>Srclen) or (not IsIdentChar[Src[CleanStartPos]]));
|
||||
end;
|
||||
|
||||
function TCustomCodeTool.CompareSrcIdentifiers(Identifier1, Identifier2: PChar
|
||||
): boolean;
|
||||
begin
|
||||
|
@ -165,6 +165,7 @@ type
|
||||
// instead return the variable declaration
|
||||
fdfFunctionResult, // if function is found, return result type
|
||||
fdfFindChilds, // search the class of a 'class of'
|
||||
fdfSkipClassForward, // when a class forward was found search the class
|
||||
|
||||
fdfCollect, // return every reachable identifier
|
||||
fdfTopLvlResolving, // set, when searching for an identifier of the
|
||||
@ -197,6 +198,7 @@ const
|
||||
'fdfFindVariable',
|
||||
'fdfFunctionResult',
|
||||
'fdfFindChilds',
|
||||
'fdfSkipClassForward',
|
||||
'fdfCollect',
|
||||
'fdfTopLvlResolving',
|
||||
'fdfDoNotCache'
|
||||
@ -517,7 +519,8 @@ type
|
||||
TFindSmartFlag = (
|
||||
fsfIncludeDirective, // search for include file
|
||||
fsfFindMainDeclaration, // stop if already on a declaration
|
||||
fsfSearchSourceName // if searching for a unit name, return the source name node
|
||||
fsfSearchSourceName, // if searching for a unit name, return the source name node
|
||||
fsfSkipClassForward // when a forward class was found, jump further to the class
|
||||
);
|
||||
TFindSmartFlags = set of TFindSmartFlag;
|
||||
|
||||
@ -532,7 +535,7 @@ type
|
||||
TFindDeclarationListFlags = set of TFindDeclarationListFlag;
|
||||
|
||||
const
|
||||
AllFindSmartFlags = [fsfIncludeDirective];
|
||||
DefaultFindSmartFlags = [fsfIncludeDirective];
|
||||
|
||||
type
|
||||
//----------------------------------------------------------------------------
|
||||
@ -653,6 +656,7 @@ type
|
||||
Params: TFindDeclarationParams; FindClassContext: boolean): boolean;
|
||||
function FindForwardIdentifier(Params: TFindDeclarationParams;
|
||||
var IsForward: boolean): boolean;
|
||||
function FindNonForwardClass(Params: TFindDeclarationParams): boolean;
|
||||
function FindExpressionResultType(Params: TFindDeclarationParams;
|
||||
StartPos, EndPos: integer): TExpressionType;
|
||||
function FindCodeToolForUsedUnit(UnitNameAtom,
|
||||
@ -1135,7 +1139,7 @@ var
|
||||
NewTool: TFindDeclarationTool;
|
||||
NewNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=FindDeclaration(CursorPos,AllFindSmartFlags,NewTool,NewNode,
|
||||
Result:=FindDeclaration(CursorPos,DefaultFindSmartFlags,NewTool,NewNode,
|
||||
NewPos,NewTopLine);
|
||||
end;
|
||||
|
||||
@ -1222,6 +1226,13 @@ var CleanCursorPos: integer;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CheckIfCursorInTypeNode;
|
||||
begin
|
||||
if (CursorNode.Desc in AllIdentifierDefinitions)
|
||||
and (fsfSkipClassForward in SearchSmartFlags) then
|
||||
Exclude(SearchSmartFlags,fsfSkipClassForward);
|
||||
end;
|
||||
|
||||
procedure CheckIfCursorInClassNode;
|
||||
begin
|
||||
if SkipChecks then exit;
|
||||
@ -1402,6 +1413,7 @@ begin
|
||||
SearchForward:=false;
|
||||
CheckIfCursorOnAForwardDefinedClass;
|
||||
CheckIfCursorInClassNode;
|
||||
CheckIfCursorInTypeNode;
|
||||
CheckIfCursorInBeginNode;
|
||||
CheckIfCursorInProcNode;
|
||||
CheckIfCursorInPropertyNode;
|
||||
@ -1426,6 +1438,8 @@ begin
|
||||
Params.Flags:=[fdfSearchInParentNodes,fdfExceptionOnNotFound,
|
||||
fdfExceptionOnPredefinedIdent,
|
||||
fdfTopLvlResolving,fdfSearchInAncestors];
|
||||
if fsfSkipClassForward in SearchSmartFlags then
|
||||
Include(Params.Flags,fdfSkipClassForward);
|
||||
if not DirectSearch then begin
|
||||
// ToDo: DirtySrc
|
||||
Result:=FindDeclarationOfIdentAtParam(Params);
|
||||
@ -1718,7 +1732,7 @@ function TFindDeclarationTool.FindNameInUsesSection(UsesNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=UsesNode.FirstChild;
|
||||
while (Result<>nil)
|
||||
and (not CompareSrcIdentifier(Result.StartPos,PChar(UnitName))) do
|
||||
and (not CompareSrcIdentifiers(Result.StartPos,PChar(UnitName))) do
|
||||
Result:=Result.NextBrother;
|
||||
end;
|
||||
|
||||
@ -1976,7 +1990,7 @@ var
|
||||
NodeStr: String;
|
||||
begin
|
||||
Result:='';
|
||||
if FindDeclaration(CursorPos,AllFindSmartFlags,
|
||||
if FindDeclaration(CursorPos,DefaultFindSmartFlags,
|
||||
NewTool,NewNode,NewPos,NewTopLine) then
|
||||
begin
|
||||
{ Examples:
|
||||
@ -2178,6 +2192,7 @@ function TFindDeclarationTool.FindDeclarationOfIdentAtParam(
|
||||
var
|
||||
StartPos, EndPos: integer;
|
||||
ExprType: TExpressionType;
|
||||
SkipForward: boolean;
|
||||
begin
|
||||
{$IFDEF CTDEBUG}
|
||||
DebugLn('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Identifier=',
|
||||
@ -2199,11 +2214,14 @@ begin
|
||||
ReadTilBracketClose(true);
|
||||
EndPos:=CurPos.EndPos;
|
||||
end;
|
||||
SkipForward:=fdfSkipClassForward in Params.Flags;
|
||||
Include(Params.Flags,fdfFindVariable);
|
||||
ExprType:=FindExpressionTypeOfVariable(StartPos,EndPos,Params,false);
|
||||
if (ExprType.Desc<>xtContext) then begin
|
||||
Params.SetResult(CleanFindContext);
|
||||
end;
|
||||
if SkipForward and (Params.NewNode<>nil) then
|
||||
Params.NewCodeTool.FindNonForwardClass(Params);
|
||||
{$IFDEF CTDEBUG}
|
||||
DbgOut('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Ident=',
|
||||
'"',GetIdentifier(Params.Identifier),'" ');
|
||||
@ -2533,8 +2551,16 @@ var
|
||||
// identifier found
|
||||
Params.SetResult(Self,ContextNode);
|
||||
Result:=CheckResult(true,true);
|
||||
if not (fdfCollect in Params.Flags) then
|
||||
if not (fdfCollect in Params.Flags) then begin
|
||||
if (fdfSkipClassForward in Params.Flags)
|
||||
and (ContextNode.FirstChild<>nil)
|
||||
and (ContextNode.FirstChild.Desc in [ctnClass,ctnClassInheritance])
|
||||
and ((ctnsForwardDeclaration and ContextNode.FirstChild.SubDesc)<>0)
|
||||
then begin
|
||||
FindNonForwardClass(Params);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
// search for enums
|
||||
Params.ContextNode:=ContextNode;
|
||||
@ -3565,7 +3591,7 @@ begin
|
||||
CurCursorPos:=CursorPos;
|
||||
CurTool:=Self;
|
||||
try
|
||||
while CurTool.FindDeclaration(CurCursorPos,AllFindSmartFlags
|
||||
while CurTool.FindDeclaration(CurCursorPos,DefaultFindSmartFlags
|
||||
+[fsfSearchSourceName],
|
||||
NewTool,NewNode,NewPos,NewTopLine) do
|
||||
begin
|
||||
@ -4533,13 +4559,13 @@ begin
|
||||
end;
|
||||
if ClassNode.Desc=ctnClass then begin
|
||||
// if this class is not TObject, TObject is class ancestor
|
||||
SearchBaseClass:=not CompareSrcIdentifier(ClassIdentNode.StartPos,'TObject');
|
||||
SearchBaseClass:=not CompareSrcIdentifiers(ClassIdentNode.StartPos,'TObject');
|
||||
end else begin
|
||||
// Delphi has as default interface IInterface
|
||||
// FPC has as default interface IUnknown and an alias IInterface = IUnknown
|
||||
SearchBaseClass:=
|
||||
(not CompareSrcIdentifier(ClassIdentNode.StartPos,'IInterface'))
|
||||
and (not CompareSrcIdentifier(ClassIdentNode.StartPos,'IUnknown'));
|
||||
(not CompareSrcIdentifiers(ClassIdentNode.StartPos,'IInterface'))
|
||||
and (not CompareSrcIdentifiers(ClassIdentNode.StartPos,'IUnknown'));
|
||||
end;
|
||||
if not SearchBaseClass then exit;
|
||||
|
||||
@ -4748,6 +4774,48 @@ begin
|
||||
Params.Load(OldInput,true);
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.FindNonForwardClass(Params: TFindDeclarationParams
|
||||
): boolean;
|
||||
var
|
||||
Node: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
Node:=Params.NewNode;
|
||||
if Node.Desc=ctnGenericType then begin
|
||||
Node:=Node.FirstChild;
|
||||
if Node=nil then exit;
|
||||
end else if Node.Desc<>ctnTypeDefinition then
|
||||
exit;
|
||||
Node:=Node.FirstChild;
|
||||
if (Node=nil)
|
||||
or (not (Node.Desc in [ctnClass,ctnClassInterface]))
|
||||
or ((ctnsForwardDeclaration and Node.SubDesc)=0) then
|
||||
exit;
|
||||
Node:=Params.NewNode;
|
||||
repeat
|
||||
//DebugLn(['TFindDeclarationTool.FindNonForwardClass Node=',dbgstr(copy(Src,Node.StartPos,20))]);
|
||||
if Node.NextBrother<>nil then
|
||||
Node:=Node.NextBrother
|
||||
else if (Node.Parent=nil)
|
||||
or (not (Node.Parent.Desc in AllDefinitionSections)) then
|
||||
break
|
||||
else begin
|
||||
Node:=Node.Parent.NextBrother;
|
||||
while (Node<>nil)
|
||||
and ((Node.FirstChild=nil) or (not (Node.Desc in AllDefinitionSections)))
|
||||
do
|
||||
Node:=Node.NextBrother;
|
||||
if Node=nil then break;
|
||||
Node:=Node.FirstChild;
|
||||
end;
|
||||
if CompareSrcIdentifiers(Node.StartPos,Params.Identifier) then begin
|
||||
Params.SetResult(Self,Node,Node.StartPos);
|
||||
Result:=true;
|
||||
exit;
|
||||
end;
|
||||
until false;
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.FindIdentifierInWithVarContext(
|
||||
WithVarNode: TCodeTreeNode; Params: TFindDeclarationParams): boolean;
|
||||
{ this function is internally used by FindIdentifierInContext }
|
||||
@ -5981,7 +6049,7 @@ var
|
||||
IdentFound:=false;
|
||||
if (ExprType.Context.Node<>nil)
|
||||
and (ExprType.Context.Node.Desc in AllPascalStatements) then begin
|
||||
if CompareSrcIdentifier(CurAtom.StartPos,'SELF') then begin
|
||||
if CompareSrcIdentifiers(CurAtom.StartPos,'SELF') then begin
|
||||
// SELF in a method is the object itself
|
||||
// -> check if in a method or nested proc of a method
|
||||
ProcNode:=ExprType.Context.Node;
|
||||
@ -5998,7 +6066,7 @@ var
|
||||
ExprType.Context:=CreateFindContext(Params);
|
||||
IdentFound:=true;
|
||||
end;
|
||||
end else if CompareSrcIdentifier(CurAtom.StartPos,'RESULT') then begin
|
||||
end else if CompareSrcIdentifiers(CurAtom.StartPos,'RESULT') then begin
|
||||
// RESULT has a special meaning in a function
|
||||
// -> check if in a function
|
||||
ProcNode:=ExprType.Context.Node.GetNodeOfType(ctnProcedure);
|
||||
|
@ -1453,26 +1453,26 @@ begin
|
||||
if (CurrentContexts.ProcName='') then exit;
|
||||
FoundContext.Tool.MoveCursorToProcName(FoundContext.Node,true);
|
||||
//DebugLn(['TIdentCompletionTool.CollectAllContexts ProcName=',GetIdentifier(@FoundContext.Tool.Src[FoundContext.Tool.CurPos.StartPos])]);
|
||||
if not FoundContext.Tool.CompareSrcIdentifier(
|
||||
if not FoundContext.Tool.CompareSrcIdentifiers(
|
||||
FoundContext.Tool.CurPos.StartPos,
|
||||
CurrentContexts.ProcName)
|
||||
PChar(CurrentContexts.ProcName))
|
||||
then exit;
|
||||
end;
|
||||
ctnProperty:
|
||||
begin
|
||||
if (CurrentContexts.ProcName='') then exit;
|
||||
FoundContext.Tool.MoveCursorToPropName(FoundContext.Node);
|
||||
if not FoundContext.Tool.CompareSrcIdentifier(
|
||||
if not FoundContext.Tool.CompareSrcIdentifiers(
|
||||
FoundContext.Tool.CurPos.StartPos,
|
||||
CurrentContexts.ProcName)
|
||||
PChar(CurrentContexts.ProcName))
|
||||
then exit;
|
||||
end;
|
||||
ctnVarDefinition:
|
||||
begin
|
||||
if (CurrentContexts.ProcName='') then exit;
|
||||
if not FoundContext.Tool.CompareSrcIdentifier(
|
||||
if not FoundContext.Tool.CompareSrcIdentifiers(
|
||||
FoundContext.Node.StartPos,
|
||||
CurrentContexts.ProcName)
|
||||
PChar(CurrentContexts.ProcName))
|
||||
then exit;
|
||||
end;
|
||||
else
|
||||
|
@ -3560,7 +3560,7 @@ begin
|
||||
ANode:=ANode.FirstChild;
|
||||
while ANode<>nil do begin
|
||||
if (ANode.Desc=ctnConstDefinition)
|
||||
and CompareSrcIdentifier(ANode.StartPos,ResStrIdentifier) then begin
|
||||
and CompareSrcIdentifiers(ANode.StartPos,PChar(ResStrIdentifier)) then begin
|
||||
Result:=true;
|
||||
exit;
|
||||
end;
|
||||
|
@ -77,7 +77,7 @@ uses
|
||||
LResources, StdCtrls, Forms, Buttons, Menus, FileUtil, Controls, GraphType,
|
||||
HelpIntfs, Graphics, ExtCtrls, Dialogs, InterfaceBase, LDockCtrl, UTF8Process,
|
||||
// codetools
|
||||
LinkScanner, BasicCodeTools, AVL_Tree, Laz_XMLCfg,
|
||||
FindDeclarationTool, LinkScanner, BasicCodeTools, AVL_Tree, Laz_XMLCfg,
|
||||
CodeToolsStructs, CodeToolManager, CodeCache, DefineTemplates,
|
||||
// synedit
|
||||
SynEditKeyCmds,
|
||||
@ -12578,8 +12578,10 @@ begin
|
||||
//DebugLn(['TMainIDE.DoFindDeclarationAtCaret LogCaretXY=',dbgs(LogCaretXY),' SynEdit.Log=',dbgs(ActiveSrcEdit.EditorComponent.LogicalCaretXY),' SynEdit.Caret=',dbgs(ActiveSrcEdit.EditorComponent.CaretXY)]);
|
||||
if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source,
|
||||
LogCaretXY.X,LogCaretXY.Y,
|
||||
NewSource,NewX,NewY,NewTopLine) then
|
||||
begin
|
||||
NewSource,NewX,NewY,NewTopLine,DefaultFindSmartFlags
|
||||
//+[fsfSkipClassForward]
|
||||
)
|
||||
then begin
|
||||
//debugln(['TMainIDE.DoFindDeclarationAtCaret ',NewSource.Filename,' NewX=',Newx,',y=',NewY,' ',NewTopLine]);
|
||||
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
|
||||
NewSource, NewX, NewY, NewTopLine, true);
|
||||
|
Loading…
Reference in New Issue
Block a user