mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-06 10:39:25 +01:00
MG: added update checks for node caching
git-svn-id: trunk@655 -
This commit is contained in:
parent
cefcefa70c
commit
3d0c615d15
@ -144,10 +144,10 @@ function CompareSubStrings(const Find, Txt: string;
|
|||||||
function CleanCodeFromComments(const DirtyCode: string;
|
function CleanCodeFromComments(const DirtyCode: string;
|
||||||
NestedComments: boolean): string;
|
NestedComments: boolean): string;
|
||||||
function CompareIdentifiers(Identifier1, Identifier2: PChar): integer;
|
function CompareIdentifiers(Identifier1, Identifier2: PChar): integer;
|
||||||
|
function GetIdentifier(Identifier: PChar): string;
|
||||||
|
|
||||||
function GetIndentStr(Indent: integer): string;
|
function GetIndentStr(Indent: integer): string;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
const
|
const
|
||||||
MaxLineLength:integer=80;
|
MaxLineLength:integer=80;
|
||||||
@ -1686,6 +1686,19 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function GetIdentifier(Identifier: PChar): string;
|
||||||
|
var len: integer;
|
||||||
|
begin
|
||||||
|
if Identifier<>nil then begin
|
||||||
|
len:=0;
|
||||||
|
while (IsIdChar[Identifier[len]]) do inc(len);
|
||||||
|
SetLength(Result,len);
|
||||||
|
if len>0 then
|
||||||
|
Move(Identifier[0],Result[1],len);
|
||||||
|
end else
|
||||||
|
Result:='';
|
||||||
|
end;
|
||||||
|
|
||||||
function GetIndentStr(Indent: integer): string;
|
function GetIndentStr(Indent: integer): string;
|
||||||
begin
|
begin
|
||||||
SetLength(Result,Indent);
|
SetLength(Result,Indent);
|
||||||
|
|||||||
@ -469,6 +469,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
FCurCodeTool:=TCodeCompletionCodeTool(GetCodeToolForSource(MainCode,true));
|
FCurCodeTool:=TCodeCompletionCodeTool(GetCodeToolForSource(MainCode,true));
|
||||||
FCurCodeTool.ErrorPosition.Code:=nil;
|
FCurCodeTool.ErrorPosition.Code:=nil;
|
||||||
|
FCurCodeTool.OnSetGlobalWriteLock:=@OnToolSetWriteLock;
|
||||||
|
FCurCodeTool.OnGetGlobalWriteLockInfo:=@OnToolGetWriteLockInfo;
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('[TCodeToolManager.InitCurCodeTool] ',Code.Filename,' ',Code.SourceLength);
|
writeln('[TCodeToolManager.InitCurCodeTool] ',Code.Filename,' ',Code.SourceLength);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|||||||
@ -128,7 +128,7 @@ const
|
|||||||
ctnClassOfType];
|
ctnClassOfType];
|
||||||
AllSourceTypes =
|
AllSourceTypes =
|
||||||
[ctnProgram,ctnPackage,ctnLibrary,ctnUnit];
|
[ctnProgram,ctnPackage,ctnLibrary,ctnUnit];
|
||||||
AllUsableSoureTypes =
|
AllUsableSourceTypes =
|
||||||
[ctnUnit];
|
[ctnUnit];
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,8 @@ type
|
|||||||
//FIgnoreMissingIncludeFiles: boolean;
|
//FIgnoreMissingIncludeFiles: boolean;
|
||||||
FLastScannerChangeStep: integer;
|
FLastScannerChangeStep: integer;
|
||||||
FScanner: TLinkScanner;
|
FScanner: TLinkScanner;
|
||||||
|
FOnGetGlobalWriteLockInfo: TOnGetWriteLockInfo;
|
||||||
|
FOnSetGlobalWriteLock: TOnSetWriteLock;
|
||||||
protected
|
protected
|
||||||
KeyWordFuncList: TKeyWordFunctionList;
|
KeyWordFuncList: TKeyWordFunctionList;
|
||||||
FForceUpdateNeeded: boolean;
|
FForceUpdateNeeded: boolean;
|
||||||
@ -93,6 +95,7 @@ type
|
|||||||
|
|
||||||
function UpdateNeeded(OnlyInterfaceNeeded: boolean): boolean;
|
function UpdateNeeded(OnlyInterfaceNeeded: boolean): boolean;
|
||||||
procedure BeginParsing(DeleteNodes, OnlyInterfaceNeeded: boolean); virtual;
|
procedure BeginParsing(DeleteNodes, OnlyInterfaceNeeded: boolean); virtual;
|
||||||
|
|
||||||
procedure MoveCursorToNodeStart(ANode: TCodeTreeNode);
|
procedure MoveCursorToNodeStart(ANode: TCodeTreeNode);
|
||||||
procedure MoveCursorToCleanPos(ACleanPos: integer);
|
procedure MoveCursorToCleanPos(ACleanPos: integer);
|
||||||
procedure MoveCursorToCleanPos(ACleanPos: PChar);
|
procedure MoveCursorToCleanPos(ACleanPos: PChar);
|
||||||
@ -133,17 +136,23 @@ type
|
|||||||
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;
|
||||||
function GetIdentifier(Identifier: PChar): string;
|
function ExtractIdentifier(CleanStartPos: integer): string;
|
||||||
function GetIdentifier(CleanStartPos: integer): string;
|
|
||||||
procedure ReadPriorAtom;
|
procedure ReadPriorAtom;
|
||||||
|
|
||||||
procedure CreateChildNode;
|
procedure CreateChildNode;
|
||||||
procedure EndChildNode;
|
procedure EndChildNode;
|
||||||
|
|
||||||
|
procedure ActivateGlobalWriteLock; virtual;
|
||||||
|
procedure DeactivateGlobalWriteLock; virtual;
|
||||||
|
property OnGetGlobalWriteLockInfo: TOnGetWriteLockInfo
|
||||||
|
read FOnGetGlobalWriteLockInfo write FOnGetGlobalWriteLockInfo;
|
||||||
|
property OnSetGlobalWriteLock: TOnSetWriteLock
|
||||||
|
read FOnSetGlobalWriteLock write FOnSetGlobalWriteLock;
|
||||||
|
|
||||||
procedure Clear; virtual;
|
procedure Clear; virtual;
|
||||||
function NodeDescToStr(Desc: integer): string;
|
function NodeDescToStr(Desc: integer): string;
|
||||||
function NodeSubDescToStr(Desc, SubDesc: integer): string;
|
function NodeSubDescToStr(Desc, SubDesc: integer): string;
|
||||||
function ConsistencyCheck: integer; // 0 = ok
|
function ConsistencyCheck: integer; virtual; // 0 = ok
|
||||||
procedure WriteDebugTreeReport;
|
procedure WriteDebugTreeReport;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -1442,20 +1451,7 @@ begin
|
|||||||
Result:=(CleanStartPos>SrcLen) or (not IsIdentChar[Src[CleanStartPos]]);
|
Result:=(CleanStartPos>SrcLen) or (not IsIdentChar[Src[CleanStartPos]]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCustomCodeTool.GetIdentifier(Identifier: PChar): string;
|
function TCustomCodeTool.ExtractIdentifier(CleanStartPos: integer): string;
|
||||||
var len: integer;
|
|
||||||
begin
|
|
||||||
if Identifier<>nil then begin
|
|
||||||
len:=0;
|
|
||||||
while (IsIdentChar[Identifier[len]]) do inc(len);
|
|
||||||
SetLength(Result,len);
|
|
||||||
if len>0 then
|
|
||||||
Move(Identifier[0],Result[1],len);
|
|
||||||
end else
|
|
||||||
Result:='';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCustomCodeTool.GetIdentifier(CleanStartPos: integer): string;
|
|
||||||
var len: integer;
|
var len: integer;
|
||||||
begin
|
begin
|
||||||
if (CleanStartPos>=1) then begin
|
if (CleanStartPos>=1) then begin
|
||||||
@ -1475,6 +1471,16 @@ begin
|
|||||||
Tree.Clear;
|
Tree.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomCodeTool.ActivateGlobalWriteLock;
|
||||||
|
begin
|
||||||
|
if Assigned(OnSetGlobalWriteLock) then OnSetGlobalWriteLock(true);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCustomCodeTool.DeactivateGlobalWriteLock;
|
||||||
|
begin
|
||||||
|
if Assigned(OnSetGlobalWriteLock) then OnSetGlobalWriteLock(false);
|
||||||
|
end;
|
||||||
|
|
||||||
{ ECodeToolError }
|
{ ECodeToolError }
|
||||||
|
|
||||||
constructor ECodeToolError.Create(ASender: TCustomCodeTool;
|
constructor ECodeToolError.Create(ASender: TCustomCodeTool;
|
||||||
|
|||||||
@ -105,20 +105,32 @@ type
|
|||||||
FItems: TAVLTree; // tree of PCodeTreeNodeCacheEntry
|
FItems: TAVLTree; // tree of PCodeTreeNodeCacheEntry
|
||||||
public
|
public
|
||||||
Next: TCodeTreeNodeCache;
|
Next: TCodeTreeNodeCache;
|
||||||
|
Owner: TCodeTreeNode;
|
||||||
function FindLeftMostAVLNode(Identifier: PChar): TAVLTreeNode;
|
function FindLeftMostAVLNode(Identifier: PChar): TAVLTreeNode;
|
||||||
function FindRightMostAVLNode(Identifier: PChar): TAVLTreeNode;
|
function FindRightMostAVLNode(Identifier: PChar): TAVLTreeNode;
|
||||||
function FindAVLNode(Identifier: PChar; CleanPos: integer): TAVLTreeNode;
|
function FindAVLNode(Identifier: PChar; CleanPos: integer): TAVLTreeNode;
|
||||||
function FindAVLNodeInRange(Identifier: PChar;
|
function FindAVLNodeInRange(Identifier: PChar;
|
||||||
CleanStartPos, CleanEndPos: integer): TAVLTreeNode;
|
CleanStartPos, CleanEndPos: integer): TAVLTreeNode;
|
||||||
|
function FindNearestAVLNode(Identifier: PChar;
|
||||||
|
CleanStartPos, CleanEndPos: integer; InFront: boolean): TAVLTreeNode;
|
||||||
function Find(Identifier: PChar): PCodeTreeNodeCacheEntry;
|
function Find(Identifier: PChar): PCodeTreeNodeCacheEntry;
|
||||||
procedure Add(Identifier: PChar; CleanStartPos, CleanEndPos: integer;
|
procedure Add(Identifier: PChar; CleanStartPos, CleanEndPos: integer;
|
||||||
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer);
|
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer);
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
constructor Create;
|
procedure BindToOwner(NewOwner: TCodeTreeNode);
|
||||||
|
procedure UnbindFromOwner;
|
||||||
|
constructor Create(AnOwner: TCodeTreeNode);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
procedure WriteDebugReport(const Prefix: string);
|
||||||
|
function ConsistencyCheck: integer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
const
|
||||||
|
// all node types which can create a cache
|
||||||
|
AllNodeCacheDescs = [ctnClass, ctnInterface, ctnInitialization, ctnProgram];
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
type
|
||||||
TGlobalIdentifierTree = class
|
TGlobalIdentifierTree = class
|
||||||
private
|
private
|
||||||
FItems: TAVLTree; // tree of PChar;
|
FItems: TAVLTree; // tree of PChar;
|
||||||
@ -157,13 +169,14 @@ type
|
|||||||
procedure FreeFirstItem; override;
|
procedure FreeFirstItem; override;
|
||||||
public
|
public
|
||||||
procedure DisposeNode(Node: TCodeTreeNodeCache);
|
procedure DisposeNode(Node: TCodeTreeNodeCache);
|
||||||
function NewNode: TCodeTreeNodeCache;
|
function NewNode(AnOwner: TCodeTreeNode): TCodeTreeNodeCache;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
GlobalIdentifierTree: TGlobalIdentifierTree;
|
GlobalIdentifierTree: TGlobalIdentifierTree;
|
||||||
InterfaceIdentCacheEntryMemManager: TInterfaceIdentCacheEntryMemManager;
|
InterfaceIdentCacheEntryMemManager: TInterfaceIdentCacheEntryMemManager;
|
||||||
NodeCacheEntryMemManager: TNodeCacheEntryMemManager;
|
NodeCacheEntryMemManager: TNodeCacheEntryMemManager;
|
||||||
|
NodeCacheMemManager: TNodeCacheMemManager;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -428,15 +441,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TCodeTreeNodeCache.Create;
|
constructor TCodeTreeNodeCache.Create(AnOwner: TCodeTreeNode);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
|
Owner:=AnOwner;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TCodeTreeNodeCache.Destroy;
|
destructor TCodeTreeNodeCache.Destroy;
|
||||||
begin
|
begin
|
||||||
Clear;
|
Clear;
|
||||||
|
UnbindFromOwner;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -607,8 +621,28 @@ function TCodeTreeNodeCache.FindAVLNodeInRange(Identifier: PChar;
|
|||||||
CleanStartPos, CleanEndPos: integer): TAVLTreeNode;
|
CleanStartPos, CleanEndPos: integer): TAVLTreeNode;
|
||||||
var
|
var
|
||||||
Entry: PCodeTreeNodeCacheEntry;
|
Entry: PCodeTreeNodeCacheEntry;
|
||||||
comp: integer;
|
|
||||||
begin
|
begin
|
||||||
|
Result:=FindNearestAVLNode(Identifier,CleanStartPos,CleanEndPos,true);
|
||||||
|
Entry:=PCodeTreeNodeCacheEntry(Result.Data);
|
||||||
|
if (CleanStartPos>=Entry^.CleanEndPos)
|
||||||
|
or (CleanEndPos<Entry^.CleanStartPos) then begin
|
||||||
|
// node is not in range
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCodeTreeNodeCache.FindNearestAVLNode(Identifier: PChar;
|
||||||
|
CleanStartPos, CleanEndPos: integer; InFront: boolean): TAVLTreeNode;
|
||||||
|
var
|
||||||
|
Entry: PCodeTreeNodeCacheEntry;
|
||||||
|
comp: integer;
|
||||||
|
DirectionSucc: boolean;
|
||||||
|
NextNode: TAVLTreeNode;
|
||||||
|
begin
|
||||||
|
if CleanStartPos>CleanEndPos then begin
|
||||||
|
raise Exception.Create('[TCodeTreeNodeCache.FindNearestAVLNode]'
|
||||||
|
+' internal error: CleanStartPos>CleanEndPos');
|
||||||
|
end;
|
||||||
if FItems<>nil then begin
|
if FItems<>nil then begin
|
||||||
Result:=FItems.Root;
|
Result:=FItems.Root;
|
||||||
while Result<>nil do begin
|
while Result<>nil do begin
|
||||||
@ -619,14 +653,36 @@ begin
|
|||||||
else if comp>0 then
|
else if comp>0 then
|
||||||
Result:=Result.Right
|
Result:=Result.Right
|
||||||
else begin
|
else begin
|
||||||
repeat
|
// cached result with identifier found
|
||||||
if CleanStartPos>=Entry^.CleanEndPos then
|
// -> check range
|
||||||
Result:=FItems.FindSuccessor(Result)
|
NextNode:=Result;
|
||||||
else if CleanEndPos<Entry^.CleanStartPos then
|
if CleanStartPos>=Entry^.CleanEndPos then begin
|
||||||
Result:=FItems.FindPrecessor(Result)
|
NextNode:=FItems.FindSuccessor(Result);
|
||||||
else
|
DirectionSucc:=true;
|
||||||
|
end else if CleanEndPos<Entry^.CleanStartPos then begin
|
||||||
|
NextNode:=FItems.FindPrecessor(Result);
|
||||||
|
DirectionSucc:=false;
|
||||||
|
end else begin
|
||||||
|
// cached result in range found
|
||||||
exit;
|
exit;
|
||||||
until Result=nil;
|
end;
|
||||||
|
while (NextNode<>nil) do begin
|
||||||
|
Entry:=PCodeTreeNodeCacheEntry(NextNode.Data);
|
||||||
|
if CompareIdentifiers(Identifier,Entry^.Identifier)<>0 then begin
|
||||||
|
Result:=nil;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result:=NextNode;
|
||||||
|
if (CleanStartPos<Entry^.CleanEndPos)
|
||||||
|
and (CleanEndPos>=Entry^.CleanStartPos) then begin
|
||||||
|
// cached result in range found
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if DirectionSucc then
|
||||||
|
NextNode:=FItems.FindSuccessor(Result)
|
||||||
|
else
|
||||||
|
NextNode:=FItems.FindPrecessor(Result);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
@ -634,6 +690,63 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCodeTreeNodeCache.ConsistencyCheck: integer;
|
||||||
|
begin
|
||||||
|
if (FItems<>nil) then begin
|
||||||
|
Result:=FItems.ConsistencyCheck;
|
||||||
|
if Result<>0 then begin
|
||||||
|
dec(Result,100);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if Owner<>nil then begin
|
||||||
|
if Owner.Cache<>Self then begin
|
||||||
|
Result:=-1;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCodeTreeNodeCache.WriteDebugReport(const Prefix: string);
|
||||||
|
var Node: TAVLTreeNode;
|
||||||
|
Entry: PCodeTreeNodeCacheEntry;
|
||||||
|
begin
|
||||||
|
writeln(Prefix,'[TCodeTreeNodeCache.WriteDebugReport] Self=',
|
||||||
|
HexStr(Cardinal(Self),8),' Consistency=',ConsistencyCheck);
|
||||||
|
if FItems<>nil then begin
|
||||||
|
Node:=FItems.FindLowest;
|
||||||
|
while Node<>nil do begin
|
||||||
|
Entry:=PCodeTreeNodeCacheEntry(Node.Data);
|
||||||
|
write(Prefix,' Ident="',GetIdentifier(Entry^.Identifier),'"');
|
||||||
|
writeln('');
|
||||||
|
Node:=FItems.FindSuccessor(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCodeTreeNodeCache.UnbindFromOwner;
|
||||||
|
begin
|
||||||
|
if Owner<>nil then begin
|
||||||
|
if Owner.Cache<>Self then
|
||||||
|
raise Exception.Create('[TCodeTreeNodeCache.UnbindFromOwner] '
|
||||||
|
+' internal error: Owner.Cache<>Self');
|
||||||
|
Owner.Cache:=nil;
|
||||||
|
Owner:=nil;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCodeTreeNodeCache.BindToOwner(NewOwner: TCodeTreeNode);
|
||||||
|
begin
|
||||||
|
if NewOwner<>nil then begin
|
||||||
|
if NewOwner.Cache<>nil then
|
||||||
|
raise Exception.Create('[TCodeTreeNodeCache.BindToOwner] internal error:'
|
||||||
|
+' NewOwner.Cache<>nil');
|
||||||
|
NewOwner.Cache:=Self;
|
||||||
|
end;
|
||||||
|
Owner:=NewOwner;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TNodeCacheMemManager }
|
{ TNodeCacheMemManager }
|
||||||
|
|
||||||
procedure TNodeCacheMemManager.DisposeNode(Node: TCodeTreeNodeCache);
|
procedure TNodeCacheMemManager.DisposeNode(Node: TCodeTreeNodeCache);
|
||||||
@ -643,6 +756,7 @@ begin
|
|||||||
// add Entry to Free list
|
// add Entry to Free list
|
||||||
Node.Next:=TCodeTreeNodeCache(FFirstFree);
|
Node.Next:=TCodeTreeNodeCache(FFirstFree);
|
||||||
TCodeTreeNodeCache(FFirstFree):=Node;
|
TCodeTreeNodeCache(FFirstFree):=Node;
|
||||||
|
Node.UnbindFromOwner;
|
||||||
inc(FFreeCount);
|
inc(FFreeCount);
|
||||||
end else begin
|
end else begin
|
||||||
// free list full -> free the Node
|
// free list full -> free the Node
|
||||||
@ -660,17 +774,19 @@ begin
|
|||||||
Node.Free;
|
Node.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TNodeCacheMemManager.NewNode: TCodeTreeNodeCache;
|
function TNodeCacheMemManager.NewNode(
|
||||||
|
AnOwner: TCodeTreeNode): TCodeTreeNodeCache;
|
||||||
begin
|
begin
|
||||||
if FFirstFree<>nil then begin
|
if FFirstFree<>nil then begin
|
||||||
// take from free list
|
// take from free list
|
||||||
Result:=TCodeTreeNodeCache(FFirstFree);
|
Result:=TCodeTreeNodeCache(FFirstFree);
|
||||||
TCodeTreeNodeCache(FFirstFree):=Result.Next;
|
TCodeTreeNodeCache(FFirstFree):=Result.Next;
|
||||||
Result.Clear;
|
Result.Clear;
|
||||||
|
Result.Owner:=AnOwner;
|
||||||
dec(FFreeCount);
|
dec(FFreeCount);
|
||||||
end else begin
|
end else begin
|
||||||
// free list empty -> create new Entry
|
// free list empty -> create new Entry
|
||||||
Result:=TCodeTreeNodeCache.Create;
|
Result:=TCodeTreeNodeCache.Create(AnOwner);
|
||||||
inc(FAllocatedCount);
|
inc(FAllocatedCount);
|
||||||
end;
|
end;
|
||||||
inc(FCount);
|
inc(FCount);
|
||||||
@ -682,6 +798,8 @@ procedure InternalInit;
|
|||||||
begin
|
begin
|
||||||
GlobalIdentifierTree:=TGlobalIdentifierTree.Create;
|
GlobalIdentifierTree:=TGlobalIdentifierTree.Create;
|
||||||
InterfaceIdentCacheEntryMemManager:=TInterfaceIdentCacheEntryMemManager.Create;
|
InterfaceIdentCacheEntryMemManager:=TInterfaceIdentCacheEntryMemManager.Create;
|
||||||
|
NodeCacheEntryMemManager:=TNodeCacheEntryMemManager.Create;
|
||||||
|
NodeCacheMemManager:=TNodeCacheMemManager.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure InternalFinal;
|
procedure InternalFinal;
|
||||||
@ -690,6 +808,10 @@ begin
|
|||||||
GlobalIdentifierTree:=nil;
|
GlobalIdentifierTree:=nil;
|
||||||
InterfaceIdentCacheEntryMemManager.Free;
|
InterfaceIdentCacheEntryMemManager.Free;
|
||||||
InterfaceIdentCacheEntryMemManager:=nil;
|
InterfaceIdentCacheEntryMemManager:=nil;
|
||||||
|
NodeCacheEntryMemManager.Free;
|
||||||
|
NodeCacheEntryMemManager:=nil;
|
||||||
|
NodeCacheMemManager.Free;
|
||||||
|
NodeCacheMemManager:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
|||||||
@ -220,6 +220,8 @@ type
|
|||||||
FInterfaceIdentifierCache: TInterfaceIdentifierCache;
|
FInterfaceIdentifierCache: TInterfaceIdentifierCache;
|
||||||
FOnGetCodeToolForBuffer: TOnGetCodeToolForBuffer;
|
FOnGetCodeToolForBuffer: TOnGetCodeToolForBuffer;
|
||||||
FOnGetUnitSourceSearchPath: TOnGetSearchPath;
|
FOnGetUnitSourceSearchPath: TOnGetSearchPath;
|
||||||
|
FFirstNodeCache: TCodeTreeNodeCache;
|
||||||
|
FLastNodeCachesGlobalWriteLockStep: integer;
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugPrefix: string;
|
DebugPrefix: string;
|
||||||
procedure IncPrefix;
|
procedure IncPrefix;
|
||||||
@ -265,6 +267,7 @@ type
|
|||||||
function PredefinedIdentToTypeDesc(Identifier: PChar): TExpressionTypeDesc;
|
function PredefinedIdentToTypeDesc(Identifier: PChar): TExpressionTypeDesc;
|
||||||
protected
|
protected
|
||||||
procedure DoDeleteNodes; override;
|
procedure DoDeleteNodes; override;
|
||||||
|
procedure ClearNodeCaches(Force: boolean);
|
||||||
function FindDeclarationOfIdentifier(
|
function FindDeclarationOfIdentifier(
|
||||||
Params: TFindDeclarationParams): boolean;
|
Params: TFindDeclarationParams): boolean;
|
||||||
function FindContextNodeAtCursor(
|
function FindContextNodeAtCursor(
|
||||||
@ -314,6 +317,8 @@ type
|
|||||||
read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer;
|
read FOnGetCodeToolForBuffer write FOnGetCodeToolForBuffer;
|
||||||
property OnGetUnitSourceSearchPath: TOnGetSearchPath
|
property OnGetUnitSourceSearchPath: TOnGetSearchPath
|
||||||
read FOnGetUnitSourceSearchPath write FOnGetUnitSourceSearchPath;
|
read FOnGetUnitSourceSearchPath write FOnGetUnitSourceSearchPath;
|
||||||
|
procedure ActivateGlobalWriteLock; override;
|
||||||
|
function ConsistencyCheck: integer; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -360,7 +365,7 @@ var CleanCursorPos: integer;
|
|||||||
Params: TFindDeclarationParams;
|
Params: TFindDeclarationParams;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
Scanner.ActivateGlobalWriteLock;
|
ActivateGlobalWriteLock;
|
||||||
try
|
try
|
||||||
// build code tree
|
// build code tree
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
@ -436,7 +441,7 @@ writeln('TFindDeclarationTool.FindDeclaration D CursorNode=',NodeDescriptionAsSt
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
finally
|
finally
|
||||||
Scanner.DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -771,6 +776,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if ContextNode<>nil then begin
|
if ContextNode<>nil then begin
|
||||||
|
if (ContextNode.Parent<>nil) and (ContextNode.Parent.Cache<>nil) then begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
{$IFDEF ShowTriedContexts}
|
{$IFDEF ShowTriedContexts}
|
||||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] A Ident=',
|
writeln('[TFindDeclarationTool.FindIdentifierInContext] A Ident=',
|
||||||
@ -1291,7 +1300,7 @@ writeln('');
|
|||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
RaiseException('identifier expected, but '+GetAtom+' found');
|
RaiseException('identifier expected, but '+GetAtom+' found');
|
||||||
end;
|
end;
|
||||||
if (Result.Node.Desc in AllUsableSoureTypes) then begin
|
if (Result.Node.Desc in AllUsableSourceTypes) then begin
|
||||||
// identifier in front of the point is a unit name
|
// identifier in front of the point is a unit name
|
||||||
if Result.Tool<>Self then begin
|
if Result.Tool<>Self then begin
|
||||||
Result.Node:=Result.Tool.GetInterfaceNode;
|
Result.Node:=Result.Tool.GetInterfaceNode;
|
||||||
@ -2345,9 +2354,6 @@ writeln(DebugPrefix,'TFindDeclarationTool.FindIdentifierInInterface',
|
|||||||
// ToDo: build codetree for ppu, ppw, dcu files
|
// ToDo: build codetree for ppu, ppw, dcu files
|
||||||
|
|
||||||
// build tree for pascal source
|
// build tree for pascal source
|
||||||
|
|
||||||
// ToDo: only check the first time during a big search
|
|
||||||
|
|
||||||
BuildTree(true);
|
BuildTree(true);
|
||||||
|
|
||||||
// search identifier in cache
|
// search identifier in cache
|
||||||
@ -2438,7 +2444,7 @@ begin
|
|||||||
CurPos.StartPos:=-1;
|
CurPos.StartPos:=-1;
|
||||||
RaiseException('[TFindDeclarationTool.GetInterfaceNode] no code tree found');
|
RaiseException('[TFindDeclarationTool.GetInterfaceNode] no code tree found');
|
||||||
end;
|
end;
|
||||||
if not (Tree.Root.Desc in AllUsableSoureTypes) then begin
|
if not (Tree.Root.Desc in AllUsableSourceTypes) then begin
|
||||||
CurPos.StartPos:=-1;
|
CurPos.StartPos:=-1;
|
||||||
RaiseException('used unit is not an pascal unit');
|
RaiseException('used unit is not an pascal unit');
|
||||||
end;
|
end;
|
||||||
@ -3433,6 +3439,7 @@ end;
|
|||||||
|
|
||||||
procedure TFindDeclarationTool.DoDeleteNodes;
|
procedure TFindDeclarationTool.DoDeleteNodes;
|
||||||
begin
|
begin
|
||||||
|
ClearNodeCaches(true);
|
||||||
if FInterfaceIdentifierCache<>nil then
|
if FInterfaceIdentifierCache<>nil then
|
||||||
FInterfaceIdentifierCache.Clear;
|
FInterfaceIdentifierCache.Clear;
|
||||||
inherited DoDeleteNodes;
|
inherited DoDeleteNodes;
|
||||||
@ -3445,6 +3452,60 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TFindDeclarationTool.ClearNodeCaches(Force: boolean);
|
||||||
|
var
|
||||||
|
NodeCache: TCodeTreeNodeCache;
|
||||||
|
GlobalWriteLockIsSet: boolean;
|
||||||
|
GlobalWriteLockStep: integer;
|
||||||
|
begin
|
||||||
|
if not Force then begin
|
||||||
|
// check if node cache must be cleared
|
||||||
|
if Assigned(OnGetGlobalWriteLockInfo) then begin
|
||||||
|
OnGetGlobalWriteLockInfo(GlobalWriteLockIsSet,GlobalWriteLockStep);
|
||||||
|
if GlobalWriteLockIsSet then begin
|
||||||
|
// The global write lock is set. That means, input variables and code
|
||||||
|
// are frozen
|
||||||
|
if (FLastNodeCachesGlobalWriteLockStep=GlobalWriteLockStep) then begin
|
||||||
|
// source and values did not change since last UpdateNeeded check
|
||||||
|
exit;
|
||||||
|
end else begin
|
||||||
|
// this is the first check in this GlobalWriteLockStep
|
||||||
|
FLastNodecachesGlobalWriteLockStep:=GlobalWriteLockStep;
|
||||||
|
// proceed normally ...
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
while FFirstNodeCache<>nil do begin
|
||||||
|
NodeCache:=FFirstNodeCache;
|
||||||
|
FFirstNodeCache:=NodeCache.Next;
|
||||||
|
NodeCacheMemManager.DisposeNode(NodeCache);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TFindDeclarationTool.ConsistencyCheck: integer;
|
||||||
|
var ANodeCache: TCodeTreeNodeCache;
|
||||||
|
begin
|
||||||
|
if FInterfaceIdentifierCache<>nil then begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
ANodeCache:=FFirstNodeCache;
|
||||||
|
while ANodeCache<>nil do begin
|
||||||
|
Result:=ANodeCache.ConsistencyCheck;
|
||||||
|
if Result<>0 then begin
|
||||||
|
dec(Result,100);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
ANodeCache:=ANodeCache.Next;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TFindDeclarationTool.ActivateGlobalWriteLock;
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
ClearNodeCaches(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TFindDeclarationParams }
|
{ TFindDeclarationParams }
|
||||||
|
|
||||||
@ -3565,7 +3626,5 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user