Skip to content

Commit 971cb19

Browse files
hayeskevin-greene-ck
authored andcommitted
fix: update how type for temp object in encode is defined to fix strict unions (#167)
* fix: update how type for temp object in encode is defined to fix strict unions * Add args interface for unions with default value
1 parent 58fd196 commit 971cb19

File tree

59 files changed

+368
-302
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+368
-302
lines changed

src/main/render/thrift-server/struct/encode.ts

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737

3838
import { DefinitionType, IRenderState } from '../../../types'
3939

40+
import { createLetStatement } from '../../shared/utils'
4041
import { looseNameForStruct, throwForField, toolkitName } from './utils'
4142

4243
export function createTempVariables(
@@ -50,32 +51,40 @@ export function createTempVariables(
5051
},
5152
)
5253

54+
// Unions use reassignment for defaults
55+
const createVariable = withDefault
56+
? createConstStatement
57+
: createLetStatement
58+
5359
if (structFields.length > 0) {
5460
return [
55-
createConstStatement(
61+
createVariable(
5662
COMMON_IDENTIFIERS.obj,
57-
ts.createTypeReferenceNode(
58-
ts.createIdentifier(looseNameForStruct(node, state)),
59-
undefined,
60-
),
61-
ts.createObjectLiteral(
62-
node.fields.map(
63-
(
64-
next: FieldDefinition,
65-
): ts.ObjectLiteralElementLike => {
66-
return ts.createPropertyAssignment(
67-
next.name.value,
68-
getInitializerForField(
69-
COMMON_IDENTIFIERS.args,
70-
next,
71-
state,
72-
withDefault,
73-
true,
74-
),
75-
)
76-
},
63+
undefined,
64+
ts.createAsExpression(
65+
ts.createObjectLiteral(
66+
node.fields.map(
67+
(
68+
next: FieldDefinition,
69+
): ts.ObjectLiteralElementLike => {
70+
return ts.createPropertyAssignment(
71+
next.name.value,
72+
getInitializerForField(
73+
COMMON_IDENTIFIERS.args,
74+
next,
75+
state,
76+
withDefault,
77+
true,
78+
),
79+
)
80+
},
81+
),
82+
true, // multiline
83+
),
84+
ts.createTypeReferenceNode(
85+
ts.createIdentifier(looseNameForStruct(node, state)),
86+
undefined,
7787
),
78-
true, // multiline
7988
),
8089
),
8190
]

src/main/render/thrift-server/union/encode.ts

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,17 +124,19 @@ function checkDefaults(
124124
[
125125
ts.createStatement(
126126
ts.createAssignment(
127-
ts.createPropertyAccess(
128-
COMMON_IDENTIFIERS.obj,
129-
ts.createIdentifier(
130-
defaultField.name.value,
127+
COMMON_IDENTIFIERS.obj,
128+
ts.createObjectLiteral([
129+
ts.createPropertyAssignment(
130+
ts.createIdentifier(
131+
defaultField.name.value,
132+
),
133+
renderValue(
134+
defaultField.fieldType,
135+
defaultField.defaultValue!,
136+
state,
137+
),
131138
),
132-
),
133-
renderValue(
134-
defaultField.fieldType,
135-
defaultField.defaultValue!,
136-
state,
137-
),
139+
]),
138140
),
139141
),
140142
],

src/main/render/thrift-server/union/union-fields.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ export function fieldInterfaceName(
9292
}
9393
}
9494

95+
export function defaultInterfaceName(nodeName: string) {
96+
return `I${nodeName}DefaultArgs`
97+
}
98+
9599
function renderInterfaceForField(
96100
node: UnionDefinition,
97101
field: FieldDefinition,
@@ -158,6 +162,30 @@ function renderInterfaceForField(
158162
)
159163
}
160164

165+
function renderInterfaceForDefault(
166+
node: UnionDefinition,
167+
isExported: boolean,
168+
): ts.InterfaceDeclaration {
169+
const signatures = node.fields.map((next: FieldDefinition) => {
170+
return ts.createPropertySignature(
171+
undefined,
172+
next.name.value,
173+
ts.createToken(ts.SyntaxKind.QuestionToken),
174+
createUndefinedType(),
175+
undefined,
176+
)
177+
})
178+
179+
return ts.createInterfaceDeclaration(
180+
undefined,
181+
tokens(isExported),
182+
ts.createIdentifier(defaultInterfaceName(node.name.value)),
183+
[],
184+
[],
185+
signatures,
186+
)
187+
}
188+
161189
export function renderUnionsForFields(
162190
node: UnionDefinition,
163191
state: IRenderState,
@@ -181,6 +209,14 @@ export function renderUnionsForFields(
181209
undefined,
182210
)
183211
}),
212+
...(isStrict || !hasDefault(node)
213+
? []
214+
: [
215+
ts.createTypeReferenceNode(
216+
defaultInterfaceName(node.name.value),
217+
undefined,
218+
),
219+
]),
184220
]),
185221
),
186222
...node.fields.map(
@@ -194,5 +230,12 @@ export function renderUnionsForFields(
194230
)
195231
},
196232
),
233+
...(isStrict || !hasDefault(node)
234+
? []
235+
: [renderInterfaceForDefault(node, true)]),
197236
]
198237
}
238+
239+
export function hasDefault(node: UnionDefinition) {
240+
return node.fields.find((field) => field.defaultValue !== null)
241+
}

src/tests/unit/fixtures/thrift-server/annotations_exception.solution.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export interface IMyExceptionArgs {
99
}
1010
export const MyExceptionCodec: thrift.IStructCodec<IMyExceptionArgs, IMyException> = {
1111
encode(args: IMyExceptionArgs, output: thrift.TProtocol): void {
12-
const obj: IMyExceptionArgs = {
12+
const obj = ({
1313
message: args.message,
1414
code: (args.code != null ? args.code : 200)
15-
};
15+
} as IMyExceptionArgs);
1616
output.writeStructBegin("MyException");
1717
if (obj.message != null) {
1818
output.writeFieldBegin("message", thrift.TType.STRING, 1);

src/tests/unit/fixtures/thrift-server/annotations_service.solution.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export interface IUserArgs {
99
}
1010
export const UserCodec: thrift.IStructCodec<IUserArgs, IUser> = {
1111
encode(args: IUserArgs, output: thrift.TProtocol): void {
12-
const obj: IUserArgs = {
12+
const obj = ({
1313
name: args.name,
1414
id: args.id
15-
};
15+
} as IUserArgs);
1616
output.writeStructBegin("User");
1717
if (obj.name != null) {
1818
output.writeFieldBegin("name", thrift.TType.STRING, 1);
@@ -160,9 +160,9 @@ export interface IGetUser__ArgsArgs {
160160
}
161161
export const GetUser__ArgsCodec: thrift.IStructCodec<IGetUser__ArgsArgs, IGetUser__Args> = {
162162
encode(args: IGetUser__ArgsArgs, output: thrift.TProtocol): void {
163-
const obj: IGetUser__ArgsArgs = {
163+
const obj = ({
164164
id: args.id
165-
};
165+
} as IGetUser__ArgsArgs);
166166
output.writeStructBegin("GetUser__Args");
167167
if (obj.id != null) {
168168
output.writeFieldBegin("id", thrift.TType.I32, 1);
@@ -248,9 +248,9 @@ export interface ISaveUser__ArgsArgs {
248248
}
249249
export const SaveUser__ArgsCodec: thrift.IStructCodec<ISaveUser__ArgsArgs, ISaveUser__Args> = {
250250
encode(args: ISaveUser__ArgsArgs, output: thrift.TProtocol): void {
251-
const obj: ISaveUser__ArgsArgs = {
251+
const obj = ({
252252
user: args.user
253-
};
253+
} as ISaveUser__ArgsArgs);
254254
output.writeStructBegin("SaveUser__Args");
255255
if (obj.user != null) {
256256
output.writeFieldBegin("user", thrift.TType.STRUCT, 1);
@@ -387,9 +387,9 @@ export interface IGetUser__ResultArgs {
387387
}
388388
export const GetUser__ResultCodec: thrift.IStructCodec<IGetUser__ResultArgs, IGetUser__Result> = {
389389
encode(args: IGetUser__ResultArgs, output: thrift.TProtocol): void {
390-
const obj: IGetUser__ResultArgs = {
390+
let obj = ({
391391
success: args.success
392-
};
392+
} as IGetUser__ResultArgs);
393393
output.writeStructBegin("GetUser__Result");
394394
if (obj.success != null) {
395395
output.writeFieldBegin("success", thrift.TType.STRUCT, 0);

src/tests/unit/fixtures/thrift-server/annotations_struct.solution.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export interface IMyStructArgs {
99
}
1010
export const MyStructCodec: thrift.IStructCodec<IMyStructArgs, IMyStruct> = {
1111
encode(args: IMyStructArgs, output: thrift.TProtocol): void {
12-
const obj: IMyStructArgs = {
12+
const obj = ({
1313
id: (args.id != null ? args.id : 45),
1414
bigID: (args.bigID != null ? (typeof args.bigID === "number" ? new thrift.Int64(args.bigID) : typeof args.bigID === "string" ? thrift.Int64.fromDecimalString(args.bigID) : args.bigID) : thrift.Int64.fromDecimalString("23948234"))
15-
};
15+
} as IMyStructArgs);
1616
output.writeStructBegin("MyStruct");
1717
if (obj.id != null) {
1818
output.writeFieldBegin("id", thrift.TType.I32, 1);

src/tests/unit/fixtures/thrift-server/annotations_union.solution.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ export interface IMyUnionArgs {
1010
export const MyUnionCodec: thrift.IStructCodec<IMyUnionArgs, IMyUnion> = {
1111
encode(args: IMyUnionArgs, output: thrift.TProtocol): void {
1212
let _fieldsSet: number = 0;
13-
const obj: IMyUnionArgs = {
13+
let obj = ({
1414
field1: args.field1,
1515
field2: (typeof args.field2 === "number" ? new thrift.Int64(args.field2) : typeof args.field2 === "string" ? thrift.Int64.fromDecimalString(args.field2) : args.field2)
16-
};
16+
} as IMyUnionArgs);
1717
output.writeStructBegin("MyUnion");
1818
if (obj.field1 != null) {
1919
_fieldsSet++;

src/tests/unit/fixtures/thrift-server/basic_exception.solution.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export interface IMyExceptionArgs {
99
}
1010
export const MyExceptionCodec: thrift.IStructCodec<IMyExceptionArgs, IMyException> = {
1111
encode(args: IMyExceptionArgs, output: thrift.TProtocol): void {
12-
const obj: IMyExceptionArgs = {
12+
const obj = ({
1313
message: args.message,
1414
code: (args.code != null ? args.code : 200)
15-
};
15+
} as IMyExceptionArgs);
1616
output.writeStructBegin("MyException");
1717
if (obj.message != null) {
1818
output.writeFieldBegin("message", thrift.TType.STRING, 1);

src/tests/unit/fixtures/thrift-server/basic_service.solution.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ export interface IUserArgs {
99
}
1010
export const UserCodec: thrift.IStructCodec<IUserArgs, IUser> = {
1111
encode(args: IUserArgs, output: thrift.TProtocol): void {
12-
const obj: IUserArgs = {
12+
const obj = ({
1313
name: args.name,
1414
id: args.id
15-
};
15+
} as IUserArgs);
1616
output.writeStructBegin("User");
1717
if (obj.name != null) {
1818
output.writeFieldBegin("name", thrift.TType.STRING, 1);
@@ -148,9 +148,9 @@ export interface IGetUser__ArgsArgs {
148148
}
149149
export const GetUser__ArgsCodec: thrift.IStructCodec<IGetUser__ArgsArgs, IGetUser__Args> = {
150150
encode(args: IGetUser__ArgsArgs, output: thrift.TProtocol): void {
151-
const obj: IGetUser__ArgsArgs = {
151+
const obj = ({
152152
id: args.id
153-
};
153+
} as IGetUser__ArgsArgs);
154154
output.writeStructBegin("GetUser__Args");
155155
if (obj.id != null) {
156156
output.writeFieldBegin("id", thrift.TType.I32, 1);
@@ -236,9 +236,9 @@ export interface ISaveUser__ArgsArgs {
236236
}
237237
export const SaveUser__ArgsCodec: thrift.IStructCodec<ISaveUser__ArgsArgs, ISaveUser__Args> = {
238238
encode(args: ISaveUser__ArgsArgs, output: thrift.TProtocol): void {
239-
const obj: ISaveUser__ArgsArgs = {
239+
const obj = ({
240240
user: args.user
241-
};
241+
} as ISaveUser__ArgsArgs);
242242
output.writeStructBegin("SaveUser__Args");
243243
if (obj.user != null) {
244244
output.writeFieldBegin("user", thrift.TType.STRUCT, 1);
@@ -375,9 +375,9 @@ export interface IGetUser__ResultArgs {
375375
}
376376
export const GetUser__ResultCodec: thrift.IStructCodec<IGetUser__ResultArgs, IGetUser__Result> = {
377377
encode(args: IGetUser__ResultArgs, output: thrift.TProtocol): void {
378-
const obj: IGetUser__ResultArgs = {
378+
let obj = ({
379379
success: args.success
380-
};
380+
} as IGetUser__ResultArgs);
381381
output.writeStructBegin("GetUser__Result");
382382
if (obj.success != null) {
383383
output.writeFieldBegin("success", thrift.TType.STRUCT, 0);

src/tests/unit/fixtures/thrift-server/basic_service.strict_union.solution.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export interface IMyUnionWithField2 {
1515
field1?: undefined;
1616
field2: thrift.Int64;
1717
}
18-
export type MyUnionArgs = IMyUnionWithField1Args | IMyUnionWithField2Args;
18+
export type MyUnionArgs = IMyUnionWithField1Args | IMyUnionWithField2Args | IMyUnionDefaultArgs;
1919
export interface IMyUnionWithField1Args {
2020
field1: number;
2121
field2?: undefined;
@@ -24,6 +24,10 @@ export interface IMyUnionWithField2Args {
2424
field1?: undefined;
2525
field2: number | string | thrift.Int64;
2626
}
27+
export interface IMyUnionDefaultArgs {
28+
field1?: undefined;
29+
field2?: undefined;
30+
}
2731
export const MyUnionCodec: thrift.IStructToolkit<MyUnionArgs, MyUnion> = {
2832
create(args: MyUnionArgs): MyUnion {
2933
let _fieldsSet: number = 0;
@@ -66,10 +70,10 @@ export const MyUnionCodec: thrift.IStructToolkit<MyUnionArgs, MyUnion> = {
6670
},
6771
encode(args: MyUnionArgs, output: thrift.TProtocol): void {
6872
let _fieldsSet: number = 0;
69-
const obj: MyUnionArgs = {
73+
let obj = ({
7074
field1: args.field1,
7175
field2: (typeof args.field2 === "number" ? new thrift.Int64(args.field2) : typeof args.field2 === "string" ? thrift.Int64.fromDecimalString(args.field2) : args.field2)
72-
};
76+
} as MyUnionArgs);
7377
output.writeStructBegin("MyUnion");
7478
if (obj.field1 != null) {
7579
_fieldsSet++;
@@ -187,9 +191,9 @@ export interface IGetUser__ArgsArgs {
187191
}
188192
export const GetUser__ArgsCodec: thrift.IStructCodec<IGetUser__ArgsArgs, IGetUser__Args> = {
189193
encode(args: IGetUser__ArgsArgs, output: thrift.TProtocol): void {
190-
const obj: IGetUser__ArgsArgs = {
194+
let obj = ({
191195
arg1: args.arg1
192-
};
196+
} as IGetUser__ArgsArgs);
193197
output.writeStructBegin("GetUser__Args");
194198
if (obj.arg1 != null) {
195199
output.writeFieldBegin("arg1", thrift.TType.STRUCT, 1);
@@ -326,9 +330,9 @@ export interface IGetUser__ResultArgs {
326330
}
327331
export const GetUser__ResultCodec: thrift.IStructCodec<IGetUser__ResultArgs, IGetUser__Result> = {
328332
encode(args: IGetUser__ResultArgs, output: thrift.TProtocol): void {
329-
const obj: IGetUser__ResultArgs = {
333+
let obj = ({
330334
success: args.success
331-
};
335+
} as IGetUser__ResultArgs);
332336
output.writeStructBegin("GetUser__Result");
333337
if (obj.success != null) {
334338
output.writeFieldBegin("success", thrift.TType.STRING, 0);

0 commit comments

Comments
 (0)