mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-03 08:19:26 +01:00
MG: fixed node cache for increased search ranges
git-svn-id: trunk@1436 -
This commit is contained in:
parent
c2bcc86b61
commit
e9ad4fc43f
@ -88,8 +88,6 @@ type
|
||||
const AMethodName: string; ATypeInfo: PTypeInfo;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
|
||||
function MethodTypeDataToStr(TypeData: PTypeData;
|
||||
Attr: TProcHeadAttributes): string;
|
||||
function CreateExprListFromMethodTypeData(TypeData: PTypeData;
|
||||
Params: TFindDeclarationParams): TExprTypeList;
|
||||
function FindPublishedMethodNodeInClass(ClassNode: TCodeTreeNode;
|
||||
@ -97,6 +95,8 @@ type
|
||||
function FindProcNodeInImplementation(const UpperClassName,
|
||||
UpperMethodName: string; BuildTreeBefore: boolean): TCodeTreeNode;
|
||||
function MethodTypeInfoToStr(ATypeInfo: PTypeInfo): string;
|
||||
function MethodTypeDataToStr(TypeData: PTypeData;
|
||||
Attr: TProcHeadAttributes): string;
|
||||
end;
|
||||
|
||||
|
||||
@ -485,53 +485,43 @@ function TEventsCodeTool.CreatePublishedMethod(const UpperClassName,
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var ClassNode: TCodeTreeNode;
|
||||
begin
|
||||
ActivateGlobalWriteLock;
|
||||
try
|
||||
BuildTree(false);
|
||||
if not EndOfSourceFound then exit;
|
||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
||||
Result:=CreatePublishedMethod(ClassNode,AMethodName,ATypeInfo,
|
||||
SourceChangeCache);
|
||||
finally
|
||||
DeactivateGlobalWriteLock;
|
||||
end;
|
||||
BuildTree(false);
|
||||
if not EndOfSourceFound then exit;
|
||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
||||
Result:=CreatePublishedMethod(ClassNode,AMethodName,ATypeInfo,
|
||||
SourceChangeCache);
|
||||
end;
|
||||
|
||||
function TEventsCodeTool.CreatePublishedMethod(ClassNode: TCodeTreeNode;
|
||||
const AMethodName: string; ATypeInfo: PTypeInfo;
|
||||
SourceChangeCache: TSourceChangeCache): boolean;
|
||||
var PublishedNode, ANode: TCodeTreeNode;
|
||||
var PublishedNode: TCodeTreeNode;
|
||||
NewMethod: string;
|
||||
begin
|
||||
Result:=false;
|
||||
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (AMethodName='')
|
||||
or (ATypeInfo=nil) or (SourceChangeCache=nil) or (Scanner=nil) then exit;
|
||||
ActivateGlobalWriteLock;
|
||||
try
|
||||
// convert TypeInfo to string
|
||||
NewMethod:=MethodTypeInfoToStr(ATypeInfo);
|
||||
// convert TypeInfo to string
|
||||
NewMethod:=MethodTypeInfoToStr(ATypeInfo);
|
||||
{$IFDEF CTDEBUG}
|
||||
writeln('[TEventsCodeTool.CreatePublishedMethod] A NewMethod="',NewMethod,'"');
|
||||
{$ENDIF}
|
||||
// add method to published section
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
BuildSubTreeForClass(ClassNode);
|
||||
PublishedNode:=ClassNode.FirstChild;
|
||||
if PublishedNode=nil then exit;
|
||||
if (PublishedNode.StartPos=PublishedNode.EndPos)
|
||||
and (PublishedNode.NextBrother<>nil)
|
||||
and (PublishedNode.NextBrother.Desc=ctnClassPublished) then
|
||||
PublishedNode:=PublishedNode.NextBrother;
|
||||
// add method to published section
|
||||
SourceChangeCache.MainScanner:=Scanner;
|
||||
BuildSubTreeForClass(ClassNode);
|
||||
PublishedNode:=ClassNode.FirstChild;
|
||||
if PublishedNode=nil then exit;
|
||||
if (PublishedNode.StartPos=PublishedNode.EndPos)
|
||||
and (PublishedNode.NextBrother<>nil)
|
||||
and (PublishedNode.NextBrother.Desc=ctnClassPublished) then
|
||||
PublishedNode:=PublishedNode.NextBrother;
|
||||
// NewMethod:=MethodKindAsString[TypeData^.MethodKind]+' '+AMethodName+
|
||||
// MethodTypeDataToStr(TypeData,[phpWithVarModifiers,phpWithParameterNames]);
|
||||
|
||||
// ToDo: check if parts already exists
|
||||
// ToDo: check if parts already exists
|
||||
|
||||
Result:=InsertNewMethodToClass(PublishedNode,AMethodName,NewMethod,
|
||||
SourceChangeCache);
|
||||
finally
|
||||
DeactivateGlobalWriteLock;
|
||||
end;
|
||||
Result:=InsertNewMethodToClass(PublishedNode,AMethodName,NewMethod,
|
||||
SourceChangeCache);
|
||||
end;
|
||||
|
||||
function TEventsCodeTool.InsertNewMethodToClass(
|
||||
|
||||
@ -95,6 +95,9 @@ const
|
||||
AllNodeCacheDescs = [ctnClass, ctnProcedure, ctnRecordType, ctnWithStatement];
|
||||
|
||||
type
|
||||
TNodeCacheEntryFlag = (ncefSearchedInParents, ncefSearchedInAncestors);
|
||||
TNodeCacheEntryFlags = set of TNodeCacheEntryFlag;
|
||||
|
||||
PCodeTreeNodeCacheEntry = ^TCodeTreeNodeCacheEntry;
|
||||
TCodeTreeNodeCacheEntry = record
|
||||
Identifier: PChar;
|
||||
@ -103,6 +106,7 @@ type
|
||||
NewNode: TCodeTreeNode;
|
||||
NewTool: TPascalParserTool;
|
||||
NewCleanPos: integer;
|
||||
Flags: TNodeCacheEntryFlags;
|
||||
NextEntry: PCodeTreeNodeCacheEntry; // used for mem manager
|
||||
end;
|
||||
|
||||
@ -126,7 +130,8 @@ type
|
||||
InFront: boolean): PCodeTreeNodeCacheEntry;
|
||||
function Find(Identifier: PChar): PCodeTreeNodeCacheEntry;
|
||||
procedure Add(Identifier: PChar; CleanStartPos, CleanEndPos: integer;
|
||||
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer);
|
||||
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer;
|
||||
Flags: TNodeCacheEntryFlags);
|
||||
procedure Clear;
|
||||
procedure BindToOwner(NewOwner: TCodeTreeNode);
|
||||
procedure UnbindFromOwner;
|
||||
@ -237,6 +242,9 @@ type
|
||||
Node: TCodeTreeNode): boolean;
|
||||
procedure FinalizeNodeStack(NodeStack: PCodeTreeNodeStack);
|
||||
|
||||
const
|
||||
ncefAllSearchRanges = [ncefSearchedInAncestors,ncefSearchedInParents];
|
||||
|
||||
var
|
||||
GlobalIdentifierTree: TGlobalIdentifierTree;
|
||||
InterfaceIdentCacheEntryMemManager: TInterfaceIdentCacheEntryMemManager;
|
||||
@ -244,6 +252,8 @@ var
|
||||
NodeCacheMemManager: TNodeCacheMemManager;
|
||||
BaseTypeCacheMemManager: TBaseTypeCacheMemManager;
|
||||
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
@ -574,7 +584,8 @@ end;
|
||||
|
||||
procedure TCodeTreeNodeCache.Add(Identifier: PChar;
|
||||
CleanStartPos, CleanEndPos: integer;
|
||||
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer);
|
||||
NewNode: TCodeTreeNode; NewTool: TPascalParserTool; NewCleanPos: integer;
|
||||
Flags: TNodeCacheEntryFlags);
|
||||
|
||||
procedure AddNewEntry;
|
||||
var NewEntry: PCodeTreeNodeCacheEntry;
|
||||
@ -592,12 +603,15 @@ procedure TCodeTreeNodeCache.Add(Identifier: PChar;
|
||||
var
|
||||
OldEntry: PCodeTreeNodeCacheEntry;
|
||||
OldNode: TAVLTreeNode;
|
||||
NewSearchRangeFlags: TNodeCacheEntryFlags;
|
||||
|
||||
procedure RaiseConflictException;
|
||||
var s: string;
|
||||
begin
|
||||
s:='[TCodeTreeNodeCache.Add] internal error:'
|
||||
+' conflicting cache nodes: ';
|
||||
+' conflicting cache nodes: Ident='+GetIdentifier(Identifier);
|
||||
if Owner<>nil then
|
||||
s:=s+' Owner='+Owner.DescAsString;
|
||||
s:=s+' Old: Start='+IntToStr(OldEntry^.CleanStartPos)
|
||||
+' End='+IntToStr(OldEntry^.CleanEndPos);
|
||||
if OldEntry^.NewNode<>nil then
|
||||
@ -630,25 +644,22 @@ begin
|
||||
AddNewEntry;
|
||||
end else begin
|
||||
// identifier was already searched in this range
|
||||
NewSearchRangeFlags:=(ncefAllSearchRanges * (OldEntry^.Flags+Flags));
|
||||
OldEntry:=PCodeTreeNodeCacheEntry(OldNode.Data);
|
||||
if (NewNode=OldEntry^.NewNode)
|
||||
and (NewTool=OldEntry^.NewTool) then
|
||||
if ((NewNode=OldEntry^.NewNode)
|
||||
and (NewTool=OldEntry^.NewTool))
|
||||
or ((OldEntry^.NewNode=nil) and (NewSearchRangeFlags<>[])) then
|
||||
begin
|
||||
// same FindContext with connected search ranges
|
||||
// same FindContext or better FindContext with overlapping search ranges
|
||||
// -> combine search ranges
|
||||
if OldEntry^.CleanStartPos>CleanStartPos then
|
||||
OldEntry^.CleanStartPos:=CleanStartPos;
|
||||
if OldEntry^.CleanEndPos<CleanEndPos then
|
||||
OldEntry^.CleanEndPos:=CleanEndPos;
|
||||
OldEntry^.Flags:=OldEntry^.Flags+NewSearchRangeFlags;
|
||||
end else begin
|
||||
// different FindContext with connected search ranges
|
||||
if (OldEntry^.CleanStartPos=CleanEndPos)
|
||||
or (OldEntry^.CleanEndPos=CleanStartPos) then begin
|
||||
// add new entry
|
||||
AddNewEntry;
|
||||
end else begin
|
||||
RaiseConflictException;
|
||||
end;
|
||||
// different FindContext with overlapping search ranges
|
||||
RaiseConflictException;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -715,8 +726,8 @@ begin
|
||||
Result:=FindNearestAVLNode(Identifier,CleanStartPos,CleanEndPos,true);
|
||||
if Result<>nil then begin
|
||||
Entry:=PCodeTreeNodeCacheEntry(Result.Data);
|
||||
if (CleanStartPos>Entry^.CleanEndPos)
|
||||
or (CleanEndPos<Entry^.CleanStartPos) then begin
|
||||
if (CleanStartPos>=Entry^.CleanEndPos)
|
||||
or (CleanEndPos<=Entry^.CleanStartPos) then begin
|
||||
// node is not in range
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
@ -279,7 +279,7 @@ type
|
||||
CreateIfNotExists: boolean): TCodeTreeNodeCache;
|
||||
procedure AddResultToNodeCaches(Identifier: PChar;
|
||||
StartNode, EndNode: TCodeTreeNode; SearchedForward: boolean;
|
||||
Params: TFindDeclarationParams);
|
||||
Params: TFindDeclarationParams; SearchRangeFlags: TNodeCacheEntryFlags);
|
||||
function FindDeclarationOfIdentifier(
|
||||
Params: TFindDeclarationParams): boolean;
|
||||
function FindContextNodeAtCursor(
|
||||
@ -833,12 +833,13 @@ function TFindDeclarationTool.FindIdentifierInContext(
|
||||
true, if NewPos+NewTopLine valid
|
||||
}
|
||||
var
|
||||
LastContextNode, StartContextNode, FirstSearchedNode,
|
||||
LastContextNode, StartContextNode, FirstSearchedNode, LastSearchedNode,
|
||||
ContextNode: TCodeTreeNode;
|
||||
IsForward: boolean;
|
||||
IdentifierFoundResult: TIdentifierFoundResult;
|
||||
LastNodeCache: TCodeTreeNodeCache;
|
||||
LastCacheEntry: PCodeTreeNodeCacheEntry;
|
||||
SearchRangeFlags: TNodeCacheEntryFlags;
|
||||
|
||||
function FindInNodeCache: boolean;
|
||||
var
|
||||
@ -876,10 +877,16 @@ var
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=false;
|
||||
ContextNode:=Params.ContextNode;
|
||||
StartContextNode:=ContextNode;
|
||||
FirstSearchedNode:=nil;
|
||||
Result:=false;
|
||||
LastSearchedNode:=nil;
|
||||
SearchRangeFlags:=[];
|
||||
if fdfSearchInParentNodes in Params.Flags then
|
||||
Include(SearchRangeFlags,ncefSearchedInParents);
|
||||
if fdfSearchInAncestors in Params.Flags then
|
||||
Include(SearchRangeFlags,ncefSearchedInAncestors);
|
||||
if ContextNode=nil then begin
|
||||
RaiseException('[TFindDeclarationTool.FindIdentifierInContext] '
|
||||
+' internal error: Params.ContextNode=nil');
|
||||
@ -908,6 +915,7 @@ if (ContextNode.Desc=ctnClass) then
|
||||
exit;
|
||||
end;
|
||||
if FirstSearchedNode=nil then FirstSearchedNode:=ContextNode;
|
||||
LastSearchedNode:=ContextNode;
|
||||
|
||||
case ContextNode.Desc of
|
||||
|
||||
@ -1089,6 +1097,8 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] no prior node accessible
|
||||
{$IFDEF ShowTriedContexts}
|
||||
//writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching prior node of ',ContextNode.DescAsString);
|
||||
{$ENDIF}
|
||||
LastSearchedNode:=ContextNode;
|
||||
|
||||
if (ContextNode.Desc=ctnClass) then begin
|
||||
if (fdfSearchInAncestors in Params.Flags) then begin
|
||||
|
||||
@ -1172,14 +1182,14 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent Con
|
||||
and (FirstSearchedNode<>nil) then begin
|
||||
// add result to caches
|
||||
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,ContextNode,
|
||||
fdfSearchForward in Params.Flags,Params);
|
||||
fdfSearchForward in Params.Flags,Params,SearchRangeFlags);
|
||||
end;
|
||||
end;
|
||||
// if we are here, the identifier was not found
|
||||
if FirstSearchedNode<>nil then begin
|
||||
// add result to cache
|
||||
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,ContextNode,
|
||||
fdfSearchForward in Params.Flags,nil);
|
||||
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,LastSearchedNode,
|
||||
fdfSearchForward in Params.Flags,nil,SearchRangeFlags);
|
||||
end;
|
||||
|
||||
if fdfExceptionOnNotFound in Params.Flags then begin
|
||||
@ -3772,7 +3782,7 @@ end;
|
||||
|
||||
procedure TFindDeclarationTool.AddResultToNodeCaches(Identifier: PChar;
|
||||
StartNode, EndNode: TCodeTreeNode; SearchedForward: boolean;
|
||||
Params: TFindDeclarationParams);
|
||||
Params: TFindDeclarationParams; SearchRangeFlags: TNodeCacheEntryFlags);
|
||||
var Node: TCodeTreeNode;
|
||||
CurNodeCache, LastNodeCache: TCodeTreeNodeCache;
|
||||
CleanStartPos, CleanEndPos: integer;
|
||||
@ -3832,7 +3842,7 @@ writeln(' CleanStartPos=',CleanStartPos,' CleanEndPos=',CleanEndPos);
|
||||
CurNodeCache:=TCodeTreeNodeCache(Node.Cache);
|
||||
if LastNodeCache<>CurNodeCache then begin
|
||||
CurNodeCache.Add(Identifier,CleanStartPos,CleanEndPos,
|
||||
NewNode,NewTool,NewCleanPos);
|
||||
NewNode,NewTool,NewCleanPos,SearchRangeFlags);
|
||||
LastNodeCache:=CurNodeCache;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
{ $DEFINE IDE_DEBUG}
|
||||
|
||||
{ $DEFINE TestEvents}
|
||||
{$DEFINE TestEvents}
|
||||
|
||||
// end.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user