Skip to content

Commit 99c9610

Browse files
committed
feat: add PrettyFormatInlineArrays feature to keep arrays on single line
Fixes #2972 Added new JSONWriter.Feature.PrettyFormatInlineArrays that, when used with PrettyFormat, keeps array elements on a single line instead of expanding each element to its own line. This matches the original fastjson behavior. Changes: - Added PrettyFormatInlineArrays feature flag (bit 46) - Added levelArray bitmask to track array vs object context at each level - Modified startArray/endArray/writeComma in JSONWriterUTF8 and JSONWriterUTF16 - Added comprehensive tests for edge cases
1 parent a2066d8 commit 99c9610

4 files changed

Lines changed: 450 additions & 7 deletions

File tree

core/src/main/java/com/alibaba/fastjson2/JSONWriter.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,22 @@ public abstract class JSONWriter
8484

8585
protected boolean startObject;
8686
protected int level;
87+
/**
88+
* Bitmask tracking which nesting levels are arrays (vs objects).
89+
* Bit N is set if level N is an array context.
90+
*/
91+
protected long levelArray;
8792
protected int off;
8893
protected Object rootObject;
8994
protected IdentityHashMap<Object, Path> refs;
9095
protected Path path;
9196
protected String lastReference;
9297
protected byte pretty;
98+
/**
99+
* When true and pretty formatting is enabled, arrays are written inline
100+
* (on a single line) rather than with line breaks between elements.
101+
*/
102+
protected boolean prettyInlineArrays;
93103
protected Object attachment;
94104

95105
protected JSONWriter(
@@ -119,6 +129,7 @@ protected JSONWriter(
119129
} else {
120130
pretty = PRETTY_NON;
121131
}
132+
prettyInlineArrays = (context.features & PrettyFormatInlineArrays.mask) != 0;
122133
}
123134

124135
/**
@@ -4430,7 +4441,18 @@ public enum Feature {
44304441
*
44314442
* @since 2.0.61
44324443
*/
4433-
WriteFloatSpecialAsString(1L << 45);
4444+
WriteFloatSpecialAsString(1L << 45),
4445+
4446+
/**
4447+
* Feature that controls whether arrays are formatted inline (on a single line) when using PrettyFormat.
4448+
* When enabled along with PrettyFormat, array elements will be written on a single line like [1, 2, 3]
4449+
* instead of having each element on a separate line.
4450+
*
4451+
* <p>This feature requires {@link PrettyFormat} to also be enabled to have any effect.</p>
4452+
*
4453+
* @since 2.0.61
4454+
*/
4455+
PrettyFormatInlineArrays(1L << 46);
44344456

44354457
public final long mask;
44364458

core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,11 @@ public final void writeComma() {
188188

189189
chars[off++] = (byte) ',';
190190
if (pretty != PRETTY_NON) {
191-
off = indent(chars, off);
191+
// Check if we're in an array context with inline arrays enabled
192+
boolean inArrayContext = (levelArray & (1L << level)) != 0;
193+
if (!(prettyInlineArrays && inArrayContext)) {
194+
off = indent(chars, off);
195+
}
192196
}
193197
this.off = off;
194198
}
@@ -198,6 +202,8 @@ public final void startArray() {
198202
if (++level > context.maxLevel) {
199203
overflowLevel();
200204
}
205+
// Mark current level as array context
206+
levelArray |= (1L << level);
201207

202208
int off = this.off;
203209
int minCapacity = off + 3 + pretty * level;
@@ -207,14 +213,16 @@ public final void startArray() {
207213
}
208214

209215
chars[off++] = (byte) '[';
210-
if (pretty != PRETTY_NON) {
216+
if (pretty != PRETTY_NON && !prettyInlineArrays) {
211217
off = indent(chars, off);
212218
}
213219
this.off = off;
214220
}
215221

216222
@Override
217223
public final void endArray() {
224+
// Clear array context for current level before decrementing
225+
levelArray &= ~(1L << level);
218226
level--;
219227
int off = this.off;
220228
int minCapacity = off + 1 + (pretty == 0 ? 0 : pretty * level + 1);
@@ -223,7 +231,7 @@ public final void endArray() {
223231
chars = grow(minCapacity);
224232
}
225233

226-
if (pretty != PRETTY_NON) {
234+
if (pretty != PRETTY_NON && !prettyInlineArrays) {
227235
off = indent(chars, off);
228236
}
229237
chars[off] = (byte) ']';

core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF8.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,11 @@ public final void writeComma() {
255255
}
256256
bytes[off++] = ',';
257257
if (pretty != PRETTY_NON) {
258-
off = indent(bytes, off);
258+
// Check if we're in an array context with inline arrays enabled
259+
boolean inArrayContext = (levelArray & (1L << level)) != 0;
260+
if (!(prettyInlineArrays && inArrayContext)) {
261+
off = indent(bytes, off);
262+
}
259263
}
260264
this.off = off;
261265
}
@@ -265,6 +269,8 @@ public final void startArray() {
265269
if (++level > context.maxLevel) {
266270
overflowLevel();
267271
}
272+
// Mark current level as array context
273+
levelArray |= (1L << level);
268274

269275
int off = this.off;
270276
int minCapacity = off + 3 + pretty * level;
@@ -273,22 +279,24 @@ public final void startArray() {
273279
bytes = grow(minCapacity);
274280
}
275281
bytes[off++] = '[';
276-
if (pretty != PRETTY_NON) {
282+
if (pretty != PRETTY_NON && !prettyInlineArrays) {
277283
off = indent(bytes, off);
278284
}
279285
this.off = off;
280286
}
281287

282288
@Override
283289
public final void endArray() {
290+
// Clear array context for current level before decrementing
291+
levelArray &= ~(1L << level);
284292
level--;
285293
int off = this.off;
286294
int minCapacity = off + 1 + (pretty == 0 ? 0 : pretty * level + 1);
287295
byte[] bytes = this.bytes;
288296
if (minCapacity > bytes.length) {
289297
bytes = grow(minCapacity);
290298
}
291-
if (pretty != PRETTY_NON) {
299+
if (pretty != PRETTY_NON && !prettyInlineArrays) {
292300
off = indent(bytes, off);
293301
}
294302
bytes[off] = ']';

0 commit comments

Comments
 (0)