@lcap/nasl-language-server-core 4.0.0-beta.9 → 4.0.0-creator.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 +85 -0
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +121 -49
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +4 -2
- package/out/index.d.ts.map +1 -1
- package/out/index.js +7 -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 +22 -11
- 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 +32 -49
- package/out/reference-manager/get-q-name.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +17 -13
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +232 -130
- 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 +61 -46
- 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 +6 -3
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +16 -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 +14 -5
- 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/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 +42 -11
- package/out/typer/component-def-manager/component-def-manager.d.ts.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.js +114 -26
- 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 +44 -15
- package/out/typer/component-def-manager/utils.js.map +1 -1
- package/out/typer/dispatch-all.d.ts +1 -1
- package/out/typer/dispatch-all.d.ts.map +1 -1
- package/out/typer/dispatch-all.js +3 -7
- 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 +22 -48
- 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 +273 -212
- 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 +22 -14
- 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.map +1 -1
- package/out/typer/dispatch-view.js +236 -148
- 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 +204 -241
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/index.d.ts +4 -5
- package/out/typer/index.d.ts.map +1 -1
- package/out/typer/index.js +4 -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 -49
- 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 +4 -1
- package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
- package/out/typer/type-hint-manager/type-hint-manager.js +2 -0
- package/out/typer/type-hint-manager/type-hint-manager.js.map +1 -1
- package/out/typer/type-manager.d.ts +9 -4
- package/out/typer/type-manager.d.ts.map +1 -1
- package/out/typer/type-manager.js +32 -22
- package/out/typer/type-manager.js.map +1 -1
- package/out/typer/type-predicate.d.ts +15 -2
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +119 -32
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +39 -8
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +93 -80
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +0 -3
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +96 -62
- package/out/typer/unifier.js.map +1 -1
- 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 +3 -3
- package/out/utils/type-operator.d.ts.map +1 -1
- package/out/utils/type-operator.js +34 -17
- package/out/utils/type-operator.js.map +1 -1
- package/package.json +16 -7
- 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.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;AAS7B,OAAO,EAA4B,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAIhE,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,kBAAkB,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,EAA4B,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAIhE,OAAO,EAAE,UAAU,IAAI,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAIpE,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;oCAmmIpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAuBb,UAAU;;kBAvmInB,UAAU,WAAW,MAAM,YAAY,YAAY;EAynIzE;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
|
@@ -338,6 +338,15 @@ function createErrorDiagnoser(context) {
|
|
|
338
338
|
}
|
|
339
339
|
else { }
|
|
340
340
|
}
|
|
341
|
+
function scopedError(node, message, context) {
|
|
342
|
+
const scope = node?.constructor?.nodeTitle;
|
|
343
|
+
if (scope) {
|
|
344
|
+
error(node, `${scope}:${message}`, context);
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
error(node, message, context);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
341
350
|
/**
|
|
342
351
|
* 获取当前错误信息
|
|
343
352
|
* @param node
|
|
@@ -691,7 +700,7 @@ function createErrorDiagnoser(context) {
|
|
|
691
700
|
* @returns
|
|
692
701
|
*/
|
|
693
702
|
function isNonRequiredParam(param) {
|
|
694
|
-
return param?.defaultValue?.expression || param?.defaultExpression || param?.optional ||
|
|
703
|
+
return param?.defaultValue?.expression || param?.defaultExpression || param?.optional || (nasl_concepts_1.asserts.isInterfaceParam(param) && !param.required);
|
|
695
704
|
}
|
|
696
705
|
/**
|
|
697
706
|
* 确定函数签名中所需的最小参数数量
|
|
@@ -701,6 +710,9 @@ function createErrorDiagnoser(context) {
|
|
|
701
710
|
let minArgsCount = 0;
|
|
702
711
|
for (let i = 0; i < paramLen; i++) {
|
|
703
712
|
const param = params[i];
|
|
713
|
+
if (param?.spread) {
|
|
714
|
+
continue;
|
|
715
|
+
}
|
|
704
716
|
if (!isNonRequiredParam(param)) {
|
|
705
717
|
minArgsCount++; // 如果参数有默认值,则跳过
|
|
706
718
|
}
|
|
@@ -803,7 +815,7 @@ function createErrorDiagnoser(context) {
|
|
|
803
815
|
/**
|
|
804
816
|
* 检查 调用表达式的参数
|
|
805
817
|
* @param node
|
|
806
|
-
* @param
|
|
818
|
+
*( @param r) as anyef
|
|
807
819
|
*/
|
|
808
820
|
function* checkCallExpressionParameters(node, ref) {
|
|
809
821
|
// Handle both TypeAnnotation and FunctionDefinition formats
|
|
@@ -823,13 +835,17 @@ function createErrorDiagnoser(context) {
|
|
|
823
835
|
}
|
|
824
836
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(args, function* (arg, index) {
|
|
825
837
|
const param = params?.[index];
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const isParamRequired = !(hasSpreadParam && index > spreadParamIndex) && !isNonRequiredParam(param);
|
|
838
|
+
// 若 param 的定义不存在,则默认是必填的。
|
|
839
|
+
const isParamRequired = param ? !isNonRequiredParam(param) : true;
|
|
829
840
|
arg.paramRequired = isParamRequired;
|
|
841
|
+
// 即便是 param 的定义不存在,也需要检查 arg。这样可以检查出 arg 是否引用了一些未定义的变量
|
|
842
|
+
const argType = yield* checkNode(arg);
|
|
843
|
+
if (!param) {
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
830
846
|
const paramType = param.typeAnnotation ??
|
|
831
847
|
(nasl_concepts_1.asserts.isTypeAnnotation(param) ? param : env.getType(param));
|
|
832
|
-
|
|
848
|
+
// 检查高阶函数参数个数是否匹配
|
|
833
849
|
if (paramType?.typeKind === 'function' && argType?.typeKind === 'function') {
|
|
834
850
|
const argTypeArgs = argType?.typeArguments || [];
|
|
835
851
|
const paramTypeArgs = paramType?.typeArguments || [];
|
|
@@ -927,12 +943,11 @@ function createErrorDiagnoser(context) {
|
|
|
927
943
|
const type = yield* checkNode(node);
|
|
928
944
|
if (isUnresolvedType(type)) {
|
|
929
945
|
const scope = node?.constructor?.nodeTitle;
|
|
930
|
-
if (node.concept === 'Identifier') {
|
|
931
|
-
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
}
|
|
946
|
+
// if (node.concept === 'Identifier') {
|
|
947
|
+
// error(node, `${scope}:${node.name} 未定义。`);
|
|
948
|
+
// } else {
|
|
949
|
+
error(node, `${scope}:所选择的内容未定义。`);
|
|
950
|
+
// }
|
|
936
951
|
return errorType;
|
|
937
952
|
}
|
|
938
953
|
return type;
|
|
@@ -1220,13 +1235,14 @@ function createErrorDiagnoser(context) {
|
|
|
1220
1235
|
}
|
|
1221
1236
|
}
|
|
1222
1237
|
/**
|
|
1223
|
-
*
|
|
1238
|
+
* 检查【局部】变量
|
|
1224
1239
|
* @param node
|
|
1225
1240
|
*/
|
|
1226
1241
|
function* checkVariable(node) {
|
|
1227
1242
|
yield* checkNode(node.defaultValue);
|
|
1228
1243
|
// 前面加了报错,省点时间,报错不用那么精确
|
|
1229
1244
|
// yield* checkVariableType(node);
|
|
1245
|
+
yield* checkNode(node.typeAnnotation);
|
|
1230
1246
|
}
|
|
1231
1247
|
/**
|
|
1232
1248
|
* 检查 前端全局变量
|
|
@@ -1721,6 +1737,7 @@ function createErrorDiagnoser(context) {
|
|
|
1721
1737
|
yield* checkNode(node.defaultValue);
|
|
1722
1738
|
// 前面加了报错,省点时间,报错不用那么精确
|
|
1723
1739
|
// yield* checkVariableType(node);
|
|
1740
|
+
yield* checkNode(node.typeAnnotation);
|
|
1724
1741
|
}
|
|
1725
1742
|
/**
|
|
1726
1743
|
* 检查 接口
|
|
@@ -1867,6 +1884,7 @@ function createErrorDiagnoser(context) {
|
|
|
1867
1884
|
...(node.variables || []),
|
|
1868
1885
|
...(node.logics || []),
|
|
1869
1886
|
]);
|
|
1887
|
+
checkVariableAndReturnTypeAnnotations(node.variables, [], false);
|
|
1870
1888
|
const module = node.getAncestor('Module');
|
|
1871
1889
|
if (!(module?.parentKey === 'dependencies')) {
|
|
1872
1890
|
if (node.params?.length) {
|
|
@@ -1997,6 +2015,21 @@ function createErrorDiagnoser(context) {
|
|
|
1997
2015
|
if (node._foldInView) {
|
|
1998
2016
|
error(node, `组件${node.name}已经极速折叠`);
|
|
1999
2017
|
}
|
|
2018
|
+
// 已知:选择器会漏报,因为 children 里是两个空 template。暂时先这样吧。
|
|
2019
|
+
let dsFilled = true;
|
|
2020
|
+
let errNode = node;
|
|
2021
|
+
const ds = node.bindAttrs.find(nd => nd.name === 'dataSource');
|
|
2022
|
+
if (ds) {
|
|
2023
|
+
if (ds.type === 'dynamic' && !ds.expression) {
|
|
2024
|
+
dsFilled = false;
|
|
2025
|
+
errNode = ds;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2028
|
+
const hasSubComponents = node.children.filter(c => c.tag !== 'template').length > 0 ||
|
|
2029
|
+
node.children.filter(c => c.tag === 'template').some(cc => cc.children.length > 0);
|
|
2030
|
+
if (!dsFilled && !hasSubComponents) {
|
|
2031
|
+
error(errNode, '数据源不能为空');
|
|
2032
|
+
}
|
|
2000
2033
|
unbindVariables?.();
|
|
2001
2034
|
}
|
|
2002
2035
|
/**
|
|
@@ -2257,7 +2290,8 @@ function createErrorDiagnoser(context) {
|
|
|
2257
2290
|
yield* checkNode(node.bind);
|
|
2258
2291
|
if (node.processDefinitions?.length) {
|
|
2259
2292
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.processDefinitions, function* (node) {
|
|
2260
|
-
|
|
2293
|
+
// 现有流程版本 [v1, v2],加个 v3 后,变成了 [proxy(v1), proxy(v2), v3],无法理解
|
|
2294
|
+
yield* checkNode(toRaw(node));
|
|
2261
2295
|
});
|
|
2262
2296
|
}
|
|
2263
2297
|
if (node?.subLogics?.length) {
|
|
@@ -2433,7 +2467,7 @@ function createErrorDiagnoser(context) {
|
|
|
2433
2467
|
const prop = getPropertyOfType(type, propertyName);
|
|
2434
2468
|
if (!prop) {
|
|
2435
2469
|
const scope = item?.constructor?.nodeTitle;
|
|
2436
|
-
error(item, `${scope}:找不到 ${type
|
|
2470
|
+
error(item, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${propertyName}。`);
|
|
2437
2471
|
}
|
|
2438
2472
|
type = env.getType(prop);
|
|
2439
2473
|
if (type?.typeKind === 'generic' && type.typeName === 'List') {
|
|
@@ -2461,6 +2495,10 @@ function createErrorDiagnoser(context) {
|
|
|
2461
2495
|
...(node.variables || []),
|
|
2462
2496
|
...(node.virtualParams || [])
|
|
2463
2497
|
]);
|
|
2498
|
+
// 仅检查用户写的逻辑
|
|
2499
|
+
// if (node.nodePath?.startsWith('app.logics')) {
|
|
2500
|
+
checkVariableAndReturnTypeAnnotations(node.variables ?? [], node.returns ?? []);
|
|
2501
|
+
// }
|
|
2464
2502
|
const module = node.getAncestor('Module');
|
|
2465
2503
|
if (!(module?.parentKey === 'dependencies')) {
|
|
2466
2504
|
if (node.params?.length) {
|
|
@@ -2641,6 +2679,9 @@ function createErrorDiagnoser(context) {
|
|
|
2641
2679
|
...(node.returns || []),
|
|
2642
2680
|
...(node.variables || []),
|
|
2643
2681
|
]);
|
|
2682
|
+
// if (nd.nodePath?.startsWith('app.logics')) {
|
|
2683
|
+
checkVariableAndReturnTypeAnnotations(node.variables, node.returns);
|
|
2684
|
+
// }
|
|
2644
2685
|
const module = node.getAncestor('Module');
|
|
2645
2686
|
if (!(module?.parentKey === 'dependencies')) {
|
|
2646
2687
|
if (node.params?.length) {
|
|
@@ -2731,30 +2772,27 @@ function createErrorDiagnoser(context) {
|
|
|
2731
2772
|
return;
|
|
2732
2773
|
}
|
|
2733
2774
|
yield* checkVoidCallUsedAsStatement(node);
|
|
2734
|
-
const ref = env.
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
yield* checkScopeOfUse(node, ref);
|
|
2742
|
-
yield* checkCallExpressionParameters(node, ref);
|
|
2743
|
-
}
|
|
2744
|
-
else if (ref && !typeUnresolved) {
|
|
2745
|
-
// 检查使用范围
|
|
2746
|
-
yield* checkScopeOfUse(node, ref);
|
|
2747
|
-
yield* checkCallExpressionParameters(node, ref);
|
|
2748
|
-
}
|
|
2749
|
-
else {
|
|
2750
|
-
if (ref.depLibName) {
|
|
2751
|
-
error(node, `找不到依赖库 ${ref.depLibName} 上的 ${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2775
|
+
const ref = env.resolveRef(node); // 前端
|
|
2776
|
+
// TODO: sql 函数的 namespace 带有数据库名 nasl.sqlFunction.mysql nasl.sqlFunction.oracle ...
|
|
2777
|
+
// 暂时不在 qNameDefs 里,用 isBuiltInCall 简单判断了
|
|
2778
|
+
if (!ref && !isBuiltInCall(node)) {
|
|
2779
|
+
const depLibName = getExtensionLibName(node);
|
|
2780
|
+
if (depLibName) {
|
|
2781
|
+
error(node, `找不到依赖库 ${depLibName} 上的 ${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2752
2782
|
}
|
|
2753
2783
|
else {
|
|
2754
2784
|
error(node, `找不到${getExpressionNodeName(node.concept)} ${node.calleeName}。`);
|
|
2755
2785
|
}
|
|
2756
2786
|
return errorType;
|
|
2757
2787
|
}
|
|
2788
|
+
/**
|
|
2789
|
+
* 目前的 callInfo:所有内置函数 + 服务端调用。前端因为有组件库调用,还没统一
|
|
2790
|
+
* 排除未求解出类型变元等引发的报错,这些不应该报 '找不到'
|
|
2791
|
+
*/
|
|
2792
|
+
// FIXME: wudengke 帮帮忙,行行好
|
|
2793
|
+
const callInfo = env.resolvedCallInfo.get(node);
|
|
2794
|
+
yield* checkScopeOfUse(node, (callInfo ?? ref));
|
|
2795
|
+
yield* checkCallExpressionParameters(node, (callInfo ?? ref));
|
|
2758
2796
|
switch (node.concept) {
|
|
2759
2797
|
case 'CallFunction':
|
|
2760
2798
|
return yield* checkCallFunction(node);
|
|
@@ -3127,18 +3165,29 @@ function createErrorDiagnoser(context) {
|
|
|
3127
3165
|
}
|
|
3128
3166
|
});
|
|
3129
3167
|
}
|
|
3168
|
+
else if (!isOtherCase(node)) {
|
|
3169
|
+
// pattern 为空时,如果不是其他就报错
|
|
3170
|
+
error(node, '匹配分支:匹配模式不能为空', {
|
|
3171
|
+
titleTip: '匹配模式不能为空',
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3130
3174
|
if (node.body?.length) {
|
|
3131
3175
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.body, function* (node) {
|
|
3132
3176
|
yield* checkNode(node);
|
|
3133
3177
|
});
|
|
3134
3178
|
}
|
|
3135
|
-
if (match?.isExpression && node.body.length === 0) {
|
|
3136
|
-
//
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3179
|
+
if (match?.isExpression && node.body.length === 0 && !isOtherCase(node)) {
|
|
3180
|
+
// 如果不是其他就报错
|
|
3181
|
+
error(node, '匹配分支:返回内容不能为空', {
|
|
3182
|
+
titleTip: '返回内容不能为空',
|
|
3183
|
+
});
|
|
3184
|
+
}
|
|
3185
|
+
function isOtherCase(node) {
|
|
3186
|
+
const indexInParent = node.getIndexOfParent();
|
|
3187
|
+
if (indexInParent === -1) {
|
|
3188
|
+
return false;
|
|
3141
3189
|
}
|
|
3190
|
+
return indexInParent === match.cases.length - 1;
|
|
3142
3191
|
}
|
|
3143
3192
|
}
|
|
3144
3193
|
/**
|
|
@@ -3235,14 +3284,6 @@ function createErrorDiagnoser(context) {
|
|
|
3235
3284
|
}
|
|
3236
3285
|
else {
|
|
3237
3286
|
const { name } = node;
|
|
3238
|
-
// 之前有一些脏数据,先兼容
|
|
3239
|
-
// if (['true', 'false'].includes(name)) {
|
|
3240
|
-
// return new TypeAnnotation({
|
|
3241
|
-
// typeKind: 'primitive',
|
|
3242
|
-
// typeName: 'Boolean',
|
|
3243
|
-
// typeNamespace: 'nasl.core',
|
|
3244
|
-
// });
|
|
3245
|
-
// }
|
|
3246
3287
|
if (
|
|
3247
3288
|
// name 是 A.B.C
|
|
3248
3289
|
name?.split('.')?.length > 1
|
|
@@ -3257,6 +3298,13 @@ function createErrorDiagnoser(context) {
|
|
|
3257
3298
|
return errorType;
|
|
3258
3299
|
}
|
|
3259
3300
|
}
|
|
3301
|
+
if (node.namespace === 'app.enums' &&
|
|
3302
|
+
node.parentNode?.concept !== 'MemberExpression' &&
|
|
3303
|
+
node.parentNode?.concept !== 'SelectMembers') {
|
|
3304
|
+
// 判断枚举类是否直接被使用
|
|
3305
|
+
scopedError(node, `${node.toNaturalTS()} 枚举类不能直接使用,请取它的枚举项`);
|
|
3306
|
+
return errorType;
|
|
3307
|
+
}
|
|
3260
3308
|
// 检查使用范围
|
|
3261
3309
|
yield* checkScopeOfUse(node, ref);
|
|
3262
3310
|
return env.getType(node);
|
|
@@ -3285,7 +3333,7 @@ function createErrorDiagnoser(context) {
|
|
|
3285
3333
|
}
|
|
3286
3334
|
else {
|
|
3287
3335
|
const scope = node?.constructor?.nodeTitle;
|
|
3288
|
-
error(node, `${scope}:找不到 ${type
|
|
3336
|
+
error(node, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${nodeProperty?.name}。`);
|
|
3289
3337
|
return errorType;
|
|
3290
3338
|
}
|
|
3291
3339
|
return env.getType(node);
|
|
@@ -3437,7 +3485,7 @@ function createErrorDiagnoser(context) {
|
|
|
3437
3485
|
}
|
|
3438
3486
|
else {
|
|
3439
3487
|
const scope = property?.constructor?.nodeTitle;
|
|
3440
|
-
error(property, `${scope}:找不到 ${type
|
|
3488
|
+
error(property, `${scope}:找不到 ${(0, type_manager_1.showUserLevelType)(type)} 上的 ${propertyName}。`);
|
|
3441
3489
|
}
|
|
3442
3490
|
});
|
|
3443
3491
|
}
|
|
@@ -4253,6 +4301,26 @@ function createErrorDiagnoser(context) {
|
|
|
4253
4301
|
function setMetadataTypeEnable(enable) {
|
|
4254
4302
|
metadataTypeEnable = enable;
|
|
4255
4303
|
}
|
|
4304
|
+
const checkVariableAndReturnTypeAnnotations = (variables, returns, inLogic = true) => {
|
|
4305
|
+
for (const v of variables) {
|
|
4306
|
+
if (v.typeAnnotation)
|
|
4307
|
+
continue;
|
|
4308
|
+
const tyAnn = v.__TypeAnnotation;
|
|
4309
|
+
if (!(0, type_predicate_1.isResolvedUserTy)(tyAnn)) {
|
|
4310
|
+
error(v, `局部变量 ${v.name} 未设置类型,在非草稿区正常使用可自动推断类型`);
|
|
4311
|
+
v.__TypeAnnotation = undefined;
|
|
4312
|
+
}
|
|
4313
|
+
}
|
|
4314
|
+
for (const r of returns) {
|
|
4315
|
+
if (r.typeAnnotation)
|
|
4316
|
+
continue;
|
|
4317
|
+
const tyAnn = r.__TypeAnnotation;
|
|
4318
|
+
if (!(0, type_predicate_1.isResolvedUserTy)(tyAnn)) {
|
|
4319
|
+
error(r, `输出参数 ${r.name} 未设置类型,在非草稿区正常使用可自动推断类型`);
|
|
4320
|
+
r.__TypeAnnotation = undefined;
|
|
4321
|
+
}
|
|
4322
|
+
}
|
|
4323
|
+
};
|
|
4256
4324
|
/**
|
|
4257
4325
|
* 诊断App
|
|
4258
4326
|
* @param app
|
|
@@ -4344,4 +4412,8 @@ const transformDiagnosticsToRecords = (fileNode, diagnostics) => {
|
|
|
4344
4412
|
exports.transformDiagnosticsToRecords = transformDiagnosticsToRecords;
|
|
4345
4413
|
// @ts-expect-error
|
|
4346
4414
|
const toRaw = (nd) => nd.__v_raw ?? nd;
|
|
4415
|
+
// 是否来自系统内置
|
|
4416
|
+
const isBuiltInCall = (nd) => nd.calleeNamespace.startsWith('nasl.');
|
|
4417
|
+
// 是否来自依赖库
|
|
4418
|
+
const getExtensionLibName = (nd) => nd.calleeNamespace.startsWith('extensions.') ? nd.calleeNamespace.split('.')[1] : undefined;
|
|
4347
4419
|
//# sourceMappingURL=checker.js.map
|