@@ -8,57 +8,12 @@ import {
8
8
isTypedArray ,
9
9
unwrapArrayItemType ,
10
10
isMap ,
11
- isEnumType
11
+ isEnumType ,
12
+ isSet ,
13
+ isPrimitiveToJson
12
14
} from '../BuilderHelpers' ;
13
15
import { findModule , findSerializerModule , isImmutable , JsonProperty , JsonSerializable } from './Serializer.common' ;
14
16
15
- function isPrimitiveToJson ( type : ts . Type , typeChecker : ts . TypeChecker ) {
16
- if ( ! type ) {
17
- return false ;
18
- }
19
-
20
- const isArray = isTypedArray ( type ) ;
21
- const arrayItemType = unwrapArrayItemType ( type , typeChecker ) ;
22
-
23
- if ( hasFlag ( type , ts . TypeFlags . Unknown ) ) {
24
- return true ;
25
- }
26
- if ( hasFlag ( type , ts . TypeFlags . Number ) ) {
27
- return true ;
28
- }
29
- if ( hasFlag ( type , ts . TypeFlags . String ) ) {
30
- return true ;
31
- }
32
- if ( hasFlag ( type , ts . TypeFlags . Boolean ) ) {
33
- return true ;
34
- }
35
-
36
- if ( arrayItemType ) {
37
- if ( isArray && hasFlag ( arrayItemType , ts . TypeFlags . Number ) ) {
38
- return true ;
39
- }
40
- if ( isArray && hasFlag ( arrayItemType , ts . TypeFlags . String ) ) {
41
- return true ;
42
- }
43
- if ( isArray && hasFlag ( arrayItemType , ts . TypeFlags . Boolean ) ) {
44
- return true ;
45
- }
46
- } else if ( type . symbol ) {
47
- switch ( type . symbol . name ) {
48
- case 'Uint8Array' :
49
- case 'Uint16Array' :
50
- case 'Uint32Array' :
51
- case 'Int8Array' :
52
- case 'Int16Array' :
53
- case 'Int32Array' :
54
- case 'Float32Array' :
55
- case 'Float64Array' :
56
- return true ;
57
- }
58
- }
59
-
60
- return false ;
61
- }
62
17
63
18
function generateToJsonBody (
64
19
program : ts . Program ,
@@ -96,7 +51,6 @@ function generateToJsonBody(
96
51
}
97
52
98
53
let propertyStatements : ts . Statement [ ] = [ ] ;
99
-
100
54
101
55
const typeChecker = program . getTypeChecker ( ) ;
102
56
const type = getTypeWithNullableInfo ( typeChecker , prop . property . type ! , prop . asRaw ) ;
@@ -154,7 +108,6 @@ function generateToJsonBody(
154
108
)
155
109
) ;
156
110
}
157
-
158
111
} else if ( isMap ( type . type ) ) {
159
112
const mapType = type . type as ts . TypeReference ;
160
113
if ( ! isPrimitiveType ( mapType . typeArguments ! [ 0 ] ) ) {
@@ -170,7 +123,9 @@ function generateToJsonBody(
170
123
for(const [k, v] of obj.${ fieldName } !) {
171
124
m.set(k.toString(), v);
172
125
}
173
- }` , ts . SyntaxKind . Block ) ;
126
+ }` ,
127
+ ts . SyntaxKind . Block
128
+ ) ;
174
129
} else if ( isEnumType ( mapType . typeArguments ! [ 1 ] ) ) {
175
130
serializeBlock = createNodeFromSource < ts . Block > (
176
131
`{
@@ -179,7 +134,9 @@ function generateToJsonBody(
179
134
for(const [k, v] of obj.${ fieldName } !) {
180
135
m.set(k.toString(), v as number);
181
136
}
182
- }` , ts . SyntaxKind . Block ) ;
137
+ }` ,
138
+ ts . SyntaxKind . Block
139
+ ) ;
183
140
} else {
184
141
const itemSerializer = mapType . typeArguments ! [ 1 ] . symbol . name + 'Serializer' ;
185
142
importer ( itemSerializer , findSerializerModule ( mapType . typeArguments ! [ 1 ] , program . getCompilerOptions ( ) ) ) ;
@@ -191,20 +148,68 @@ function generateToJsonBody(
191
148
for(const [k, v] of obj.${ fieldName } !) {
192
149
m.set(k.toString(), ${ itemSerializer } .toJson(v));
193
150
}
194
- }` , ts . SyntaxKind . Block ) ;
151
+ }` ,
152
+ ts . SyntaxKind . Block
153
+ ) ;
154
+ }
155
+
156
+ if ( type . isNullable ) {
157
+ propertyStatements . push (
158
+ ts . factory . createIfStatement (
159
+ ts . factory . createBinaryExpression (
160
+ ts . factory . createPropertyAccessExpression ( ts . factory . createIdentifier ( 'obj' ) , fieldName ) ,
161
+ ts . SyntaxKind . ExclamationEqualsEqualsToken ,
162
+ ts . factory . createNull ( )
163
+ ) ,
164
+ serializeBlock
165
+ )
166
+ ) ;
167
+ } else {
168
+ propertyStatements . push ( serializeBlock ) ;
169
+ }
170
+ } else if ( isSet ( type . type ) ) {
171
+ const setType = type . type as ts . TypeReference ;
172
+ if ( ! isPrimitiveType ( setType . typeArguments ! [ 0 ] ) ) {
173
+ throw new Error ( 'only Set<Primitive> maps are supported, extend if needed!' ) ;
174
+ }
175
+
176
+ let serializeBlock : ts . Block ;
177
+ if ( isPrimitiveToJson ( setType . typeArguments ! [ 1 ] , typeChecker ) ) {
178
+ serializeBlock = createNodeFromSource < ts . Block > (
179
+ `{
180
+ const a:unknown[] = [];
181
+ o.set(${ JSON . stringify ( jsonName ) } , a);
182
+ for(const v of obj.${ fieldName } !) {
183
+ a.push(v);
184
+ }
185
+ }` ,
186
+ ts . SyntaxKind . Block
187
+ ) ;
188
+ } else if ( isEnumType ( setType . typeArguments ! [ 0 ] ) ) {
189
+ serializeBlock = createNodeFromSource < ts . Block > (
190
+ `{
191
+ const a:number[] = [];
192
+ o.set(${ JSON . stringify ( jsonName ) } , a);
193
+ for(const v of obj.${ fieldName } !) {
194
+ a.push(v as number);
195
+ }
196
+ }` ,
197
+ ts . SyntaxKind . Block
198
+ ) ;
199
+ } else {
200
+ throw new Error ( 'only Set<Primitive> maps are supported, extend if needed!' ) ;
195
201
}
196
202
197
203
if ( type . isNullable ) {
198
- propertyStatements . push ( ts . factory . createIfStatement (
199
- ts . factory . createBinaryExpression (
200
- ts . factory . createPropertyAccessExpression (
201
- ts . factory . createIdentifier ( 'obj' ) ,
202
- fieldName
204
+ propertyStatements . push (
205
+ ts . factory . createIfStatement (
206
+ ts . factory . createBinaryExpression (
207
+ ts . factory . createPropertyAccessExpression ( ts . factory . createIdentifier ( 'obj' ) , fieldName ) ,
208
+ ts . SyntaxKind . ExclamationEqualsEqualsToken ,
209
+ ts . factory . createNull ( )
203
210
) ,
204
- ts . SyntaxKind . ExclamationEqualsEqualsToken ,
205
- ts . factory . createNull ( )
206
- ) ,
207
- serializeBlock )
211
+ serializeBlock
212
+ )
208
213
) ;
209
214
} else {
210
215
propertyStatements . push ( serializeBlock ) ;
@@ -242,13 +247,12 @@ function generateToJsonBody(
242
247
statements . push ( ...propertyStatements ) ;
243
248
}
244
249
245
- if ( serializable . hasToJsonExtension ) {
246
- statements . push ( createNodeFromSource < ts . ExpressionStatement > (
247
- `obj.toJson(o);` ,
248
- ts . SyntaxKind . ExpressionStatement
249
- ) ) ;
250
+ if ( serializable . hasToJsonExtension ) {
251
+ statements . push (
252
+ createNodeFromSource < ts . ExpressionStatement > ( `obj.toJson(o);` , ts . SyntaxKind . ExpressionStatement )
253
+ ) ;
250
254
}
251
-
255
+
252
256
statements . push ( ts . factory . createReturnStatement ( ts . factory . createIdentifier ( 'o' ) ) ) ;
253
257
254
258
return ts . factory . createBlock ( statements , true ) ;
0 commit comments