@cicctencent/tars2node-cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,483 @@
1
+ 'use strict';
2
+
3
+ const BaseDef = require('./base');
4
+
5
+ const VERSION_CHECK = 'version === TarsStream.Tup.TUP_SIMPLE || version === TarsStream.Tup.TUP_COMPLEX';
6
+
7
+ class ProxyEnum extends BaseDef {
8
+ /**
9
+ *
10
+ * 声明JCE-Struct节点类型
11
+ * @typedef { refType | vecType | string | mapType } tarsType
12
+ *
13
+ * @typedef {object} refType
14
+ * @property {string} target
15
+ * @property {string[]} nested
16
+ *
17
+ * @typedef {object} vecType
18
+ * @property {'vector'} type
19
+ * @property {tarsType} target
20
+ *
21
+ * @typedef {object} mapType
22
+ * @property {'map'} type
23
+ * @property {tarsType} key
24
+ * @property {tarsType} value
25
+ *
26
+ * @typedef {object} param
27
+ * @property {string} id
28
+ * @property {'in'|'out'} io
29
+ * @property {tarsType} type
30
+ *
31
+ * @typedef {object} TarsInterfMethod
32
+ * @property {string} id
33
+ * @property {'func'} type
34
+ * @property {tarsType} output
35
+ * @property {param[]} params
36
+ *
37
+ * @typedef {object} TarsInterfNode
38
+ * @property {string} id
39
+ * @property {'interface'} type
40
+ * @property {TarsInterfMethod[]} methods
41
+ *
42
+ * 工具类类型
43
+ * @typedef {import("../printer")} Printer
44
+ * @typedef {import("../typing")} Typing
45
+ *
46
+ * @typedef {object} CompilerOptions
47
+ * @property {'all'|'client'|'service'} mode
48
+ * @property {'string'|'number'|'bigint'} long
49
+ * @property {boolean} withReturn
50
+ * @property {boolean} gather
51
+ * @property {boolean} interface
52
+ * @property {string} [output]
53
+ *
54
+ * 创建Struct解析实例
55
+ * @constructor
56
+ * @param {Printer} printer - print类实例
57
+ * @param {Typing} typing - Typing类实例
58
+ * @param {CompilerOptions} options - 编译配置选项
59
+ */
60
+ constructor(printer, typing, options) {
61
+ super('', printer, typing, options);
62
+ this._id = '';
63
+ /** @type {TarsInterfMethod[]} methods */
64
+ this._methods = [];
65
+ this._prxy = '';
66
+ this._underscoreName = '';
67
+ }
68
+
69
+ /**
70
+ * @param {string} name
71
+ * @param {TarsInterfNode} node
72
+ */
73
+ reset(name, node) {
74
+ this.setModuleName(name);
75
+ this.setNode(node);
76
+
77
+ return this;
78
+ }
79
+
80
+ /**
81
+ * @param {TarsInterfNode} node
82
+ */
83
+ setNode({ id, methods }) {
84
+ this._id = id;
85
+ this._methods = methods;
86
+ this._prxy = `${id}Proxy`;
87
+ this._underscoreName = `__${this._moduleName}_${id}`;
88
+ }
89
+
90
+ /**
91
+ * @param {string} name
92
+ */
93
+ setModuleName(name) {
94
+ super.setModuleName(name);
95
+ this._underscoreName = `__${this._moduleName}_${this._id}`;
96
+ }
97
+
98
+ build() {
99
+ this._methods.forEach(this._consts.bind(this));
100
+ this._methods.forEach(this._interface.bind(this));
101
+ this._class();
102
+ }
103
+
104
+ _class() {
105
+ this._printer
106
+ .newline()
107
+ .word('export', 'R')
108
+ .word('class', 'R')
109
+ .word(this._prxy, 'R')
110
+ .scope(() => {
111
+ this._classCommon();
112
+ this._methods.forEach(this._method.bind(this));
113
+ });
114
+ }
115
+
116
+ _classCommon() {
117
+ this._printer.classProps({
118
+ name: '_name',
119
+ valueType: 'string',
120
+ value: "''",
121
+ type: 'protected',
122
+ });
123
+
124
+ // _worker member
125
+ this._printer
126
+ .line('protected _worker: ')
127
+ .scope(() => {
128
+ this._printer
129
+ .word('timeout: number;')
130
+ .line('version: number;')
131
+ .line('tup_invoke: Function;')
132
+ .line('taf_invoke: Function;');
133
+ })
134
+ .word('=', 'LR')
135
+ .scope(() => {
136
+ this._printer
137
+ .line('timeout: 0,')
138
+ .line('version: 0,')
139
+ .line('tup_invoke: () => {},')
140
+ .line('taf_invoke: () => {},');
141
+ })
142
+ .semicolon();
143
+
144
+ this._printer
145
+ .classMethod({
146
+ name: 'setTimeout',
147
+ params: [['iTimeout', 'number']],
148
+ returnType: 'void',
149
+ callback: () => {
150
+ this._printer
151
+ .line('this._worker.timeout = iTimeout;');
152
+ },
153
+ })
154
+ .classMethod({
155
+ name: 'getTimeout',
156
+ params: [],
157
+ returnType: 'number',
158
+ callback: () => {
159
+ this._printer
160
+ .line('return this._worker.timeout;');
161
+ },
162
+ })
163
+ .classMethod({
164
+ name: 'setVersion',
165
+ params: [['iVersion', 'number']],
166
+ returnType: 'void',
167
+ callback: () => {
168
+ this._printer
169
+ .line('this._worker.version = iVersion;');
170
+ },
171
+ })
172
+ .classMethod({
173
+ name: 'getVersion',
174
+ params: [],
175
+ returnType: 'number',
176
+ callback: () => {
177
+ this._printer
178
+ .line('return this._worker.version;');
179
+ },
180
+ });
181
+ }
182
+
183
+ /**
184
+ * @param {TarsInterfMethod} method
185
+ */
186
+ _interface({ id, params, output }) {
187
+ params = params || [];// 测试函数允许没有参数
188
+ this._printer
189
+ .line(`export interface ${this._methodConsts(id, 'DE')} `)
190
+ .scope(() => {
191
+ this._printer
192
+ .line('request: object;')
193
+ .line('response: ')
194
+ .scope(() => {
195
+ this._printer
196
+ .line('costtime: number;')
197
+ .line(`return: ${this._typing.toTSType(output, this._moduleName)};`)
198
+ .line('arguments: ')
199
+ .scope(() => {
200
+ params.filter(({ io }) => io === 'out').forEach(({ id: pid, type: ptype }) => {
201
+ this._printer
202
+ .line(`${pid}: ${this._typing.toTSType(ptype, this._moduleName)};`);
203
+ });
204
+ })
205
+ .semicolon();
206
+ })
207
+ .semicolon();
208
+ });
209
+ }
210
+
211
+ /**
212
+ * @param {TarsInterfMethod} method
213
+ */
214
+ _method({ id, params }) {
215
+ params = params || [];// 测试函数允许没有参数
216
+ const name = `${this._underscoreName}$${id}`;
217
+
218
+ const inputParams = params.filter(({ io }) => io === 'in');
219
+ const ps = inputParams
220
+ .map(({ id: pid, type: ptype }) => [pid, this._typing.toTSType(ptype, this._moduleName)]);
221
+ const inputPsToString = inputParams.map(({ id: pid }) => pid).join(', ');
222
+
223
+ ps.push(['_property?', 'TarsRpc.InvokeProperty']);
224
+
225
+ this._printer
226
+ .classMethod({
227
+ name: id,
228
+ params: /** @type {Array<[string, string]>} */ (ps),
229
+ returnType: `Promise<${this._methodConsts(id, 'DE')}>`,
230
+ callback: () => {
231
+ this._printer
232
+ .line('const version = this._worker.version;')
233
+ .line(`if(${VERSION_CHECK}) {`)
234
+ .indent()
235
+ .line(`return this._worker.tup_invoke("${id}", ${name}$PE(${inputPsToString.length > 0 ? `${inputPsToString}, ` : ''}version), arguments[arguments.length - 1], ${name}$IF).then(${name}$PD, ${name}$ER);`)
236
+ .dedent()
237
+ .line('} else {')
238
+ .indent()
239
+ .line(`return this._worker.taf_invoke("${id}", ${name}$IE(${inputPsToString}), arguments[arguments.length - 1], ${name}$IF).then(${name}$ID, ${name}$ER);`)
240
+ .dedent()
241
+ .line('}');
242
+ },
243
+ })
244
+ .classProps({
245
+ name: id,
246
+ valueType: 'SharedFunctionInfo',
247
+ value: `<SharedFunctionInfo>${name}$IF`,
248
+ type: 'static',
249
+ });
250
+ }
251
+
252
+ /**
253
+ * @param {TarsInterfMethod} method
254
+ */
255
+ _consts(method) {
256
+ this._consts$if(method);
257
+ this._consts$ie(method);
258
+ this._consts$id(method);
259
+ this._consts$pe(method);
260
+ this._consts$pd(method);
261
+ this._consts$er(method);
262
+ }
263
+
264
+ /**
265
+ * @param {TarsInterfMethod} method
266
+ */
267
+ _consts$if({ id, output, params }) {
268
+ params = params || [];// 测试函数允许没有参数
269
+ const name = `${this._underscoreName}$${id}`;
270
+ this._printer
271
+ .line(`export const ${name}$IF = `)
272
+ .scope(() => {
273
+ this._printer
274
+ .newline()
275
+ .word(`name: "${id}",`)
276
+ .line(`return: "${this._typing.toString(output, this._moduleName)}",`)
277
+ .line('arguments: [')
278
+ .indent();
279
+ params.forEach(({ id: pid, type: ptype, io }) => {
280
+ this._printer
281
+ .newline()
282
+ .scope(() => {
283
+ this._printer
284
+ .word(`name: "${pid}",`)
285
+ .line(`class: "${this._typing.toString(ptype, this._moduleName)}",`)
286
+ .line(`direction: "${io}"`);
287
+ })
288
+ .word(',');
289
+ });
290
+ this._printer.dedent().line(']');
291
+ })
292
+ .semicolon();
293
+ }
294
+
295
+ /**
296
+ * @param {TarsInterfMethod} method
297
+ */
298
+ _consts$ie({ id, params }) {
299
+ params = params || [];// 测试函数允许没有参数
300
+ const name = `${this._underscoreName}$${id}`;
301
+ const inputParams = params.filter(({ io }) => io === 'in');
302
+ this._printer
303
+ .line(`const ${name}$IE = function(${inputParams.map(({ id: pid }) => `${pid}: any`).join(', ')})`)
304
+ .space(1)
305
+ .scope(() => {
306
+ this._printer.line('const os = new TarsStream.TarsOutputStream();');
307
+ inputParams.forEach(({ id: pid, type: ptype }) => {
308
+ const ioType = this._typing.toIOType(ptype, this._moduleName);
309
+ const index = params.findIndex(({ id: iid }) => pid === iid) + 1;
310
+ this._printer.line(`os.write${ioType}(${index}, ${pid}${this._needGenerateTrueForLong(ptype)})`);
311
+ });
312
+
313
+ this._printer.line('return os.getBinBuffer();');
314
+ })
315
+ .semicolon();
316
+ }
317
+
318
+ /**
319
+ * @param {TarsInterfMethod} method
320
+ */
321
+ _consts$id({ id, params, output }) {
322
+ params = params || [];// 测试函数允许没有参数
323
+ const name = `${this._underscoreName}$${id}`;
324
+ this._printer
325
+ .line(`const ${name}$ID = function(data: any)`)
326
+ .space(1)
327
+ .scope(() => {
328
+ this._printer
329
+ .newline()
330
+ .word('try', 'R')
331
+ .scope(() => {
332
+ this._printer
333
+ .line('const is = new TarsStream.TarsInputStream(data.response.sBuffer);')
334
+ .newline()
335
+ .word('return', 'R')
336
+ .scope(() => {
337
+ this._printer
338
+ .line('request: data.request,')
339
+ .newline()
340
+ .word('response: ')
341
+ .scope(() => {
342
+ this._printer.line('costtime: data.request.costtime,');
343
+ if (output !== 'void') {
344
+ this._printer
345
+ .line(`return: is.read${this._typing.toIOType(output, this._moduleName)}(0, true, ${this._typing.toTarsValue(output, this._moduleName)}${this._needGenerateTrueForLong(output)}),`);
346
+ }
347
+ this._printer
348
+ .line('arguments: ')
349
+ .scope(() => {
350
+ params.filter(({ io }) => io === 'out').forEach(({ id: pid, type: ptype }) => {
351
+ const ioType = this._typing.toIOType(ptype, this._moduleName);
352
+ const index = params.findIndex(({ id: iid }) => iid === pid) + 1;
353
+ this._printer
354
+ .line(`${pid}: is.read${ioType}(${index}, true, ${this._typing.toTarsValue(ptype, this._moduleName)}${this._needGenerateTrueForLong(ptype)}),`);
355
+ });
356
+ });
357
+ });
358
+ })
359
+ .semicolon();
360
+ })
361
+ .word('catch (e)', 'LR')
362
+ .scope(() => {
363
+ this._printer
364
+ .line('throw _makeError(data, e.message, TarsRpc.error.CLIENT.DECODE_ERROR);')
365
+ .semicolon();
366
+ });
367
+ })
368
+ .semicolon();
369
+ }
370
+
371
+ /**
372
+ * @param {TarsInterfMethod} method
373
+ */
374
+ _consts$pe({ id, params }) {
375
+ params = params || [];// 测试函数允许没有参数
376
+ const name = `${this._underscoreName}$${id}`;
377
+ const inputParams = params.filter(({ io }) => io === 'in');
378
+ const ps = inputParams.map(({ id: pid }) => [pid, 'any']).concat([['__$PROTOCOL$VERSION', 'number']]);
379
+
380
+ this._printer
381
+ .line(`const ${name}$PE = function(${ps.map(([k, t]) => `${k}: ${t}`).join(', ')})`)
382
+ .space(1)
383
+ .scope(() => {
384
+ this._printer
385
+ .line('const tup = new TarsStream.UniAttribute();')
386
+ .line('tup.tupVersion = __$PROTOCOL$VERSION;');
387
+ inputParams.forEach(({ id: pid, type: ptype }) => {
388
+ this._printer
389
+ .line(`tup.write${this._typing.toIOType(ptype, this._moduleName)}("${pid}", ${pid}${this._needGenerateTrueForLong(ptype)})`);
390
+ });
391
+ this._printer.line('return tup;');
392
+ })
393
+ .semicolon();
394
+ }
395
+
396
+ /**
397
+ * @param {TarsInterfMethod} method
398
+ */
399
+ _consts$pd({ id, output, params }) {
400
+ params = params || [];// 测试函数允许没有参数
401
+ const name = `${this._underscoreName}$${id}`;
402
+ this._printer
403
+ .line(`const ${name}$PD = function(data: any)`)
404
+ .space(1)
405
+ .scope(() => {
406
+ this._printer
407
+ .newline()
408
+ .word('try', 'R')
409
+ .scope(() => {
410
+ this._printer
411
+ .line('const tup = data.response.tup;')
412
+ .line('return ')
413
+ .scope(() => {
414
+ this._printer
415
+ .line('request: data.request,')
416
+ .line('response: ')
417
+ .scope(() => {
418
+ const retType = this._typing.toTarsValue(output, this._moduleName, true);
419
+ this._printer
420
+ .line('consttime: data.request.costtime,');
421
+ if (output !== 'void') {
422
+ this._printer
423
+ .line(`return: tup.read${this._typing.toIOType(output, this._moduleName)}("", ${retType}${this._needGenerateTrueForLong(output)}),`);
424
+ }
425
+ this._printer
426
+ .line('arguments: ')
427
+ .scope(() => {
428
+ params.filter(({ io }) => io === 'out').forEach(({ id: pid, type: ptype }) => {
429
+ const needTypeConstructor = this._typing
430
+ .isNotObjectType(ptype, this._moduleName)
431
+ ? ''
432
+ : `, ${this._typing.toTarsStreamType(ptype, this._moduleName).tafType}`;
433
+ this._printer
434
+ .line(`${pid}: tup.read${this._typing.toIOType(ptype, this._moduleName)}("${pid}"${needTypeConstructor}),`);
435
+ });
436
+ });
437
+ });
438
+ })
439
+ .semicolon();
440
+ })
441
+ .word('catch (e)', 'LR')
442
+ .scope(() => {
443
+ this._printer
444
+ .line('throw _makeError(data, e.message, TarsRpc.error.CLIENT.DECODE_ERROR);');
445
+ });
446
+ })
447
+ .semicolon();
448
+ }
449
+
450
+ /**
451
+ * @param {TarsInterfMethod} method
452
+ */
453
+ _consts$er({ id }) {
454
+ const name = `${this._underscoreName}$${id}`;
455
+ this._printer
456
+ .line(`const ${name}$ER = function(data: any)`)
457
+ .space(1)
458
+ .scope(() => {
459
+ this._printer.line(`throw _makeError(data, "Call ${this._id}::${id} failed");`);
460
+ })
461
+ .semicolon();
462
+ }
463
+
464
+ /**
465
+ * @param {string} name
466
+ * @param {string} type
467
+ * @return {string}
468
+ */
469
+ _methodConsts(name, type) {
470
+ return `${this._id}$${name}$${type}`;
471
+ }
472
+
473
+ /**
474
+ * @param {tarsType} type
475
+ * @return {string}
476
+ */
477
+ _needGenerateTrueForLong(type) {
478
+ const longLastParam = type === 'long' && this.generateLastParamForLong();
479
+ return longLastParam ? `, ${longLastParam}` : '';
480
+ }
481
+ }
482
+
483
+ module.exports = ProxyEnum;