codetools: identifier completion search at start of identifier and at end of valid code, bug #10548

git-svn-id: trunk@19613 -
This commit is contained in:
mattias 2009-04-24 18:01:03 +00:00
parent 0c273e0445
commit 8f2bc2fdb1
3 changed files with 45 additions and 11 deletions

View File

@ -2150,19 +2150,21 @@ function TCustomCodeTool.FindDeepestNodeAtPos(StartNode: TCodeTreeNode;
var
ChildNode: TCodeTreeNode;
Brother: TCodeTreeNode;
Node: TCodeTreeNode;
begin
{$IFDEF CheckNodeTool}CheckNodeTool(StartNode);{$ENDIF}
Result:=nil;
while StartNode<>nil do begin
Node:=StartNode;
while Node<>nil do begin
//DebugLn('SearchInNode ',NodeDescriptionAsString(ANode.Desc),
//',',ANode.StartPos,',',ANode.EndPos,', p=',p,
//' "',copy(Src,ANode.StartPos,4),'" - "',copy(Src,ANode.EndPos-5,4),'"');
if (StartNode.StartPos<=P)
and ((StartNode.EndPos>P) or (StartNode.EndPos<1)) then begin
if (Node.StartPos<=P)
and ((Node.EndPos>P) or (Node.EndPos<1)) then begin
// StartNode contains P
Result:=StartNode;
Result:=Node;
// -> search for a child that contains P
Brother:=StartNode;
Brother:=Node;
while (Brother<>nil)
and (Brother.StartPos<=P) do begin
// brother also contains P
@ -2178,9 +2180,22 @@ begin
break;
end else begin
// search in next node
StartNode:=StartNode.NextBrother;
Node:=Node.NextBrother;
end;
end;
if (Result=nil) and (Tree.Root<>nil) then begin
Node:=Tree.Root;
while Node.NextBrother<>nil do
Node:=Node.NextBrother;
if (Node<>nil) and (Node.EndPos=p) then begin
// cursor at end of source
Result:=Node;
while (Result.LastChild<>nil) and (Result.LastChild.EndPos=p) do
Result:=Result.LastChild;
exit;
end;
end;
if (Result=nil) and ExceptionOnNotFound then begin
MoveCursorToCleanPos(P);
RaiseNoNodeFoundAtCursor;

View File

@ -52,7 +52,7 @@ uses
MemCheck,
{$ENDIF}
Classes, SysUtils, FileProcs, CodeTree, CodeAtom, CustomCodeTool,
KeywordFuncLists, BasicCodeTools, LinkScanner,
CodeToolsStrConsts, KeywordFuncLists, BasicCodeTools, LinkScanner,
AVL_Tree, CodeToolMemManager, DefineTemplates,
SourceChanger, FindDeclarationTool, PascalParserTool;
@ -309,6 +309,8 @@ type
procedure ParseSourceTillCollectionStart(const CursorPos: TCodeXYPosition;
out CleanCursorPos: integer; out CursorNode: TCodeTreeNode;
out IdentStartPos, IdentEndPos: integer);
function FindIdentifierStartPos(const CursorPos: TCodeXYPosition
): TCodeXYPosition;
procedure FindCollectionContext(Params: TFindDeclarationParams;
IdentStartPos: integer; CursorNode: TCodeTreeNode;
out GatherContext: TFindContext; out ContextExprStartPos: LongInt;
@ -1327,7 +1329,7 @@ begin
// build code tree
{$IFDEF CTDEBUG}
DebugLn('TIdentCompletionTool.GatherIdentifiers A CursorPos=',dbgs(CursorPos.X),',',dbgs(CursorPos.Y));
DebugLn('TIdentCompletionTool.ParseSourceTillCollectionStart A CursorPos=',dbgs(CursorPos.X),',',dbgs(CursorPos.Y),' ',DbgsCXY(IdentStartXYPos));
{$ENDIF}
BuildTreeAndGetCleanPos(trTillCursor,CursorPos,CleanCursorPos,
[{$IFNDEF DisableIgnoreErrorAfter}btSetIgnoreErrorPos{$ENDIF}]);
@ -1344,6 +1346,21 @@ begin
GetIdentStartEndAtPosition(Src,CleanCursorPos,IdentStartPos,IdentEndPos);
end;
function TIdentCompletionTool.FindIdentifierStartPos(
const CursorPos: TCodeXYPosition): TCodeXYPosition;
var
p: integer;
IdentStartPos, IdentEndPos: integer;
begin
CursorPos.Code.LineColToPosition(CursorPos.Y,CursorPos.X,p);
if p<1 then
RaiseException(ctsCursorPosOutsideOfCode);
GetIdentStartEndAtPosition(CursorPos.Code.Source,p,IdentStartPos,IdentEndPos);
Result:=CursorPos;
if IdentStartPos>0 then
dec(Result.X,p-IdentStartPos);
end;
procedure TIdentCompletionTool.FindCollectionContext(
Params: TFindDeclarationParams; IdentStartPos: integer;
CursorNode: TCodeTreeNode;
@ -1514,6 +1531,7 @@ var
StartInSubContext: Boolean;
StartPosOfVariable: LongInt;
CursorContext: TFindContext;
IdentStartXY: TCodeXYPosition;
procedure CheckProcedureDeclarationContext;
var
@ -1561,7 +1579,8 @@ begin
Params:=TFindDeclarationParams.Create;
try
InitCollectIdentifiers(CursorPos,IdentifierList);
ParseSourceTillCollectionStart(CursorPos,CleanCursorPos,CursorNode,
IdentStartXY:=FindIdentifierStartPos(CursorPos);
ParseSourceTillCollectionStart(IdentStartXY,CleanCursorPos,CursorNode,
IdentStartPos,IdentEndPos);
if CleanCursorPos=0 then ;
@ -1586,7 +1605,7 @@ begin
GatherSourceNames(GatherContext);
end else begin
// find class and ancestors if existing (needed for protected identifiers)
FindContextClassAndAncestors(CursorPos,ClassAndAncestors);
FindContextClassAndAncestors(IdentStartXY,ClassAndAncestors);
FindCollectionContext(Params,IdentStartPos,CursorNode,
GatherContext,ContextExprStartPos,StartInSubContext);

View File

@ -4048,7 +4048,7 @@ begin
IgnorePos.Code:=CursorPos.Code;
IgnorePos.Code.LineColToPosition(CursorPos.Y,CursorPos.X,IgnorePos.P);
if IgnorePos.P<1 then IgnorePos.Code:=nil;
//debugln('TPascalParserTool.BuildTreeAndGetCleanPos IgnorePos=',dbgsCP(IgnorePos));
//debugln(['TPascalParserTool.BuildTreeAndGetCleanPos IgnorePos=',dbgsCP(IgnorePos),' After=',IgnorePos.P,'=',copy(CursorPos.Code.Source,IgnorePos.P,10)]);
IgnoreErrorAfter:=IgnorePos;
end else
ClearIgnoreErrorAfter;