@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.
- package/README.md +74 -0
- package/bin/tars.js +81 -0
- package/jce.pegjs +359 -0
- package/lib/generator/finder.js +122 -0
- package/lib/generator/printer.js +116 -0
- package/lib/generator/ts/def/base.js +55 -0
- package/lib/generator/ts/def/const.js +108 -0
- package/lib/generator/ts/def/enum.js +144 -0
- package/lib/generator/ts/def/interf.js +508 -0
- package/lib/generator/ts/def/proxy.js +483 -0
- package/lib/generator/ts/def/struct.js +383 -0
- package/lib/generator/ts/generator.js +645 -0
- package/lib/generator/ts/printer.js +66 -0
- package/lib/generator/ts/typing.js +193 -0
- package/lib/generator/ts/util.js +21 -0
- package/lib/generator/typing.js +351 -0
- package/lib/parser/parser.js +383 -0
- package/main.d.ts +29 -0
- package/main.js +35 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Tars2Node CLI
|
|
2
|
+
该项目fork by`@tencent/jce2node-cli`
|
|
3
|
+
提供了node环境的tars2node编译器,方便和框架进行工程化集成。
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
`npm i -D @jv/tars2node-cli`
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
|
|
10
|
+
### With CLI:
|
|
11
|
+
Command: `tars [options] <entry-file>`
|
|
12
|
+
|
|
13
|
+
Options:
|
|
14
|
+
```
|
|
15
|
+
-T --type 编译出的文件类型,默认为es5,可选项:ts | es5
|
|
16
|
+
-W --watch 监听指定文件或文件夹,支持模式匹配
|
|
17
|
+
-O --output 指定存放编译后文件的文件夹的路径
|
|
18
|
+
-M --mode 指定编译的目标服务类型,默认为all,可选项:client | service | all | web
|
|
19
|
+
-R --return 仅对生成service代码有效,service代码调用中添加ret参数
|
|
20
|
+
-G --gather 仅对生成service代码有效,service代码调用中的参数根据入参和出参聚合
|
|
21
|
+
-I --interface 仅对生成ts格式的service代码有效,service中附带含有servant所有的方法的interface
|
|
22
|
+
-E --entry (deprected) 入口文件路径
|
|
23
|
+
-L --long long转译的类型,默认为string,可选项:string | number | bigint
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Example: `tars -T ts -W ./demo/**/*.tars -O ./dist -M web demo/interface.tar`
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
tars -T ts -W ./_Proto/**/*.tars -O ./dist -M web
|
|
30
|
+
### With Node:
|
|
31
|
+
```javascript
|
|
32
|
+
const tars = require('tars2node-cli');
|
|
33
|
+
const ast = tars.ast('./foo/bar/your-tars-entry.tar');
|
|
34
|
+
/*
|
|
35
|
+
* type与options中的type相同
|
|
36
|
+
* mode与options中的mode相同,默认为'service'
|
|
37
|
+
* config支持的选项:
|
|
38
|
+
* * withReturn: 与options中-R相同
|
|
39
|
+
* * gather: 与options中-G相同
|
|
40
|
+
* * interface: 与options中-I相同
|
|
41
|
+
* * long: 与options中-L相同
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
const runCompiler = tars.run('./foo/bar/your-tars-entry.tar', 'ts', './dist', 'client', { withReturn: true });
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Featrue List
|
|
48
|
+
[x] 生成服务端代码
|
|
49
|
+
[x] Interface -> js
|
|
50
|
+
[x] Enum -> js
|
|
51
|
+
[x] Struct -> js
|
|
52
|
+
[x] 生成typescript代码
|
|
53
|
+
[x] 生成客户端代码
|
|
54
|
+
[x] 添加默认值
|
|
55
|
+
[x] 添加const类型
|
|
56
|
+
|
|
57
|
+
## TODO
|
|
58
|
+
|
|
59
|
+
### P0
|
|
60
|
+
[ ] 生成d.ts代码
|
|
61
|
+
|
|
62
|
+
### P1
|
|
63
|
+
[ ] 添加key类型
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Author
|
|
67
|
+
@tencent/kealxiao
|
|
68
|
+
|
|
69
|
+
## Contributors
|
|
70
|
+
* @tencent/shanelv
|
|
71
|
+
* @tencent/carvenzhang
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
MIT
|
package/bin/tars.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const program = require('commander');
|
|
6
|
+
const pkg = require('../package.json');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
program
|
|
10
|
+
.version(pkg.version)
|
|
11
|
+
.usage('[options] <file>')
|
|
12
|
+
.option('-T, --type <type>', '输出文件类型')
|
|
13
|
+
.option('-M, --mode <type>', '目标服务类型')
|
|
14
|
+
.option('-W, --watch <path>', '监听文件夹')
|
|
15
|
+
.option('-O, --output <path>', '输出文件夹')
|
|
16
|
+
.option('-R, --return', '添加ret参数')
|
|
17
|
+
.option('-G, --gather', '聚合出入参数')
|
|
18
|
+
.option('-I, --interface', '生成服务接口类型')
|
|
19
|
+
.option('-L, --long <type>', 'long转译的类型')
|
|
20
|
+
.action(action)
|
|
21
|
+
.parse(process.argv);
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
function action(file, cmd) {
|
|
25
|
+
console.info('\x1b[36m', `☕️ Generating JCE files from entry: ${file}.\n`);
|
|
26
|
+
const startTime = new Date();
|
|
27
|
+
|
|
28
|
+
/* eslint-disable global-require */
|
|
29
|
+
const type = cmd.type || 'es5';
|
|
30
|
+
const mode = cmd.mode || 'all';
|
|
31
|
+
const long = cmd.long || 'string';
|
|
32
|
+
|
|
33
|
+
const Generator = require('../lib/generator/ts/generator');
|
|
34
|
+
const TsParser = require('../lib/parser/parser');
|
|
35
|
+
|
|
36
|
+
const Parser = TsParser;
|
|
37
|
+
|
|
38
|
+
const options = {
|
|
39
|
+
mode,
|
|
40
|
+
type,
|
|
41
|
+
long,
|
|
42
|
+
withReturn: Boolean(cmd.return),
|
|
43
|
+
gather: Boolean(cmd.gather),
|
|
44
|
+
interface: Boolean(cmd.interface),
|
|
45
|
+
output: cmd.output,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const build = parser => new Generator(parser.buildAST(), file, options).build();
|
|
49
|
+
|
|
50
|
+
const buildOnce = async () => {
|
|
51
|
+
try {
|
|
52
|
+
const parser = new Parser(file);
|
|
53
|
+
|
|
54
|
+
await build(parser);
|
|
55
|
+
const endTime = new Date();
|
|
56
|
+
const timeDiff = (endTime - startTime).toFixed(2);
|
|
57
|
+
console.info();
|
|
58
|
+
console.info('\x1b[32m', `⚡️ Spend Time: ${timeDiff}ms.`);
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.error('\x1b[31m', '💔 An error occur!');
|
|
61
|
+
console.error('\x1b[31m', `💔 ${e.message}\n`);
|
|
62
|
+
console.error('\x1b[31m', `💔 ${e.stack}\n`);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
if (cmd.watch) {
|
|
67
|
+
const chokidar = require('chokidar');
|
|
68
|
+
|
|
69
|
+
const watcher = chokidar.watch(cmd.watch);
|
|
70
|
+
watcher.on('ready', () => {
|
|
71
|
+
buildOnce();
|
|
72
|
+
watcher.on('all', () => {
|
|
73
|
+
buildOnce();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
buildOnce();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* eslint-enable global-require */
|
|
81
|
+
}
|
package/jce.pegjs
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
Tars
|
|
2
|
+
= refs:RefDefinition* m:ModuleDefinition+ {
|
|
3
|
+
return [...refs, ...m];
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
RefDefinition
|
|
7
|
+
= _* '#include' _* '"' cs:Char+ '"' _* {
|
|
8
|
+
return {
|
|
9
|
+
type: 'ref',
|
|
10
|
+
target: cs.join(''),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
ModuleDefinition
|
|
15
|
+
= _* 'module' _+ id:Identifier _* '{' value:Definition+ _* '}' _* ';'? _* {
|
|
16
|
+
return {
|
|
17
|
+
type: 'module',
|
|
18
|
+
id,
|
|
19
|
+
value,
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Definition
|
|
24
|
+
= ConstDefinition
|
|
25
|
+
/ EnumDefinition
|
|
26
|
+
/ StructDefinition
|
|
27
|
+
/ InterfaceDefinition
|
|
28
|
+
/ CompareDefinition
|
|
29
|
+
/ KeyDeclaration
|
|
30
|
+
|
|
31
|
+
TypeSpecifier
|
|
32
|
+
= VectorSpecifier
|
|
33
|
+
/ MapSpecifier
|
|
34
|
+
/ SimpleTypeSpecifier
|
|
35
|
+
|
|
36
|
+
SimpleTypeSpecifier
|
|
37
|
+
= 'void'
|
|
38
|
+
/ 'bool'
|
|
39
|
+
/ 'byte'
|
|
40
|
+
/ 'short'
|
|
41
|
+
/ 'int'
|
|
42
|
+
/ type:('unsigned' blank 'int') { return type.join("") }
|
|
43
|
+
/ type:('unsigned' blank 'short') { return type.join("") }
|
|
44
|
+
/ 'long'
|
|
45
|
+
/ 'float'
|
|
46
|
+
/ 'double'
|
|
47
|
+
/ 'string'
|
|
48
|
+
/ nest:((Identifier _* '::' _* )*)? target:Identifier {
|
|
49
|
+
return nest.reduce((acc, [key]) => Object.assign({}, acc, { nested: [...acc.nested, key] }), { target, nested:[] });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
VectorSpecifier
|
|
53
|
+
= 'vector' blank* '<' blank* target:TypeSpecifier blank* '>' {
|
|
54
|
+
return {
|
|
55
|
+
type: 'vector',
|
|
56
|
+
target,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
MapSpecifier
|
|
61
|
+
= 'map' blank* '<' blank* key:TypeSpecifier _* ',' _* value:TypeSpecifier blank* '>' {
|
|
62
|
+
return {
|
|
63
|
+
type: 'map',
|
|
64
|
+
key,
|
|
65
|
+
value,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ConstDefinition
|
|
70
|
+
= beforeComment:_* 'const' _+ t:TypeSpecifier _+ id:Identifier _* init:ConstInitializer _* ';' {
|
|
71
|
+
return {
|
|
72
|
+
id,
|
|
73
|
+
type: 'const',
|
|
74
|
+
beforeComment: beforeComment.join(''),
|
|
75
|
+
value: {
|
|
76
|
+
type: t,
|
|
77
|
+
init,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
ConstInitializer
|
|
83
|
+
= '=' _* value:ConstValuer {
|
|
84
|
+
return value;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
ConstValuer
|
|
88
|
+
= value:(FloatingLiteral / IntegerLiteral / StringLiteral / BooleanLiteral) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
/ nest:((Identifier _* '::' _* )*)? target:Identifier {
|
|
92
|
+
return nest.reduce((acc, [key]) => Object.assign({}, acc, { nested: [...acc.nested, key] }), { target, nested:[] });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
EnumDefinition
|
|
96
|
+
= beforeComment:_* 'enum' _+ id:Identifier _* '{' _* es:EnumeratorSequence _* '}' _* ';' {
|
|
97
|
+
return {
|
|
98
|
+
id,
|
|
99
|
+
type: 'enum',
|
|
100
|
+
value: es,
|
|
101
|
+
beforeComment: beforeComment.join(''),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
EnumeratorSequence
|
|
106
|
+
= head:Enumerator _* tail:EnumeratorSequence {
|
|
107
|
+
return [head, ...tail];
|
|
108
|
+
}
|
|
109
|
+
/ e:Enumerator {
|
|
110
|
+
return [e];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Enumerator
|
|
114
|
+
= id:Identifier _* '=' _* v:IntegerLiteral _* ','? comment: _* {
|
|
115
|
+
return {
|
|
116
|
+
id,
|
|
117
|
+
value: v,
|
|
118
|
+
comment: comment.join('').replace(/^[\n\r]+|\s+$/g, '')
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/ id:Identifier ','? comment: _* {
|
|
122
|
+
return {
|
|
123
|
+
id,
|
|
124
|
+
value: undefined,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/ id:Identifier {
|
|
128
|
+
return {
|
|
129
|
+
id,
|
|
130
|
+
value: undefined,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
StructDefinition
|
|
135
|
+
= beforeComment:_* 'struct' _+ id:Identifier _* '{' _* ms:MemberDeclaration* _* '}' _* ';' {
|
|
136
|
+
return {
|
|
137
|
+
id,
|
|
138
|
+
type: 'struct',
|
|
139
|
+
members: ms,
|
|
140
|
+
beforeComment: beforeComment.join(''),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
KeyDeclaration
|
|
145
|
+
= beforeComment:_* 'key' _* '[' v:KeyMemberList _* ']' _* ';' mock:Mockcomment? comment:_* {
|
|
146
|
+
comment = comment.join('').replace(/^[\n\r]+|\s+$/g, '');
|
|
147
|
+
return {
|
|
148
|
+
type: 'key',
|
|
149
|
+
value:v,
|
|
150
|
+
beforeComment: beforeComment.join(''),
|
|
151
|
+
mock: mock,
|
|
152
|
+
comment,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
MemberDeclaration
|
|
157
|
+
= i:IntegerLiteral _+ r:('require' / 'optional') _+ t:TypeSpecifier _+ id:Identifier _* init:ConstInitializer? _* ';' mock:Mockcomment? comment:_* {
|
|
158
|
+
comment = comment.join('').replace(/^[\n\r]+|\s+$/g, '');
|
|
159
|
+
if(mock ){
|
|
160
|
+
return {
|
|
161
|
+
index: parseInt(i, 10),
|
|
162
|
+
id,
|
|
163
|
+
require: r === 'require',
|
|
164
|
+
type: t,
|
|
165
|
+
init,
|
|
166
|
+
mock: mock,
|
|
167
|
+
comment,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
index: parseInt(i, 10),
|
|
172
|
+
id,
|
|
173
|
+
require: r === 'require',
|
|
174
|
+
type: t,
|
|
175
|
+
init,
|
|
176
|
+
comment,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
InterfaceDefinition
|
|
181
|
+
= beforeComment:_* 'interface' _+ id:Identifier _* '{' _* fn:FunctionDefinition* _* '}' _* ';' {
|
|
182
|
+
return {
|
|
183
|
+
id,
|
|
184
|
+
type: 'interface',
|
|
185
|
+
methods: fn,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
FunctionDefinition
|
|
190
|
+
= t:TypeSpecifier _+ id:Identifier _* '(' _* ps:ParameterDefinitionList? _* ')' _* ';' _* {
|
|
191
|
+
return {
|
|
192
|
+
id,
|
|
193
|
+
type: 'func',
|
|
194
|
+
output: t,
|
|
195
|
+
params: ps,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
ParameterDefinitionList
|
|
200
|
+
= head:ParameterDefinition _* ',' _* tail:ParameterDefinitionList {
|
|
201
|
+
return [head, ...tail];
|
|
202
|
+
}
|
|
203
|
+
/ p:ParameterDefinition {
|
|
204
|
+
return [p];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
ParameterDefinition
|
|
208
|
+
= 'out' _+ type:TypeSpecifier _+ id:Identifier {
|
|
209
|
+
return {
|
|
210
|
+
id,
|
|
211
|
+
io: 'out',
|
|
212
|
+
type,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/ 'routekey' _+ type:TypeSpecifier _+ id:Identifier {
|
|
216
|
+
return {
|
|
217
|
+
id,
|
|
218
|
+
io: 'routekey',
|
|
219
|
+
type,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/ type:TypeSpecifier _+ id:Identifier {
|
|
223
|
+
return {
|
|
224
|
+
id,
|
|
225
|
+
io: 'in',
|
|
226
|
+
type,
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
CompareDefinition
|
|
231
|
+
= beforeComment:_* 'key' _+ '[' _* nest:((Identifier '::')*)? target:Identifier _* ',' _* v:KeyMemberList _* ']' _* ';' {
|
|
232
|
+
const t = nest.reduce((acc, [key]) => Object.assign({}, acc, { nested: [...acc.nested, key] }), { target, nested:[] });
|
|
233
|
+
return {
|
|
234
|
+
type: 'key',
|
|
235
|
+
value: t,
|
|
236
|
+
seq: v,
|
|
237
|
+
beforeComment: beforeComment.join(''),
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
KeyMemberList
|
|
242
|
+
= head:Identifier _* ',' _* tail:KeyMemberList {
|
|
243
|
+
return [head, ...tail];
|
|
244
|
+
}
|
|
245
|
+
/ id:Identifier {
|
|
246
|
+
return [id];
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
IntegerLiteral
|
|
250
|
+
= num:(HexLiteral / OctalLiteral / DecimalLiteral) { return Number(num); }
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
DecimalLiteral
|
|
254
|
+
= head:(Sign? NonezeroDigit) tail:Digit* {
|
|
255
|
+
return [head.join(''), ...tail].join('');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
OctalLiteral
|
|
259
|
+
= head:(Sign? [0]+) tail:OctalDigit* {
|
|
260
|
+
return [head.join(''), ...tail].join('');
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
HexLiteral
|
|
264
|
+
= head:(Sign? "0x"i) tail:HexDigit+ {
|
|
265
|
+
return [head.join(''), ...tail].join('');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
FloatingLiteral
|
|
269
|
+
= f:FractionalConstant e:ExponentPart? FloatingSuffix? {
|
|
270
|
+
if (e !== null) return (f + e);
|
|
271
|
+
return f;
|
|
272
|
+
}
|
|
273
|
+
/ d:Digit+ e:ExponentPart? FloatingSuffix? {
|
|
274
|
+
const ds = d.join('');
|
|
275
|
+
if (e !== null) return (ds + e);
|
|
276
|
+
return ds;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
FractionalConstant
|
|
280
|
+
= s:Sign? l:Digit* '.' r:Digit+ {
|
|
281
|
+
if (s === '-') {
|
|
282
|
+
return [s, ...l, '.', ...r].join('');
|
|
283
|
+
}
|
|
284
|
+
return [...l, '.', ...r].join('');
|
|
285
|
+
}
|
|
286
|
+
/ s:Sign? head:Digit+ '.' {
|
|
287
|
+
if (s === '-') {
|
|
288
|
+
return [s, ...head].join('');
|
|
289
|
+
}
|
|
290
|
+
return head.join('');
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
Digit
|
|
294
|
+
= [0-9]
|
|
295
|
+
|
|
296
|
+
NonezeroDigit
|
|
297
|
+
= [1-9]
|
|
298
|
+
|
|
299
|
+
OctalDigit
|
|
300
|
+
= [1-6]
|
|
301
|
+
|
|
302
|
+
HexDigit
|
|
303
|
+
= [0-9a-fA-F]
|
|
304
|
+
|
|
305
|
+
ExponentPart
|
|
306
|
+
= 'e'i s:Sign? d:Digit+ {
|
|
307
|
+
if (s === null) {
|
|
308
|
+
return ['e', ...d].join('');
|
|
309
|
+
}
|
|
310
|
+
return ['e', s, ...d].join('');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
Sign
|
|
314
|
+
= [+-]
|
|
315
|
+
|
|
316
|
+
FloatingSuffix
|
|
317
|
+
= 'f'i
|
|
318
|
+
|
|
319
|
+
BooleanLiteral
|
|
320
|
+
= 'true'
|
|
321
|
+
/ 'false'
|
|
322
|
+
|
|
323
|
+
StringLiteral
|
|
324
|
+
= '"' str:Char* '"' {
|
|
325
|
+
return `"${str.join('')}"`;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
Char
|
|
329
|
+
= [^\n\"]
|
|
330
|
+
|
|
331
|
+
Identifier
|
|
332
|
+
= head:NonDigit tail:(NonDigit / Digit)* {
|
|
333
|
+
return [head, ...tail].join('');
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
NonDigit
|
|
337
|
+
= [_a-zA-Z]
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
Mockcomment
|
|
341
|
+
= [^\n\/]*'//' [^\n\{]* '{{' str:[^\n\{\}]+ '}}' [^\n\}]* {
|
|
342
|
+
return str.join('');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
comment
|
|
346
|
+
= c:('/*' (!'*/' .)* '*/'
|
|
347
|
+
/ '//' [^\n]*){
|
|
348
|
+
// console.log('comment', c);
|
|
349
|
+
const toString = (a) => typeof a === 'string' ? a : ( a && a.length ? a.map(toString).join('') : '');
|
|
350
|
+
return toString(c);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
blank
|
|
354
|
+
= [ ]
|
|
355
|
+
|
|
356
|
+
_
|
|
357
|
+
= c:([ \t\n\r] / comment) {
|
|
358
|
+
return c;
|
|
359
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* 声明JCE-Struct节点类型
|
|
6
|
+
* @typedef { refType | vecType | string | mapType } tarsType
|
|
7
|
+
*
|
|
8
|
+
* @typedef {object} refType
|
|
9
|
+
* @property {string} target
|
|
10
|
+
* @property {string[]} nested
|
|
11
|
+
*
|
|
12
|
+
* @typedef {object} vecType
|
|
13
|
+
* @property {'vector'} type
|
|
14
|
+
* @property {tarsType} target
|
|
15
|
+
*
|
|
16
|
+
* @typedef {object} mapType
|
|
17
|
+
* @property {'map'} type
|
|
18
|
+
* @property {tarsType} key
|
|
19
|
+
* @property {tarsType} value
|
|
20
|
+
*
|
|
21
|
+
* @typedef {object} constValue
|
|
22
|
+
* @property {tarsType} type
|
|
23
|
+
* @property {*} init
|
|
24
|
+
*
|
|
25
|
+
* @typedef {object} TarsConstNode
|
|
26
|
+
* @property {string} id
|
|
27
|
+
* @property {'const'} type
|
|
28
|
+
* @property {constValue} value
|
|
29
|
+
*
|
|
30
|
+
* @typedef {object} enumValue
|
|
31
|
+
* @property {string} id
|
|
32
|
+
* @property {number} value
|
|
33
|
+
*
|
|
34
|
+
* @typedef {object} TarsEnumNode
|
|
35
|
+
* @property {string} id
|
|
36
|
+
* @property {'enum'} type
|
|
37
|
+
* @property {enumValue[]} value
|
|
38
|
+
*
|
|
39
|
+
* @typedef {object} param
|
|
40
|
+
* @property {string} id
|
|
41
|
+
* @property {'in'|'out'} io
|
|
42
|
+
* @property {tarsType} type
|
|
43
|
+
*
|
|
44
|
+
* @typedef {object} TarsInterfMethod
|
|
45
|
+
* @property {string} id
|
|
46
|
+
* @property {'func'} type
|
|
47
|
+
* @property {tarsType} output
|
|
48
|
+
* @property {param[]} params
|
|
49
|
+
*
|
|
50
|
+
* @typedef {object} TarsInterfNode
|
|
51
|
+
* @property {string} id
|
|
52
|
+
* @property {'interface'} type
|
|
53
|
+
* @property {TarsInterfMethod[]} methods
|
|
54
|
+
*
|
|
55
|
+
* @typedef {object} member
|
|
56
|
+
* @property {number} index
|
|
57
|
+
* @property {string} id
|
|
58
|
+
* @property {boolean} require
|
|
59
|
+
* @property {tarsType} type
|
|
60
|
+
* @property {null|string} init
|
|
61
|
+
*
|
|
62
|
+
* @typedef {object} TarsStructNode
|
|
63
|
+
* @property {string} id
|
|
64
|
+
* @property {'struct'} type
|
|
65
|
+
* @property {member[]} members
|
|
66
|
+
*
|
|
67
|
+
* @typedef {TarsStructNode|TarsInterfNode|TarsEnumNode|TarsConstNode} TarsNode
|
|
68
|
+
*
|
|
69
|
+
* @typedef {object} TarsModule
|
|
70
|
+
* @property {string} pathname
|
|
71
|
+
* @property {TarsNode[]} value
|
|
72
|
+
*
|
|
73
|
+
* @typedef {Object.<string, TarsModule>} TarsTree
|
|
74
|
+
*
|
|
75
|
+
* 工具类类型
|
|
76
|
+
* @typedef {import("./printer")} Printer
|
|
77
|
+
* @typedef {import("./typing")} Typing
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
class Finder {
|
|
81
|
+
/**
|
|
82
|
+
* @param {TarsTree} tree
|
|
83
|
+
*/
|
|
84
|
+
constructor(tree) {
|
|
85
|
+
this._tree = tree;
|
|
86
|
+
/** @type {Map<string, *>} */
|
|
87
|
+
this._memo = new Map();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
refresh() {
|
|
91
|
+
this._memo = new Map();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @param {refType} type
|
|
96
|
+
* @param {string} current
|
|
97
|
+
* @return {*}
|
|
98
|
+
*/
|
|
99
|
+
find(type, current) {
|
|
100
|
+
const jsonType = JSON.stringify(type);
|
|
101
|
+
if (!this._memo.has(jsonType)) {
|
|
102
|
+
if (!type.target || !type.nested) throw new Error(`Type: #${JSON.stringify(type)}# is not a ref type`);
|
|
103
|
+
|
|
104
|
+
let currentPath;
|
|
105
|
+
if (type.nested.length === 0) currentPath = [current];
|
|
106
|
+
else currentPath = [...type.nested];
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const [moduleName] = currentPath;
|
|
110
|
+
const targetModule = this._tree[moduleName];
|
|
111
|
+
const target = targetModule.value.find(({ id: mid }) => mid === type.target);
|
|
112
|
+
this._memo.set(jsonType, target);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
throw new Error(`Cannot find target for type: #${JSON.stringify(type)}#`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return this._memo.get(jsonType);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = Finder;
|