@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.
Files changed (98) hide show
  1. package/out/breakpoint/shared/utils.js +1 -19
  2. package/out/breakpoint/shared/utils.js.map +1 -1
  3. package/out/breakpoint/store/core.js +1 -1
  4. package/out/breakpoint/store/core.js.map +1 -1
  5. package/out/common/BaseNode.d.ts +9 -0
  6. package/out/common/BaseNode.js +15 -0
  7. package/out/common/BaseNode.js.map +1 -1
  8. package/out/common/Command.js +1 -0
  9. package/out/common/Command.js.map +1 -1
  10. package/out/common/EventEmitter.d.ts +1 -1
  11. package/out/common/EventEmitter.js +0 -4
  12. package/out/common/EventEmitter.js.map +1 -1
  13. package/out/concepts/AnonymousFunction__.d.ts +6 -1
  14. package/out/concepts/AnonymousFunction__.js +34 -16
  15. package/out/concepts/AnonymousFunction__.js.map +1 -1
  16. package/out/concepts/App__.d.ts +29 -0
  17. package/out/concepts/App__.js +120 -21
  18. package/out/concepts/App__.js.map +1 -1
  19. package/out/concepts/BindAttribute__.js.map +1 -1
  20. package/out/concepts/BindEvent__.js +2 -2
  21. package/out/concepts/BindEvent__.js.map +1 -1
  22. package/out/concepts/BusinessComponent__.d.ts +1 -1
  23. package/out/concepts/BusinessComponent__.js +107 -87
  24. package/out/concepts/BusinessComponent__.js.map +1 -1
  25. package/out/concepts/CallEvent__.d.ts +4 -0
  26. package/out/concepts/CallEvent__.js +18 -1
  27. package/out/concepts/CallEvent__.js.map +1 -1
  28. package/out/concepts/CallFunction__.d.ts +0 -1
  29. package/out/concepts/CallFunction__.js +0 -8
  30. package/out/concepts/CallFunction__.js.map +1 -1
  31. package/out/concepts/Destination__.js +3 -3
  32. package/out/concepts/Destination__.js.map +1 -1
  33. package/out/concepts/Entity__.d.ts +1 -1
  34. package/out/concepts/Entity__.js +2 -0
  35. package/out/concepts/Entity__.js.map +1 -1
  36. package/out/concepts/Logic__.js +15 -8
  37. package/out/concepts/Logic__.js.map +1 -1
  38. package/out/concepts/Match__.d.ts +1 -1
  39. package/out/concepts/ValidationRule__.js +2 -1
  40. package/out/concepts/ValidationRule__.js.map +1 -1
  41. package/out/concepts/ViewElement__.d.ts +1 -0
  42. package/out/concepts/ViewElement__.js +20 -3
  43. package/out/concepts/ViewElement__.js.map +1 -1
  44. package/out/concepts/View__.js +19 -18
  45. package/out/concepts/View__.js.map +1 -1
  46. package/out/server/extendBaseNode.js +18 -0
  47. package/out/server/extendBaseNode.js.map +1 -1
  48. package/out/server/getProcesses.js +3 -3
  49. package/out/server/getProcesses.js.map +1 -1
  50. package/out/server/naslServer.js +16 -12
  51. package/out/server/naslServer.js.map +1 -1
  52. package/out/service/storage/init.js +24 -1
  53. package/out/service/storage/init.js.map +1 -1
  54. package/out/templator/genCurdMultipleKeyBlock.d.ts +27 -0
  55. package/out/templator/genCurdMultipleKeyBlock.js +673 -1
  56. package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
  57. package/out/templator/genGetBlock.js +2 -1
  58. package/out/templator/genGetBlock.js.map +1 -1
  59. package/out/templator/genTableBlock.d.ts +2 -0
  60. package/out/templator/genTableBlock.js +114 -1
  61. package/out/templator/genTableBlock.js.map +1 -1
  62. package/out/templator/genUpdateBlock.js +2 -1
  63. package/out/templator/genUpdateBlock.js.map +1 -1
  64. package/out/translator/utils.js +30 -1
  65. package/out/translator/utils.js.map +1 -1
  66. package/out/utils/index.d.ts +17 -0
  67. package/out/utils/index.js +184 -1
  68. package/out/utils/index.js.map +1 -1
  69. package/package.json +1 -1
  70. package/src/breakpoint/shared/utils.ts +2 -24
  71. package/src/breakpoint/store/core.ts +1 -1
  72. package/src/common/BaseNode.ts +19 -0
  73. package/src/common/Command.ts +1 -0
  74. package/src/common/EventEmitter.ts +1 -6
  75. package/src/concepts/AnonymousFunction__.ts +36 -18
  76. package/src/concepts/App__.ts +132 -21
  77. package/src/concepts/BindAttribute__.ts +0 -1
  78. package/src/concepts/BindEvent__.ts +2 -2
  79. package/src/concepts/BusinessComponent__.ts +122 -98
  80. package/src/concepts/CallEvent__.ts +19 -2
  81. package/src/concepts/CallFunction__.ts +0 -11
  82. package/src/concepts/Destination__.ts +3 -3
  83. package/src/concepts/Entity__.ts +3 -1
  84. package/src/concepts/Logic__.ts +15 -9
  85. package/src/concepts/ValidationRule__.ts +6 -1
  86. package/src/concepts/ViewElement__.ts +26 -3
  87. package/src/concepts/View__.ts +19 -18
  88. package/src/server/extendBaseNode.ts +21 -0
  89. package/src/server/getProcesses.ts +3 -3
  90. package/src/server/naslServer.ts +17 -11
  91. package/src/service/storage/init.ts +31 -1
  92. package/src/templator/genCurdMultipleKeyBlock.ts +781 -57
  93. package/src/templator/genGetBlock.ts +2 -1
  94. package/src/templator/genTableBlock.ts +127 -2
  95. package/src/templator/genUpdateBlock.ts +2 -1
  96. package/src/translator/utils.ts +32 -1
  97. package/src/utils/index.ts +211 -1
  98. 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="${nameGroup.viewElementMainView}" :data-source="${dataSourceValue}" :pagination="true" :page-size="20" :page-number="1" :show-sizer="true" data-schema="${nameGroup.structure}">
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, '&quot;');
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
  }
@@ -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: state.position,
195
+ start,
165
196
  end: shiftPosition(state.position, code),
166
197
  });
167
198
 
@@ -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
+ }
@@ -370,6 +370,7 @@ const context = {
370
370
  = item.sortText === '11'
371
371
  && item.name !== 'arguments'
372
372
  && item.kind !== 'function'
373
+ && item.kind !== 'local function'
373
374
  && item.kind !== 'module'
374
375
  && item.kind !== 'method'
375
376
  && item.kind !== 'class'