@lcap/nasl 3.5.0-beta.4 → 3.6.0-alpha.2
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/out/breakpoint/shared/utils.js +1 -19
- package/out/breakpoint/shared/utils.js.map +1 -1
- package/out/breakpoint/store/core.js +1 -1
- package/out/breakpoint/store/core.js.map +1 -1
- package/out/common/BaseNode.d.ts +9 -0
- package/out/common/BaseNode.js +15 -0
- package/out/common/BaseNode.js.map +1 -1
- package/out/common/Command.js +1 -0
- package/out/common/Command.js.map +1 -1
- package/out/common/EventEmitter.d.ts +1 -1
- package/out/common/EventEmitter.js +0 -4
- package/out/common/EventEmitter.js.map +1 -1
- package/out/concepts/AnonymousFunction__.d.ts +6 -1
- package/out/concepts/AnonymousFunction__.js +34 -16
- package/out/concepts/AnonymousFunction__.js.map +1 -1
- package/out/concepts/App__.d.ts +29 -0
- package/out/concepts/App__.js +120 -21
- package/out/concepts/App__.js.map +1 -1
- package/out/concepts/BindAttribute__.js.map +1 -1
- package/out/concepts/BindEvent__.js +2 -2
- package/out/concepts/BindEvent__.js.map +1 -1
- package/out/concepts/BusinessComponent__.d.ts +1 -1
- package/out/concepts/BusinessComponent__.js +107 -87
- package/out/concepts/BusinessComponent__.js.map +1 -1
- package/out/concepts/CallEvent__.d.ts +4 -0
- package/out/concepts/CallEvent__.js +18 -1
- package/out/concepts/CallEvent__.js.map +1 -1
- package/out/concepts/CallFunction__.d.ts +0 -1
- package/out/concepts/CallFunction__.js +0 -8
- package/out/concepts/CallFunction__.js.map +1 -1
- package/out/concepts/Destination__.js +3 -3
- package/out/concepts/Destination__.js.map +1 -1
- package/out/concepts/Entity__.d.ts +1 -1
- package/out/concepts/Entity__.js +2 -0
- package/out/concepts/Entity__.js.map +1 -1
- package/out/concepts/Logic__.js +15 -8
- package/out/concepts/Logic__.js.map +1 -1
- package/out/concepts/Match__.d.ts +1 -1
- package/out/concepts/ValidationRule__.js +2 -1
- package/out/concepts/ValidationRule__.js.map +1 -1
- package/out/concepts/ViewElement__.d.ts +1 -0
- package/out/concepts/ViewElement__.js +20 -3
- package/out/concepts/ViewElement__.js.map +1 -1
- package/out/concepts/View__.js +19 -18
- package/out/concepts/View__.js.map +1 -1
- package/out/server/extendBaseNode.js +18 -0
- package/out/server/extendBaseNode.js.map +1 -1
- package/out/server/getProcesses.js +3 -3
- package/out/server/getProcesses.js.map +1 -1
- package/out/server/naslServer.js +16 -12
- package/out/server/naslServer.js.map +1 -1
- package/out/service/storage/init.js +24 -1
- package/out/service/storage/init.js.map +1 -1
- package/out/templator/genCurdMultipleKeyBlock.d.ts +27 -0
- package/out/templator/genCurdMultipleKeyBlock.js +673 -1
- package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
- package/out/templator/genGetBlock.js +2 -1
- package/out/templator/genGetBlock.js.map +1 -1
- package/out/templator/genTableBlock.d.ts +2 -0
- package/out/templator/genTableBlock.js +114 -1
- package/out/templator/genTableBlock.js.map +1 -1
- package/out/templator/genUpdateBlock.js +2 -1
- package/out/templator/genUpdateBlock.js.map +1 -1
- package/out/translator/utils.js +30 -1
- package/out/translator/utils.js.map +1 -1
- package/out/utils/index.d.ts +17 -0
- package/out/utils/index.js +184 -1
- package/out/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/breakpoint/shared/utils.ts +2 -24
- package/src/breakpoint/store/core.ts +1 -1
- package/src/common/BaseNode.ts +19 -0
- package/src/common/Command.ts +1 -0
- package/src/common/EventEmitter.ts +1 -6
- package/src/concepts/AnonymousFunction__.ts +36 -18
- package/src/concepts/App__.ts +132 -21
- package/src/concepts/BindAttribute__.ts +0 -1
- package/src/concepts/BindEvent__.ts +2 -2
- package/src/concepts/BusinessComponent__.ts +122 -98
- package/src/concepts/CallEvent__.ts +19 -2
- package/src/concepts/CallFunction__.ts +0 -11
- package/src/concepts/Destination__.ts +3 -3
- package/src/concepts/Entity__.ts +3 -1
- package/src/concepts/Logic__.ts +15 -9
- package/src/concepts/ValidationRule__.ts +6 -1
- package/src/concepts/ViewElement__.ts +26 -3
- package/src/concepts/View__.ts +19 -18
- package/src/server/extendBaseNode.ts +21 -0
- package/src/server/getProcesses.ts +3 -3
- package/src/server/naslServer.ts +17 -11
- package/src/service/storage/init.ts +31 -1
- package/src/templator/genCurdMultipleKeyBlock.ts +781 -57
- package/src/templator/genGetBlock.ts +2 -1
- package/src/templator/genTableBlock.ts +127 -2
- package/src/templator/genUpdateBlock.ts +2 -1
- package/src/translator/utils.ts +32 -1
- package/src/utils/index.ts +211 -1
- package/ts-worker/src/index.js +1 -0
|
@@ -69,6 +69,7 @@ export function genH5GetTemplate(entity: Entity, nameGroup: NameGroup) {
|
|
|
69
69
|
|
|
70
70
|
export function genGetBlock(entity: Entity, oldNode: ViewElement) {
|
|
71
71
|
const likeComponent = oldNode?.likeComponent;
|
|
72
|
+
const isBusinessComponent = likeComponent.concept === 'BusinessComponent';
|
|
72
73
|
const { ns } = entity;
|
|
73
74
|
const getLogic = ns?.logics?.find((logic) => logic.name === `get`);
|
|
74
75
|
|
|
@@ -85,7 +86,7 @@ export function genGetBlock(entity: Entity, oldNode: ViewElement) {
|
|
|
85
86
|
{
|
|
86
87
|
"viewParams": [
|
|
87
88
|
{
|
|
88
|
-
"concept": "Param",
|
|
89
|
+
"concept": "${isBusinessComponent ? 'ParamWithGroup' : 'Param'}",
|
|
89
90
|
"name": "${nameGroup.viewParamId}",
|
|
90
91
|
"typeAnnotation": ${JSON.stringify(NaslCoreTypeAnnotation.Long)}
|
|
91
92
|
}
|
|
@@ -62,7 +62,7 @@ export function genTableColumnTemplate(property: EntityProperty, currentName: st
|
|
|
62
62
|
* @param entity 实体
|
|
63
63
|
* @param nameGroup 命名组
|
|
64
64
|
*/
|
|
65
|
-
export function genTableTemplate(entity: Entity, nameGroup: NameGroup,newLogic: any, modifyable?: boolean, entryFromCall?: string) {
|
|
65
|
+
export function genTableTemplate(entity: Entity, nameGroup: NameGroup, newLogic: any, modifyable?: boolean, entryFromCall?: string) {
|
|
66
66
|
const currentName = nameGroup.currentName || 'current';
|
|
67
67
|
const properties = entity.properties.filter(filterProperty('inTable'));
|
|
68
68
|
let dataSourceValue = `(params) => ${newLogic.name}(elements.$ce.page, elements.$ce.size,elements.$ce.sort,elements.$ce.order)`;
|
|
@@ -277,7 +277,9 @@ export function genTableColumnBlock(property: EntityProperty, oldNode: ViewEleme
|
|
|
277
277
|
let dataSourceValue = `(params) => ${entityLogic.name}(elements.$ce.page, elements.$ce.size,elements.$ce.sort,elements.$ce.order)`;
|
|
278
278
|
return `
|
|
279
279
|
<template>
|
|
280
|
-
<u-table-view ref="${
|
|
280
|
+
<u-table-view ref="${
|
|
281
|
+
nameGroup.viewElementMainView
|
|
282
|
+
}" :data-source="${dataSourceValue}" :pagination="true" :page-size="20" :page-number="1" :show-sizer="true" data-schema="${nameGroup.structure}">
|
|
281
283
|
${properties.map((property) => `${genTableColumnTemplate(property)}\n`).join('')}
|
|
282
284
|
</u-table-view>
|
|
283
285
|
</template>
|
|
@@ -294,3 +296,126 @@ export function genTableColumnBlock(property: EntityProperty, oldNode: ViewEleme
|
|
|
294
296
|
}
|
|
295
297
|
|
|
296
298
|
export default genTableBlock;
|
|
299
|
+
|
|
300
|
+
export function genTableTemplateTableDesigner(
|
|
301
|
+
entity: Entity,
|
|
302
|
+
nameGroup: NameGroup,
|
|
303
|
+
newLogic: any,
|
|
304
|
+
modifyable?: boolean,
|
|
305
|
+
entryFromCall?: string,
|
|
306
|
+
optionsMap?: any
|
|
307
|
+
) {
|
|
308
|
+
const currentName = nameGroup.currentName || 'current';
|
|
309
|
+
const properties = entity.properties.filter(filterProperty('inTable'));
|
|
310
|
+
let dataSourceValue = `(params) => ${newLogic.name}(elements.$ce.page, elements.$ce.size,elements.$ce.sort,elements.$ce.order)`;
|
|
311
|
+
if (['genCurdMultipleKeyBlock'].includes(entryFromCall)) {
|
|
312
|
+
dataSourceValue = `(params) => ${newLogic.name}(elements.$ce.page, elements.$ce.size,elements.$ce.sort,elements.$ce.order,${nameGroup.viewVariableFilter})`;
|
|
313
|
+
}
|
|
314
|
+
return `
|
|
315
|
+
<u-linear-layout style="background: #fff; padding: 15px" >
|
|
316
|
+
<u-button color="primary" @click="${nameGroup.viewLogicCreate}" style="margin-right: 5px" icon="add">新 增</u-button>
|
|
317
|
+
<u-uploader
|
|
318
|
+
style="--custom-start: auto;margin-right: 5px"
|
|
319
|
+
display="inline"
|
|
320
|
+
url="/api/${entity.name.toLowerCase()}/import"
|
|
321
|
+
url-field="filePath"
|
|
322
|
+
:limit="999"
|
|
323
|
+
max-size="50MB"
|
|
324
|
+
converter="json"
|
|
325
|
+
:file-icon-switcher="false"
|
|
326
|
+
:download-icon-switcher="false"
|
|
327
|
+
:file-size="false"
|
|
328
|
+
:show-file-list="false"
|
|
329
|
+
name="file"
|
|
330
|
+
accept=""
|
|
331
|
+
@success="${nameGroup.viewLogicReload}"
|
|
332
|
+
>
|
|
333
|
+
<template #file-list>
|
|
334
|
+
<i-ico
|
|
335
|
+
style="margin: 0px 8px 0px 0px"
|
|
336
|
+
flag="file-icon"
|
|
337
|
+
name="file-default"
|
|
338
|
+
icotype="only"
|
|
339
|
+
></i-ico>
|
|
340
|
+
<u-text
|
|
341
|
+
style="
|
|
342
|
+
margin: 0px 8px 0px 0px;
|
|
343
|
+
white-space: nowrap;
|
|
344
|
+
overflow: hidden;
|
|
345
|
+
text-overflow: ellipsis;
|
|
346
|
+
display: inherit;
|
|
347
|
+
"
|
|
348
|
+
flag="file-name"
|
|
349
|
+
text="文件名称"
|
|
350
|
+
></u-text>
|
|
351
|
+
<u-text style="margin: 0px 8px 0px 0px" flag="file-size" text="文件大小"></u-text>
|
|
352
|
+
<i-ico
|
|
353
|
+
style="margin: 0px 8px 0px 0px"
|
|
354
|
+
flag="download-icon"
|
|
355
|
+
name="download"
|
|
356
|
+
icotype="only"
|
|
357
|
+
></i-ico>
|
|
358
|
+
</template>
|
|
359
|
+
<u-button color="default" icon="upload" text="上传"></u-button
|
|
360
|
+
></u-uploader>
|
|
361
|
+
<u-button style="margin-right: 5px" icon="download" @click="${nameGroup.viewLogicExportData}">导 出</u-button>
|
|
362
|
+
<u-table-view ref="${nameGroup.viewElementMainView}" :data-source="${dataSourceValue}" data-schema="${nameGroup.structure}"
|
|
363
|
+
value-field="${nameGroup.viewVariableEntity}.id"
|
|
364
|
+
:pagination="true" :show-sizer="true" :page-size="20" :page-number="1" style="margin-top: 12px">
|
|
365
|
+
<u-table-view-column type="index" width="60"><template #title><u-text text="序号"></u-text></template><template #cell="current"></template></u-table-view-column>
|
|
366
|
+
${properties.map((property) => `${genTableColumnTemplateTableDesigner(property, currentName, optionsMap)}\n`).join('')}
|
|
367
|
+
<u-table-view-column title="操作">
|
|
368
|
+
<template #title><u-text text="操作"></u-text></template>
|
|
369
|
+
<template #cell="current">
|
|
370
|
+
<u-link style="margin-right:5px;" @click="${nameGroup.viewLogicPreview}">详情</u-link>
|
|
371
|
+
<u-link ${modifyable ? `@click="${nameGroup.viewLogicModify || 'modify'}"` : ''} style="margin-right:5px;">编辑</u-link>
|
|
372
|
+
<u-link style="margin-right:5px;" @click="${nameGroup.viewLogicOpenDelModal}">删除</u-link>
|
|
373
|
+
</template>
|
|
374
|
+
</u-table-view-column>
|
|
375
|
+
</u-table-view>
|
|
376
|
+
</u-linear-layout>
|
|
377
|
+
|
|
378
|
+
`;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
export const genTableColumnTemplateTableDesigner = (property: EntityProperty, currentName: string = 'current', optionsMap?: any) => {
|
|
382
|
+
const { entity } = property;
|
|
383
|
+
const hasOptions = optionsMap?.[property.name];
|
|
384
|
+
|
|
385
|
+
const dataSource = entity.parentNode as DataSource;
|
|
386
|
+
const lowerEntityName = utils.firstLowerCase(entity.name);
|
|
387
|
+
let valueExpression = `${currentName}.item.${lowerEntityName}.${property.name}`;
|
|
388
|
+
const title = (property.label || property.name).replace(/"/g, '"');
|
|
389
|
+
const multiple = property?.typeAnnotation?.typeName === 'List';
|
|
390
|
+
|
|
391
|
+
if (property.relationEntity) {
|
|
392
|
+
const relationLowerEntityName = utils.firstLowerCase(property.relationEntity);
|
|
393
|
+
const relationEntity = dataSource?.findEntityByName(property.relationEntity);
|
|
394
|
+
const displayedProperty = getFirstDisplayedProperty(relationEntity);
|
|
395
|
+
valueExpression = `${currentName}.item.${relationLowerEntityName}.${displayedProperty?.name || property.relationProperty}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const getText = (property: EntityProperty) => {
|
|
399
|
+
if (hasOptions) {
|
|
400
|
+
const options = optionsMap[property.name];
|
|
401
|
+
return `
|
|
402
|
+
<u-select :preview="true" :value="${valueExpression}" placeholder="--" ${multiple ? 'multiple' : ''}>
|
|
403
|
+
${options.map((option: any) => `<u-select-item value="${option.value}" text="${option.label}">${option.label}</u-select-item>`)}
|
|
404
|
+
</u-select>
|
|
405
|
+
`;
|
|
406
|
+
} else if (property.typeAnnotation.typeName === 'Boolean') {
|
|
407
|
+
return `
|
|
408
|
+
<u-text v-if="${valueExpression}" text="是"></u-text>
|
|
409
|
+
<u-text v-if="!${valueExpression}" text="否"></u-text>
|
|
410
|
+
`;
|
|
411
|
+
}
|
|
412
|
+
return `<u-text :text="${valueExpression}"></u-text>`;
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
return `<u-table-view-column field="${lowerEntityName}.${property.name}">
|
|
416
|
+
<template #title><u-text text="${title}"></u-text></template>
|
|
417
|
+
<template #cell="current">
|
|
418
|
+
${getText(property)}
|
|
419
|
+
</template>
|
|
420
|
+
</u-table-view-column>`;
|
|
421
|
+
};
|
|
@@ -308,6 +308,7 @@ function genLoadLogic(getLogic: Logic, nameGroup: NameGroup) {
|
|
|
308
308
|
// 生成修改区块
|
|
309
309
|
export function genUpdateBlock(entity: Entity, oldNode: ViewElement) {
|
|
310
310
|
const likeComponent = oldNode?.likeComponent;
|
|
311
|
+
const isBusinessComponent = likeComponent.concept === 'BusinessComponent';
|
|
311
312
|
const dataSource = entity.parentNode as DataSource;
|
|
312
313
|
const module = dataSource.app;
|
|
313
314
|
const { ns } = entity;
|
|
@@ -357,7 +358,7 @@ export function genUpdateBlock(entity: Entity, oldNode: ViewElement) {
|
|
|
357
358
|
{
|
|
358
359
|
"viewParams": [
|
|
359
360
|
{
|
|
360
|
-
"concept": "Param",
|
|
361
|
+
"concept": "${isBusinessComponent ? 'ParamWithGroup' : 'Param'}",
|
|
361
362
|
"name": "${nameGroup.viewParamId}",
|
|
362
363
|
"typeAnnotation": ${JSON.stringify(NaslCoreTypeAnnotation.Long)}
|
|
363
364
|
}
|
package/src/translator/utils.ts
CHANGED
|
@@ -58,6 +58,22 @@ export function isSameRange(rangeA: Range, rangeB : Range) {
|
|
|
58
58
|
return rangeA.start.offset === rangeB.start.offset && rangeA.end.offset === rangeB.end.offset;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
const statementMap = [
|
|
62
|
+
"Assignment",
|
|
63
|
+
"BatchAssignment",
|
|
64
|
+
"IfStatement",
|
|
65
|
+
"ForEachStatement",
|
|
66
|
+
"SwitchStatement",
|
|
67
|
+
"WhileStatement",
|
|
68
|
+
"Match",
|
|
69
|
+
"Comment",
|
|
70
|
+
"CallLogic",
|
|
71
|
+
"CallInterface",
|
|
72
|
+
"Destination",
|
|
73
|
+
"JSBlock",
|
|
74
|
+
'JavaLogic'
|
|
75
|
+
];
|
|
76
|
+
|
|
61
77
|
/**
|
|
62
78
|
* 翻译方法修饰器
|
|
63
79
|
*
|
|
@@ -115,6 +131,10 @@ export function withSourceMap() {
|
|
|
115
131
|
end: shiftPosition(state.position, code),
|
|
116
132
|
});
|
|
117
133
|
|
|
134
|
+
if (isNatural && statementMap?.includes(this.concept) && code) {
|
|
135
|
+
before += `// nodePath: '${this.nodePath}' \n`;
|
|
136
|
+
}
|
|
137
|
+
|
|
118
138
|
return before + code;
|
|
119
139
|
};
|
|
120
140
|
|
|
@@ -160,8 +180,19 @@ export function withSourceMapGenerator(target: any, key: string, descriptor: Pro
|
|
|
160
180
|
const code = yield* oldMethod.call(this, state, ...args);
|
|
161
181
|
yield;
|
|
162
182
|
|
|
183
|
+
const start = {
|
|
184
|
+
...state.position
|
|
185
|
+
};
|
|
186
|
+
if (this.concept === 'BusinessComponent') {
|
|
187
|
+
const lines: string[] = code.split('\n');
|
|
188
|
+
const lineOffset = lines.findIndex((item) => item.startsWith('export class '));
|
|
189
|
+
if (lineOffset) {
|
|
190
|
+
start.line = start.line + lineOffset + 1;
|
|
191
|
+
start.offset = 13;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
163
194
|
state.sourceMap?.set(this, {
|
|
164
|
-
start
|
|
195
|
+
start,
|
|
165
196
|
end: shiftPosition(state.position, code),
|
|
166
197
|
});
|
|
167
198
|
|
package/src/utils/index.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { compare } from 'compare-versions';
|
|
2
|
-
import { BaseNode, LogicItem } from '..';
|
|
2
|
+
import { BaseNode, LogicItem, AnonymousFunction, Param } from '..';
|
|
3
|
+
import type { ForEachStatement, Logic, View } from '..';
|
|
4
|
+
import * as types from '../concepts/utils/types';
|
|
5
|
+
import { getConceptPropertyMap } from '../decorators/index';
|
|
3
6
|
import { traverse } from './traverse';
|
|
4
7
|
// import TypeAnnotation from '../concepts/TypeAnnotation__';
|
|
5
8
|
// import App from '../concepts/App__';
|
|
@@ -202,3 +205,210 @@ export function attrConvertCamelCase(str: string) {
|
|
|
202
205
|
});
|
|
203
206
|
return strList.join('');
|
|
204
207
|
}
|
|
208
|
+
|
|
209
|
+
export class AnonymousFnNode {
|
|
210
|
+
node: types.SyntaxNode;
|
|
211
|
+
descendants: AnonymousFnNode[];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* 收集匿名函数
|
|
216
|
+
* @param param0
|
|
217
|
+
* @returns
|
|
218
|
+
*/
|
|
219
|
+
function collectAnonymousFn({
|
|
220
|
+
anonymousFnNode,
|
|
221
|
+
cb
|
|
222
|
+
}: {
|
|
223
|
+
anonymousFnNode: AnonymousFnNode;
|
|
224
|
+
cb: (anonymousFnNode: AnonymousFnNode) => void
|
|
225
|
+
}) {
|
|
226
|
+
const descendantsAnonyList: any = cb(anonymousFnNode);
|
|
227
|
+
const { node } = anonymousFnNode;
|
|
228
|
+
const propertyMap = getConceptPropertyMap(node?.concept);
|
|
229
|
+
if (!propertyMap) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
for (const property of propertyMap.keys()) {
|
|
233
|
+
const child = node[property as keyof BaseNode];
|
|
234
|
+
if (!child) {
|
|
235
|
+
continue;
|
|
236
|
+
} else if (Array.isArray(child)) {
|
|
237
|
+
child.forEach((node: types.SyntaxNode) => collectAnonymousFn({
|
|
238
|
+
anonymousFnNode: {
|
|
239
|
+
node,
|
|
240
|
+
descendants: descendantsAnonyList
|
|
241
|
+
},
|
|
242
|
+
cb
|
|
243
|
+
}));
|
|
244
|
+
} else {
|
|
245
|
+
collectAnonymousFn({
|
|
246
|
+
anonymousFnNode: {
|
|
247
|
+
node: child,
|
|
248
|
+
descendants: descendantsAnonyList
|
|
249
|
+
},
|
|
250
|
+
cb
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function getAnonymousFnNodes(node: types.SyntaxNode) {
|
|
257
|
+
const anonymousFnNodes: AnonymousFnNode[] = [];
|
|
258
|
+
// 1.匿名函数可能在里层,如:ListDistinctBy
|
|
259
|
+
// 2.存在多级匿名数据结构
|
|
260
|
+
collectAnonymousFn({
|
|
261
|
+
anonymousFnNode: {
|
|
262
|
+
node,
|
|
263
|
+
descendants: anonymousFnNodes
|
|
264
|
+
},
|
|
265
|
+
cb: (anonymousFnNode) => {
|
|
266
|
+
const { node, descendants } = anonymousFnNode;
|
|
267
|
+
if (node?.concept === 'AnonymousFunction') {
|
|
268
|
+
const newAnonymousNode: any = {
|
|
269
|
+
node,
|
|
270
|
+
descendants: [],
|
|
271
|
+
};
|
|
272
|
+
descendants?.push(newAnonymousNode);
|
|
273
|
+
return newAnonymousNode.descendants;
|
|
274
|
+
}
|
|
275
|
+
return descendants;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return anonymousFnNodes;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* 父链上存在的参数名字
|
|
283
|
+
* @returns
|
|
284
|
+
*/
|
|
285
|
+
function getAncestorExistingParamNames(baseNode: types.SyntaxNode) {
|
|
286
|
+
let node: BaseNode = baseNode;
|
|
287
|
+
const names: Set<string> = new Set();
|
|
288
|
+
while (node) {
|
|
289
|
+
node = node.parentNode;
|
|
290
|
+
switch (node?.concept) {
|
|
291
|
+
case 'AnonymousFunction':
|
|
292
|
+
(node as AnonymousFunction).params.forEach((param: Param) => {
|
|
293
|
+
names.add(param.name);
|
|
294
|
+
});
|
|
295
|
+
break;
|
|
296
|
+
case 'ForEachStatement':
|
|
297
|
+
names.add((node as ForEachStatement).item?.name);
|
|
298
|
+
names.add((node as ForEachStatement).index?.name);
|
|
299
|
+
break;
|
|
300
|
+
case 'Logic':
|
|
301
|
+
case 'View':
|
|
302
|
+
const varList = [
|
|
303
|
+
...((node as Logic | View).params || []),
|
|
304
|
+
...((node as Logic).returns || []),
|
|
305
|
+
...((node as Logic | View).variables || [])
|
|
306
|
+
];
|
|
307
|
+
varList?.forEach((variable) => {
|
|
308
|
+
names.add(variable?.name);
|
|
309
|
+
});
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return names;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* 确保匿名函数的参数名称都是不重复的,且更新内部的引用关系
|
|
318
|
+
* @param param0
|
|
319
|
+
*/
|
|
320
|
+
function ensureAnonymousFnsParamName({
|
|
321
|
+
ancestorParamNames,
|
|
322
|
+
anonymousFnNodes,
|
|
323
|
+
}: {
|
|
324
|
+
ancestorParamNames: Set<string>;
|
|
325
|
+
anonymousFnNodes: AnonymousFnNode[];
|
|
326
|
+
}) {
|
|
327
|
+
const paramInfoMapList: Map<string, any>[] = [];
|
|
328
|
+
anonymousFnNodes.forEach((anonymousFnNode) => {
|
|
329
|
+
const { node: anonymousFn, descendants } = anonymousFnNode || {};
|
|
330
|
+
const tempParamInfoMap = (anonymousFn as AnonymousFunction)?.ensureParamName(ancestorParamNames);
|
|
331
|
+
paramInfoMapList.push(tempParamInfoMap);
|
|
332
|
+
if (Array.isArray(descendants)) {
|
|
333
|
+
const paramNames = new Set([...ancestorParamNames]);
|
|
334
|
+
tempParamInfoMap.forEach((value) => {
|
|
335
|
+
paramNames.add(value.newName);
|
|
336
|
+
});
|
|
337
|
+
const descendantTempParamInfoMap = ensureAnonymousFnsParamName({
|
|
338
|
+
ancestorParamNames: paramNames,
|
|
339
|
+
anonymousFnNodes: descendants,
|
|
340
|
+
});
|
|
341
|
+
paramInfoMapList.push(...descendantTempParamInfoMap);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
return paramInfoMapList;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* 校验匿名函数的局部变量是否重名
|
|
349
|
+
*/
|
|
350
|
+
export function checkParamNameOfAnonymousFunction(node: types.SyntaxNode) {
|
|
351
|
+
const anonymousFnNodes: any = getAnonymousFnNodes(node);
|
|
352
|
+
// 从外到里计算更改的name
|
|
353
|
+
const paramInfoMapList = ensureAnonymousFnsParamName({
|
|
354
|
+
ancestorParamNames: getAncestorExistingParamNames(node),
|
|
355
|
+
anonymousFnNodes
|
|
356
|
+
});
|
|
357
|
+
paramInfoMapList?.forEach((paramInfoMap: Map<string, any>) => {
|
|
358
|
+
paramInfoMap.forEach((paramInfo) => {
|
|
359
|
+
const { newName, param, identifiers } = paramInfo || {};
|
|
360
|
+
param?.update({
|
|
361
|
+
name: newName,
|
|
362
|
+
});
|
|
363
|
+
if (Array.isArray(identifiers)) {
|
|
364
|
+
identifiers.forEach((identifier) => {
|
|
365
|
+
identifier?.update({
|
|
366
|
+
name: newName,
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// 获取内部匿名函数的局部变量
|
|
375
|
+
function collectAnonymousFnNodesParams(node: types.SyntaxNode) {
|
|
376
|
+
const paramNames: Set<string> = new Set();
|
|
377
|
+
const anonymousFnNodes = getAnonymousFnNodes(node);
|
|
378
|
+
if (Array.isArray(anonymousFnNodes)) {
|
|
379
|
+
anonymousFnNodes.forEach((anonymousFnNode) => {
|
|
380
|
+
const { node: anonymousFn, descendants } = anonymousFnNode || {};
|
|
381
|
+
(anonymousFn as AnonymousFunction).params.forEach((param: Param) => {
|
|
382
|
+
paramNames.add(param.name);
|
|
383
|
+
});
|
|
384
|
+
if (Array.isArray(descendants)) {
|
|
385
|
+
descendants.forEach(({
|
|
386
|
+
node: descendantNode
|
|
387
|
+
}) => {
|
|
388
|
+
const descendantParamNames = collectAnonymousFnNodesParams(descendantNode);
|
|
389
|
+
descendantParamNames.forEach((descendantParamName) => {
|
|
390
|
+
paramNames.add(descendantParamName);
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
return paramNames;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* 新的参数名是否存在同名
|
|
401
|
+
* @param param0
|
|
402
|
+
*/
|
|
403
|
+
export function hasParamNameOfAnonymousFunction({
|
|
404
|
+
node,
|
|
405
|
+
newName,
|
|
406
|
+
}: {
|
|
407
|
+
node: types.SyntaxNode,
|
|
408
|
+
newName: string
|
|
409
|
+
}) {
|
|
410
|
+
const ancestorParamNames = getAncestorExistingParamNames(node);
|
|
411
|
+
const anonymousFnNodesParams = collectAnonymousFnNodesParams(node);
|
|
412
|
+
const paramNames = new Set([...ancestorParamNames.values(), ...anonymousFnNodesParams.values()]);
|
|
413
|
+
return paramNames.has(newName);
|
|
414
|
+
}
|
package/ts-worker/src/index.js
CHANGED