MG: find declaration of local variables

git-svn-id: trunk@592 -
This commit is contained in:
lazarus 2002-01-13 16:26:32 +00:00
parent 10f8e1e489
commit 931b619b18
2 changed files with 77 additions and 11 deletions

View File

@ -120,6 +120,8 @@ type
const ASource: string): integer;
function CompareNodeUpSrc(ANode: TCodeTreeNode;
const ASource: string): integer;
function CompareSrcIdentifiers(
CleanStartPos1, CleanStartPos2: integer): boolean;
procedure ReadPriorAtom;
procedure CreateChildNode;
@ -379,6 +381,23 @@ begin
Result:=-1;
end;
function TCustomCodeTool.CompareSrcIdentifiers(
CleanStartPos1, CleanStartPos2: integer): boolean;
begin
Result:=(CleanStartPos1>=1) and (CleanStartPos1<=SrcLen)
and (CleanStartPos2>=1) and (CleanStartPos2<=SrcLen);
if not Result then exit;
while (CleanStartPos1<=SrcLen) and (IsIdentChar[Src[CleanStartPos1]]) do begin
if (UpperSrc[CleanStartPos1]<>UpperSrc[CleanStartPos2]) then begin
Result:=false;
exit;
end;
inc(CleanStartPos1);
inc(CleanStartPos2);
end;
Result:=(CleanStartPos2>SrcLen) or (not IsIdentChar[Src[CleanStartPos2]]);
end;
function TCustomCodeTool.AtomIsChar(const c: char): boolean;
begin
Result:=(CurPos.StartPos<=SrcLen)

View File

@ -35,6 +35,8 @@ interface
{$I codetools.inc}
{ $DEFINE CTDEBUG}
uses
{$IFDEF MEM_CHECK}
MemCheck,
@ -103,6 +105,9 @@ writeln('TFindDeclarationTool.FindDeclaration C CleanCursorPos=',CleanCursorPos)
Result:=true;
exit;
end;
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindDeclaration D CursorNode=',NodeDescriptionAsString(CursorNode.Desc));
{$ENDIF}
if CursorNode.Desc=ctnUsesSection then begin
// find used unit
Result:=FindDeclarationInUsesSection(CursorNode,CleanCursorPos,
@ -111,10 +116,12 @@ writeln('TFindDeclarationTool.FindDeclaration C CleanCursorPos=',CleanCursorPos)
if CursorNode.Desc=ctnBeginBlock then
BuildSubTreeForBeginBlock(CursorNode);
MoveCursorToCleanPos(CleanCursorPos);
while (CurPos.StartPos>=1) and (IsIdentChar[Src[CurPos.StartPos]]) do
while (CurPos.StartPos>1) and (IsIdentChar[Src[CurPos.StartPos-1]]) do
dec(CurPos.StartPos);
writeln('AAA ',CurPos.StartPos,',',Src[CurPos.StartPos]);
if (CurPos.StartPos>=1) and (IsIdentStartChar[Src[CurPos.StartPos]]) then
begin
writeln('AAA2');
CurPos.EndPos:=CurPos.StartPos;
while (CurPos.EndPos<=SrcLen) and IsIdentChar[Src[CurPos.EndPos]] do
inc(CurPos.EndPos);
@ -388,9 +395,17 @@ function TFindDeclarationTool.FindDeclarationOfIdentifier(
A^.B().C[].Identifier
}
begin
{$IFDEF CTDEBUG}
writeln('[TFindDeclarationTool.FindDeclarationOfIdentifier] Identifier=',
copy(Src,IdentifierStartPos,IdentifierEndPos-IdentifierStartPos),
' DeepestNode=',NodeDescriptionAsString(DeepestNode.Desc));
{$ENDIF}
Result:=false;
MoveCursorToCleanPos(IdentifierStartPos);
ReadPriorAtom;
{$IFDEF CTDEBUG}
writeln('[TFindDeclarationTool.FindDeclarationOfIdentifier] B PriorAtom=',GetAtom);
{$ENDIF}
if AtomIsChar('.') then begin
// first search context, then search in context
@ -440,23 +455,55 @@ end;
function TFindDeclarationTool.FindIdentifierInContext(IdentifierStartPos,
IdentifierEndPos: integer; ContextNode: TCodeTreeNode;
SearchInParentNodes: boolean; var NewPos: TCodeXYPosition;
var NewTopLine: integer): boolean;
SearchInParentNodes: boolean;
var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
{ searches an identifier in context node
It does not care about code in front
It does not care about code in front of the identifier like 'a.Identifer'.
}
var LastContextNode: TCodeTreeNode;
begin
Result:=false;
if ContextNode<>nil then begin
case ContextNode.Desc of
ctnBeginBlock:
begin
if not SearchInParentNodes then exit;
// ToDo
repeat
{$IFDEF CTDEBUG}
writeln('[TFindDeclarationTool.FindIdentifierInContext] ',NodeDescriptionAsString(ContextNode.Desc));
{$ENDIF}
LastContextNode:=ContextNode;
case ContextNode.Desc of
ctnTypeSection, ctnVarSection, ctnConstSection, ctnResStrSection:
begin
if ContextNode.LastChild<>nil then
ContextNode:=ContextNode.LastChild;
end;
ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition:
begin
if CompareSrcIdentifiers(IdentifierStartPos,ContextNode.StartPos) then
begin
// identifier found
Result:=CleanPosToCaretAndTopLine(ContextNode.StartPos,
NewPos,NewTopLine);
exit;
end;
// search for enums
// ToDo
end;
end;
end;
if LastContextNode=ContextNode then begin
// same context -> search in higher context
if not SearchInParentNodes then exit;
if ContextNode.PriorBrother<>nil then
ContextNode:=ContextNode.PriorBrother
else if ContextNode.Parent<>nil then
ContextNode:=ContextNode.Parent
else
break;
end;
until ContextNode=nil;
end else begin
// DeepestNode=nil
end;