MG: fixed node cache for increased search ranges

git-svn-id: trunk@1436 -
This commit is contained in:
lazarus 2002-02-11 09:29:19 +00:00
parent c2bcc86b61
commit e9ad4fc43f
4 changed files with 68 additions and 57 deletions

View File

@ -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(

View File

@ -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;

View File

@ -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;

View File

@ -13,7 +13,7 @@
{ $DEFINE IDE_DEBUG}
{ $DEFINE TestEvents}
{$DEFINE TestEvents}
// end.