Skip to content

Commit 100bff1

Browse files
committed
#81 support indention in dynamic codegen, part 5: collection
1 parent 0b2329f commit 100bff1

File tree

4 files changed

+88
-34
lines changed

4 files changed

+88
-34
lines changed

src/main/java/com/jsoniter/output/CodegenImplArray.java

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,31 @@
88

99
class CodegenImplArray {
1010

11+
public static CodegenResult genCollection(String cacheKey, ClassInfo classInfo) {
12+
Type[] typeArgs = classInfo.typeArgs;
13+
Class clazz = classInfo.clazz;
14+
Type compType = Object.class;
15+
if (typeArgs.length == 0) {
16+
// default to List<Object>
17+
} else if (typeArgs.length == 1) {
18+
compType = typeArgs[0];
19+
} else {
20+
throw new IllegalArgumentException(
21+
"can not bind to generic collection without argument types, " +
22+
"try syntax like TypeLiteral<List<Integer>>{}");
23+
}
24+
if (clazz == List.class) {
25+
clazz = ArrayList.class;
26+
} else if (clazz == Set.class) {
27+
clazz = HashSet.class;
28+
}
29+
if (List.class.isAssignableFrom(clazz)) {
30+
return genList(cacheKey, clazz, compType);
31+
} else {
32+
return genCollection(cacheKey, clazz, compType);
33+
}
34+
}
35+
1136
public static CodegenResult genArray(String cacheKey, ClassInfo classInfo) {
1237
boolean noIndention = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
1338
Class clazz = classInfo.clazz;
@@ -27,12 +52,9 @@ public static CodegenResult genArray(String cacheKey, ClassInfo classInfo) {
2752
ctx.append(String.format("%s[] arr = (%s[])obj;", compType.getCanonicalName(), compType.getCanonicalName()));
2853
if (noIndention) {
2954
ctx.append("if (arr.length == 0) { return; }");
30-
} else {
31-
ctx.append("if (arr.length == 0) { stream.write((byte)'[', (byte)']'); return; }");
32-
}
33-
if (noIndention) {
3455
ctx.buffer('[');
3556
} else {
57+
ctx.append("if (arr.length == 0) { stream.write((byte)'[', (byte)']'); return; }");
3658
ctx.append("stream.writeArrayStart(); stream.writeIndention();");
3759
}
3860
ctx.append("int i = 0;");
@@ -68,31 +90,6 @@ public static CodegenResult genArray(String cacheKey, ClassInfo classInfo) {
6890
return ctx;
6991
}
7092

71-
public static CodegenResult genCollection(String cacheKey, ClassInfo classInfo) {
72-
Type[] typeArgs = classInfo.typeArgs;
73-
Class clazz = classInfo.clazz;
74-
Type compType = Object.class;
75-
if (typeArgs.length == 0) {
76-
// default to List<Object>
77-
} else if (typeArgs.length == 1) {
78-
compType = typeArgs[0];
79-
} else {
80-
throw new IllegalArgumentException(
81-
"can not bind to generic collection without argument types, " +
82-
"try syntax like TypeLiteral<List<Integer>>{}");
83-
}
84-
if (clazz == List.class) {
85-
clazz = ArrayList.class;
86-
} else if (clazz == Set.class) {
87-
clazz = HashSet.class;
88-
}
89-
if (List.class.isAssignableFrom(clazz)) {
90-
return genList(cacheKey, clazz, compType);
91-
} else {
92-
return genCollection(cacheKey, clazz, compType);
93-
}
94-
}
95-
9693
private static CodegenResult genList(String cacheKey, Class clazz, Type compType) {
9794
boolean isCollectionValueNullable = true;
9895
if (cacheKey.endsWith("__value_not_nullable")) {
@@ -129,15 +126,21 @@ private static CodegenResult genList(String cacheKey, Class clazz, Type compType
129126
}
130127

131128
private static CodegenResult genCollection(String cacheKey, Class clazz, Type compType) {
129+
boolean noIndention = JsoniterSpi.getCurrentConfig().indentionStep() == 0;
132130
boolean isCollectionValueNullable = true;
133131
if (cacheKey.endsWith("__value_not_nullable")) {
134132
isCollectionValueNullable = false;
135133
}
136134
CodegenResult ctx = new CodegenResult();
137135
ctx.append("public static void encode_(java.lang.Object obj, com.jsoniter.output.JsonStream stream) throws java.io.IOException {");
138136
ctx.append("java.util.Iterator iter = ((java.util.Collection)obj).iterator();");
139-
ctx.append("if (!iter.hasNext()) { return; }");
140-
ctx.buffer('[');
137+
if (noIndention) {
138+
ctx.append("if (!iter.hasNext()) { return; }");
139+
ctx.buffer('[');
140+
} else {
141+
ctx.append("if (!iter.hasNext()) { stream.write((byte)'[', (byte)']'); return; }");
142+
ctx.append("stream.writeArrayStart(); stream.writeIndention();");
143+
}
141144
ctx.append("java.lang.Object e = iter.next();");
142145
if (isCollectionValueNullable) {
143146
ctx.append("if (e == null) { stream.writeNull(); } else {");
@@ -147,7 +150,11 @@ private static CodegenResult genCollection(String cacheKey, Class clazz, Type co
147150
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
148151
}
149152
ctx.append("while (iter.hasNext()) {");
150-
ctx.append("stream.write(',');");
153+
if (noIndention) {
154+
ctx.append("stream.write(',');");
155+
} else {
156+
ctx.append("stream.writeMore();");
157+
}
151158
ctx.append("e = iter.next();");
152159
if (isCollectionValueNullable) {
153160
ctx.append("if (e == null) { stream.writeNull(); } else {");
@@ -157,7 +164,11 @@ private static CodegenResult genCollection(String cacheKey, Class clazz, Type co
157164
CodegenImplNative.genWriteOp(ctx, "e", compType, false);
158165
}
159166
ctx.append("}"); // while
160-
ctx.buffer(']');
167+
if (noIndention) {
168+
ctx.buffer(']');
169+
} else {
170+
ctx.append("stream.writeArrayEnd();");
171+
}
161172
ctx.append("}"); // public static void encode_
162173
return ctx;
163174
}

src/main/java/com/jsoniter/output/ReflectionCollectionEncoder.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public void encode(Object obj, JsonStream stream) throws IOException {
3434
return;
3535
}
3636
stream.writeArrayStart();
37+
stream.writeIndention();
3738
stream.writeVal(compTypeLiteral, iter.next());
3839
while (iter.hasNext()) {
3940
stream.writeMore();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.jsoniter.output;
2+
3+
import com.jsoniter.spi.Config;
4+
import junit.framework.TestCase;
5+
6+
import java.util.HashSet;
7+
8+
public class TestCollection extends TestCase {
9+
10+
public void test_indention() {
11+
HashSet<Integer> set = new HashSet<Integer>();
12+
set.add(1);
13+
Config cfg = new Config.Builder()
14+
.encodingMode(EncodingMode.REFLECTION_MODE)
15+
.indentionStep(2)
16+
.build();
17+
assertEquals("[\n" +
18+
" 1\n" +
19+
"]", JsonStream.serialize(cfg, set));
20+
cfg = new Config.Builder()
21+
.encodingMode(EncodingMode.DYNAMIC_MODE)
22+
.indentionStep(2)
23+
.build();
24+
assertEquals("[\n" +
25+
" 1\n" +
26+
"]", JsonStream.serialize(cfg, set));
27+
}
28+
29+
public void test_indention_with_empty_array() {
30+
Config cfg = new Config.Builder()
31+
.encodingMode(EncodingMode.REFLECTION_MODE)
32+
.indentionStep(2)
33+
.build();
34+
assertEquals("[]", JsonStream.serialize(cfg, new HashSet<Integer>()));
35+
cfg = new Config.Builder()
36+
.encodingMode(EncodingMode.DYNAMIC_MODE)
37+
.indentionStep(2)
38+
.build();
39+
assertEquals("[]", JsonStream.serialize(cfg, new HashSet<Integer>()));
40+
}
41+
}

src/test/java/com/jsoniter/suite/AllTestCases.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
TestSpiPropertyDecoder.class,
4949
TestGson.class,
5050
com.jsoniter.output.TestGson.class,
51-
TestStreamBuffer.class})
51+
TestStreamBuffer.class,
52+
TestCollection.class})
5253
public abstract class AllTestCases {
5354
}

0 commit comments

Comments
 (0)