diff --git a/components/codetools/customcodetool.pas b/components/codetools/customcodetool.pas index 992beb6efa..9c72dfa27e 100644 --- a/components/codetools/customcodetool.pas +++ b/components/codetools/customcodetool.pas @@ -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; diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index 98fd085c4d..efeea59ea7 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -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); diff --git a/components/codetools/pascalparsertool.pas b/components/codetools/pascalparsertool.pas index 4e1967227f..0032d0c7b5 100644 --- a/components/codetools/pascalparsertool.pas +++ b/components/codetools/pascalparsertool.pas @@ -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;