Skip to content

Commit ec5c324

Browse files
committed
Update to Java commit 25e8f4e (2025.08.25): CLJ-2916 LazySeq - realize before serializing and do not serialize.
I had made a partial update previously. Finally figure out a good way to do this.
1 parent f4e4e89 commit ec5c324

File tree

1 file changed

+23
-5
lines changed

1 file changed

+23
-5
lines changed

Clojure/Clojure/Lib/LazySeq.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System;
1616
using System.Collections;
1717
using System.Collections.Generic;
18+
using System.Runtime.Serialization;
1819
using System.Threading;
1920

2021
namespace clojure.lang
@@ -24,11 +25,6 @@ namespace clojure.lang
2425
{
2526
#region Data
2627

27-
// TODO: Making this field non-serialized is only part of the solution to CLJ-2916 LazySeq - realize before serializing and do not serialize IFn.
28-
// Unfortunately, making the LazySeq realize before serializing requires implementatin ISerializable, then making Obj implement it also.
29-
// And doing that causes 49 errors in the test suite -- we need to add an additional constructor and probably also GetObjectData for every class derived from Obj.
30-
// That's too much. Defer this until we decide what to do about BinaryFormatter being declared obsolete/unsafe.
31-
3228
[NonSerialized]
3329
private IFn _fn;
3430
private object _sv;
@@ -54,6 +50,26 @@ private LazySeq(IPersistentMap meta, ISeq seq)
5450

5551
#endregion
5652

53+
#region Serialization support
54+
55+
// Per issue CLJ-2916 "LazySeq - realize before serializing and do not serialize IFn":
56+
// We can handle not serializing the IFn by marking it [NonSerialized].
57+
// To realize before serializing, we can use the OnSerializing attribute as below.
58+
59+
[OnSerializing]
60+
private void OnSerializing(StreamingContext context)
61+
{
62+
// Realize the sequence before serializing, so that we don't have to serialize the IFn.
63+
// We can check if _fn is null to avoid doing this more than once, since the same instance may be serialized multiple times.
64+
ISeq s = this;
65+
while (s != null)
66+
{
67+
s = s.next();
68+
}
69+
}
70+
71+
#endregion
72+
5773
#region Implementation details
5874

5975
// MUST be locked when called
@@ -432,5 +448,7 @@ public int hasheq()
432448

433449
#endregion
434450

451+
452+
435453
}
436454
}

0 commit comments

Comments
 (0)