@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.
Files changed (164) hide show
  1. package/README.md +85 -0
  2. package/out/checker.d.ts.map +1 -1
  3. package/out/checker.js +121 -49
  4. package/out/checker.js.map +1 -1
  5. package/out/index.d.ts +4 -2
  6. package/out/index.d.ts.map +1 -1
  7. package/out/index.js +7 -2
  8. package/out/index.js.map +1 -1
  9. package/out/module/graph.js +6 -6
  10. package/out/module/graph.js.map +1 -1
  11. package/out/module/module.d.ts.map +1 -1
  12. package/out/module/module.js +3 -6
  13. package/out/module/module.js.map +1 -1
  14. package/out/query/context-variable-query.d.ts +31 -0
  15. package/out/query/context-variable-query.d.ts.map +1 -0
  16. package/out/query/context-variable-query.js +105 -0
  17. package/out/query/context-variable-query.js.map +1 -0
  18. package/out/query/index.d.ts +2 -0
  19. package/out/query/index.d.ts.map +1 -0
  20. package/out/query/index.js +18 -0
  21. package/out/query/index.js.map +1 -0
  22. package/out/reference-manager/builtin-q-name.d.ts +10 -3
  23. package/out/reference-manager/builtin-q-name.d.ts.map +1 -1
  24. package/out/reference-manager/builtin-q-name.js +67 -9
  25. package/out/reference-manager/builtin-q-name.js.map +1 -1
  26. package/out/reference-manager/collect-q-name.d.ts +4 -2
  27. package/out/reference-manager/collect-q-name.d.ts.map +1 -1
  28. package/out/reference-manager/collect-q-name.js +22 -11
  29. package/out/reference-manager/collect-q-name.js.map +1 -1
  30. package/out/reference-manager/get-q-name.d.ts +0 -2
  31. package/out/reference-manager/get-q-name.d.ts.map +1 -1
  32. package/out/reference-manager/get-q-name.js +32 -49
  33. package/out/reference-manager/get-q-name.js.map +1 -1
  34. package/out/reference-manager/reference-manager.d.ts +17 -13
  35. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  36. package/out/reference-manager/reference-manager.js +232 -130
  37. package/out/reference-manager/reference-manager.js.map +1 -1
  38. package/out/reference-manager/remove-q-name.d.ts +31 -28
  39. package/out/reference-manager/remove-q-name.d.ts.map +1 -1
  40. package/out/reference-manager/remove-q-name.js +61 -46
  41. package/out/reference-manager/remove-q-name.js.map +1 -1
  42. package/out/reference-manager/rename-q-name.d.ts +4 -2
  43. package/out/reference-manager/rename-q-name.d.ts.map +1 -1
  44. package/out/reference-manager/rename-q-name.js +43 -36
  45. package/out/reference-manager/rename-q-name.js.map +1 -1
  46. package/out/reference-manager/symbol-type.d.ts +6 -3
  47. package/out/reference-manager/symbol-type.d.ts.map +1 -1
  48. package/out/reference-manager/symbol-type.js +16 -10
  49. package/out/reference-manager/symbol-type.js.map +1 -1
  50. package/out/reference-manager/update-nasl-fragment.d.ts +2 -1
  51. package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
  52. package/out/reference-manager/update-nasl-fragment.js +14 -5
  53. package/out/reference-manager/update-nasl-fragment.js.map +1 -1
  54. package/out/symbol/graph.js +2 -2
  55. package/out/symbol/graph.js.map +1 -1
  56. package/out/typer/collectGlobalDefs.d.ts +1 -1
  57. package/out/typer/collectGlobalDefs.d.ts.map +1 -1
  58. package/out/typer/collectGlobalDefs.js +81 -17
  59. package/out/typer/collectGlobalDefs.js.map +1 -1
  60. package/out/typer/component-def-manager/component-def-manager.d.ts +42 -11
  61. package/out/typer/component-def-manager/component-def-manager.d.ts.map +1 -1
  62. package/out/typer/component-def-manager/component-def-manager.js +114 -26
  63. package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
  64. package/out/typer/component-def-manager/utils.d.ts.map +1 -1
  65. package/out/typer/component-def-manager/utils.js +44 -15
  66. package/out/typer/component-def-manager/utils.js.map +1 -1
  67. package/out/typer/dispatch-all.d.ts +1 -1
  68. package/out/typer/dispatch-all.d.ts.map +1 -1
  69. package/out/typer/dispatch-all.js +3 -7
  70. package/out/typer/dispatch-all.js.map +1 -1
  71. package/out/typer/dispatch-def.d.ts +1 -3
  72. package/out/typer/dispatch-def.d.ts.map +1 -1
  73. package/out/typer/dispatch-def.js +22 -48
  74. package/out/typer/dispatch-def.js.map +1 -1
  75. package/out/typer/dispatch-expr.d.ts +6 -3
  76. package/out/typer/dispatch-expr.d.ts.map +1 -1
  77. package/out/typer/dispatch-expr.js +273 -212
  78. package/out/typer/dispatch-expr.js.map +1 -1
  79. package/out/typer/dispatch-process.d.ts +0 -1
  80. package/out/typer/dispatch-process.d.ts.map +1 -1
  81. package/out/typer/dispatch-process.js +22 -14
  82. package/out/typer/dispatch-process.js.map +1 -1
  83. package/out/typer/dispatch-stmt.d.ts.map +1 -1
  84. package/out/typer/dispatch-stmt.js +50 -29
  85. package/out/typer/dispatch-stmt.js.map +1 -1
  86. package/out/typer/dispatch-view.d.ts.map +1 -1
  87. package/out/typer/dispatch-view.js +236 -148
  88. package/out/typer/dispatch-view.js.map +1 -1
  89. package/out/typer/helper.js +3 -3
  90. package/out/typer/helper.js.map +1 -1
  91. package/out/typer/incremental-update.d.ts +21 -42
  92. package/out/typer/incremental-update.d.ts.map +1 -1
  93. package/out/typer/incremental-update.js +204 -241
  94. package/out/typer/incremental-update.js.map +1 -1
  95. package/out/typer/index.d.ts +4 -5
  96. package/out/typer/index.d.ts.map +1 -1
  97. package/out/typer/index.js +4 -5
  98. package/out/typer/index.js.map +1 -1
  99. package/out/typer/nasl-predicate.d.ts +1 -1
  100. package/out/typer/nasl-predicate.d.ts.map +1 -1
  101. package/out/typer/overload-helper.d.ts +12 -0
  102. package/out/typer/overload-helper.d.ts.map +1 -0
  103. package/out/typer/overload-helper.js +110 -0
  104. package/out/typer/overload-helper.js.map +1 -0
  105. package/out/typer/sem-diag.d.ts +6 -0
  106. package/out/typer/sem-diag.d.ts.map +1 -1
  107. package/out/typer/sem-diag.js +38 -17
  108. package/out/typer/sem-diag.js.map +1 -1
  109. package/out/typer/solver.d.ts +40 -26
  110. package/out/typer/solver.d.ts.map +1 -1
  111. package/out/typer/solver.js +217 -432
  112. package/out/typer/solver.js.map +1 -1
  113. package/out/typer/subster.d.ts +4 -6
  114. package/out/typer/subster.d.ts.map +1 -1
  115. package/out/typer/subster.js +76 -49
  116. package/out/typer/subster.js.map +1 -1
  117. package/out/typer/topo-sort.d.ts.map +1 -1
  118. package/out/typer/topo-sort.js +9 -2
  119. package/out/typer/topo-sort.js.map +1 -1
  120. package/out/typer/type-hint-manager/type-hint-manager.d.ts +4 -1
  121. package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
  122. package/out/typer/type-hint-manager/type-hint-manager.js +2 -0
  123. package/out/typer/type-hint-manager/type-hint-manager.js.map +1 -1
  124. package/out/typer/type-manager.d.ts +9 -4
  125. package/out/typer/type-manager.d.ts.map +1 -1
  126. package/out/typer/type-manager.js +32 -22
  127. package/out/typer/type-manager.js.map +1 -1
  128. package/out/typer/type-predicate.d.ts +15 -2
  129. package/out/typer/type-predicate.d.ts.map +1 -1
  130. package/out/typer/type-predicate.js +119 -32
  131. package/out/typer/type-predicate.js.map +1 -1
  132. package/out/typer/typer.d.ts +39 -8
  133. package/out/typer/typer.d.ts.map +1 -1
  134. package/out/typer/typer.js +93 -80
  135. package/out/typer/typer.js.map +1 -1
  136. package/out/typer/unifier.d.ts +0 -3
  137. package/out/typer/unifier.d.ts.map +1 -1
  138. package/out/typer/unifier.js +96 -62
  139. package/out/typer/unifier.js.map +1 -1
  140. package/out/utils/nasl-type-manipulation.d.ts +1 -0
  141. package/out/utils/nasl-type-manipulation.d.ts.map +1 -1
  142. package/out/utils/nasl-type-manipulation.js +3 -1
  143. package/out/utils/nasl-type-manipulation.js.map +1 -1
  144. package/out/utils/parseTsClassType.d.ts +4 -3
  145. package/out/utils/parseTsClassType.d.ts.map +1 -1
  146. package/out/utils/parseTsClassType.js +37 -61
  147. package/out/utils/parseTsClassType.js.map +1 -1
  148. package/out/utils/string.d.ts +4 -0
  149. package/out/utils/string.d.ts.map +1 -0
  150. package/out/utils/string.js +29 -0
  151. package/out/utils/string.js.map +1 -0
  152. package/out/utils/type-operator.d.ts +3 -3
  153. package/out/utils/type-operator.d.ts.map +1 -1
  154. package/out/utils/type-operator.js +34 -17
  155. package/out/utils/type-operator.js.map +1 -1
  156. package/package.json +16 -7
  157. package/out/utils/vue-hack.d.ts +0 -25
  158. package/out/utils/vue-hack.d.ts.map +0 -1
  159. package/out/utils/vue-hack.js +0 -33
  160. package/out/utils/vue-hack.js.map +0 -1
  161. package/out/utils/vue.d.ts +0 -2
  162. package/out/utils/vue.d.ts.map +0 -1
  163. package/out/utils/vue.js +0 -10
  164. 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
@@ -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;AAEpE,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;oCAwiIpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BAsCf,UAAU;2BAuBb,UAAU;;kBAthInB,UAAU,WAAW,MAAM,YAAY,YAAY;EAwiIzE;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"}
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 || param?.spread || (nasl_concepts_1.asserts.isInterfaceParam(param) && !param.required);
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 ref
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
- if (!param)
827
- return;
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
- const argType = yield* checkNode(arg);
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
- error(node, `${scope}:${node.name} 未定义。`);
932
- }
933
- else {
934
- error(node, `${scope}:所选择的内容未定义。`);
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
- yield* checkNode(node);
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?.typeTitle} 上的 ${propertyName}。`);
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.resolvedCallInfo.get(node) ?? env.resolveRef(node);
2735
- const typeUnresolved = ref.ret
2736
- ? (0, type_manager_1.hasUnresolvedTyInCallInfo)(ref) // 其他
2737
- : (0, type_predicate_1.isUnResolvedTy)(ref); // 前端页面,TODO: 需要统一处理
2738
- // Handle the new FunctionDefinition structure
2739
- if (ref?.params && !typeUnresolved) {
2740
- // It's a FunctionDefinition object
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
- if (node?.getIndexOfParent() !== (match?.cases?.length || 0) - 1) {
3138
- error(node, '匹配分支:返回内容不能为空', {
3139
- titleTip: '返回内容不能为空',
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?.typeTitle} 上的 ${nodeProperty?.name}。`);
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?.typeTitle} 上的 ${propertyName}。`);
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