mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-10-31 22:10:55 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			291 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			291 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
| {
 | |
|  ***************************************************************************
 | |
|  *                                                                         *
 | |
|  *   This source is free software; you can redistribute it and/or modify   *
 | |
|  *   it under the terms of the GNU General Public License as published by  *
 | |
|  *   the Free Software Foundation; either version 2 of the License, or     *
 | |
|  *   (at your option) any later version.                                   *
 | |
|  *                                                                         *
 | |
|  *   This code is distributed in the hope that it will be useful, but      *
 | |
|  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 | |
|  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 | |
|  *   General Public License for more details.                              *
 | |
|  *                                                                         *
 | |
|  *   A copy of the GNU General Public License is available on the World    *
 | |
|  *   Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also      *
 | |
|  *   obtain it by writing to the Free Software Foundation,                 *
 | |
|  *   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.        *
 | |
|  *                                                                         *
 | |
|  ***************************************************************************
 | |
| 
 | |
|   Author: Mattias Gaertner
 | |
| 
 | |
|   Abstract:
 | |
|     - tree storing identifiers of other languages (e.g. javascript)
 | |
|     - identifier completion for other languages
 | |
| }
 | |
| unit OtherIdentifierTree;
 | |
| 
 | |
| {$mode objfpc}{$H+}
 | |
| 
 | |
| interface
 | |
| 
 | |
| uses
 | |
|   Classes, SysUtils, FileProcs, CodeTree;
 | |
| 
 | |
| type
 | |
| 
 | |
|   { TOtherIdentifierTreeNode }
 | |
| 
 | |
|   TOtherIdentifierTreeNode = class
 | |
|   public
 | |
|     Desc: TCodeTreeNodeDesc;
 | |
|     SubDesc: TCodeTreeNodeSubDesc;
 | |
|     Parent: TOtherIdentifierTreeNode;
 | |
|     NextSibling, PrevSibling: TOtherIdentifierTreeNode;
 | |
|     FirstChild, LastChild: TOtherIdentifierTreeNode;
 | |
|     constructor Create; virtual;
 | |
|     destructor Destroy; override;
 | |
|     procedure ClearChilds;
 | |
|     procedure AddLastChild(Child: TOtherIdentifierTreeNode); virtual;
 | |
|     procedure RemoveChild(Child: TOtherIdentifierTreeNode); virtual;
 | |
|     function Next: TOtherIdentifierTreeNode;
 | |
|     function NextSkipChilds: TOtherIdentifierTreeNode;
 | |
|     function Prev: TOtherIdentifierTreeNode;
 | |
|     function PrevSkipChilds: TOtherIdentifierTreeNode;
 | |
|     function HasAsParent(Node: TOtherIdentifierTreeNode): boolean;
 | |
|     function HasAsChild(Node: TOtherIdentifierTreeNode): boolean;
 | |
|     function HasParentOfType(ParentDesc: TCodeTreeNodeDesc): boolean;
 | |
|     function HasAsRoot(RootNode: TOtherIdentifierTreeNode): boolean;
 | |
|     function GetRootNode: TOtherIdentifierTreeNode;
 | |
|     function GetParentOfType(ADesc: TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
 | |
|     function GetParentOfTypes(Descriptors: array of TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
 | |
|     function ChildCount: integer; virtual;
 | |
|     function AsString: string; virtual;
 | |
|     procedure ConsistencyCheck; virtual;
 | |
|     procedure WriteDebugReport(const Prefix: string; WithChilds: boolean); virtual;
 | |
|   end;
 | |
| 
 | |
|   TOtherIdentifierTree = class
 | |
|   public
 | |
|     Root: TOtherIdentifierTreeNode;
 | |
|     constructor Create;
 | |
|     destructor Destroy; override;
 | |
|     procedure ClearNodes;
 | |
|   end;
 | |
| 
 | |
| implementation
 | |
| 
 | |
| { TOtherIdentifierTreeNode }
 | |
| 
 | |
| procedure TOtherIdentifierTreeNode.AddLastChild(Child: TOtherIdentifierTreeNode
 | |
|   );
 | |
| begin
 | |
|   Child.Parent:=Self;
 | |
|   if LastChild<>nil then
 | |
|     LastChild.NextSibling:=Child;
 | |
|   Child.PrevSibling:=LastChild;
 | |
|   LastChild:=Child;
 | |
|   if FirstChild=nil then FirstChild:=Child;
 | |
| end;
 | |
| 
 | |
| procedure TOtherIdentifierTreeNode.RemoveChild(Child: TOtherIdentifierTreeNode
 | |
|   );
 | |
| begin
 | |
|   if FirstChild=Child then FirstChild:=Child.NextSibling;
 | |
|   if LastChild=Child then LastChild:=Child.PrevSibling;
 | |
|   Child.Parent:=nil;
 | |
| end;
 | |
| 
 | |
| constructor TOtherIdentifierTreeNode.Create;
 | |
| begin
 | |
| 
 | |
| end;
 | |
| 
 | |
| destructor TOtherIdentifierTreeNode.Destroy;
 | |
| begin
 | |
|   ClearChilds;
 | |
|   if Parent<>nil then Parent.RemoveChild(Self);
 | |
|   if NextSibling<>nil then NextSibling.PrevSibling:=PrevSibling;
 | |
|   if PrevSibling<>nil then PrevSibling.NextSibling:=NextSibling;
 | |
|   PrevSibling:=nil;
 | |
|   NextSibling:=nil;
 | |
|   inherited Destroy;
 | |
| end;
 | |
| 
 | |
| procedure TOtherIdentifierTreeNode.ClearChilds;
 | |
| begin
 | |
|   while LastChild<>nil do LastChild.Free;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.Next: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   Result:=FirstChild;
 | |
|   if Result<>nil then exit;
 | |
|   Result:=NextSkipChilds;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.NextSkipChilds: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   Result:=Self;
 | |
|   while (Result<>nil) do begin
 | |
|     if Result.NextSibling<>nil then
 | |
|       exit(Result.NextSibling);
 | |
|     Result:=Result.Parent;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.Prev: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   if PrevSibling=nil then
 | |
|     Result:=Parent
 | |
|   else begin
 | |
|     Result:=PrevSibling;
 | |
|     while Result.LastChild<>nil do Result:=Result.LastChild;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.PrevSkipChilds: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   if PrevSibling<>nil then
 | |
|     Result:=PrevSibling
 | |
|   else
 | |
|     Result:=Parent;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.HasAsParent(Node: TOtherIdentifierTreeNode
 | |
|   ): boolean;
 | |
| var
 | |
|   CurNode: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   CurNode:=Parent;
 | |
|   while CurNode<>nil do begin
 | |
|     if CurNode=Node then exit(true);
 | |
|     CurNode:=CurNode.Parent;
 | |
|   end;
 | |
|   Result:=false;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.HasAsChild(Node: TOtherIdentifierTreeNode
 | |
|   ): boolean;
 | |
| begin
 | |
|   Result:=(Node<>nil) and Node.HasAsParent(Self);
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.HasParentOfType(ParentDesc: TCodeTreeNodeDesc
 | |
|   ): boolean;
 | |
| begin
 | |
|   Result:=GetParentOfType(ParentDesc)<>nil;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.HasAsRoot(RootNode: TOtherIdentifierTreeNode
 | |
|   ): boolean;
 | |
| begin
 | |
|   Result:=GetRootNode=RootNode;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.GetRootNode: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   Result:=Self;
 | |
|   while Result.Parent<>nil do Result:=Result.Parent;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.GetParentOfType(ADesc: TCodeTreeNodeDesc
 | |
|   ): TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   Result:=Parent;
 | |
|   while (Result<>nil) do begin
 | |
|     if Result.Desc=ADesc then exit;
 | |
|     Result:=Result.Parent;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.GetParentOfTypes(
 | |
|   Descriptors: array of TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
 | |
| var
 | |
|   i: Integer;
 | |
| begin
 | |
|   Result:=Parent;
 | |
|   while (Result<>nil) do begin
 | |
|     for i:=low(Descriptors) to high(Descriptors) do
 | |
|       if Result.Desc=Descriptors[i] then exit;
 | |
|     Result:=Result.Parent;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.ChildCount: integer;
 | |
| var
 | |
|   Node: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   Result:=0;
 | |
|   Node:=FirstChild;
 | |
|   while Node<>nil do begin
 | |
|     inc(Result);
 | |
|     Node:=Node.NextSibling;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| function TOtherIdentifierTreeNode.AsString: string;
 | |
| begin
 | |
|   Result:=IntToStr(Desc);
 | |
| end;
 | |
| 
 | |
| procedure TOtherIdentifierTreeNode.ConsistencyCheck;
 | |
| var
 | |
|   Node: TOtherIdentifierTreeNode;
 | |
| begin
 | |
|   if (NextSibling=Self) then
 | |
|     raise Exception.Create('');
 | |
|   if (PrevSibling=Self) then
 | |
|     raise Exception.Create('');
 | |
|   if (NextSibling<>nil) and (NextSibling.PrevSibling<>Self) then
 | |
|     raise Exception.Create('');
 | |
|   if (PrevSibling<>nil) and (PrevSibling.NextSibling<>Self) then
 | |
|     raise Exception.Create('');
 | |
|   if Parent=Self then
 | |
|     raise Exception.Create('');
 | |
| 
 | |
|   if (FirstChild=nil)<>(LastChild=nil) then
 | |
|     raise Exception.Create('');
 | |
|   Node:=FirstChild;
 | |
|   while Node<>nil do begin
 | |
|     if Node.Parent<>Self then
 | |
|       raise Exception.Create('');
 | |
|     if (Node=FirstChild) and (Node.PrevSibling<>nil) then
 | |
|       raise Exception.Create('');
 | |
|     if (Node=LastChild) and (Node.NextSibling<>nil) then
 | |
|       raise Exception.Create('');
 | |
|     Node.ConsistencyCheck;
 | |
|     Node:=Node.NextSibling;
 | |
|   end;
 | |
| end;
 | |
| 
 | |
| procedure TOtherIdentifierTreeNode.WriteDebugReport(const Prefix: string;
 | |
|   WithChilds: boolean);
 | |
| begin
 | |
|   writeln(Prefix,AsString);
 | |
|   if WithChilds then
 | |
|     WriteDebugReport(Prefix+'  ',true);
 | |
| end;
 | |
| 
 | |
| { TOtherIdentifierTree }
 | |
| 
 | |
| constructor TOtherIdentifierTree.Create;
 | |
| begin
 | |
| 
 | |
| end;
 | |
| 
 | |
| destructor TOtherIdentifierTree.Destroy;
 | |
| begin
 | |
|   ClearNodes;
 | |
|   inherited Destroy;
 | |
| end;
 | |
| 
 | |
| procedure TOtherIdentifierTree.ClearNodes;
 | |
| begin
 | |
|   FreeAndNil(Root);
 | |
| end;
 | |
| 
 | |
| end.
 | |
| 
 | 
