implemented hiding protected members in identifier completion

git-svn-id: trunk@7526 -
This commit is contained in:
mattias 2005-08-19 19:10:31 +00:00
parent 6516ac7baa
commit f4f414bbed
6 changed files with 372 additions and 54 deletions

View File

@ -142,11 +142,18 @@ function CodePosition(P: integer; Code: TCodeBuffer): TCodePosition;
function CodeXYPosition(X, Y: integer; Code: TCodeBuffer): TCodeXYPosition;
function CompareCodeXYPositions(Pos1, Pos2: PCodeXYPosition): integer;
procedure AddCodePosition(var ListOfPCodeXYPosition: TFPList;
const NewCodePos: TCodeXYPosition);
function IndexOfCodePosition(var ListOfPCodeXYPosition: TFPList;
const APosition: PCodeXYPosition): integer;
procedure FreeListOfPCodeXYPosition(ListOfPCodeXYPosition: TFPList);
var
WordToAtomFlag: TWordToAtomFlag;
function DbgsCXY(const p: TCodeXYPosition): string;
function DbgsCP(const p: TCodePosition): string;
function ListOfPCodeXYPositionToStr(const ListOfPCodeXYPosition: TFPList): string;
implementation
@ -184,6 +191,45 @@ begin
else Result:=0;
end;
procedure AddCodePosition(var ListOfPCodeXYPosition: TFPList;
const NewCodePos: TCodeXYPosition);
var
AddCodePos: PCodeXYPosition;
begin
if ListOfPCodeXYPosition=nil then ListOfPCodeXYPosition:=TFPList.Create;
New(AddCodePos);
AddCodePos^:=NewCodePos;
ListOfPCodeXYPosition.Add(AddCodePos);
end;
function IndexOfCodePosition(var ListOfPCodeXYPosition: TFPList;
const APosition: PCodeXYPosition): integer;
begin
if ListOfPCodeXYPosition=nil then
Result:=-1
else begin
Result:=ListOfPCodeXYPosition.Count-1;
while (Result>=0)
and (CompareCodeXYPositions(APosition,
PCodeXYPosition(ListOfPCodeXYPosition[Result]))<>0)
do
dec(Result);
end;
end;
procedure FreeListOfPCodeXYPosition(ListOfPCodeXYPosition: TFPList);
var
CurCodePos: PCodeXYPosition;
i: Integer;
begin
if ListOfPCodeXYPosition=nil then exit;
for i:=0 to ListOfPCodeXYPosition.Count-1 do begin
CurCodePos:=PCodeXYPosition(ListOfPCodeXYPosition[i]);
Dispose(CurCodePos);
end;
ListOfPCodeXYPosition.Free;
end;
function DbgsCXY(const p: TCodeXYPosition): string;
begin
if p.Code=nil then
@ -204,6 +250,23 @@ begin
Result:=DbgsCXY(CodeXYPosition);
end;
function ListOfPCodeXYPositionToStr(const ListOfPCodeXYPosition: TFPList
): string;
var
p: TCodeXYPosition;
i: Integer;
begin
if ListOfPCodeXYPosition=nil then
Result:='nil'
else begin
Result:='';
for i:=0 to ListOfPCodeXYPosition.Count-1 do begin
p:=PCodeXYPosition(ListOfPCodeXYPosition[i])^;
Result:=Result+' '+DbgsCXY(p)+LineEnding;
end;
end;
end;
{ TAtomRing }
constructor TAtomRing.Create;

View File

@ -296,7 +296,7 @@ type
function FindDeclarationInInterface(Code: TCodeBuffer;
const Identifier: string; var NewCode: TCodeBuffer;
var NewX, NewY, NewTopLine: integer): boolean;
function FindDeclarationsAndAncestors(Code: TCodeBuffer; X,Y: integer;
function FindDeclarationAndOverload(Code: TCodeBuffer; X,Y: integer;
var ListOfPCodeXYPosition: TFPList): boolean;
function FindMainDeclaration(Code: TCodeBuffer; X,Y: integer;
var NewCode: TCodeBuffer;
@ -1367,30 +1367,30 @@ begin
{$ENDIF}
end;
function TCodeToolManager.FindDeclarationsAndAncestors(Code: TCodeBuffer; X,
function TCodeToolManager.FindDeclarationAndOverload(Code: TCodeBuffer; X,
Y: integer; var ListOfPCodeXYPosition: TFPList): boolean;
var
CursorPos: TCodeXYPosition;
begin
Result:=false;
{$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.FindDeclarationsAndAncestors A ',Code.Filename,' x=',dbgs(x),' y=',dbgs(y));
DebugLn('TCodeToolManager.FindDeclarationAndOverload A ',Code.Filename,' x=',dbgs(x),' y=',dbgs(y));
{$ENDIF}
if not InitCurCodeTool(Code) then exit;
CursorPos.X:=X;
CursorPos.Y:=Y;
CursorPos.Code:=Code;
{$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.FindDeclarationsAndAncestors B ',dbgs(FCurCodeTool.Scanner<>nil));
DebugLn('TCodeToolManager.FindDeclarationAndOverload B ',dbgs(FCurCodeTool.Scanner<>nil));
{$ENDIF}
try
Result:=FCurCodeTool.FindDeclarationsAndAncestors(CursorPos,
Result:=FCurCodeTool.FindDeclarationAndOverload(CursorPos,
ListOfPCodeXYPosition);
except
on e: Exception do Result:=HandleException(e);
end;
{$IFDEF CTDEBUG}
DebugLn('TCodeToolManager.FindDeclarationsAndAncestors END ');
DebugLn('TCodeToolManager.FindDeclarationAndOverload END ');
{$ENDIF}
end;

View File

@ -215,6 +215,7 @@ type
Node: TCodeTreeNode;
Tool: TFindDeclarationTool;
end;
PFindContext = ^TFindContext;
const
CleanFindContext: TFindContext = (Node:nil; Tool:nil);
@ -662,10 +663,14 @@ type
function BaseTypeOfNodeHasSubIdents(ANode: TCodeTreeNode): boolean;
function FindBaseTypeOfNode(Params: TFindDeclarationParams;
Node: TCodeTreeNode): TFindContext;
function FindDeclarationsAndAncestors(const CursorPos: TCodeXYPosition;
var ListOfPCodeXYPosition: TFPList): boolean;
function FindDeclarationAndOverload(const CursorPos: TCodeXYPosition;
out ListOfPCodeXYPosition: TFPList): boolean;
function FindClassAndAncestors(ClassNode: TCodeTreeNode;
out ListOfPFindContext: TFPList): boolean;
function FindContextClassAndAncestors(const CursorPos: TCodeXYPosition;
var ListOfPFindContext: TFPList): boolean;
function FindReferences(const CursorPos: TCodeXYPosition;
SkipComments: boolean; var ListOfPCodeXYPosition: TFPList): boolean;
SkipComments: boolean; out ListOfPCodeXYPosition: TFPList): boolean;
function CleanPosIsDeclarationIdentifier(CleanPos: integer;
Node: TCodeTreeNode): boolean;
@ -698,6 +703,16 @@ function CreateFindContext(NewTool: TFindDeclarationTool;
function CreateFindContext(Params: TFindDeclarationParams): TFindContext;
function CreateFindContext(BaseTypeCache: TBaseTypeCache): TFindContext;
function FindContextAreEqual(const Context1, Context2: TFindContext): boolean;
function CompareFindContexts(const Context1, Context2: PFindContext): integer;
procedure AddFindContext(var ListOfPFindContext: TFPList;
const NewContext: TFindContext);
function IndexOfFindContext(var ListOfPFindContext: TFPList;
const AContext: PFindContext): integer;
procedure FreeListOfPFindContext(ListOfPFindContext: TFPList);
function ListOfPFindContextToStr(const ListOfPFindContext: TFPList): string;
function DbgsFC(const Context: TFindContext): string;
function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc;
function FindDeclarationFlagsAsString(
const Flags: TFindDeclarationFlags): string;
@ -736,6 +751,39 @@ begin
end;
end;
function ListOfPFindContextToStr(const ListOfPFindContext: TFPList): string;
var
Context: TFindContext;
i: Integer;
begin
if ListOfPFindContext=nil then
Result:='nil'
else begin
Result:='';
for i:=0 to ListOfPFindContext.Count-1 do begin
Context:=PFindContext(ListOfPFindContext[i])^;
Result:=Result+' '+DbgsFC(Context)+LineEnding;
end;
end;
end;
function DbgsFC(const Context: TFindContext): string;
var
CursorPos: TCodeXYPosition;
begin
if Context.Tool=nil then
Result:='nil'
else begin
Result:=Context.Tool.MainFilename;
if Context.Node=nil then
Result:=Result+'()'
else begin
Context.Tool.CleanPosToCaret(Context.Node.StartPos,CursorPos);
Result:=Result+'(y='+dbgs(CursorPos.Y)+',x='+dbgs(CursorPos.X)+')';
end;
end;
end;
function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc;
begin
// predefined identifiers
@ -862,6 +910,59 @@ begin
Result:=(Context1.Tool=Context2.Tool) and (Context1.Node=Context2.Node);
end;
function CompareFindContexts(const Context1, Context2: PFindContext): integer;
begin
if Pointer(Context1^.Tool)>Pointer(Context2^.Tool) then
Result:=1
else if Pointer(Context1^.Tool)<Pointer(Context2^.Tool) then
Result:=-1
else if Pointer(Context1^.Node)>Pointer(Context2^.Node) then
Result:=1
else if Pointer(Context1^.Node)<Pointer(Context2^.Node) then
Result:=-1
else
Result:=0;
end;
procedure AddFindContext(var ListOfPFindContext: TFPList;
const NewContext: TFindContext);
var
AddContext: PFindContext;
begin
if ListOfPFindContext=nil then ListOfPFindContext:=TFPList.Create;
New(AddContext);
AddContext^:=NewContext;
ListOfPFindContext.Add(AddContext);
end;
function IndexOfFindContext(var ListOfPFindContext: TFPList;
const AContext: PFindContext): integer;
begin
if ListOfPFindContext=nil then
Result:=-1
else begin
Result:=ListOfPFindContext.Count-1;
while (Result>=0)
and (CompareFindContexts(AContext,
PFindContext(ListOfPFindContext[Result]))<>0)
do
dec(Result);
end;
end;
procedure FreeListOfPFindContext(ListOfPFindContext: TFPList);
var
CurContext: PFindContext;
i: Integer;
begin
if ListOfPFindContext=nil then exit;
for i:=0 to ListOfPFindContext.Count-1 do begin
CurContext:=PFindContext(ListOfPFindContext[i]);
Dispose(CurContext);
end;
ListOfPFindContext.Free;
end;
{ TFindDeclarationTool }
@ -2896,34 +2997,9 @@ begin
{$ENDIF}
end;
function TFindDeclarationTool.FindDeclarationsAndAncestors(
const CursorPos: TCodeXYPosition; var ListOfPCodeXYPosition: TFPList
function TFindDeclarationTool.FindDeclarationAndOverload(
const CursorPos: TCodeXYPosition; out ListOfPCodeXYPosition: TFPList
): boolean;
procedure AddCodePosition(const NewCodePos: TCodeXYPosition);
var
AddCodePos: PCodeXYPosition;
begin
if ListOfPCodeXYPosition=nil then ListOfPCodeXYPosition:=TFPList.Create;
New(AddCodePos);
AddCodePos^:=NewCodePos;
ListOfPCodeXYPosition.Add(AddCodePos);
end;
function IndexOfCodePosition(APosition: PCodeXYPosition): integer;
begin
if ListOfPCodeXYPosition=nil then
Result:=-1
else begin
Result:=ListOfPCodeXYPosition.Count-1;
while (Result>=0)
and (CompareCodeXYPositions(APosition,
PCodeXYPosition(ListOfPCodeXYPosition[Result]))<>0)
do
dec(Result);
end;
end;
var
CurCursorPos: TCodeXYPosition;
NewTool: TFindDeclarationTool;
@ -2934,7 +3010,7 @@ var
begin
Result:=true;
ListOfPCodeXYPosition:=nil;
AddCodePosition(CursorPos);
AddCodePosition(ListOfPCodeXYPosition,CursorPos);
NewTool:=nil;
NewNode:=nil;
@ -2947,18 +3023,16 @@ begin
+[fsfSearchSourceName],
NewTool,NewNode,NewPos,NewTopLine) do
begin
if IndexOfCodePosition(@NewPos)>=0 then break;
AddCodePosition(NewPos);
if IndexOfCodePosition(ListOfPCodeXYPosition,@NewPos)>=0 then break;
AddCodePosition(ListOfPCodeXYPosition,NewPos);
CurCursorPos:=NewPos;
CurTool:=NewTool;
{$IFDEF VerboseFindWithAncestors}
debugln('TFindDeclarationTool.FindDeclarationsAndAncestors ',
{debugln('TFindDeclarationTool.FindDeclarationAndOverload ',
' Self="',MainFilename,'" ');
if CurCursorPos.Code<>nil then
debugln(' CurCursorPos=',CurCursorPos.Code.Filename,' ',dbgs(CurCursorPos.X),',',dbgs(CurCursorPos.Y));
if CurTool<>nil then
debugln(' CurTool=',CurTool.MainFilename);
{$ENDIF}
debugln(' CurTool=',CurTool.MainFilename);}
if (CurTool=nil) then exit;
end;
except
@ -2971,6 +3045,83 @@ begin
end;
end;
function TFindDeclarationTool.FindClassAndAncestors(ClassNode: TCodeTreeNode;
out ListOfPFindContext: TFPList): boolean;
var
FoundContext: TFindContext;
CurTool: TFindDeclarationTool;
Params: TFindDeclarationParams;
begin
Result:=true;
ListOfPFindContext:=nil;
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (ClassNode.Parent=nil)
or (ClassNode.Parent.Desc<>ctnTypeDefinition) then exit;
AddFindContext(ListOfPFindContext,CreateFindContext(Self,ClassNode));
Params:=TFindDeclarationParams.Create;
try
try
CurTool:=Self;
while CurTool.FindAncestorOfClass(ClassNode,Params,true) do begin
if (Params.NewCodeTool=nil) then break;
FoundContext.Tool:=Params.NewCodeTool;
FoundContext.Node:=Params.NewNode;
if IndexOfFindContext(ListOfPFindContext,@FoundContext)>=0 then break;
AddFindContext(ListOfPFindContext,FoundContext);
//debugln('TFindDeclarationTool.FindClassAndAncestors FoundContext=',DbgsFC(FoundContext));
CurTool:=Params.NewCodeTool;
ClassNode:=Params.NewNode;
if (ClassNode=nil)
or (not (ClassNode.Desc in [ctnClass,ctnClassInterface])) then
break;
end;
except
// just stop on errors
on E: ECodeToolError do ;
on E: ELinkScannerError do ;
end;
finally
Params.Free;
end;
end;
function TFindDeclarationTool.FindContextClassAndAncestors(
const CursorPos: TCodeXYPosition; var ListOfPFindContext: TFPList
): boolean;
// returns a list of nodes of ctnClass
var
CleanCursorPos: integer;
ANode: TCodeTreeNode;
ClassNode: TCodeTreeNode;
begin
Result:=false;
ListOfPFindContext:=nil;
ActivateGlobalWriteLock;
try
BuildTreeAndGetCleanPos(trTillCursor,CursorPos,CleanCursorPos,
[{$IFNDEF DisableIgnoreErrorAfter}btSetIgnoreErrorPos{$ENDIF}]);
// find class node
ANode:=FindDeepestNodeAtPos(CleanCursorPos,true);
ClassNode:=FindClassNode(ANode);
if (ClassNode=nil) or (ClassNode.Parent=nil)
or (ClassNode.Parent.Desc<>ctnTypeDefinition) then exit;
//debugln('TFindDeclarationTool.FindContextClassAndAncestors A ClassName=',ExtractClassName(ClassNode,false));
// add class and ancestors type definition to ListOfPCodeXYPosition
if not FindClassAndAncestors(ClassNode,ListOfPFindContext)
then exit;
//debugln('TFindDeclarationTool.FindContextClassAndAncestors List: ',ListOfPFindContextToStr(ListOfPFindContext));
finally
DeactivateGlobalWriteLock;
end;
Result:=true;
end;
{-------------------------------------------------------------------------------
function TFindDeclarationTool.FindReferences(const CursorPos: TCodeXYPosition;
SkipComments: boolean; var ListOfPCodeXYPosition: TFPList): boolean;
@ -2979,7 +3130,7 @@ end;
at CursorPos.
-------------------------------------------------------------------------------}
function TFindDeclarationTool.FindReferences(const CursorPos: TCodeXYPosition;
SkipComments: boolean; var ListOfPCodeXYPosition: TFPList): boolean;
SkipComments: boolean; out ListOfPCodeXYPosition: TFPList): boolean;
var
Identifier: string;
DeclarationTool: TFindDeclarationTool;

View File

@ -23,7 +23,6 @@
Abstract:
TIdentCompletionTool enhances the TFindDeclarationTool with the ability
to create lists of valid identifiers at a specific code position.
}
unit IdentCompletionTool;
@ -216,6 +215,7 @@ type
private
LastGatheredIdentParent: TCodeTreeNode;
LastGatheredIdentLevel: integer;
ClassAndAncestors: TFPList;// list of PCodeXYPosition
protected
CurrentIdentifierList: TIdentifierList;
function CollectAllIdentifiers(Params: TFindDeclarationParams;
@ -623,6 +623,28 @@ end;
function TIdentCompletionTool.CollectAllIdentifiers(
Params: TFindDeclarationParams; const FoundContext: TFindContext
): TIdentifierFoundResult;
function ProtectedNodeIsInAllowedClass: boolean;
var
CurClassNode: TCodeTreeNode;
p: TFindContext;
begin
Result:=true;
if ClassAndAncestors=nil then exit;
CurClassNode:=FoundContext.Node;
while (CurClassNode<>nil)
and (not (CurClassNode.Desc in [ctnClass,ctnClassInterface])) do
CurClassNode:=CurClassNode.Parent;
if CurClassNode=nil then exit;
p:=CreateFindContext(Params.NewCodeTool,CurClassNode);
if IndexOfFindContext(ClassAndAncestors,@p)>=0 then begin
// this class node is the class or on of the ancestors of the class
// of the start context of the identifier completion
exit;
end;
Result:=false;
end;
var
NewItem: TIdentifierListItem;
Ident: PChar;
@ -651,6 +673,15 @@ begin
// skip private definitions in other units
exit;
end;
if (FoundContext.Node.Parent.Desc=ctnClassProtected) then begin
// protected defnitions are only accessible from descendants
if ProtectedNodeIsInAllowedClass then begin
//debugln('TIdentCompletionTool.CollectAllIdentifiers ALLOWED Protected '+StringToPascalConst(copy(FoundContext.Tool.Src,FoundContext.Node.StartPos,50)));
end else begin
//debugln('TIdentCompletionTool.CollectAllIdentifiers FORBIDDEN Protected '+StringToPascalConst(copy(FoundContext.Tool.Src,FoundContext.Node.StartPos,50)));
exit;
end;
end;
end;
end;
@ -861,6 +892,9 @@ begin
CursorNode:=FindDeepestExpandedNodeAtPos(CleanCursorPos,true);
CurrentIdentifierList.StartContext.Node:=CursorNode;
// find class and ancestors if existing (needed for protected identifiers)
FindContextClassAndAncestors(CursorPos,ClassAndAncestors);
// get identifier position
GetIdentStartEndAtPosition(Src,CleanCursorPos,IdentStartPos,IdentEndPos);
@ -963,6 +997,7 @@ begin
Result:=true;
finally
FreeListOfPFindContext(ClassAndAncestors);
Params.Free;
ClearIgnoreErrorAfter;
DeactivateGlobalWriteLock;

View File

@ -42,6 +42,9 @@ uses
LinkScanner, AVL_Tree;
type
{ TPascalReaderTool }
TPascalReaderTool = class(TPascalParserTool)
public
function FindDeepestExpandedNodeAtPos(CleanCursorPos: integer;
@ -107,6 +110,12 @@ type
function FindClassNode(StartNode: TCodeTreeNode;
const AClassName: string;
IgnoreForwards, IgnoreNonForwards: boolean): TCodeTreeNode;
function FindClassNodeBackwards(StartNode: TCodeTreeNode;
const AClassName: string;
IgnoreForwards, IgnoreNonForwards: boolean): TCodeTreeNode;
function FindClassNode(CursorNode: TCodeTreeNode): TCodeTreeNode;
function FindClassNodeForMethodBody(ProcNode: TCodeTreeNode;
IgnoreForwards, IgnoreNonForwards: boolean): TCodeTreeNode;
function FindClassSection(ClassNode: TCodeTreeNode;
NodeDesc: TCodeTreeNodeDesc): TCodeTreeNode;
function FindLastClassSection(ClassNode: TCodeTreeNode;
@ -1068,6 +1077,71 @@ begin
end;
end;
function TPascalReaderTool.FindClassNodeBackwards(StartNode: TCodeTreeNode;
const AClassName: string; IgnoreForwards, IgnoreNonForwards: boolean
): TCodeTreeNode;
var
ANode: TCodeTreeNode;
CurClassNode: TCodeTreeNode;
begin
ANode:=StartNode;
while ANode<>nil do begin
if ANode.Desc=ctnTypeDefinition then begin
CurClassNode:=ANode.FirstChild;
if (CurClassNode<>nil) and (CurClassNode.Desc=ctnClass) then begin
if (not (IgnoreForwards
and ((CurClassNode.SubDesc and ctnsForwardDeclaration)>0)))
and (not (IgnoreNonForwards
and ((CurClassNode.SubDesc and ctnsForwardDeclaration)=0)))
then begin
if CompareIdentifiers(PChar(AClassName),@Src[ANode.StartPos])=0
then begin
Result:=CurClassNode;
exit;
end;
end;
end;
end;
if ANode.PriorBrother<>nil then begin
ANode:=ANode.PriorBrother;
if (ANode.FirstChild<>nil) and (ANode.Desc in AllCodeSections) then
ANode:=ANode.LastChild;
if (ANode.FirstChild<>nil) and (ANode.Desc in AllDefinitionSections) then
ANode:=ANode.LastChild;
end else begin
ANode:=ANode.Parent;
end;
end;
end;
function TPascalReaderTool.FindClassNode(CursorNode: TCodeTreeNode
): TCodeTreeNode;
begin
while CursorNode<>nil do begin
if CursorNode.Desc=ctnClass then begin
Result:=CursorNode;
exit;
end else if NodeIsMethodBody(CursorNode) then begin
Result:=FindClassNodeForMethodBody(CursorNode,true,false);
exit;
end;
CursorNode:=CursorNode.Parent;
end;
Result:=nil;
end;
function TPascalReaderTool.FindClassNodeForMethodBody(ProcNode: TCodeTreeNode;
IgnoreForwards, IgnoreNonForwards: boolean): TCodeTreeNode;
var
ProcClassName: String;
begin
Result:=nil;
ProcClassName:=ExtractClassNameOfProcNode(ProcNode);
if ProcClassName='' then exit;
Result:=FindClassNodeBackwards(ProcNode,ProcClassName,IgnoreForwards,
IgnoreNonForwards);
end;
function TPascalReaderTool.FindClassSection(ClassNode: TCodeTreeNode;
NodeDesc: TCodeTreeNodeDesc): TCodeTreeNode;
begin
@ -1260,7 +1334,8 @@ end;
function TPascalReaderTool.NodeIsMethodBody(ProcNode: TCodeTreeNode): boolean;
begin
Result:=false;
if (ProcNode<>nil) and (ProcNode.Desc=ctnProcedure) then begin
if (ProcNode<>nil) and (ProcNode.Desc=ctnProcedure)
and (ProcNode.FirstChild<>nil) then begin
// ToDo: ppu, ppw, dcu

View File

@ -628,7 +628,7 @@ begin
PascalHelpContextLists:=nil;
try
// get all possible declarations for this identifier
if CodeToolBoss.FindDeclarationsAndAncestors(CodeBuffer,CodePos.X,CodePos.Y,
if CodeToolBoss.FindDeclarationAndOverload(CodeBuffer,CodePos.X,CodePos.Y,
ListOfPCodeXYPosition) then
begin
debugln('THelpManager.ShowHelpForSourcePosition B Success ',dbgs(ListOfPCodeXYPosition.Count));
@ -653,13 +653,7 @@ begin
MainIDEInterface.DoJumpToCodeToolBossError;
end;
finally
if ListOfPCodeXYPosition<>nil then begin
for i:=0 to ListOfPCodeXYPosition.Count-1 do begin
CurCodePos:=PCodeXYPosition(ListOfPCodeXYPosition[i]);
Dispose(CurCodePos);
end;
ListOfPCodeXYPosition.Free;
end;
FreeListOfPCodeXYPosition(ListOfPCodeXYPosition);
if PascalHelpContextLists<>nil then begin
for i:=0 to PascalHelpContextLists.Count-1 do
TObject(PascalHelpContextLists[i]).Free;