1*16467b97STreehugger Robot unit Antlr.Runtime.Collections;
2*16467b97STreehugger Robot (*
3*16467b97STreehugger Robot [The "BSD licence"]
4*16467b97STreehugger Robot Copyright (c) 2008 Erik van Bilsen
5*16467b97STreehugger Robot Copyright (c) 2005-2007 Kunle Odutola
6*16467b97STreehugger Robot All rights reserved.
7*16467b97STreehugger Robot
8*16467b97STreehugger Robot Redistribution and use in source and binary forms, with or without
9*16467b97STreehugger Robot modification, are permitted provided that the following conditions
10*16467b97STreehugger Robot are met:
11*16467b97STreehugger Robot 1. Redistributions of source code MUST RETAIN the above copyright
12*16467b97STreehugger Robot notice, this list of conditions and the following disclaimer.
13*16467b97STreehugger Robot 2. Redistributions in binary form MUST REPRODUCE the above copyright
14*16467b97STreehugger Robot notice, this list of conditions and the following disclaimer in
15*16467b97STreehugger Robot the documentation and/or other materials provided with the
16*16467b97STreehugger Robot distribution.
17*16467b97STreehugger Robot 3. The name of the author may not be used to endorse or promote products
18*16467b97STreehugger Robot derived from this software without specific prior WRITTEN permission.
19*16467b97STreehugger Robot 4. Unless explicitly state otherwise, any contribution intentionally
20*16467b97STreehugger Robot submitted for inclusion in this work to the copyright owner or licensor
21*16467b97STreehugger Robot shall be under the terms and conditions of this license, without any
22*16467b97STreehugger Robot additional terms or conditions.
23*16467b97STreehugger Robot
24*16467b97STreehugger Robot THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25*16467b97STreehugger Robot IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26*16467b97STreehugger Robot OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27*16467b97STreehugger Robot IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28*16467b97STreehugger Robot INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29*16467b97STreehugger Robot NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30*16467b97STreehugger Robot DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31*16467b97STreehugger Robot THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32*16467b97STreehugger Robot (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33*16467b97STreehugger Robot THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*16467b97STreehugger Robot *)
35*16467b97STreehugger Robot
36*16467b97STreehugger Robot interface
37*16467b97STreehugger Robot
38*16467b97STreehugger Robot {$IF CompilerVersion < 20}
39*16467b97STreehugger Robot {$MESSAGE ERROR 'You need Delphi 2009 or higher to use the Antlr runtime'}
40*16467b97STreehugger Robot {$IFEND}
41*16467b97STreehugger Robot
42*16467b97STreehugger Robot uses
43*16467b97STreehugger Robot Generics.Collections,
44*16467b97STreehugger Robot Antlr.Runtime.Tools;
45*16467b97STreehugger Robot
46*16467b97STreehugger Robot type
47*16467b97STreehugger Robot /// <summary>
48*16467b97STreehugger Robot /// An Hashtable-backed dictionary that enumerates Keys and Values in
49*16467b97STreehugger Robot /// insertion order.
50*16467b97STreehugger Robot /// </summary>
51*16467b97STreehugger Robot IHashList<TKey, TValue> = interface(IDictionary<TKey, TValue>)
52*16467b97STreehugger Robot end;
53*16467b97STreehugger Robot
54*16467b97STreehugger Robot /// <summary>
55*16467b97STreehugger Robot /// Stack abstraction that also supports the IList interface
56*16467b97STreehugger Robot /// </summary>
57*16467b97STreehugger Robot IStackList<T> = interface(IList<T>)
58*16467b97STreehugger Robot { Methods }
59*16467b97STreehugger Robot
60*16467b97STreehugger Robot /// <summary>
61*16467b97STreehugger Robot /// Adds an element to the top of the stack list.
62*16467b97STreehugger Robot /// </summary>
63*16467b97STreehugger Robot procedure Push(const Item: T);
64*16467b97STreehugger Robot
65*16467b97STreehugger Robot /// <summary>
66*16467b97STreehugger Robot /// Removes the element at the top of the stack list and returns it.
67*16467b97STreehugger Robot /// </summary>
68*16467b97STreehugger Robot /// <returns>The element at the top of the stack.</returns>
Pop()69*16467b97STreehugger Robot function Pop: T;
70*16467b97STreehugger Robot
71*16467b97STreehugger Robot /// <summary>
72*16467b97STreehugger Robot /// Removes the element at the top of the stack list without removing it.
73*16467b97STreehugger Robot /// </summary>
74*16467b97STreehugger Robot /// <returns>The element at the top of the stack.</returns>
Peek()75*16467b97STreehugger Robot function Peek: T;
76*16467b97STreehugger Robot end;
77*16467b97STreehugger Robot
78*16467b97STreehugger Robot type
79*16467b97STreehugger Robot THashList<TKey, TValue> = class(TANTLRObject, IHashList<TKey, TValue>)
80*16467b97STreehugger Robot strict private
81*16467b97STreehugger Robot type
82*16467b97STreehugger Robot TPairEnumerator = class(TEnumerator<TPair<TKey, TValue>>)
83*16467b97STreehugger Robot private
84*16467b97STreehugger Robot FHashList: THashList<TKey, TValue>;
85*16467b97STreehugger Robot FOrderList: IList<TKey>;
86*16467b97STreehugger Robot FIndex: Integer;
87*16467b97STreehugger Robot FVersion: Integer;
88*16467b97STreehugger Robot FPair: TPair<TKey, TValue>;
GetCurrent()89*16467b97STreehugger Robot function GetCurrent: TPair<TKey, TValue>;
90*16467b97STreehugger Robot protected
DoGetCurrent()91*16467b97STreehugger Robot function DoGetCurrent: TPair<TKey, TValue>; override;
DoMoveNext()92*16467b97STreehugger Robot function DoMoveNext: Boolean; override;
93*16467b97STreehugger Robot public
94*16467b97STreehugger Robot constructor Create(const AHashList: THashList<TKey, TValue>);
MoveNext()95*16467b97STreehugger Robot function MoveNext: Boolean;
96*16467b97STreehugger Robot property Current: TPair<TKey, TValue> read GetCurrent;
97*16467b97STreehugger Robot end;
98*16467b97STreehugger Robot private
99*16467b97STreehugger Robot FDictionary: IDictionary<TKey, TValue>;
100*16467b97STreehugger Robot FInsertionOrderList: IList<TKey>;
101*16467b97STreehugger Robot FVersion: Integer;
102*16467b97STreehugger Robot protected
103*16467b97STreehugger Robot { IDictionary<TKey, TValue> }
GetItem(const Key: TKey)104*16467b97STreehugger Robot function GetItem(const Key: TKey): TValue;
105*16467b97STreehugger Robot procedure SetItem(const Key: TKey; const Value: TValue);
GetCount()106*16467b97STreehugger Robot function GetCount: Integer;
107*16467b97STreehugger Robot
108*16467b97STreehugger Robot procedure Add(const Key: TKey; const Value: TValue);
109*16467b97STreehugger Robot procedure Remove(const Key: TKey);
110*16467b97STreehugger Robot procedure Clear;
111*16467b97STreehugger Robot procedure TrimExcess;
TryGetValue(const Key: TKey; out Value: TValue)112*16467b97STreehugger Robot function TryGetValue(const Key: TKey; out Value: TValue): Boolean;
113*16467b97STreehugger Robot procedure AddOrSetValue(const Key: TKey; const Value: TValue);
ContainsKey(const Key: TKey)114*16467b97STreehugger Robot function ContainsKey(const Key: TKey): Boolean;
ContainsValue(const Value: TValue)115*16467b97STreehugger Robot function ContainsValue(const Value: TValue): Boolean;
116*16467b97STreehugger Robot public
117*16467b97STreehugger Robot constructor Create; overload;
118*16467b97STreehugger Robot constructor Create(const ACapacity: Integer); overload;
GetEnumerator()119*16467b97STreehugger Robot function GetEnumerator: TEnumerator<TPair<TKey, TValue>>;
120*16467b97STreehugger Robot
121*16467b97STreehugger Robot property Items[const Key: TKey]: TValue read GetItem write SetItem; default;
122*16467b97STreehugger Robot end;
123*16467b97STreehugger Robot
124*16467b97STreehugger Robot TStackList<T> = class(TList<T>, IStackList<T>)
125*16467b97STreehugger Robot protected
126*16467b97STreehugger Robot { IStackList<T> }
127*16467b97STreehugger Robot procedure Push(const Item: T);
Pop()128*16467b97STreehugger Robot function Pop: T;
Peek()129*16467b97STreehugger Robot function Peek: T;
130*16467b97STreehugger Robot end;
131*16467b97STreehugger Robot
132*16467b97STreehugger Robot TCollectionUtils = class
133*16467b97STreehugger Robot public
134*16467b97STreehugger Robot /// <summary>
135*16467b97STreehugger Robot /// Returns a string representation of this IDictionary.
136*16467b97STreehugger Robot /// </summary>
137*16467b97STreehugger Robot /// <remarks>
138*16467b97STreehugger Robot /// The string representation is a list of the collection's elements in the order
139*16467b97STreehugger Robot /// they are returned by its enumerator, enclosed in curly brackets ("{}").
140*16467b97STreehugger Robot /// The separator is a comma followed by a space i.e. ", ".
141*16467b97STreehugger Robot /// </remarks>
142*16467b97STreehugger Robot /// <param name="dict">Dictionary whose string representation will be returned</param>
143*16467b97STreehugger Robot /// <returns>A string representation of the specified dictionary or "null"</returns>
DictionaryToString(const Dict: IDictionary<Integer, IList<IANTLRInterface>>)144*16467b97STreehugger Robot class function DictionaryToString(const Dict: IDictionary<Integer, IList<IANTLRInterface>>): String; static;
145*16467b97STreehugger Robot
146*16467b97STreehugger Robot /// <summary>
147*16467b97STreehugger Robot /// Returns a string representation of this IList.
148*16467b97STreehugger Robot /// </summary>
149*16467b97STreehugger Robot /// <remarks>
150*16467b97STreehugger Robot /// The string representation is a list of the collection's elements in the order
151*16467b97STreehugger Robot /// they are returned by its enumerator, enclosed in square brackets ("[]").
152*16467b97STreehugger Robot /// The separator is a comma followed by a space i.e. ", ".
153*16467b97STreehugger Robot /// </remarks>
154*16467b97STreehugger Robot /// <param name="coll">Collection whose string representation will be returned</param>
155*16467b97STreehugger Robot /// <returns>A string representation of the specified collection or "null"</returns>
ListToString(const Coll: IList<IANTLRInterface>)156*16467b97STreehugger Robot class function ListToString(const Coll: IList<IANTLRInterface>): String; overload; static;
ListToString(const Coll: IList<String>)157*16467b97STreehugger Robot class function ListToString(const Coll: IList<String>): String; overload; static;
158*16467b97STreehugger Robot end;
159*16467b97STreehugger Robot
160*16467b97STreehugger Robot implementation
161*16467b97STreehugger Robot
162*16467b97STreehugger Robot uses
163*16467b97STreehugger Robot Classes,
164*16467b97STreehugger Robot SysUtils;
165*16467b97STreehugger Robot
166*16467b97STreehugger Robot { THashList<TKey, TValue> }
167*16467b97STreehugger Robot
168*16467b97STreehugger Robot procedure THashList<TKey, TValue>.Add(const Key: TKey; const Value: TValue);
169*16467b97STreehugger Robot begin
170*16467b97STreehugger Robot FDictionary.Add(Key, Value);
171*16467b97STreehugger Robot FInsertionOrderList.Add(Key);
172*16467b97STreehugger Robot Inc(FVersion);
173*16467b97STreehugger Robot end;
174*16467b97STreehugger Robot
175*16467b97STreehugger Robot procedure THashList<TKey, TValue>.AddOrSetValue(const Key: TKey;
176*16467b97STreehugger Robot const Value: TValue);
177*16467b97STreehugger Robot begin
178*16467b97STreehugger Robot if FDictionary.ContainsKey(Key) then
179*16467b97STreehugger Robot SetItem(Key, Value)
180*16467b97STreehugger Robot else
181*16467b97STreehugger Robot Add(Key, Value);
182*16467b97STreehugger Robot end;
183*16467b97STreehugger Robot
184*16467b97STreehugger Robot procedure THashList<TKey, TValue>.Clear;
185*16467b97STreehugger Robot begin
186*16467b97STreehugger Robot FDictionary.Clear;
187*16467b97STreehugger Robot FInsertionOrderList.Clear;
188*16467b97STreehugger Robot Inc(FVersion);
189*16467b97STreehugger Robot end;
190*16467b97STreehugger Robot
THashList(const Key: TKey)191*16467b97STreehugger Robot function THashList<TKey, TValue>.ContainsKey(const Key: TKey): Boolean;
192*16467b97STreehugger Robot begin
193*16467b97STreehugger Robot Result := FDictionary.ContainsKey(Key);
194*16467b97STreehugger Robot end;
195*16467b97STreehugger Robot
THashList(const Value: TValue)196*16467b97STreehugger Robot function THashList<TKey, TValue>.ContainsValue(const Value: TValue): Boolean;
197*16467b97STreehugger Robot begin
198*16467b97STreehugger Robot Result := FDictionary.ContainsValue(Value);
199*16467b97STreehugger Robot end;
200*16467b97STreehugger Robot
201*16467b97STreehugger Robot constructor THashList<TKey, TValue>.Create;
202*16467b97STreehugger Robot begin
203*16467b97STreehugger Robot Create(-1);
204*16467b97STreehugger Robot end;
205*16467b97STreehugger Robot
206*16467b97STreehugger Robot constructor THashList<TKey, TValue>.Create(const ACapacity: Integer);
207*16467b97STreehugger Robot begin
208*16467b97STreehugger Robot inherited Create;
209*16467b97STreehugger Robot if (ACapacity < 0) then
210*16467b97STreehugger Robot begin
211*16467b97STreehugger Robot FDictionary := TDictionary<TKey, TValue>.Create;
212*16467b97STreehugger Robot FInsertionOrderList := TList<TKey>.Create;
213*16467b97STreehugger Robot end
214*16467b97STreehugger Robot else
215*16467b97STreehugger Robot begin
216*16467b97STreehugger Robot FDictionary := TDictionary<TKey, TValue>.Create(ACapacity);
217*16467b97STreehugger Robot FInsertionOrderList := TList<TKey>.Create;
218*16467b97STreehugger Robot FInsertionOrderList.Capacity := ACapacity;
219*16467b97STreehugger Robot end;
220*16467b97STreehugger Robot end;
221*16467b97STreehugger Robot
THashList()222*16467b97STreehugger Robot function THashList<TKey, TValue>.GetCount: Integer;
223*16467b97STreehugger Robot begin
224*16467b97STreehugger Robot Result := FDictionary.Count;
225*16467b97STreehugger Robot end;
226*16467b97STreehugger Robot
THashList()227*16467b97STreehugger Robot function THashList<TKey, TValue>.GetEnumerator: TEnumerator<TPair<TKey, TValue>>;
228*16467b97STreehugger Robot begin
229*16467b97STreehugger Robot Result := TPairEnumerator.Create(Self);
230*16467b97STreehugger Robot end;
231*16467b97STreehugger Robot
GetItemnull232*16467b97STreehugger Robot function THashList<TKey, TValue>.GetItem(const Key: TKey): TValue;
233*16467b97STreehugger Robot begin
234*16467b97STreehugger Robot Result := FDictionary[Key];
235*16467b97STreehugger Robot end;
236*16467b97STreehugger Robot
237*16467b97STreehugger Robot procedure THashList<TKey, TValue>.Remove(const Key: TKey);
238*16467b97STreehugger Robot begin
239*16467b97STreehugger Robot FDictionary.Remove(Key);
240*16467b97STreehugger Robot FInsertionOrderList.Remove(Key);
241*16467b97STreehugger Robot Inc(FVersion);
242*16467b97STreehugger Robot end;
243*16467b97STreehugger Robot
244*16467b97STreehugger Robot procedure THashList<TKey, TValue>.SetItem(const Key: TKey; const Value: TValue);
245*16467b97STreehugger Robot var
246*16467b97STreehugger Robot IsNewEntry: Boolean;
247*16467b97STreehugger Robot begin
248*16467b97STreehugger Robot IsNewEntry := (not FDictionary.ContainsKey(Key));
249*16467b97STreehugger Robot FDictionary[Key] := Value;
250*16467b97STreehugger Robot if (IsNewEntry) then
251*16467b97STreehugger Robot FInsertionOrderList.Add(Key);
252*16467b97STreehugger Robot Inc(FVersion);
253*16467b97STreehugger Robot end;
254*16467b97STreehugger Robot
255*16467b97STreehugger Robot procedure THashList<TKey, TValue>.TrimExcess;
256*16467b97STreehugger Robot begin
257*16467b97STreehugger Robot FDictionary.TrimExcess;
258*16467b97STreehugger Robot FInsertionOrderList.Capacity := FDictionary.Count;
259*16467b97STreehugger Robot end;
260*16467b97STreehugger Robot
THashList(const Key: TKey;261*16467b97STreehugger Robot function THashList<TKey, TValue>.TryGetValue(const Key: TKey;
262*16467b97STreehugger Robot out Value: TValue): Boolean;
263*16467b97STreehugger Robot begin
264*16467b97STreehugger Robot Result := FDictionary.TryGetValue(Key,Value);
265*16467b97STreehugger Robot end;
266*16467b97STreehugger Robot
267*16467b97STreehugger Robot { THashList<TKey, TValue>.TPairEnumerator }
268*16467b97STreehugger Robot
269*16467b97STreehugger Robot constructor THashList<TKey, TValue>.TPairEnumerator.Create(
270*16467b97STreehugger Robot const AHashList: THashList<TKey, TValue>);
271*16467b97STreehugger Robot begin
272*16467b97STreehugger Robot inherited Create;
273*16467b97STreehugger Robot FHashList := AHashList;
274*16467b97STreehugger Robot FVersion := FHashList.FVersion;
275*16467b97STreehugger Robot FOrderList := FHashList.FInsertionOrderList;
276*16467b97STreehugger Robot end;
277*16467b97STreehugger Robot
THashList()278*16467b97STreehugger Robot function THashList<TKey, TValue>.TPairEnumerator.DoGetCurrent: TPair<TKey, TValue>;
279*16467b97STreehugger Robot begin
280*16467b97STreehugger Robot Result := GetCurrent;
281*16467b97STreehugger Robot end;
282*16467b97STreehugger Robot
THashList()283*16467b97STreehugger Robot function THashList<TKey, TValue>.TPairEnumerator.DoMoveNext: Boolean;
284*16467b97STreehugger Robot begin
285*16467b97STreehugger Robot Result := MoveNext;
286*16467b97STreehugger Robot end;
287*16467b97STreehugger Robot
THashList()288*16467b97STreehugger Robot function THashList<TKey, TValue>.TPairEnumerator.GetCurrent: TPair<TKey, TValue>;
289*16467b97STreehugger Robot begin
290*16467b97STreehugger Robot Result := FPair;
291*16467b97STreehugger Robot end;
292*16467b97STreehugger Robot
THashList()293*16467b97STreehugger Robot function THashList<TKey, TValue>.TPairEnumerator.MoveNext: Boolean;
294*16467b97STreehugger Robot begin
295*16467b97STreehugger Robot if (FVersion <> FHashList.FVersion) then
296*16467b97STreehugger Robot raise EInvalidOperation.Create('Collection was modified; enumeration operation may not execute.');
297*16467b97STreehugger Robot if (FIndex < FOrderList.Count) then
298*16467b97STreehugger Robot begin
299*16467b97STreehugger Robot FPair.Key := FOrderList[FIndex];
300*16467b97STreehugger Robot FPair.Value := FHashList[FPair.Key];
301*16467b97STreehugger Robot Inc(FIndex);
302*16467b97STreehugger Robot Result := True;
303*16467b97STreehugger Robot end
304*16467b97STreehugger Robot else
305*16467b97STreehugger Robot begin
306*16467b97STreehugger Robot FPair.Key := Default(TKey);
307*16467b97STreehugger Robot FPair.Value := Default(TValue);
308*16467b97STreehugger Robot Result := False;
309*16467b97STreehugger Robot end;
310*16467b97STreehugger Robot end;
311*16467b97STreehugger Robot
312*16467b97STreehugger Robot { TStackList<T> }
313*16467b97STreehugger Robot
TStackList()314*16467b97STreehugger Robot function TStackList<T>.Peek: T;
315*16467b97STreehugger Robot begin
316*16467b97STreehugger Robot Result := GetItem(GetCount - 1);
317*16467b97STreehugger Robot end;
318*16467b97STreehugger Robot
Popnull319*16467b97STreehugger Robot function TStackList<T>.Pop: T;
320*16467b97STreehugger Robot var
321*16467b97STreehugger Robot I: Integer;
322*16467b97STreehugger Robot begin
323*16467b97STreehugger Robot I := GetCount - 1;
324*16467b97STreehugger Robot Result := GetItem(I);
325*16467b97STreehugger Robot Delete(I);
326*16467b97STreehugger Robot end;
327*16467b97STreehugger Robot
328*16467b97STreehugger Robot procedure TStackList<T>.Push(const Item: T);
329*16467b97STreehugger Robot begin
330*16467b97STreehugger Robot Add(Item);
331*16467b97STreehugger Robot end;
332*16467b97STreehugger Robot
333*16467b97STreehugger Robot { TCollectionUtils }
334*16467b97STreehugger Robot
TCollectionUtils.DictionaryToString(335*16467b97STreehugger Robot class function TCollectionUtils.DictionaryToString(
336*16467b97STreehugger Robot const Dict: IDictionary<Integer, IList<IANTLRInterface>>): String;
337*16467b97STreehugger Robot var
338*16467b97STreehugger Robot SB: TStringBuilder;
339*16467b97STreehugger Robot I: Integer;
340*16467b97STreehugger Robot E: TPair<Integer, IList<IANTLRInterface>>;
341*16467b97STreehugger Robot begin
342*16467b97STreehugger Robot SB := TStringBuilder.Create;
343*16467b97STreehugger Robot try
344*16467b97STreehugger Robot if Assigned(Dict) then
345*16467b97STreehugger Robot begin
346*16467b97STreehugger Robot SB.Append('{');
347*16467b97STreehugger Robot I := 0;
348*16467b97STreehugger Robot for E in Dict do
349*16467b97STreehugger Robot begin
350*16467b97STreehugger Robot if (I > 0) then
351*16467b97STreehugger Robot SB.Append(', ');
352*16467b97STreehugger Robot SB.AppendFormat('%d=%s', [E.Key, ListToString(E.Value)]);
353*16467b97STreehugger Robot Inc(I);
354*16467b97STreehugger Robot end;
355*16467b97STreehugger Robot SB.Append('}');
356*16467b97STreehugger Robot end
357*16467b97STreehugger Robot else
358*16467b97STreehugger Robot SB.Insert(0, 'null');
359*16467b97STreehugger Robot Result := SB.ToString;
360*16467b97STreehugger Robot finally
361*16467b97STreehugger Robot SB.Free;
362*16467b97STreehugger Robot end;
363*16467b97STreehugger Robot end;
364*16467b97STreehugger Robot
TCollectionUtils.ListToString(365*16467b97STreehugger Robot class function TCollectionUtils.ListToString(
366*16467b97STreehugger Robot const Coll: IList<IANTLRInterface>): String;
367*16467b97STreehugger Robot var
368*16467b97STreehugger Robot SB: TStringBuilder;
369*16467b97STreehugger Robot I: Integer;
370*16467b97STreehugger Robot Element: IANTLRInterface;
371*16467b97STreehugger Robot Dict: IDictionary<Integer, IList<IANTLRInterface>>;
372*16467b97STreehugger Robot List: IList<IANTLRInterface>;
373*16467b97STreehugger Robot begin
374*16467b97STreehugger Robot SB := TStringBuilder.Create;
375*16467b97STreehugger Robot try
376*16467b97STreehugger Robot if (Coll <> nil) then
377*16467b97STreehugger Robot begin
378*16467b97STreehugger Robot SB.Append('[');
379*16467b97STreehugger Robot for I := 0 to Coll.Count - 1 do
380*16467b97STreehugger Robot begin
381*16467b97STreehugger Robot if (I > 0) then
382*16467b97STreehugger Robot SB.Append(', ');
383*16467b97STreehugger Robot Element := Coll[I];
384*16467b97STreehugger Robot if (Element = nil) then
385*16467b97STreehugger Robot SB.Append('null')
386*16467b97STreehugger Robot else
387*16467b97STreehugger Robot if Supports(Element, IDictionary<Integer, IList<IANTLRInterface>>, Dict) then
388*16467b97STreehugger Robot SB.Append(DictionaryToString(Dict))
389*16467b97STreehugger Robot else
390*16467b97STreehugger Robot if Supports(Element, IList<IANTLRInterface>, List) then
391*16467b97STreehugger Robot SB.Append(ListToString(List))
392*16467b97STreehugger Robot else
393*16467b97STreehugger Robot SB.Append(Element.ToString);
394*16467b97STreehugger Robot end;
395*16467b97STreehugger Robot SB.Append(']');
396*16467b97STreehugger Robot end
397*16467b97STreehugger Robot else
398*16467b97STreehugger Robot SB.Insert(0, 'null');
399*16467b97STreehugger Robot Result := SB.ToString;
400*16467b97STreehugger Robot finally
401*16467b97STreehugger Robot SB.Free;
402*16467b97STreehugger Robot end;
403*16467b97STreehugger Robot end;
404*16467b97STreehugger Robot
TCollectionUtils.ListToString(const Coll: IList<String>)405*16467b97STreehugger Robot class function TCollectionUtils.ListToString(const Coll: IList<String>): String;
406*16467b97STreehugger Robot var
407*16467b97STreehugger Robot SB: TStringBuilder;
408*16467b97STreehugger Robot I: Integer;
409*16467b97STreehugger Robot begin
410*16467b97STreehugger Robot SB := TStringBuilder.Create;
411*16467b97STreehugger Robot try
412*16467b97STreehugger Robot if (Coll <> nil) then
413*16467b97STreehugger Robot begin
414*16467b97STreehugger Robot SB.Append('[');
415*16467b97STreehugger Robot for I := 0 to Coll.Count - 1 do
416*16467b97STreehugger Robot begin
417*16467b97STreehugger Robot if (I > 0) then
418*16467b97STreehugger Robot SB.Append(', ');
419*16467b97STreehugger Robot SB.Append(Coll[I]);
420*16467b97STreehugger Robot end;
421*16467b97STreehugger Robot SB.Append(']');
422*16467b97STreehugger Robot end
423*16467b97STreehugger Robot else
424*16467b97STreehugger Robot SB.Insert(0, 'null');
425*16467b97STreehugger Robot Result := SB.ToString;
426*16467b97STreehugger Robot finally
427*16467b97STreehugger Robot SB.Free;
428*16467b97STreehugger Robot end;
429*16467b97STreehugger Robot end;
430*16467b97STreehugger Robot
431*16467b97STreehugger Robot end.
432