codetools: find declaratuion: added flag to skip forward class

git-svn-id: trunk@19814 -
This commit is contained in:
mattias 2009-05-05 18:02:20 +00:00
parent ed6ba36741
commit 3e5a744e2d
6 changed files with 101 additions and 46 deletions

View File

@ -364,7 +364,8 @@ type
// find declaration // find declaration
function FindDeclaration(Code: TCodeBuffer; X,Y: integer; function FindDeclaration(Code: TCodeBuffer; X,Y: integer;
out NewCode: TCodeBuffer; 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; function FindDeclarationOfIdentifier(Code: TCodeBuffer; X,Y: integer;
Identifier: PChar; Identifier: PChar;
out NewCode: TCodeBuffer; out NewCode: TCodeBuffer;
@ -1708,10 +1709,13 @@ end;
function TCodeToolManager.FindDeclaration(Code: TCodeBuffer; X,Y: integer; function TCodeToolManager.FindDeclaration(Code: TCodeBuffer; X,Y: integer;
out NewCode: TCodeBuffer; out NewCode: TCodeBuffer;
out NewX, NewY, NewTopLine: integer): boolean; out NewX, NewY, NewTopLine: integer;
Flags: TFindSmartFlags): boolean;
var var
CursorPos: TCodeXYPosition; CursorPos: TCodeXYPosition;
NewPos: TCodeXYPosition; NewPos: TCodeXYPosition;
NewTool: TFindDeclarationTool;
NewNode: TCodeTreeNode;
begin begin
Result:=false; Result:=false;
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
@ -1729,11 +1733,13 @@ begin
DebugLn('TCodeToolManager.FindDeclaration NOT HANDLING EXCEPTIONS'); DebugLn('TCodeToolManager.FindDeclaration NOT HANDLING EXCEPTIONS');
RaiseUnhandableExceptions:=true; RaiseUnhandableExceptions:=true;
{$ENDIF} {$ENDIF}
Result:=FCurCodeTool.FindDeclaration(CursorPos,NewPos,NewTopLine); Result:=FCurCodeTool.FindDeclaration(CursorPos,Flags,NewTool,NewNode,
NewPos,NewTopLine);
if Result then begin if Result then begin
NewX:=NewPos.X; NewX:=NewPos.X;
NewY:=NewPos.Y; NewY:=NewPos.Y;
NewCode:=NewPos.Code; NewCode:=NewPos.Code;
if (NewTool=nil) and (NewNode<>nil) then ;
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
debugln(['TCodeToolManager.FindDeclaration ',DbgsCXY(NewPos)]); debugln(['TCodeToolManager.FindDeclaration ',DbgsCXY(NewPos)]);
{$ENDIF} {$ENDIF}

View File

@ -277,8 +277,6 @@ type
const AnUpperIdent: string): integer; const AnUpperIdent: string): integer;
function CompareSrcIdentifiers( function CompareSrcIdentifiers(
CleanStartPos1, CleanStartPos2: integer): boolean; CleanStartPos1, CleanStartPos2: integer): boolean;
function CompareSrcIdentifier(CleanStartPos: integer;
const Identifier: string): boolean;
function CompareSrcIdentifiers(Identifier1, Identifier2: PChar): boolean; function CompareSrcIdentifiers(Identifier1, Identifier2: PChar): boolean;
function CompareSrcIdentifiers(CleanStartPos: integer; function CompareSrcIdentifiers(CleanStartPos: integer;
AnIdentifier: PChar): boolean; AnIdentifier: PChar): boolean;
@ -2453,25 +2451,6 @@ begin
{$ENDIF} {$ENDIF}
end; 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 function TCustomCodeTool.CompareSrcIdentifiers(Identifier1, Identifier2: PChar
): boolean; ): boolean;
begin begin

View File

@ -165,6 +165,7 @@ type
// instead return the variable declaration // instead return the variable declaration
fdfFunctionResult, // if function is found, return result type fdfFunctionResult, // if function is found, return result type
fdfFindChilds, // search the class of a 'class of' fdfFindChilds, // search the class of a 'class of'
fdfSkipClassForward, // when a class forward was found search the class
fdfCollect, // return every reachable identifier fdfCollect, // return every reachable identifier
fdfTopLvlResolving, // set, when searching for an identifier of the fdfTopLvlResolving, // set, when searching for an identifier of the
@ -197,6 +198,7 @@ const
'fdfFindVariable', 'fdfFindVariable',
'fdfFunctionResult', 'fdfFunctionResult',
'fdfFindChilds', 'fdfFindChilds',
'fdfSkipClassForward',
'fdfCollect', 'fdfCollect',
'fdfTopLvlResolving', 'fdfTopLvlResolving',
'fdfDoNotCache' 'fdfDoNotCache'
@ -517,7 +519,8 @@ type
TFindSmartFlag = ( TFindSmartFlag = (
fsfIncludeDirective, // search for include file fsfIncludeDirective, // search for include file
fsfFindMainDeclaration, // stop if already on a declaration 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; TFindSmartFlags = set of TFindSmartFlag;
@ -532,7 +535,7 @@ type
TFindDeclarationListFlags = set of TFindDeclarationListFlag; TFindDeclarationListFlags = set of TFindDeclarationListFlag;
const const
AllFindSmartFlags = [fsfIncludeDirective]; DefaultFindSmartFlags = [fsfIncludeDirective];
type type
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -653,6 +656,7 @@ type
Params: TFindDeclarationParams; FindClassContext: boolean): boolean; Params: TFindDeclarationParams; FindClassContext: boolean): boolean;
function FindForwardIdentifier(Params: TFindDeclarationParams; function FindForwardIdentifier(Params: TFindDeclarationParams;
var IsForward: boolean): boolean; var IsForward: boolean): boolean;
function FindNonForwardClass(Params: TFindDeclarationParams): boolean;
function FindExpressionResultType(Params: TFindDeclarationParams; function FindExpressionResultType(Params: TFindDeclarationParams;
StartPos, EndPos: integer): TExpressionType; StartPos, EndPos: integer): TExpressionType;
function FindCodeToolForUsedUnit(UnitNameAtom, function FindCodeToolForUsedUnit(UnitNameAtom,
@ -1135,7 +1139,7 @@ var
NewTool: TFindDeclarationTool; NewTool: TFindDeclarationTool;
NewNode: TCodeTreeNode; NewNode: TCodeTreeNode;
begin begin
Result:=FindDeclaration(CursorPos,AllFindSmartFlags,NewTool,NewNode, Result:=FindDeclaration(CursorPos,DefaultFindSmartFlags,NewTool,NewNode,
NewPos,NewTopLine); NewPos,NewTopLine);
end; end;
@ -1222,6 +1226,13 @@ var CleanCursorPos: integer;
end; end;
end; end;
procedure CheckIfCursorInTypeNode;
begin
if (CursorNode.Desc in AllIdentifierDefinitions)
and (fsfSkipClassForward in SearchSmartFlags) then
Exclude(SearchSmartFlags,fsfSkipClassForward);
end;
procedure CheckIfCursorInClassNode; procedure CheckIfCursorInClassNode;
begin begin
if SkipChecks then exit; if SkipChecks then exit;
@ -1402,6 +1413,7 @@ begin
SearchForward:=false; SearchForward:=false;
CheckIfCursorOnAForwardDefinedClass; CheckIfCursorOnAForwardDefinedClass;
CheckIfCursorInClassNode; CheckIfCursorInClassNode;
CheckIfCursorInTypeNode;
CheckIfCursorInBeginNode; CheckIfCursorInBeginNode;
CheckIfCursorInProcNode; CheckIfCursorInProcNode;
CheckIfCursorInPropertyNode; CheckIfCursorInPropertyNode;
@ -1426,6 +1438,8 @@ begin
Params.Flags:=[fdfSearchInParentNodes,fdfExceptionOnNotFound, Params.Flags:=[fdfSearchInParentNodes,fdfExceptionOnNotFound,
fdfExceptionOnPredefinedIdent, fdfExceptionOnPredefinedIdent,
fdfTopLvlResolving,fdfSearchInAncestors]; fdfTopLvlResolving,fdfSearchInAncestors];
if fsfSkipClassForward in SearchSmartFlags then
Include(Params.Flags,fdfSkipClassForward);
if not DirectSearch then begin if not DirectSearch then begin
// ToDo: DirtySrc // ToDo: DirtySrc
Result:=FindDeclarationOfIdentAtParam(Params); Result:=FindDeclarationOfIdentAtParam(Params);
@ -1718,7 +1732,7 @@ function TFindDeclarationTool.FindNameInUsesSection(UsesNode: TCodeTreeNode;
begin begin
Result:=UsesNode.FirstChild; Result:=UsesNode.FirstChild;
while (Result<>nil) while (Result<>nil)
and (not CompareSrcIdentifier(Result.StartPos,PChar(UnitName))) do and (not CompareSrcIdentifiers(Result.StartPos,PChar(UnitName))) do
Result:=Result.NextBrother; Result:=Result.NextBrother;
end; end;
@ -1976,7 +1990,7 @@ var
NodeStr: String; NodeStr: String;
begin begin
Result:=''; Result:='';
if FindDeclaration(CursorPos,AllFindSmartFlags, if FindDeclaration(CursorPos,DefaultFindSmartFlags,
NewTool,NewNode,NewPos,NewTopLine) then NewTool,NewNode,NewPos,NewTopLine) then
begin begin
{ Examples: { Examples:
@ -2178,6 +2192,7 @@ function TFindDeclarationTool.FindDeclarationOfIdentAtParam(
var var
StartPos, EndPos: integer; StartPos, EndPos: integer;
ExprType: TExpressionType; ExprType: TExpressionType;
SkipForward: boolean;
begin begin
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
DebugLn('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Identifier=', DebugLn('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Identifier=',
@ -2199,11 +2214,14 @@ begin
ReadTilBracketClose(true); ReadTilBracketClose(true);
EndPos:=CurPos.EndPos; EndPos:=CurPos.EndPos;
end; end;
SkipForward:=fdfSkipClassForward in Params.Flags;
Include(Params.Flags,fdfFindVariable); Include(Params.Flags,fdfFindVariable);
ExprType:=FindExpressionTypeOfVariable(StartPos,EndPos,Params,false); ExprType:=FindExpressionTypeOfVariable(StartPos,EndPos,Params,false);
if (ExprType.Desc<>xtContext) then begin if (ExprType.Desc<>xtContext) then begin
Params.SetResult(CleanFindContext); Params.SetResult(CleanFindContext);
end; end;
if SkipForward and (Params.NewNode<>nil) then
Params.NewCodeTool.FindNonForwardClass(Params);
{$IFDEF CTDEBUG} {$IFDEF CTDEBUG}
DbgOut('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Ident=', DbgOut('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Ident=',
'"',GetIdentifier(Params.Identifier),'" '); '"',GetIdentifier(Params.Identifier),'" ');
@ -2533,8 +2551,16 @@ var
// identifier found // identifier found
Params.SetResult(Self,ContextNode); Params.SetResult(Self,ContextNode);
Result:=CheckResult(true,true); 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; exit;
end;
end; end;
// search for enums // search for enums
Params.ContextNode:=ContextNode; Params.ContextNode:=ContextNode;
@ -3565,7 +3591,7 @@ begin
CurCursorPos:=CursorPos; CurCursorPos:=CursorPos;
CurTool:=Self; CurTool:=Self;
try try
while CurTool.FindDeclaration(CurCursorPos,AllFindSmartFlags while CurTool.FindDeclaration(CurCursorPos,DefaultFindSmartFlags
+[fsfSearchSourceName], +[fsfSearchSourceName],
NewTool,NewNode,NewPos,NewTopLine) do NewTool,NewNode,NewPos,NewTopLine) do
begin begin
@ -4533,13 +4559,13 @@ begin
end; end;
if ClassNode.Desc=ctnClass then begin if ClassNode.Desc=ctnClass then begin
// if this class is not TObject, TObject is class ancestor // 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 end else begin
// Delphi has as default interface IInterface // Delphi has as default interface IInterface
// FPC has as default interface IUnknown and an alias IInterface = IUnknown // FPC has as default interface IUnknown and an alias IInterface = IUnknown
SearchBaseClass:= SearchBaseClass:=
(not CompareSrcIdentifier(ClassIdentNode.StartPos,'IInterface')) (not CompareSrcIdentifiers(ClassIdentNode.StartPos,'IInterface'))
and (not CompareSrcIdentifier(ClassIdentNode.StartPos,'IUnknown')); and (not CompareSrcIdentifiers(ClassIdentNode.StartPos,'IUnknown'));
end; end;
if not SearchBaseClass then exit; if not SearchBaseClass then exit;
@ -4748,6 +4774,48 @@ begin
Params.Load(OldInput,true); Params.Load(OldInput,true);
end; 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( function TFindDeclarationTool.FindIdentifierInWithVarContext(
WithVarNode: TCodeTreeNode; Params: TFindDeclarationParams): boolean; WithVarNode: TCodeTreeNode; Params: TFindDeclarationParams): boolean;
{ this function is internally used by FindIdentifierInContext } { this function is internally used by FindIdentifierInContext }
@ -5981,7 +6049,7 @@ var
IdentFound:=false; IdentFound:=false;
if (ExprType.Context.Node<>nil) if (ExprType.Context.Node<>nil)
and (ExprType.Context.Node.Desc in AllPascalStatements) then begin 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 // SELF in a method is the object itself
// -> check if in a method or nested proc of a method // -> check if in a method or nested proc of a method
ProcNode:=ExprType.Context.Node; ProcNode:=ExprType.Context.Node;
@ -5998,7 +6066,7 @@ var
ExprType.Context:=CreateFindContext(Params); ExprType.Context:=CreateFindContext(Params);
IdentFound:=true; IdentFound:=true;
end; 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 // RESULT has a special meaning in a function
// -> check if in a function // -> check if in a function
ProcNode:=ExprType.Context.Node.GetNodeOfType(ctnProcedure); ProcNode:=ExprType.Context.Node.GetNodeOfType(ctnProcedure);

View File

@ -1453,26 +1453,26 @@ begin
if (CurrentContexts.ProcName='') then exit; if (CurrentContexts.ProcName='') then exit;
FoundContext.Tool.MoveCursorToProcName(FoundContext.Node,true); FoundContext.Tool.MoveCursorToProcName(FoundContext.Node,true);
//DebugLn(['TIdentCompletionTool.CollectAllContexts ProcName=',GetIdentifier(@FoundContext.Tool.Src[FoundContext.Tool.CurPos.StartPos])]); //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, FoundContext.Tool.CurPos.StartPos,
CurrentContexts.ProcName) PChar(CurrentContexts.ProcName))
then exit; then exit;
end; end;
ctnProperty: ctnProperty:
begin begin
if (CurrentContexts.ProcName='') then exit; if (CurrentContexts.ProcName='') then exit;
FoundContext.Tool.MoveCursorToPropName(FoundContext.Node); FoundContext.Tool.MoveCursorToPropName(FoundContext.Node);
if not FoundContext.Tool.CompareSrcIdentifier( if not FoundContext.Tool.CompareSrcIdentifiers(
FoundContext.Tool.CurPos.StartPos, FoundContext.Tool.CurPos.StartPos,
CurrentContexts.ProcName) PChar(CurrentContexts.ProcName))
then exit; then exit;
end; end;
ctnVarDefinition: ctnVarDefinition:
begin begin
if (CurrentContexts.ProcName='') then exit; if (CurrentContexts.ProcName='') then exit;
if not FoundContext.Tool.CompareSrcIdentifier( if not FoundContext.Tool.CompareSrcIdentifiers(
FoundContext.Node.StartPos, FoundContext.Node.StartPos,
CurrentContexts.ProcName) PChar(CurrentContexts.ProcName))
then exit; then exit;
end; end;
else else

View File

@ -3560,7 +3560,7 @@ begin
ANode:=ANode.FirstChild; ANode:=ANode.FirstChild;
while ANode<>nil do begin while ANode<>nil do begin
if (ANode.Desc=ctnConstDefinition) if (ANode.Desc=ctnConstDefinition)
and CompareSrcIdentifier(ANode.StartPos,ResStrIdentifier) then begin and CompareSrcIdentifiers(ANode.StartPos,PChar(ResStrIdentifier)) then begin
Result:=true; Result:=true;
exit; exit;
end; end;

View File

@ -77,7 +77,7 @@ uses
LResources, StdCtrls, Forms, Buttons, Menus, FileUtil, Controls, GraphType, LResources, StdCtrls, Forms, Buttons, Menus, FileUtil, Controls, GraphType,
HelpIntfs, Graphics, ExtCtrls, Dialogs, InterfaceBase, LDockCtrl, UTF8Process, HelpIntfs, Graphics, ExtCtrls, Dialogs, InterfaceBase, LDockCtrl, UTF8Process,
// codetools // codetools
LinkScanner, BasicCodeTools, AVL_Tree, Laz_XMLCfg, FindDeclarationTool, LinkScanner, BasicCodeTools, AVL_Tree, Laz_XMLCfg,
CodeToolsStructs, CodeToolManager, CodeCache, DefineTemplates, CodeToolsStructs, CodeToolManager, CodeCache, DefineTemplates,
// synedit // synedit
SynEditKeyCmds, SynEditKeyCmds,
@ -12578,8 +12578,10 @@ begin
//DebugLn(['TMainIDE.DoFindDeclarationAtCaret LogCaretXY=',dbgs(LogCaretXY),' SynEdit.Log=',dbgs(ActiveSrcEdit.EditorComponent.LogicalCaretXY),' SynEdit.Caret=',dbgs(ActiveSrcEdit.EditorComponent.CaretXY)]); //DebugLn(['TMainIDE.DoFindDeclarationAtCaret LogCaretXY=',dbgs(LogCaretXY),' SynEdit.Log=',dbgs(ActiveSrcEdit.EditorComponent.LogicalCaretXY),' SynEdit.Caret=',dbgs(ActiveSrcEdit.EditorComponent.CaretXY)]);
if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source, if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source,
LogCaretXY.X,LogCaretXY.Y, LogCaretXY.X,LogCaretXY.Y,
NewSource,NewX,NewY,NewTopLine) then NewSource,NewX,NewY,NewTopLine,DefaultFindSmartFlags
begin //+[fsfSkipClassForward]
)
then begin
//debugln(['TMainIDE.DoFindDeclarationAtCaret ',NewSource.Filename,' NewX=',Newx,',y=',NewY,' ',NewTopLine]); //debugln(['TMainIDE.DoFindDeclarationAtCaret ',NewSource.Filename,' NewX=',Newx,',y=',NewY,' ',NewTopLine]);
DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo, DoJumpToCodePos(ActiveSrcEdit, ActiveUnitInfo,
NewSource, NewX, NewY, NewTopLine, true); NewSource, NewX, NewY, NewTopLine, true);