@lcap/nasl-language-server-core 4.1.0-beta.1 → 4.1.0-beta.10
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 +85 -0
- package/out/checker.d.ts +1 -1
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +172 -56
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +5 -2
- package/out/index.d.ts.map +1 -1
- package/out/index.js +9 -2
- package/out/index.js.map +1 -1
- package/out/module/graph.js +6 -6
- package/out/module/graph.js.map +1 -1
- package/out/module/module.d.ts.map +1 -1
- package/out/module/module.js +3 -6
- package/out/module/module.js.map +1 -1
- package/out/query/context-variable-query.d.ts +31 -0
- package/out/query/context-variable-query.d.ts.map +1 -0
- package/out/query/context-variable-query.js +105 -0
- package/out/query/context-variable-query.js.map +1 -0
- package/out/query/index.d.ts +2 -0
- package/out/query/index.d.ts.map +1 -0
- package/out/query/index.js +18 -0
- package/out/query/index.js.map +1 -0
- package/out/reference-manager/builtin-q-name.d.ts +10 -3
- package/out/reference-manager/builtin-q-name.d.ts.map +1 -1
- package/out/reference-manager/builtin-q-name.js +67 -9
- package/out/reference-manager/builtin-q-name.js.map +1 -1
- package/out/reference-manager/collect-q-name.d.ts +4 -2
- package/out/reference-manager/collect-q-name.d.ts.map +1 -1
- package/out/reference-manager/collect-q-name.js +30 -17
- package/out/reference-manager/collect-q-name.js.map +1 -1
- package/out/reference-manager/get-q-name.d.ts +0 -2
- package/out/reference-manager/get-q-name.d.ts.map +1 -1
- package/out/reference-manager/get-q-name.js +35 -49
- package/out/reference-manager/get-q-name.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +36 -19
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +350 -163
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/remove-q-name.d.ts +31 -28
- package/out/reference-manager/remove-q-name.d.ts.map +1 -1
- package/out/reference-manager/remove-q-name.js +73 -51
- package/out/reference-manager/remove-q-name.js.map +1 -1
- package/out/reference-manager/rename-q-name.d.ts +4 -2
- package/out/reference-manager/rename-q-name.d.ts.map +1 -1
- package/out/reference-manager/rename-q-name.js +43 -36
- package/out/reference-manager/rename-q-name.js.map +1 -1
- package/out/reference-manager/symbol-type.d.ts +7 -3
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +22 -10
- package/out/reference-manager/symbol-type.js.map +1 -1
- package/out/reference-manager/update-nasl-fragment.d.ts +2 -1
- package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
- package/out/reference-manager/update-nasl-fragment.js +18 -9
- package/out/reference-manager/update-nasl-fragment.js.map +1 -1
- package/out/symbol/graph.js +2 -2
- package/out/symbol/graph.js.map +1 -1
- package/out/symbol/traverse/concepts/index.d.ts +1 -1
- package/out/symbol/traverse/concepts/index.d.ts.map +1 -1
- package/out/typer/collectGlobalDefs.d.ts +1 -1
- package/out/typer/collectGlobalDefs.d.ts.map +1 -1
- package/out/typer/collectGlobalDefs.js +81 -17
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.d.ts +50 -12
- package/out/typer/component-def-manager/component-def-manager.d.ts.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.js +129 -27
- package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
- package/out/typer/component-def-manager/utils.d.ts.map +1 -1
- package/out/typer/component-def-manager/utils.js +50 -15
- package/out/typer/component-def-manager/utils.js.map +1 -1
- package/out/typer/dispatch-all.d.ts +2 -2
- package/out/typer/dispatch-all.d.ts.map +1 -1
- package/out/typer/dispatch-all.js +6 -10
- package/out/typer/dispatch-all.js.map +1 -1
- package/out/typer/dispatch-def.d.ts +1 -3
- package/out/typer/dispatch-def.d.ts.map +1 -1
- package/out/typer/dispatch-def.js +28 -54
- package/out/typer/dispatch-def.js.map +1 -1
- package/out/typer/dispatch-expr.d.ts +6 -3
- package/out/typer/dispatch-expr.d.ts.map +1 -1
- package/out/typer/dispatch-expr.js +341 -226
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.d.ts +0 -1
- package/out/typer/dispatch-process.d.ts.map +1 -1
- package/out/typer/dispatch-process.js +26 -17
- package/out/typer/dispatch-process.js.map +1 -1
- package/out/typer/dispatch-stmt.d.ts.map +1 -1
- package/out/typer/dispatch-stmt.js +50 -29
- package/out/typer/dispatch-stmt.js.map +1 -1
- package/out/typer/dispatch-view.d.ts +1 -1
- package/out/typer/dispatch-view.d.ts.map +1 -1
- package/out/typer/dispatch-view.js +265 -158
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/helper.js +3 -3
- package/out/typer/helper.js.map +1 -1
- package/out/typer/incremental-update.d.ts +21 -42
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +214 -263
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/index.d.ts +5 -5
- package/out/typer/index.d.ts.map +1 -1
- package/out/typer/index.js +6 -5
- package/out/typer/index.js.map +1 -1
- package/out/typer/nasl-predicate.d.ts +1 -1
- package/out/typer/nasl-predicate.d.ts.map +1 -1
- package/out/typer/overload-helper.d.ts +12 -0
- package/out/typer/overload-helper.d.ts.map +1 -0
- package/out/typer/overload-helper.js +110 -0
- package/out/typer/overload-helper.js.map +1 -0
- package/out/typer/sem-diag.d.ts +6 -0
- package/out/typer/sem-diag.d.ts.map +1 -1
- package/out/typer/sem-diag.js +38 -17
- package/out/typer/sem-diag.js.map +1 -1
- package/out/typer/solver.d.ts +40 -26
- package/out/typer/solver.d.ts.map +1 -1
- package/out/typer/solver.js +217 -432
- package/out/typer/solver.js.map +1 -1
- package/out/typer/subster.d.ts +4 -6
- package/out/typer/subster.d.ts.map +1 -1
- package/out/typer/subster.js +76 -54
- package/out/typer/subster.js.map +1 -1
- package/out/typer/topo-sort.d.ts.map +1 -1
- package/out/typer/topo-sort.js +9 -2
- package/out/typer/topo-sort.js.map +1 -1
- package/out/typer/type-hint-manager/type-hint-manager.d.ts +5 -2
- package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
- package/out/typer/type-hint-manager/type-hint-manager.js +6 -4
- package/out/typer/type-hint-manager/type-hint-manager.js.map +1 -1
- package/out/typer/type-manager.d.ts +9 -3
- package/out/typer/type-manager.d.ts.map +1 -1
- package/out/typer/type-manager.js +64 -22
- package/out/typer/type-manager.js.map +1 -1
- package/out/typer/type-predicate.d.ts +17 -2
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +124 -36
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +50 -8
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +110 -78
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +0 -1
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +111 -85
- package/out/typer/unifier.js.map +1 -1
- package/out/utils/error-boundary.d.ts.map +1 -1
- package/out/utils/error-boundary.js +5 -11
- package/out/utils/error-boundary.js.map +1 -1
- package/out/utils/file-node-cache.d.ts +12 -0
- package/out/utils/file-node-cache.d.ts.map +1 -0
- package/out/utils/file-node-cache.js +30 -0
- package/out/utils/file-node-cache.js.map +1 -0
- package/out/utils/nasl-type-manipulation.d.ts +1 -0
- package/out/utils/nasl-type-manipulation.d.ts.map +1 -1
- package/out/utils/nasl-type-manipulation.js +3 -1
- package/out/utils/nasl-type-manipulation.js.map +1 -1
- package/out/utils/parseTsClassType.d.ts +4 -3
- package/out/utils/parseTsClassType.d.ts.map +1 -1
- package/out/utils/parseTsClassType.js +37 -61
- package/out/utils/parseTsClassType.js.map +1 -1
- package/out/utils/string.d.ts +4 -0
- package/out/utils/string.d.ts.map +1 -0
- package/out/utils/string.js +29 -0
- package/out/utils/string.js.map +1 -0
- package/out/utils/type-operator.d.ts +7 -7
- package/out/utils/type-operator.d.ts.map +1 -1
- package/out/utils/type-operator.js +72 -35
- package/out/utils/type-operator.js.map +1 -1
- package/package.json +18 -9
- package/out/utils/vue-hack.d.ts +0 -25
- package/out/utils/vue-hack.d.ts.map +0 -1
- package/out/utils/vue-hack.js +0 -33
- package/out/utils/vue-hack.js.map +0 -1
- package/out/utils/vue.d.ts +0 -2
- package/out/utils/vue.d.ts.map +0 -1
- package/out/utils/vue.js +0 -10
- package/out/utils/vue.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,3 +1,88 @@
|
|
|
1
1
|
# Nasl Language Server
|
|
2
2
|
|
|
3
3
|
Nasl 语言服务
|
|
4
|
+
|
|
5
|
+
## 描述
|
|
6
|
+
|
|
7
|
+
NetEase Application Specific Language (NASL) 语言服务器核心包,提供 NASL 语言的类型检查、语法分析和其他语言服务功能。
|
|
8
|
+
|
|
9
|
+
## 技术栈
|
|
10
|
+
|
|
11
|
+
### 核心技术
|
|
12
|
+
- **TypeScript 5.4.4** - 主要开发语言
|
|
13
|
+
- **Node.js 18+** - 运行环境
|
|
14
|
+
|
|
15
|
+
### 主要依赖
|
|
16
|
+
- **@lcap/nasl-concepts** - NASL 概念定义
|
|
17
|
+
- **@lcap/nasl-types** - NASL 类型系统
|
|
18
|
+
- **@lcap/nasl-utils** - NASL 工具库
|
|
19
|
+
- **decimal.js** - 精确数值计算
|
|
20
|
+
- **json5** - JSON5 格式支持
|
|
21
|
+
- **lodash** - 实用工具库
|
|
22
|
+
- **mnemonist** - 数据结构库
|
|
23
|
+
|
|
24
|
+
### 开发工具
|
|
25
|
+
- **Vitest 3.2.4** - 现代测试框架
|
|
26
|
+
- **Chai 4.3.7** - 断言库
|
|
27
|
+
- **Mocha** - 传统测试框架(通过 @lcap/nasl-test-toolkit)
|
|
28
|
+
|
|
29
|
+
## 开发
|
|
30
|
+
|
|
31
|
+
### 构建
|
|
32
|
+
```bash
|
|
33
|
+
# 清理输出目录
|
|
34
|
+
npm run clear
|
|
35
|
+
|
|
36
|
+
# 构建项目
|
|
37
|
+
npm run build
|
|
38
|
+
|
|
39
|
+
# 监听模式构建
|
|
40
|
+
npm run watch
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 测试
|
|
44
|
+
|
|
45
|
+
#### Vitest 测试(推荐)
|
|
46
|
+
```bash
|
|
47
|
+
# 运行所有 Vitest 测试
|
|
48
|
+
npm run test:vite
|
|
49
|
+
|
|
50
|
+
# 监听模式运行测试
|
|
51
|
+
npm run test:watch
|
|
52
|
+
|
|
53
|
+
# 启动测试 UI 界面
|
|
54
|
+
npm run test:ui
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Mocha 测试 (遗留)
|
|
58
|
+
|
|
59
|
+
注意:
|
|
60
|
+
- Mocha 测试框架已经废弃,对于新的单元测试的编写,请使用 Vitest 测试框架。
|
|
61
|
+
- Mocha 测试框架的测试用例,请迁移到 Vitest 测试框架。请参考 [TESTING_MIGRATION.md](./tests/TESTING_MIGRATION.md) 文件,让LLM自动化地完成迁移。
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# 运行标准 Mocha 测试套件
|
|
65
|
+
npm run test
|
|
66
|
+
|
|
67
|
+
# 运行应用测试
|
|
68
|
+
npm run test:apps
|
|
69
|
+
|
|
70
|
+
# 运行 CI 测试
|
|
71
|
+
npm run test:ci
|
|
72
|
+
|
|
73
|
+
# 更新测试快照
|
|
74
|
+
npm run test:update
|
|
75
|
+
|
|
76
|
+
# 运行性能测试
|
|
77
|
+
npm run test:perf
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 其他工具
|
|
81
|
+
```bash
|
|
82
|
+
# 压缩测试数据
|
|
83
|
+
npm run compress-test-data
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 许可证
|
|
87
|
+
|
|
88
|
+
MIT
|
package/out/checker.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SyntaxNode, App, BaseNode } from '@lcap/nasl-concepts';
|
|
2
2
|
import { TypeAnnotation } from '@lcap/nasl-concepts';
|
|
3
|
-
import { type SemEnv } from './typer';
|
|
3
|
+
import { type SemEnv } from './typer/typer';
|
|
4
4
|
import { Diagnostic as NaslTypeDiagnostic } from '@lcap/nasl-types';
|
|
5
5
|
export declare enum Severity {
|
|
6
6
|
WARN = "warning",
|
package/out/checker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAU0F,GAAG,EAMvG,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACgE,cAAc,EAGpF,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAU0F,GAAG,EAMvG,QAAQ,EACT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACgE,cAAc,EAGpF,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAK5C,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAMpE,oBAAY,QAAQ;IAClB,IAAI,YAAY;IAChB,KAAK,UAAU;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;AAEnE,KAAK,YAAY,GAAG;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC;AAMF,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAMrE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAqBF,KAAK,eAAe,GAAG;IACrB,GAAG,EAAE,GAAG,CAAC;IACT,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,yBAAyB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/C,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAC;AAiQF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCAsoIpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAuBb,UAAU;;kBA1oInB,UAAU,WAAW,MAAM,YAAY,YAAY;EA4pIzE;AAGD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACrC,mBAAmB,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IACvC,qBAAqB,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,6BAA6B,aAAc,UAAU,sCAAoC,MAAM,gBAAgB,CAmC3H,CAAA;AAMD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
|
package/out/checker.js
CHANGED
|
@@ -4,11 +4,13 @@ exports.transformDiagnosticsToRecords = exports.createErrorDiagnoser = exports.S
|
|
|
4
4
|
const decimal_js_1 = require("decimal.js");
|
|
5
5
|
const nasl_concepts_1 = require("@lcap/nasl-concepts");
|
|
6
6
|
const service_1 = require("@lcap/nasl-concepts/service");
|
|
7
|
+
const file_node_cache_1 = require("./utils/file-node-cache");
|
|
7
8
|
const nasl_utils_1 = require("@lcap/nasl-utils");
|
|
8
|
-
const
|
|
9
|
+
const sem_diag_1 = require("./typer/sem-diag");
|
|
9
10
|
const type_predicate_1 = require("./typer/type-predicate");
|
|
10
11
|
const type_manager_1 = require("./typer/type-manager");
|
|
11
12
|
const nasl_predicate_1 = require("./typer/nasl-predicate");
|
|
13
|
+
const helper_1 = require("./typer/helper");
|
|
12
14
|
var Severity;
|
|
13
15
|
(function (Severity) {
|
|
14
16
|
Severity["WARN"] = "warning";
|
|
@@ -91,7 +93,7 @@ function getExpressionNodeName(concept) {
|
|
|
91
93
|
function isDescendant(node, rangeNode) {
|
|
92
94
|
let currentNode = node;
|
|
93
95
|
while (currentNode) {
|
|
94
|
-
if (currentNode === rangeNode) {
|
|
96
|
+
if (toRaw(currentNode) === toRaw(rangeNode)) {
|
|
95
97
|
return true;
|
|
96
98
|
}
|
|
97
99
|
currentNode = currentNode.parentNode;
|
|
@@ -332,11 +334,20 @@ function createErrorDiagnoser(context) {
|
|
|
332
334
|
currentNode = currentNode.parentNode;
|
|
333
335
|
}
|
|
334
336
|
const finalNode = memberExpression ?? node;
|
|
335
|
-
(0,
|
|
337
|
+
(0, helper_1.createOnPush)(diagnostics, finalNode, diagnostic);
|
|
336
338
|
finalNode.tsErrorDetail = diagnostic;
|
|
337
339
|
}
|
|
338
340
|
else { }
|
|
339
341
|
}
|
|
342
|
+
function scopedError(node, message, context) {
|
|
343
|
+
const scope = node?.constructor?.nodeTitle;
|
|
344
|
+
if (scope) {
|
|
345
|
+
error(node, `${scope}:${message}`, context);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
error(node, message, context);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
340
351
|
/**
|
|
341
352
|
* 获取当前错误信息
|
|
342
353
|
* @param node
|
|
@@ -671,7 +682,7 @@ function createErrorDiagnoser(context) {
|
|
|
671
682
|
// 允许在当前业务组件中访问
|
|
672
683
|
businessComponent,
|
|
673
684
|
],
|
|
674
|
-
errMsg:
|
|
685
|
+
errMsg: `"${node.name}"是私有的,只能在"${businessComponent.name}"中访问。`,
|
|
675
686
|
} : null;
|
|
676
687
|
case 'ConfigProperty':
|
|
677
688
|
return node.isPrivate ? {
|
|
@@ -690,7 +701,7 @@ function createErrorDiagnoser(context) {
|
|
|
690
701
|
* @returns
|
|
691
702
|
*/
|
|
692
703
|
function isNonRequiredParam(param) {
|
|
693
|
-
return param?.defaultValue?.expression || param?.defaultExpression || param?.optional ||
|
|
704
|
+
return param?.defaultValue?.expression || param?.defaultExpression || param?.optional || (nasl_concepts_1.asserts.isInterfaceParam(param) && !param.required);
|
|
694
705
|
}
|
|
695
706
|
/**
|
|
696
707
|
* 确定函数签名中所需的最小参数数量
|
|
@@ -700,6 +711,9 @@ function createErrorDiagnoser(context) {
|
|
|
700
711
|
let minArgsCount = 0;
|
|
701
712
|
for (let i = 0; i < paramLen; i++) {
|
|
702
713
|
const param = params[i];
|
|
714
|
+
if (param?.spread) {
|
|
715
|
+
continue;
|
|
716
|
+
}
|
|
703
717
|
if (!isNonRequiredParam(param)) {
|
|
704
718
|
minArgsCount++; // 如果参数有默认值,则跳过
|
|
705
719
|
}
|
|
@@ -802,7 +816,7 @@ function createErrorDiagnoser(context) {
|
|
|
802
816
|
/**
|
|
803
817
|
* 检查 调用表达式的参数
|
|
804
818
|
* @param node
|
|
805
|
-
* @param
|
|
819
|
+
*( @param r) as anyef
|
|
806
820
|
*/
|
|
807
821
|
function* checkCallExpressionParameters(node, ref) {
|
|
808
822
|
// Handle both TypeAnnotation and FunctionDefinition formats
|
|
@@ -822,13 +836,17 @@ function createErrorDiagnoser(context) {
|
|
|
822
836
|
}
|
|
823
837
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(args, function* (arg, index) {
|
|
824
838
|
const param = params?.[index];
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
const isParamRequired = !(hasSpreadParam && index > spreadParamIndex) && !isNonRequiredParam(param);
|
|
839
|
+
// 若 param 的定义不存在,则默认是必填的。
|
|
840
|
+
const isParamRequired = param ? !isNonRequiredParam(param) : true;
|
|
828
841
|
arg.paramRequired = isParamRequired;
|
|
842
|
+
// 即便是 param 的定义不存在,也需要检查 arg。这样可以检查出 arg 是否引用了一些未定义的变量
|
|
843
|
+
const argType = yield* checkNode(arg);
|
|
844
|
+
if (!param) {
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
829
847
|
const paramType = param.typeAnnotation ??
|
|
830
848
|
(nasl_concepts_1.asserts.isTypeAnnotation(param) ? param : env.getType(param));
|
|
831
|
-
|
|
849
|
+
// 检查高阶函数参数个数是否匹配
|
|
832
850
|
if (paramType?.typeKind === 'function' && argType?.typeKind === 'function') {
|
|
833
851
|
const argTypeArgs = argType?.typeArguments || [];
|
|
834
852
|
const paramTypeArgs = paramType?.typeArguments || [];
|
|
@@ -926,12 +944,11 @@ function createErrorDiagnoser(context) {
|
|
|
926
944
|
const type = yield* checkNode(node);
|
|
927
945
|
if (isUnresolvedType(type)) {
|
|
928
946
|
const scope = node?.constructor?.nodeTitle;
|
|
929
|
-
if (node.concept === 'Identifier') {
|
|
930
|
-
|
|
931
|
-
}
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
}
|
|
947
|
+
// if (node.concept === 'Identifier') {
|
|
948
|
+
// error(node, `${scope}:${node.name} 未定义。`);
|
|
949
|
+
// } else {
|
|
950
|
+
error(node, `${scope}:所选择的内容未定义。`);
|
|
951
|
+
// }
|
|
935
952
|
return errorType;
|
|
936
953
|
}
|
|
937
954
|
return type;
|
|
@@ -1094,8 +1111,8 @@ function createErrorDiagnoser(context) {
|
|
|
1094
1111
|
const status = getStatusOfSharedApp(node);
|
|
1095
1112
|
if (status) {
|
|
1096
1113
|
const msgMap = {
|
|
1097
|
-
update: `共享数据 ${node.name}
|
|
1098
|
-
delete: `共享数据 ${node.name}
|
|
1114
|
+
update: `共享数据 ${node.name} 已在"${node.provider}应用"中更新,请同步更新`,
|
|
1115
|
+
delete: `共享数据 ${node.name} 已在"${node.provider}应用"中被删除,请同步删除`,
|
|
1099
1116
|
};
|
|
1100
1117
|
error(node, msgMap[status], {
|
|
1101
1118
|
severity: Severity.WARN,
|
|
@@ -1219,13 +1236,14 @@ function createErrorDiagnoser(context) {
|
|
|
1219
1236
|
}
|
|
1220
1237
|
}
|
|
1221
1238
|
/**
|
|
1222
|
-
*
|
|
1239
|
+
* 检查【局部】变量
|
|
1223
1240
|
* @param node
|
|
1224
1241
|
*/
|
|
1225
1242
|
function* checkVariable(node) {
|
|
1226
1243
|
yield* checkNode(node.defaultValue);
|
|
1227
1244
|
// 前面加了报错,省点时间,报错不用那么精确
|
|
1228
1245
|
// yield* checkVariableType(node);
|
|
1246
|
+
yield* checkNode(node.typeAnnotation);
|
|
1229
1247
|
}
|
|
1230
1248
|
/**
|
|
1231
1249
|
* 检查 前端全局变量
|
|
@@ -1720,6 +1738,7 @@ function createErrorDiagnoser(context) {
|
|
|
1720
1738
|
yield* checkNode(node.defaultValue);
|
|
1721
1739
|
// 前面加了报错,省点时间,报错不用那么精确
|
|
1722
1740
|
// yield* checkVariableType(node);
|
|
1741
|
+
yield* checkNode(node.typeAnnotation);
|
|
1723
1742
|
}
|
|
1724
1743
|
/**
|
|
1725
1744
|
* 检查 接口
|
|
@@ -1866,6 +1885,7 @@ function createErrorDiagnoser(context) {
|
|
|
1866
1885
|
...(node.variables || []),
|
|
1867
1886
|
...(node.logics || []),
|
|
1868
1887
|
]);
|
|
1888
|
+
checkVariableAndReturnTypeAnnotations(node.variables, [], false);
|
|
1869
1889
|
const module = node.getAncestor('Module');
|
|
1870
1890
|
if (!(module?.parentKey === 'dependencies')) {
|
|
1871
1891
|
if (node.params?.length) {
|
|
@@ -1996,6 +2016,21 @@ function createErrorDiagnoser(context) {
|
|
|
1996
2016
|
if (node._foldInView) {
|
|
1997
2017
|
error(node, `组件${node.name}已经极速折叠`);
|
|
1998
2018
|
}
|
|
2019
|
+
// 已知:选择器会漏报,因为 children 里是两个空 template。暂时先这样吧。
|
|
2020
|
+
let dsFilled = true;
|
|
2021
|
+
let errNode = node;
|
|
2022
|
+
const ds = node.bindAttrs.find(nd => nd.name === 'dataSource');
|
|
2023
|
+
if (ds) {
|
|
2024
|
+
if (ds.type === 'dynamic' && !ds.expression) {
|
|
2025
|
+
dsFilled = false;
|
|
2026
|
+
errNode = ds;
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
const hasSubComponents = node.children.filter(c => c.tag !== 'template').length > 0 ||
|
|
2030
|
+
node.children.filter(c => c.tag === 'template').some(cc => cc.children.length > 0);
|
|
2031
|
+
if (!dsFilled && !hasSubComponents) {
|
|
2032
|
+
error(errNode, '数据源不能为空');
|
|
2033
|
+
}
|
|
1999
2034
|
unbindVariables?.();
|
|
2000
2035
|
}
|
|
2001
2036
|
/**
|
|
@@ -2256,7 +2291,8 @@ function createErrorDiagnoser(context) {
|
|
|
2256
2291
|
yield* checkNode(node.bind);
|
|
2257
2292
|
if (node.processDefinitions?.length) {
|
|
2258
2293
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.processDefinitions, function* (node) {
|
|
2259
|
-
|
|
2294
|
+
// 现有流程版本 [v1, v2],加个 v3 后,变成了 [proxy(v1), proxy(v2), v3],无法理解
|
|
2295
|
+
yield* checkNode(toRaw(node));
|
|
2260
2296
|
});
|
|
2261
2297
|
}
|
|
2262
2298
|
if (node?.subLogics?.length) {
|
|
@@ -2432,7 +2468,7 @@ function createErrorDiagnoser(context) {
|
|
|
2432
2468
|
const prop = getPropertyOfType(type, propertyName);
|
|
2433
2469
|
if (!prop) {
|
|
2434
2470
|
const scope = item?.constructor?.nodeTitle;
|
|
2435
|
-
error(item, `${scope}:找不到 ${type
|
|
2471
|
+
error(item, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${propertyName}。`);
|
|
2436
2472
|
}
|
|
2437
2473
|
type = env.getType(prop);
|
|
2438
2474
|
if (type?.typeKind === 'generic' && type.typeName === 'List') {
|
|
@@ -2460,6 +2496,10 @@ function createErrorDiagnoser(context) {
|
|
|
2460
2496
|
...(node.variables || []),
|
|
2461
2497
|
...(node.virtualParams || [])
|
|
2462
2498
|
]);
|
|
2499
|
+
// 仅检查用户写的逻辑
|
|
2500
|
+
// if (node.nodePath?.startsWith('app.logics')) {
|
|
2501
|
+
checkVariableAndReturnTypeAnnotations(node.variables ?? [], node.returns ?? []);
|
|
2502
|
+
// }
|
|
2463
2503
|
const module = node.getAncestor('Module');
|
|
2464
2504
|
if (!(module?.parentKey === 'dependencies')) {
|
|
2465
2505
|
if (node.params?.length) {
|
|
@@ -2640,6 +2680,9 @@ function createErrorDiagnoser(context) {
|
|
|
2640
2680
|
...(node.returns || []),
|
|
2641
2681
|
...(node.variables || []),
|
|
2642
2682
|
]);
|
|
2683
|
+
// if (nd.nodePath?.startsWith('app.logics')) {
|
|
2684
|
+
checkVariableAndReturnTypeAnnotations(node.variables, node.returns);
|
|
2685
|
+
// }
|
|
2643
2686
|
const module = node.getAncestor('Module');
|
|
2644
2687
|
if (!(module?.parentKey === 'dependencies')) {
|
|
2645
2688
|
if (node.params?.length) {
|
|
@@ -2730,22 +2773,27 @@ function createErrorDiagnoser(context) {
|
|
|
2730
2773
|
return;
|
|
2731
2774
|
}
|
|
2732
2775
|
yield* checkVoidCallUsedAsStatement(node);
|
|
2733
|
-
const ref = env.
|
|
2734
|
-
//
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
}
|
|
2745
|
-
else {
|
|
2746
|
-
error(node, `找不到${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2776
|
+
const ref = env.resolveRef(node); // 前端
|
|
2777
|
+
// TODO: sql 函数的 namespace 带有数据库名 nasl.sqlFunction.mysql nasl.sqlFunction.oracle ...
|
|
2778
|
+
// 暂时不在 qNameDefs 里,用 isBuiltInCall 简单判断了
|
|
2779
|
+
if (!ref && !isBuiltInCall(node)) {
|
|
2780
|
+
const depLibName = getExtensionLibName(node);
|
|
2781
|
+
if (depLibName) {
|
|
2782
|
+
error(node, `找不到依赖库 ${depLibName} 上的 ${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2783
|
+
}
|
|
2784
|
+
else {
|
|
2785
|
+
error(node, `找不到${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2786
|
+
}
|
|
2747
2787
|
return errorType;
|
|
2748
2788
|
}
|
|
2789
|
+
/**
|
|
2790
|
+
* 目前的 callInfo:所有内置函数 + 服务端调用。前端因为有组件库调用,还没统一
|
|
2791
|
+
* 排除未求解出类型变元等引发的报错,这些不应该报 '找不到'
|
|
2792
|
+
*/
|
|
2793
|
+
// FIXME: wudengke 帮帮忙,行行好
|
|
2794
|
+
const callInfo = env.resolvedCallInfo.get(node);
|
|
2795
|
+
yield* checkScopeOfUse(node, (callInfo ?? ref));
|
|
2796
|
+
yield* checkCallExpressionParameters(node, (callInfo ?? ref));
|
|
2749
2797
|
switch (node.concept) {
|
|
2750
2798
|
case 'CallFunction':
|
|
2751
2799
|
return yield* checkCallFunction(node);
|
|
@@ -2769,6 +2817,9 @@ function createErrorDiagnoser(context) {
|
|
|
2769
2817
|
if (node.calleeName === 'Clear' && type?.typeKind === 'union') {
|
|
2770
2818
|
error(node, `传入类型错误,接收类型:非union类型`);
|
|
2771
2819
|
}
|
|
2820
|
+
if (node.calleeName === 'ListSort' || node.calleeName === 'ListSortAsync') {
|
|
2821
|
+
checkListSort(node);
|
|
2822
|
+
}
|
|
2772
2823
|
if (node.typeArguments?.length) {
|
|
2773
2824
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.typeArguments, function* (node) {
|
|
2774
2825
|
yield* checkNode(node);
|
|
@@ -2812,6 +2863,23 @@ function createErrorDiagnoser(context) {
|
|
|
2812
2863
|
}
|
|
2813
2864
|
}
|
|
2814
2865
|
return type;
|
|
2866
|
+
function checkListSort(nd) {
|
|
2867
|
+
for (let i = 1; i < nd.arguments.length; i++) {
|
|
2868
|
+
const expr = nd.arguments[i].expression;
|
|
2869
|
+
let resTy;
|
|
2870
|
+
if (expr?.concept === 'AnonymousFunction') {
|
|
2871
|
+
resTy = env.getType(expr.body);
|
|
2872
|
+
}
|
|
2873
|
+
else if (expr?.concept === 'SubLogic') {
|
|
2874
|
+
resTy = env.getType(expr.returns?.[0]);
|
|
2875
|
+
}
|
|
2876
|
+
const byTy = resTy?.properties?.find((prop) => prop.name === 'by')?.typeAnnotation;
|
|
2877
|
+
if (byTy?.typeKind === 'union') {
|
|
2878
|
+
// 这里使用 node.arguments[i] 则无红框,猜测是 ListSort 的特殊交互导致的问题
|
|
2879
|
+
error(node, (0, sem_diag_1.mkIncompatibleTyErr)(env, byTy, '非 union 的基础类型:如字符串、整数、布尔等'));
|
|
2880
|
+
}
|
|
2881
|
+
}
|
|
2882
|
+
}
|
|
2815
2883
|
}
|
|
2816
2884
|
/**
|
|
2817
2885
|
* 检查 调用逻辑
|
|
@@ -3118,18 +3186,29 @@ function createErrorDiagnoser(context) {
|
|
|
3118
3186
|
}
|
|
3119
3187
|
});
|
|
3120
3188
|
}
|
|
3189
|
+
else if (!isOtherCase(node)) {
|
|
3190
|
+
// pattern 为空时,如果不是其他就报错
|
|
3191
|
+
error(node, '匹配分支:匹配模式不能为空', {
|
|
3192
|
+
titleTip: '匹配模式不能为空',
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
3121
3195
|
if (node.body?.length) {
|
|
3122
3196
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.body, function* (node) {
|
|
3123
3197
|
yield* checkNode(node);
|
|
3124
3198
|
});
|
|
3125
3199
|
}
|
|
3126
|
-
if (match?.isExpression && node.body.length === 0) {
|
|
3127
|
-
//
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3200
|
+
if (match?.isExpression && node.body.length === 0 && !isOtherCase(node)) {
|
|
3201
|
+
// 如果不是其他就报错
|
|
3202
|
+
error(node, '匹配分支:返回内容不能为空', {
|
|
3203
|
+
titleTip: '返回内容不能为空',
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
3206
|
+
function isOtherCase(node) {
|
|
3207
|
+
const indexInParent = node.getIndexOfParent();
|
|
3208
|
+
if (indexInParent === -1) {
|
|
3209
|
+
return false;
|
|
3132
3210
|
}
|
|
3211
|
+
return indexInParent === match.cases.length - 1;
|
|
3133
3212
|
}
|
|
3134
3213
|
}
|
|
3135
3214
|
/**
|
|
@@ -3219,21 +3298,13 @@ function createErrorDiagnoser(context) {
|
|
|
3219
3298
|
/**
|
|
3220
3299
|
* 参考类型检查器的 {@link tpIdentifier}方法
|
|
3221
3300
|
*/
|
|
3222
|
-
return
|
|
3301
|
+
return type_manager_1.naslLongTy;
|
|
3223
3302
|
}
|
|
3224
3303
|
else if (node.name === 'it') {
|
|
3225
3304
|
return env.getType(node);
|
|
3226
3305
|
}
|
|
3227
3306
|
else {
|
|
3228
3307
|
const { name } = node;
|
|
3229
|
-
// 之前有一些脏数据,先兼容
|
|
3230
|
-
// if (['true', 'false'].includes(name)) {
|
|
3231
|
-
// return new TypeAnnotation({
|
|
3232
|
-
// typeKind: 'primitive',
|
|
3233
|
-
// typeName: 'Boolean',
|
|
3234
|
-
// typeNamespace: 'nasl.core',
|
|
3235
|
-
// });
|
|
3236
|
-
// }
|
|
3237
3308
|
if (
|
|
3238
3309
|
// name 是 A.B.C
|
|
3239
3310
|
name?.split('.')?.length > 1
|
|
@@ -3248,6 +3319,13 @@ function createErrorDiagnoser(context) {
|
|
|
3248
3319
|
return errorType;
|
|
3249
3320
|
}
|
|
3250
3321
|
}
|
|
3322
|
+
if (node.namespace === 'app.enums' &&
|
|
3323
|
+
node.parentNode?.concept !== 'MemberExpression' &&
|
|
3324
|
+
node.parentNode?.concept !== 'SelectMembers') {
|
|
3325
|
+
// 判断枚举类是否直接被使用
|
|
3326
|
+
scopedError(node, `${node.toNaturalTS()} 枚举类不能直接使用,请取它的枚举项`);
|
|
3327
|
+
return errorType;
|
|
3328
|
+
}
|
|
3251
3329
|
// 检查使用范围
|
|
3252
3330
|
yield* checkScopeOfUse(node, ref);
|
|
3253
3331
|
return env.getType(node);
|
|
@@ -3276,7 +3354,7 @@ function createErrorDiagnoser(context) {
|
|
|
3276
3354
|
}
|
|
3277
3355
|
else {
|
|
3278
3356
|
const scope = node?.constructor?.nodeTitle;
|
|
3279
|
-
error(node, `${scope}:找不到 ${type
|
|
3357
|
+
error(node, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${nodeProperty?.name}。`);
|
|
3280
3358
|
return errorType;
|
|
3281
3359
|
}
|
|
3282
3360
|
return env.getType(node);
|
|
@@ -3428,7 +3506,7 @@ function createErrorDiagnoser(context) {
|
|
|
3428
3506
|
}
|
|
3429
3507
|
else {
|
|
3430
3508
|
const scope = property?.constructor?.nodeTitle;
|
|
3431
|
-
error(property, `${scope}:找不到 ${type
|
|
3509
|
+
error(property, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${propertyName}。`);
|
|
3432
3510
|
}
|
|
3433
3511
|
});
|
|
3434
3512
|
}
|
|
@@ -3481,7 +3559,7 @@ function createErrorDiagnoser(context) {
|
|
|
3481
3559
|
if (ensureNodeKeyExists(node, 'members')) {
|
|
3482
3560
|
if (node.members?.length) {
|
|
3483
3561
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.members, function* (node) {
|
|
3484
|
-
yield* checkNode(node);
|
|
3562
|
+
yield* checkNode(toRaw(node));
|
|
3485
3563
|
});
|
|
3486
3564
|
}
|
|
3487
3565
|
}
|
|
@@ -3776,6 +3854,18 @@ function createErrorDiagnoser(context) {
|
|
|
3776
3854
|
}
|
|
3777
3855
|
return env.getType(node);
|
|
3778
3856
|
}
|
|
3857
|
+
function* checkVariadicExpression(node) {
|
|
3858
|
+
if (!node.expressions?.[0]) {
|
|
3859
|
+
error(node, '表达式不能为空!');
|
|
3860
|
+
}
|
|
3861
|
+
if (!node.expressions?.[1]) {
|
|
3862
|
+
error(node, '表达式不能为空!');
|
|
3863
|
+
}
|
|
3864
|
+
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.expressions, function* (node) {
|
|
3865
|
+
yield* checkNode(node);
|
|
3866
|
+
});
|
|
3867
|
+
return env.getType(node);
|
|
3868
|
+
}
|
|
3779
3869
|
/**
|
|
3780
3870
|
* 检查 一元表达式
|
|
3781
3871
|
* @param node
|
|
@@ -3883,7 +3973,7 @@ function createErrorDiagnoser(context) {
|
|
|
3883
3973
|
}
|
|
3884
3974
|
// 元数据
|
|
3885
3975
|
if (!metadataTypeEnable && node.typeNamespace?.endsWith('.metadataTypes')) {
|
|
3886
|
-
error(node, '
|
|
3976
|
+
error(node, '未启用元数据功能,请在"偏好设置"中启用元数据。');
|
|
3887
3977
|
}
|
|
3888
3978
|
if (node.typeArguments?.length) {
|
|
3889
3979
|
// 有同名的
|
|
@@ -4165,6 +4255,8 @@ function createErrorDiagnoser(context) {
|
|
|
4165
4255
|
return yield* checkPaginate(node);
|
|
4166
4256
|
case 'BinaryExpression':
|
|
4167
4257
|
return yield* checkBinaryExpression(node);
|
|
4258
|
+
case 'VariadicExpression':
|
|
4259
|
+
return yield* checkVariadicExpression(node);
|
|
4168
4260
|
case 'UnaryExpression':
|
|
4169
4261
|
return yield* checkUnaryExpression(node);
|
|
4170
4262
|
case 'Comment':
|
|
@@ -4201,8 +4293,8 @@ function createErrorDiagnoser(context) {
|
|
|
4201
4293
|
* @returns 清理函数
|
|
4202
4294
|
*/
|
|
4203
4295
|
function handleFileNode(node) {
|
|
4204
|
-
// TODO:
|
|
4205
|
-
const isFileModule = fileNodes.length ? (0,
|
|
4296
|
+
// TODO: checkNodeIsFileModuleInIdeWithCache 也慢,后续可以优化
|
|
4297
|
+
const isFileModule = fileNodes.length ? (0, file_node_cache_1.checkNodeIsFileModuleInIdeWithCache)(node) : true;
|
|
4206
4298
|
if (isFileModule) {
|
|
4207
4299
|
fileNodes.push(node);
|
|
4208
4300
|
let diagnostics = diagnosticMap.get(node);
|
|
@@ -4244,6 +4336,26 @@ function createErrorDiagnoser(context) {
|
|
|
4244
4336
|
function setMetadataTypeEnable(enable) {
|
|
4245
4337
|
metadataTypeEnable = enable;
|
|
4246
4338
|
}
|
|
4339
|
+
const checkVariableAndReturnTypeAnnotations = (variables, returns, inLogic = true) => {
|
|
4340
|
+
for (const v of variables) {
|
|
4341
|
+
if (v.typeAnnotation)
|
|
4342
|
+
continue;
|
|
4343
|
+
const tyAnn = v.__TypeAnnotation;
|
|
4344
|
+
if (!(0, type_predicate_1.isResolvedUserTy)(tyAnn)) {
|
|
4345
|
+
error(v, `局部变量 ${v.name} 未设置类型,在非草稿区正常使用可自动推断类型`);
|
|
4346
|
+
v.__TypeAnnotation = undefined;
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
for (const r of returns) {
|
|
4350
|
+
if (r.typeAnnotation)
|
|
4351
|
+
continue;
|
|
4352
|
+
const tyAnn = r.__TypeAnnotation;
|
|
4353
|
+
if (!(0, type_predicate_1.isResolvedUserTy)(tyAnn)) {
|
|
4354
|
+
error(r, `输出参数 ${r.name} 未设置类型,在非草稿区正常使用可自动推断类型`);
|
|
4355
|
+
r.__TypeAnnotation = undefined;
|
|
4356
|
+
}
|
|
4357
|
+
}
|
|
4358
|
+
};
|
|
4247
4359
|
/**
|
|
4248
4360
|
* 诊断App
|
|
4249
4361
|
* @param app
|
|
@@ -4335,4 +4447,8 @@ const transformDiagnosticsToRecords = (fileNode, diagnostics) => {
|
|
|
4335
4447
|
exports.transformDiagnosticsToRecords = transformDiagnosticsToRecords;
|
|
4336
4448
|
// @ts-expect-error
|
|
4337
4449
|
const toRaw = (nd) => nd.__v_raw ?? nd;
|
|
4450
|
+
// 是否来自系统内置
|
|
4451
|
+
const isBuiltInCall = (nd) => nd.calleeNamespace.startsWith('nasl.');
|
|
4452
|
+
// 是否来自依赖库
|
|
4453
|
+
const getExtensionLibName = (nd) => nd.calleeNamespace.startsWith('extensions.') ? nd.calleeNamespace.split('.')[1] : undefined;
|
|
4338
4454
|
//# sourceMappingURL=checker.js.map
|