From b7b30e862a6fdb0d63058f9da0d296b9d4ce82e8 Mon Sep 17 00:00:00 2001 From: mattias Date: Mon, 5 May 2008 20:06:28 +0000 Subject: [PATCH] codetools: identifier completion can exists while rebuilding code trees git-svn-id: trunk@15048 - --- components/codetools/codetoolmanager.pas | 3 +- components/codetools/codetree.pas | 13 +++ components/codetools/identcompletiontool.pas | 102 ++++++++++++++++++- ide/sourceeditor.pp | 3 +- 4 files changed, 116 insertions(+), 5 deletions(-) diff --git a/components/codetools/codetoolmanager.pas b/components/codetools/codetoolmanager.pas index ce218ea85a..1a73f881bb 100644 --- a/components/codetools/codetoolmanager.pas +++ b/components/codetools/codetoolmanager.pas @@ -1151,7 +1151,6 @@ end; procedure TCodeToolManager.ClearCurCodeTool; begin ClearError; - if IdentifierList<>nil then IdentifierList.Clear; FCurCodeTool:=nil; end; @@ -4380,6 +4379,8 @@ begin inc(FCodeTreeNodesDeletedStep) else FCodeTreeNodesDeletedStep:=Low(Integer); + if IdentifierList<>nil then + IdentifierList.ToolTreeChange(Tool,NodesDeleting); end; end; diff --git a/components/codetools/codetree.pas b/components/codetools/codetree.pas index b9a582f399..91aca1d9b2 100644 --- a/components/codetools/codetree.pas +++ b/components/codetools/codetree.pas @@ -228,6 +228,7 @@ type function HasAsParent(Node: TCodeTreeNode): boolean; function HasAsChild(Node: TCodeTreeNode): boolean; function HasParentOfType(ParentDesc: TCodeTreeNodeDesc): boolean; + function HasAsRoot(RootNode: TCodeTreeNode): boolean; function GetNodeOfType(ADesc: TCodeTreeNodeDesc): TCodeTreeNode; function GetNodeOfTypes(Descriptors: array of TCodeTreeNodeDesc): TCodeTreeNode; function GetFindContextParent: TCodeTreeNode; @@ -690,6 +691,18 @@ begin Result:=ANode<>nil; end; +function TCodeTreeNode.HasAsRoot(RootNode: TCodeTreeNode): boolean; +var + CurNode: TCodeTreeNode; +begin + CurNode:=Self; + repeat + if CurNode=RootNode then exit(true); + CurNode:=CurNode.Parent; + until CurNode=nil; + Result:=false; +end; + function TCodeTreeNode.GetNodeOfType(ADesc: TCodeTreeNodeDesc ): TCodeTreeNode; begin diff --git a/components/codetools/identcompletiontool.pas b/components/codetools/identcompletiontool.pas index f7d89c6caf..f50118bd16 100644 --- a/components/codetools/identcompletiontool.pas +++ b/components/codetools/identcompletiontool.pas @@ -80,7 +80,8 @@ type iliIsAbstractMethod, iliIsAbstractMethodValid, iliParamListValid, - iliNodeValid + iliNodeValid, + iliNodeHashValid ); TIdentListItemFlags = set of TIdentListItemFlag; @@ -100,6 +101,9 @@ type FParamList: string; FNode: TCodeTreeNode; FToolNodesDeletedStep: integer;// only valid if iliNodeValid + FNodeStartPos: integer; + FNodeDesc: TCodeTreeNodeDesc; + FNodeHash: string; function GetNode: TCodeTreeNode; function GetParamList: string; procedure SetNode(const AValue: TCodeTreeNode); @@ -129,6 +133,10 @@ type function IsFunction: boolean; function IsAbstractMethod: boolean; procedure Clear; + procedure UnbindNode; + procedure StoreNodeHash; + function RestoreNode: boolean; + function GetNodeHash(ANode: TCodeTreeNode): string; function CompareParamList(CompareItem: TIdentifierListItem): integer; function CompareParamList(CompareItem: TIdentifierListSearchItem): integer; public @@ -183,6 +191,7 @@ type function StartUpAtomInFrontIs(const s: string): boolean; function StartUpAtomBehindIs(const s: string): boolean; function CompletePrefix(const OldPrefix: string): string; + procedure ToolTreeChange(Tool: TCustomCodeTool; NodesDeleting: boolean); public property Context: TFindContext read FContext write FContext; property ContextFlags: TIdentifierListContextFlags @@ -724,6 +733,31 @@ begin end; end; +procedure TIdentifierList.ToolTreeChange(Tool: TCustomCodeTool; + NodesDeleting: boolean); +var + AVLNode: TAVLTreeNode; + Item: TIdentifierListItem; + RootNode: TCodeTreeNode; +begin + DebugLn(['TIdentifierList.ToolTreeChange ',Tool.MainFilename,' ',NodesDeleting]); + if (Tool.Tree=nil) then exit; + RootNode:=Tool.Tree.Root; + DebugLn(['TIdentifierList.ToolTreeChange AAA1']); + if FIdentView.Count>0 then CTDumpStack; + if RootNode=nil then exit; + AVLNode:=FIdentView.FindLowest; + DebugLn(['TIdentifierList.ToolTreeChange AAA2 ',FIdentView.Count]); + while AVLNode<>nil do begin + Item:=TIdentifierListItem(AVLNode.Data); + if (Item.Node<>nil) and Item.Node.HasAsRoot(RootNode) then begin + Item.UnbindNode; + DebugLn(['TIdentifierList.ToolTreeChange ',Item.FNodeHash]); + end; + AVLNode:=FIdentView.FindSuccessor(AVLNode); + end; +end; + { TIdentCompletionTool } function TIdentCompletionTool.CollectAllIdentifiers( @@ -1760,8 +1794,16 @@ end; function TIdentifierListItem.GetNode: TCodeTreeNode; begin - if (not (iliNodeValid in Flags)) or (Tool=nil) then begin - Result:=nil; + Result:=nil; + if Tool=nil then + exit; + if (not (iliNodeValid in Flags)) then begin + if iliNodeHashValid in Flags then begin + RestoreNode; + if (iliNodeValid in Flags) then begin + Result:=FNode; + end; + end; exit; end else begin if FToolNodesDeletedStep=Tool.NodesDeletedChangeStep then begin @@ -1783,6 +1825,7 @@ procedure TIdentifierListItem.SetNode(const AValue: TCodeTreeNode); begin FNode:=AValue; Include(Flags,iliNodeValid); + Exclude(Flags,iliNodeHashValid); if (FNode<>nil) and (Tool=nil) then RaiseToolMissing; if (Tool<>nil) then @@ -1967,6 +2010,59 @@ begin BaseExprType:=CleanExpressionType; end; +procedure TIdentifierListItem.UnbindNode; +begin + if Node=nil then exit; + StoreNodeHash; + Exclude(Flags,iliNodeValid); + FNode:=nil; +end; + +procedure TIdentifierListItem.StoreNodeHash; +begin + Include(Flags,iliNodeHashValid); + FNodeStartPos:=FNode.StartPos; + FNodeDesc:=FNode.Desc; + FNodeHash:=GetNodeHash(FNode); +end; + +function TIdentifierListItem.RestoreNode: boolean; +var + NewNode: TCodeTreeNode; + NewHash: String; +begin + if not (iliNodeHashValid in Flags) then exit(true); + NewNode:=Tool.FindDeepestExpandedNodeAtPos(FNodeStartPos,false); + Result:=false; + if (NewNode=nil) or (NewNode.StartPos<>FNodeStartPos) then begin + Exclude(Flags,iliNodeHashValid); + exit; + end; + NewHash:=GetNodeHash(NewNode); + if NewHash<>FNodeHash then begin + Exclude(Flags,iliNodeHashValid); + exit; + end; + Node:=NewNode; + Result:=true; +end; + +function TIdentifierListItem.GetNodeHash(ANode: TCodeTreeNode): string; +var + StartPos: LongInt; + EndPos: LongInt; +begin + case Node.Desc of + ctnVarDefinition,ctnConstDefinition,ctnTypeDefinition,ctnGenericType: + Result:=Tool.ExtractDefinitionName(Node) + else + StartPos:=Node.StartPos; + EndPos:=StartPos+20; + if EndPos>Node.EndPos then EndPos:=Node.EndPos; + Result:=copy(Tool.Src,StartPos,EndPos); + end; +end; + function TIdentifierListItem.CompareParamList(CompareItem: TIdentifierListItem ): integer; var diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 67f2f10c39..d2d9a9ca8f 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -3558,6 +3558,7 @@ var OldCompletionControl: TSynCompletion; begin if CurCompletionControl=nil then exit; + CodeToolBoss.IdentifierList.Clear; OldCompletionControl:=CurCompletionControl; CurCompletionControl:=nil; @@ -3637,7 +3638,7 @@ var OldCompletionType: TCompletionType; Begin if CurCompletionControl=nil then exit; - OldCompletionType:= CurrentCompletionType; + OldCompletionType:=CurrentCompletionType; case CurrentCompletionType of ctIdentCompletion: