1 {
2 ***************************************************************************
3 * *
4 * This source is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This code is distributed in the hope that it will be useful, but *
10 * WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * General Public License for more details. *
13 * *
14 * A copy of the GNU General Public License is available on the World *
15 * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
16 * obtain it by writing to the Free Software Foundation, *
17 * Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1335, USA. *
18 * *
19 ***************************************************************************
20
21 Author: Mattias Gaertner
22
23 Abstract:
24 - tree storing identifiers of other languages (e.g. javascript)
25 - identifier completion for other languages
26 }
27 unit OtherIdentifierTree;
28
29 {$mode objfpc}{$H+}
30
31 interface
32
33 uses
34 Classes, SysUtils, FileProcs, CodeTree;
35
36 type
37
38 { TOtherIdentifierTreeNode }
39
40 TOtherIdentifierTreeNode = class
41 public
42 Desc: TCodeTreeNodeDesc;
43 SubDesc: TCodeTreeNodeSubDesc;
44 Parent: TOtherIdentifierTreeNode;
45 NextSibling, PrevSibling: TOtherIdentifierTreeNode;
46 FirstChild, LastChild: TOtherIdentifierTreeNode;
47 constructor Create; virtual;
48 destructor Destroy; override;
49 procedure ClearChilds;
50 procedure AddLastChild(Child: TOtherIdentifierTreeNode); virtual;
51 procedure RemoveChild(Child: TOtherIdentifierTreeNode); virtual;
Nextnull52 function Next: TOtherIdentifierTreeNode;
NextSkipChildsnull53 function NextSkipChilds: TOtherIdentifierTreeNode;
Prevnull54 function Prev: TOtherIdentifierTreeNode;
PrevSkipChildsnull55 function PrevSkipChilds: TOtherIdentifierTreeNode;
HasAsParentnull56 function HasAsParent(Node: TOtherIdentifierTreeNode): boolean;
HasAsChildnull57 function HasAsChild(Node: TOtherIdentifierTreeNode): boolean;
HasParentOfTypenull58 function HasParentOfType(ParentDesc: TCodeTreeNodeDesc): boolean;
HasAsRootnull59 function HasAsRoot(RootNode: TOtherIdentifierTreeNode): boolean;
GetRootNodenull60 function GetRootNode: TOtherIdentifierTreeNode;
GetParentOfTypenull61 function GetParentOfType(ADesc: TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
GetParentOfTypesnull62 function GetParentOfTypes(Descriptors: array of TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
ChildCountnull63 function ChildCount: integer; virtual;
AsStringnull64 function AsString: string; virtual;
65 procedure ConsistencyCheck; virtual;
66 procedure WriteDebugReport(const Prefix: string; WithChilds: boolean); virtual;
67 end;
68
69 TOtherIdentifierTree = class
70 public
71 Root: TOtherIdentifierTreeNode;
72 constructor Create;
73 destructor Destroy; override;
74 procedure ClearNodes;
75 end;
76
77 implementation
78
79 { TOtherIdentifierTreeNode }
80
81 procedure TOtherIdentifierTreeNode.AddLastChild(Child: TOtherIdentifierTreeNode);
82 begin
83 Child.Parent:=Self;
84 if LastChild<>nil then
85 LastChild.NextSibling:=Child;
86 Child.PrevSibling:=LastChild;
87 LastChild:=Child;
88 if FirstChild=nil then FirstChild:=Child;
89 end;
90
91 procedure TOtherIdentifierTreeNode.RemoveChild(Child: TOtherIdentifierTreeNode);
92 begin
93 if FirstChild=Child then FirstChild:=Child.NextSibling;
94 if LastChild=Child then LastChild:=Child.PrevSibling;
95 Child.Parent:=nil;
96 end;
97
98 constructor TOtherIdentifierTreeNode.Create;
99 begin
100
101 end;
102
103 destructor TOtherIdentifierTreeNode.Destroy;
104 begin
105 ClearChilds;
106 if Parent<>nil then Parent.RemoveChild(Self);
107 if NextSibling<>nil then NextSibling.PrevSibling:=PrevSibling;
108 if PrevSibling<>nil then PrevSibling.NextSibling:=NextSibling;
109 PrevSibling:=nil;
110 NextSibling:=nil;
111 inherited Destroy;
112 end;
113
114 procedure TOtherIdentifierTreeNode.ClearChilds;
115 begin
116 while LastChild<>nil do LastChild.Free;
117 end;
118
Nextnull119 function TOtherIdentifierTreeNode.Next: TOtherIdentifierTreeNode;
120 begin
121 Result:=FirstChild;
122 if Result<>nil then exit;
123 Result:=NextSkipChilds;
124 end;
125
NextSkipChildsnull126 function TOtherIdentifierTreeNode.NextSkipChilds: TOtherIdentifierTreeNode;
127 begin
128 Result:=Self;
129 while (Result<>nil) do begin
130 if Result.NextSibling<>nil then
131 exit(Result.NextSibling);
132 Result:=Result.Parent;
133 end;
134 end;
135
Prevnull136 function TOtherIdentifierTreeNode.Prev: TOtherIdentifierTreeNode;
137 begin
138 if PrevSibling=nil then
139 Result:=Parent
140 else begin
141 Result:=PrevSibling;
142 while Result.LastChild<>nil do Result:=Result.LastChild;
143 end;
144 end;
145
TOtherIdentifierTreeNode.PrevSkipChildsnull146 function TOtherIdentifierTreeNode.PrevSkipChilds: TOtherIdentifierTreeNode;
147 begin
148 if PrevSibling<>nil then
149 Result:=PrevSibling
150 else
151 Result:=Parent;
152 end;
153
TOtherIdentifierTreeNode.HasAsParentnull154 function TOtherIdentifierTreeNode.HasAsParent(Node: TOtherIdentifierTreeNode
155 ): boolean;
156 var
157 CurNode: TOtherIdentifierTreeNode;
158 begin
159 CurNode:=Parent;
160 while CurNode<>nil do begin
161 if CurNode=Node then exit(true);
162 CurNode:=CurNode.Parent;
163 end;
164 Result:=false;
165 end;
166
HasAsChildnull167 function TOtherIdentifierTreeNode.HasAsChild(Node: TOtherIdentifierTreeNode
168 ): boolean;
169 begin
170 Result:=(Node<>nil) and Node.HasAsParent(Self);
171 end;
172
HasParentOfTypenull173 function TOtherIdentifierTreeNode.HasParentOfType(ParentDesc: TCodeTreeNodeDesc
174 ): boolean;
175 begin
176 Result:=GetParentOfType(ParentDesc)<>nil;
177 end;
178
HasAsRootnull179 function TOtherIdentifierTreeNode.HasAsRoot(RootNode: TOtherIdentifierTreeNode
180 ): boolean;
181 begin
182 Result:=GetRootNode=RootNode;
183 end;
184
GetRootNodenull185 function TOtherIdentifierTreeNode.GetRootNode: TOtherIdentifierTreeNode;
186 begin
187 Result:=Self;
188 while Result.Parent<>nil do Result:=Result.Parent;
189 end;
190
GetParentOfTypenull191 function TOtherIdentifierTreeNode.GetParentOfType(ADesc: TCodeTreeNodeDesc
192 ): TOtherIdentifierTreeNode;
193 begin
194 Result:=Parent;
195 while (Result<>nil) do begin
196 if Result.Desc=ADesc then exit;
197 Result:=Result.Parent;
198 end;
199 end;
200
TOtherIdentifierTreeNode.GetParentOfTypesnull201 function TOtherIdentifierTreeNode.GetParentOfTypes(
202 Descriptors: array of TCodeTreeNodeDesc): TOtherIdentifierTreeNode;
203 var
204 i: Integer;
205 begin
206 Result:=Parent;
207 while (Result<>nil) do begin
208 for i:=low(Descriptors) to high(Descriptors) do
209 if Result.Desc=Descriptors[i] then exit;
210 Result:=Result.Parent;
211 end;
212 end;
213
TOtherIdentifierTreeNode.ChildCountnull214 function TOtherIdentifierTreeNode.ChildCount: integer;
215 var
216 Node: TOtherIdentifierTreeNode;
217 begin
218 Result:=0;
219 Node:=FirstChild;
220 while Node<>nil do begin
221 inc(Result);
222 Node:=Node.NextSibling;
223 end;
224 end;
225
AsStringnull226 function TOtherIdentifierTreeNode.AsString: string;
227 begin
228 Result:=IntToStr(Desc);
229 end;
230
231 procedure TOtherIdentifierTreeNode.ConsistencyCheck;
232 var
233 Node: TOtherIdentifierTreeNode;
234 begin
235 if (NextSibling=Self) then
236 raise Exception.Create('');
237 if (PrevSibling=Self) then
238 raise Exception.Create('');
239 if (NextSibling<>nil) and (NextSibling.PrevSibling<>Self) then
240 raise Exception.Create('');
241 if (PrevSibling<>nil) and (PrevSibling.NextSibling<>Self) then
242 raise Exception.Create('');
243 if Parent=Self then
244 raise Exception.Create('');
245
246 if (FirstChild=nil)<>(LastChild=nil) then
247 raise Exception.Create('');
248 Node:=FirstChild;
249 while Node<>nil do begin
250 if Node.Parent<>Self then
251 raise Exception.Create('');
252 if (Node=FirstChild) and (Node.PrevSibling<>nil) then
253 raise Exception.Create('');
254 if (Node=LastChild) and (Node.NextSibling<>nil) then
255 raise Exception.Create('');
256 Node.ConsistencyCheck;
257 Node:=Node.NextSibling;
258 end;
259 end;
260
261 procedure TOtherIdentifierTreeNode.WriteDebugReport(const Prefix: string;
262 WithChilds: boolean);
263 begin
264 writeln(Prefix,AsString);
265 if WithChilds then
266 WriteDebugReport(Prefix+' ',true);
267 end;
268
269 { TOtherIdentifierTree }
270
271 constructor TOtherIdentifierTree.Create;
272 begin
273
274 end;
275
276 destructor TOtherIdentifierTree.Destroy;
277 begin
278 ClearNodes;
279 inherited Destroy;
280 end;
281
282 procedure TOtherIdentifierTree.ClearNodes;
283 begin
284 FreeAndNil(Root);
285 end;
286
287 end.
288
289