@lcap/nasl-language-server-core 4.0.1-rc.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.
Files changed (102) hide show
  1. package/out/checker.d.ts +1 -1
  2. package/out/checker.d.ts.map +1 -1
  3. package/out/checker.js +38 -3
  4. package/out/checker.js.map +1 -1
  5. package/out/index.d.ts +2 -1
  6. package/out/index.d.ts.map +1 -1
  7. package/out/index.js +4 -1
  8. package/out/index.js.map +1 -1
  9. package/out/reference-manager/builtin-q-name.d.ts +1 -1
  10. package/out/reference-manager/builtin-q-name.d.ts.map +1 -1
  11. package/out/reference-manager/builtin-q-name.js +14 -10
  12. package/out/reference-manager/builtin-q-name.js.map +1 -1
  13. package/out/reference-manager/collect-q-name.d.ts.map +1 -1
  14. package/out/reference-manager/collect-q-name.js +15 -13
  15. package/out/reference-manager/collect-q-name.js.map +1 -1
  16. package/out/reference-manager/get-q-name.d.ts +0 -2
  17. package/out/reference-manager/get-q-name.d.ts.map +1 -1
  18. package/out/reference-manager/get-q-name.js +30 -46
  19. package/out/reference-manager/get-q-name.js.map +1 -1
  20. package/out/reference-manager/reference-manager.d.ts +19 -10
  21. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  22. package/out/reference-manager/reference-manager.js +141 -101
  23. package/out/reference-manager/reference-manager.js.map +1 -1
  24. package/out/reference-manager/remove-q-name.d.ts.map +1 -1
  25. package/out/reference-manager/remove-q-name.js +22 -15
  26. package/out/reference-manager/remove-q-name.js.map +1 -1
  27. package/out/reference-manager/symbol-type.d.ts +3 -2
  28. package/out/reference-manager/symbol-type.d.ts.map +1 -1
  29. package/out/reference-manager/symbol-type.js +7 -1
  30. package/out/reference-manager/symbol-type.js.map +1 -1
  31. package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
  32. package/out/reference-manager/update-nasl-fragment.js +4 -4
  33. package/out/reference-manager/update-nasl-fragment.js.map +1 -1
  34. package/out/symbol/traverse/concepts/index.d.ts +1 -1
  35. package/out/symbol/traverse/concepts/index.d.ts.map +1 -1
  36. package/out/typer/collectGlobalDefs.d.ts +1 -1
  37. package/out/typer/collectGlobalDefs.d.ts.map +1 -1
  38. package/out/typer/collectGlobalDefs.js +2 -2
  39. package/out/typer/collectGlobalDefs.js.map +1 -1
  40. package/out/typer/component-def-manager/component-def-manager.js +2 -2
  41. package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
  42. package/out/typer/dispatch-all.d.ts +1 -1
  43. package/out/typer/dispatch-all.d.ts.map +1 -1
  44. package/out/typer/dispatch-all.js +2 -2
  45. package/out/typer/dispatch-all.js.map +1 -1
  46. package/out/typer/dispatch-expr.d.ts.map +1 -1
  47. package/out/typer/dispatch-expr.js +150 -106
  48. package/out/typer/dispatch-expr.js.map +1 -1
  49. package/out/typer/dispatch-process.js +1 -1
  50. package/out/typer/dispatch-process.js.map +1 -1
  51. package/out/typer/dispatch-view.d.ts +1 -1
  52. package/out/typer/dispatch-view.d.ts.map +1 -1
  53. package/out/typer/dispatch-view.js +13 -10
  54. package/out/typer/dispatch-view.js.map +1 -1
  55. package/out/typer/incremental-update.d.ts.map +1 -1
  56. package/out/typer/incremental-update.js +23 -39
  57. package/out/typer/incremental-update.js.map +1 -1
  58. package/out/typer/index.d.ts +2 -1
  59. package/out/typer/index.d.ts.map +1 -1
  60. package/out/typer/index.js +3 -1
  61. package/out/typer/index.js.map +1 -1
  62. package/out/typer/overload-helper.d.ts +12 -0
  63. package/out/typer/overload-helper.d.ts.map +1 -0
  64. package/out/typer/overload-helper.js +110 -0
  65. package/out/typer/overload-helper.js.map +1 -0
  66. package/out/typer/sem-diag.d.ts +5 -0
  67. package/out/typer/sem-diag.d.ts.map +1 -1
  68. package/out/typer/sem-diag.js +15 -1
  69. package/out/typer/sem-diag.js.map +1 -1
  70. package/out/typer/solver.d.ts +2 -2
  71. package/out/typer/solver.d.ts.map +1 -1
  72. package/out/typer/solver.js +17 -19
  73. package/out/typer/solver.js.map +1 -1
  74. package/out/typer/subster.js +3 -3
  75. package/out/typer/subster.js.map +1 -1
  76. package/out/typer/type-hint-manager/type-hint-manager.d.ts +1 -1
  77. package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
  78. package/out/typer/type-manager.d.ts.map +1 -1
  79. package/out/typer/type-manager.js +3 -3
  80. package/out/typer/type-manager.js.map +1 -1
  81. package/out/typer/type-predicate.js +5 -5
  82. package/out/typer/type-predicate.js.map +1 -1
  83. package/out/typer/typer.d.ts +7 -4
  84. package/out/typer/typer.d.ts.map +1 -1
  85. package/out/typer/typer.js +24 -17
  86. package/out/typer/typer.js.map +1 -1
  87. package/out/typer/unifier.d.ts.map +1 -1
  88. package/out/typer/unifier.js +10 -4
  89. package/out/typer/unifier.js.map +1 -1
  90. package/out/utils/parseTsClassType.d.ts +2 -3
  91. package/out/utils/parseTsClassType.d.ts.map +1 -1
  92. package/out/utils/parseTsClassType.js +25 -58
  93. package/out/utils/parseTsClassType.js.map +1 -1
  94. package/out/utils/string.d.ts +4 -0
  95. package/out/utils/string.d.ts.map +1 -0
  96. package/out/utils/string.js +29 -0
  97. package/out/utils/string.js.map +1 -0
  98. package/out/utils/type-operator.d.ts +1 -1
  99. package/out/utils/type-operator.d.ts.map +1 -1
  100. package/out/utils/type-operator.js +12 -12
  101. package/out/utils/type-operator.js.map +1 -1
  102. package/package.json +10 -7
@@ -9,15 +9,16 @@ const helper_1 = require("./helper");
9
9
  const dispatch_stmt_1 = require("./dispatch-stmt");
10
10
  const dispatch_stmt_2 = require("./dispatch-stmt");
11
11
  const dispatch_def_1 = require("./dispatch-def");
12
+ const get_q_name_1 = require("../reference-manager/get-q-name");
12
13
  const reference_manager_1 = require("../reference-manager/reference-manager");
13
14
  const symbol_type_1 = require("../reference-manager/symbol-type");
15
+ const string_1 = require("../utils/string");
14
16
  const assertion_1 = require("../utils/assertion");
15
17
  const nasl_predicate_1 = require("./nasl-predicate");
16
18
  const asserts_1 = require("@lcap/nasl-concepts/asserts");
17
19
  const type_manager_1 = require("./type-manager");
18
20
  const type_predicate_1 = require("./type-predicate");
19
21
  const type_predicate_2 = require("./type-predicate");
20
- const sem_diag_2 = require("./sem-diag");
21
22
  const dispatch_process_1 = require("./dispatch-process");
22
23
  const dispatch_view_1 = require("./dispatch-view");
23
24
  const subster_2 = require("./subster");
@@ -26,6 +27,7 @@ const error_boundary_1 = require("../utils/error-boundary");
26
27
  const types_1 = require("../utils/types");
27
28
  const type_operator_1 = require("../utils/type-operator");
28
29
  const nasl_type_manipulation_1 = require("../utils/nasl-type-manipulation");
30
+ const overload_helper_1 = require("./overload-helper");
29
31
  // speed consideration
30
32
  function dispatchExpr(env, nd, tgtTy) {
31
33
  if (!nd) {
@@ -36,6 +38,7 @@ function dispatchExpr(env, nd, tgtTy) {
36
38
  case 'Identifier': return tpIdentifier(env, nd, tgtTy);
37
39
  case 'MemberExpression': return tpMemberExpression(env, nd, tgtTy);
38
40
  case 'BinaryExpression': return tpBinaryExpression(env, nd, tgtTy);
41
+ case 'VariadicExpression': return tpVariadicExpression(env, nd, tgtTy);
39
42
  case 'UnaryExpression': return tpUnaryExpression(env, nd, tgtTy);
40
43
  case 'StringLiteral': return tpStringLiteral(env, nd, tgtTy);
41
44
  case 'NumericLiteral': return tpNumericLiteral(env, nd, tgtTy);
@@ -70,6 +73,8 @@ function dispatchExpr(env, nd, tgtTy) {
70
73
  case 'Anchor': return tpAnchor(env, nd, tgtTy);
71
74
  case 'JSBlock': return;
72
75
  case 'NewStructure': return tpNewStructure(env, nd, tgtTy);
76
+ case 'Break': return undefined;
77
+ case 'Continue': return undefined;
73
78
  default: {
74
79
  // 不要 throw,草稿区或者脏数据经常有莫名其妙的东西进来,如 break continue 等
75
80
  console.log(`未知的 LogicItem ${nd.concept},先忽略`);
@@ -223,7 +228,7 @@ function tpMemberExpression(env, nd, tgtTy) {
223
228
  rawObjTyAnn = dispatchExpr(env, nd.object, undefined);
224
229
  }
225
230
  if (!rawObjTyAnn) {
226
- env.addError((0, sem_diag_2.mkTypeNotFoundErr)(nd.object.name ?? ' '));
231
+ env.addError((0, sem_diag_1.mkTypeNotFoundErr)(nd.object.name ?? ' '));
227
232
  env.setType(nd.object, type_manager_1.naslAnyTy);
228
233
  env.setType(nd, type_manager_1.naslAnyTy);
229
234
  return type_manager_1.naslAnyTy;
@@ -304,7 +309,7 @@ function tpMemberExpression(env, nd, tgtTy) {
304
309
  let ndTy = env.getRawType(nd.property) ?? type_manager_1.naslAnyTy;
305
310
  // 为了 match!マッチのために
306
311
  {
307
- const specialName = (0, reference_manager_1.getTokenQualifiedNameForMatchedExpr)(env, nd);
312
+ const specialName = (0, get_q_name_1.getTokenQualifiedNameForMatchedExpr)(env, nd);
308
313
  if (env.matchedVars.has(specialName)) {
309
314
  const ty = env.matchedVars.get(specialName);
310
315
  ndTy = ty;
@@ -318,7 +323,7 @@ function tpMemberExpression(env, nd, tgtTy) {
318
323
  const processRefProp = (env, nd, objTyAnn) => {
319
324
  const vRefTyDef = env.refMgr.findOrCreateTypeDef(objTyAnn);
320
325
  if (!vRefTyDef) {
321
- env.addError((0, sem_diag_2.mkDefNotFoundErr)(objTyAnn, nd.property.name ?? ''));
326
+ env.addError((0, sem_diag_1.mkDefNotFoundErr)(objTyAnn, nd.property.name ?? ''));
322
327
  env.setType(nd.property, type_manager_1.naslAnyTy);
323
328
  return;
324
329
  }
@@ -329,7 +334,7 @@ const processRefProp = (env, nd, objTyAnn) => {
329
334
  env.setType(nd.property, type_manager_1.processSystemCommonTy);
330
335
  }
331
336
  else {
332
- env.addError((0, sem_diag_2.mkMemNotFoundErr)(objTyAnn, nd.property.name));
337
+ env.addError((0, sem_diag_1.mkMemNotFoundErr)(objTyAnn, nd.property.name));
333
338
  env.setType(nd.property, type_manager_1.naslAnyTy);
334
339
  }
335
340
  return;
@@ -430,7 +435,7 @@ function tpBinaryExpression(env, nd, tgtTy) {
430
435
  return ty;
431
436
  if ((0, type_predicate_2.isMetadataType)(ty)) {
432
437
  // 使用typeAlias来查找元数据类型的底层类型
433
- const qName = (0, reference_manager_1.getTokenQualifiedName)(ty);
438
+ const qName = (0, get_q_name_1.getTokenQualifiedName)(ty);
434
439
  if (qName && env.typeAlias.has(qName)) {
435
440
  return env.typeAlias.get(qName);
436
441
  }
@@ -458,7 +463,8 @@ function tpBinaryExpression(env, nd, tgtTy) {
458
463
  const isStringOperationValid = (0, type_predicate_2.isStringTy)(baseLeftTy) || (0, type_predicate_2.isStringTy)(baseRightTy) || (0, type_predicate_2.isAnyTy)(baseLeftTy) || (0, type_predicate_2.isAnyTy)(baseRightTy);
459
464
  const isNumericOperationValid = isUnionNumericTy(baseLeftTy) && isUnionNumericTy(baseRightTy);
460
465
  if (!isStringOperationValid && !isNumericOperationValid && baseLeftTy && baseRightTy) {
461
- env.addError((0, sem_diag_1.mkIncompatibleTyErr)(env, leftTy || type_manager_1.naslAnyTy, rightTy || type_manager_1.naslAnyTy), fileNode, errBoundary, severity);
466
+ // 对于不支持的操作,使用更清晰的错误消息
467
+ env.addError((0, sem_diag_1.mkUnsupportedBinaryOperationErr)(nd.operator, baseLeftTy, baseRightTy), fileNode, errBoundary, severity);
462
468
  }
463
469
  };
464
470
  env.addPostCheckTask(nd, postChk(env.getCurFileNode(), nd, env.errSeverity));
@@ -484,6 +490,7 @@ function tpBinaryExpression(env, nd, tgtTy) {
484
490
  dispatchExpr(env, nd.left, type_manager_1.naslBooleanTy);
485
491
  dispatchExpr(env, nd.right, type_manager_1.naslBooleanTy);
486
492
  env.setType(nd, type_manager_1.naslBooleanTy);
493
+ env.unifier.unify(type_manager_1.naslBooleanTy, tgtTy);
487
494
  return type_manager_1.naslBooleanTy;
488
495
  }
489
496
  ;
@@ -494,19 +501,30 @@ function tpBinaryExpression(env, nd, tgtTy) {
494
501
  dispatchExpr(env, nd.left, type_manager_1.naslStringTy);
495
502
  dispatchExpr(env, nd.right, type_manager_1.naslStringTy);
496
503
  env.setType(nd, type_manager_1.naslBooleanTy);
504
+ env.unifier.unify(type_manager_1.naslBooleanTy, tgtTy);
497
505
  return type_manager_1.naslBooleanTy;
498
506
  }
499
507
  case 'in': {
500
508
  const leftTy = dispatchExpr(env, nd.left, undefined);
501
509
  const rightTy = dispatchExpr(env, nd.right, undefined);
502
510
  // T in List<T>
503
- env.unifier.unify((0, type_manager_1.createListTyAnn)(leftTy ?? type_manager_1.naslAnyTy), rightTy);
504
511
  env.setType(nd, type_manager_1.naslBooleanTy);
512
+ env.unifier.unify((0, type_manager_1.createListTyAnn)(leftTy ?? type_manager_1.naslAnyTy), rightTy);
513
+ env.unifier.unify(type_manager_1.naslBooleanTy, tgtTy);
505
514
  return type_manager_1.naslBooleanTy;
506
515
  }
507
516
  default: return undefined;
508
517
  }
509
518
  }
519
+ const tpVariadicExpression = (env, nd, tgtTy) => {
520
+ // 根据经验,带数组的经常会被 proxy 动态污染,防患于未然先 toRaws
521
+ for (const expr of toRaws(nd.expressions)) {
522
+ dispatchExpr(env, expr, type_manager_1.naslBooleanTy);
523
+ }
524
+ env.setType(nd, type_manager_1.naslBooleanTy);
525
+ env.unifier.unify(type_manager_1.naslBooleanTy, tgtTy);
526
+ return type_manager_1.naslBooleanTy;
527
+ };
510
528
  /*
511
529
  // 备份一下,未来可能有用
512
530
  function tpPlusExpression(env: SemEnv, nd: BinaryExpression, tgtTy: TypeAnnotation | undefined) {
@@ -626,7 +644,7 @@ const tpBinaryOrderExpr = (env, nd, tgtTy) => {
626
644
  if ((0, type_predicate_1.isUnionTy)(ty)) {
627
645
  return ty.typeArguments?.every(memberTy => isValidTy(memberTy)) ?? false;
628
646
  }
629
- const qName = (0, reference_manager_1.getTokenQualifiedName)(ty);
647
+ const qName = (0, get_q_name_1.getTokenQualifiedName)(ty);
630
648
  return !!qName && env.typeAlias.has(qName);
631
649
  };
632
650
  // 不调用 solver 则无法判断,调用则影响速度,所以报错后移了
@@ -699,7 +717,7 @@ function tpCallLogic(env, nd, tgtTy) {
699
717
  }
700
718
  else {
701
719
  // 'nasl.util' 时 是 json 序列化
702
- def = env.quickGetLibDef(nd);
720
+ def = env.quickGetLibDef(nd, nd.calleeName, undefined);
703
721
  }
704
722
  // 处理调用处的验证规则
705
723
  if (nd.validation?.rules && nd.validation.rules.length > 0 && def) {
@@ -791,7 +809,7 @@ function determineCallLogicFnTy(env, nd, def) {
791
809
  return env.getRawType(def);
792
810
  }
793
811
  else {
794
- const qName = (0, reference_manager_1.getTokenQualifiedName)(nd);
812
+ const qName = (0, get_q_name_1.getTokenQualifiedName)(nd);
795
813
  if (!qName) {
796
814
  return undefined;
797
815
  }
@@ -857,34 +875,12 @@ function tpCallFunction(env, nd, tgtTy) {
857
875
  if (parseTsClassType_1.enumBuiltinFns.includes(calleeName)) {
858
876
  return handleEnumFn(env, nd, tgtTy);
859
877
  }
860
- if (calleeName === 'Convert' || calleeName === 'Length') {
861
- return tpLengthAndConvertCall(env, nd, tgtTy);
862
- }
863
- else if (parseTsClassType_1.overloadedFns.includes(calleeName)) {
864
- const argTys = [];
865
- for (const arg of nd.arguments) {
866
- argTys.push(dispatchExpr(env, arg, undefined) ?? type_manager_1.naslAnyTy);
867
- }
868
- let argTy = argTys[(0, parseTsClassType_1.getOvParamIdx)(calleeName)];
869
- if (calleeName === 'CAST') {
870
- const litTy = nasl_concepts_1.TypeAnnotation.createProtoTypeOnly({
871
- typeKind: 'literal',
872
- typeNamespace: 'nasl.core',
873
- typeName: 'String',
874
- literal: nd.arguments?.[(0, parseTsClassType_1.getOvParamIdx)(calleeName)]?.expression?.value ?? ''
875
- });
876
- argTy = litTy;
877
- }
878
- const mangledCalleeName = (0, parseTsClassType_1.mangleOvFnName)(calleeName, argTy);
879
- const fnDef = env.quickGetLibDef(nd, mangledCalleeName);
880
- const fnTy = fnDef?.__TypeAnnotation;
881
- (0, helper_1.zipWith_)(env.unifier.unify, argTys, fnTy?.typeArguments);
882
- env.setType(nd, fnTy?.returnType?.[0] ?? type_manager_1.naslAnyTy); // 似乎不可能为空
883
- const callInfo = (0, type_manager_1.createFunctionDef)(argTys, fnTy?.returnType?.[0] ?? type_manager_1.naslAnyTy, fnDef, undefined);
884
- env.resolvedCallInfo.set(nd, callInfo);
885
- return env.getRawType(nd);
878
+ // 前端全局类型推导 + 重载函数几乎无法做任何类型推导,只能做后置验证。后端可以推导,但简单起见,不区分前后端了。
879
+ // 总结:全局类型推导 + 重载 = 灾难
880
+ if (parseTsClassType_1.overloadedFns.includes(calleeName)) {
881
+ return handleOverloadedFunction(env, nd, tgtTy, calleeName);
886
882
  }
887
- const fnDef = env.quickGetLibDef(nd);
883
+ const fnDef = env.quickGetLibDef(nd, calleeName, env.ctxCQC?.dataSourceSqlType);
888
884
  let fnTy = fnDef?.__TypeAnnotation;
889
885
  if (!fnTy) {
890
886
  env.addError('无法找到函数定义(类型)');
@@ -898,7 +894,34 @@ function tpCallFunction(env, nd, tgtTy) {
898
894
  const elemTy = parTy.typeArguments[0];
899
895
  // 余下的一并处理
900
896
  for (let i = idx; i < nd.arguments.length; ++i) {
901
- dispatchExpr(env, nd.arguments[i], elemTy);
897
+ /**
898
+ * ListSort 只能特殊处理了。
899
+ * nasl.util 里定义为 { asc: Boolean, by: Long | Decimal | ... } 的话会有匿名数据类型不匹配报错(invariance)
900
+ * 如果定义为泛型 T2 extends Long | Decimal | ... 且 { asc: Boolean, by: T2 } 的话 T2 不支持实例化成 Union
901
+ * (页面是全局求解,暂时不好区分 T2 的约束是来自多个赋值还是一个赋值,如果是多个则报错,如果是一个则使用 Union 作为解这种复杂的机制
902
+ */
903
+ if (calleeName === 'ListSort' || calleeName === 'ListSortAsync') {
904
+ const expr = nd.arguments[i].expression;
905
+ // 抠出函数类型的参数和返回类型
906
+ if (!(0, type_predicate_2.isFuncTy)(elemTy)) {
907
+ continue; // 干不了了
908
+ }
909
+ const parTy = elemTy.typeArguments?.[0];
910
+ const retTy = elemTy.returnType?.[0];
911
+ // 留给 checker.ts 去做后置检查吧
912
+ if (expr?.concept === 'AnonymousFunction') {
913
+ tpAnonymousFunction(env, expr, (0, type_manager_1.createFnTyFromTyAnns)([parTy], undefined), true);
914
+ // dispatchExpr(env, expr.params[0], parTy);
915
+ // dispatchExpr(env, expr.body, retTy);
916
+ }
917
+ else if (expr?.concept === 'SubLogic') {
918
+ tpSubLogic(env, expr, (0, type_manager_1.createFnTyFromTyAnns)([parTy], undefined), true);
919
+ }
920
+ }
921
+ else {
922
+ // 正常处理
923
+ dispatchExpr(env, nd.arguments[i], elemTy);
924
+ }
902
925
  }
903
926
  }
904
927
  else {
@@ -1006,60 +1029,82 @@ function tpCallFunction(env, nd, tgtTy) {
1006
1029
  }
1007
1030
  }
1008
1031
  exports.tpCallFunction = tpCallFunction;
1009
- // 目前只有 CallFunction 支持重载
1010
- function tpLengthAndConvertCall(env, nd, tgtTy) {
1011
- // 处理重载函数,重载函数不能用 unify(paramTy, argTy) 只能 dispatchExpr(arg, undefined)
1012
- // 且部分情况 type arguments 还需要推
1013
- // Ensure we don't have undefined values in our argTys array
1014
- const argTys = nd.arguments.map(arg => dispatchExpr(env, arg, undefined) ?? type_manager_1.naslAnyTy);
1015
- let calleeName = nd.calleeName;
1016
- if (calleeName === 'Length') {
1017
- env.unifier.unify(type_manager_1.naslLongTy, tgtTy); // 返回类型确定
1018
- env.setType(nd, type_manager_1.naslLongTy);
1019
- // For Length function, the parameter is required
1020
- // Create a mock definition for the Length function
1021
- const mockLengthDef = {
1022
- params: [{ name: 'collection', optional: false }]
1023
- };
1024
- const callInfo = (0, type_manager_1.createFunctionDef)(argTys, type_manager_1.naslLongTy, mockLengthDef, undefined);
1025
- env.resolvedCallInfo.set(nd, callInfo); // 存储函数定义(含参数和返回类型)
1026
- return type_manager_1.naslLongTy;
1027
- }
1028
- if (calleeName === 'Convert') {
1029
- const arg0Ty = env.getRawType(nd.arguments?.[0]);
1030
- const normaliseArg0Ty = (ty) => {
1031
- switch (ty.typeKind) {
1032
- case 'primitive':
1033
- return ty;
1034
- default:
1035
- return type_manager_1.naslAnyTy;
1036
- }
1037
- };
1038
- const qName = (0, reference_manager_1.getTokenQualifiedName)(nd);
1039
- const mangledQName = (0, parseTsClassType_1.mangleOvFnName)(qName, normaliseArg0Ty(arg0Ty ?? type_manager_1.naslAnyTy));
1040
- // 检查 ConvertTo 的类型是否符合要求
1041
- const tyParam0 = env.refMgr.qNameDefs.get(mangledQName)?.__TypeAnnotation.typeParams?.[0];
1042
- const paramTys = env.refMgr.qNameDefs.get(mangledQName)?.__TypeAnnotation.typeArguments;
1043
- // 简单点
1044
- if ((0, type_predicate_2.isValidNaslTy)(nd.typeArguments?.[0])) { // @ts-expect-error
1045
- env.unifier.unify(nd.typeArguments[0], tyParam0?.constraints); // @ts-expect-error
1046
- tgtTy && env.unifier.unify(nd.typeArguments[0], tgtTy); // @ts-expect-error
1047
- env.setType(nd, nd.typeArguments[0]);
1032
+ /**
1033
+ * 处理重载函数的调用
1034
+ * @param env 语义环境
1035
+ * @param nd 函数调用节点
1036
+ * @param tgtTy 目标类型
1037
+ * @param calleeName 被调用函数名
1038
+ * @returns 处理后的类型注解
1039
+ */
1040
+ const handleOverloadedFunction = (env, nd, tgtTy, calleeName) => {
1041
+ const ovParamIdx = (0, overload_helper_1.getOvParamIdx)(calleeName);
1042
+ const argTys = [];
1043
+ for (const arg of nd.arguments) {
1044
+ argTys.push(dispatchExpr(env, arg, undefined) ?? type_manager_1.naslAnyTy);
1045
+ }
1046
+ if (calleeName === 'CAST') {
1047
+ argTys[ovParamIdx] = (0, overload_helper_1.createCastLiteralType)(nd.arguments?.[ovParamIdx]?.expression?.value ?? '');
1048
+ }
1049
+ // Convert, Length, CAST 的返回类型可以从用户选择的类型(通过 type picker)拿到
1050
+ // 其他重载函数都在 SQL 里,都在服务端逻辑里,可以立即从参数类型获得,没有页面全局类型推导的问题
1051
+ let retTy = (0, overload_helper_1.getOverloadFuncRetTy)(nd, argTys[ovParamIdx]);
1052
+ if (!retTy) {
1053
+ if (!env.isView) {
1054
+ const mangledCalleeName = (0, overload_helper_1.mangleOvFnName)(calleeName, argTys[ovParamIdx]);
1055
+ const fnDef = env.quickGetLibDef(nd, mangledCalleeName, env.ctxCQC?.dataSourceSqlType);
1056
+ const fnTy = fnDef?.__TypeAnnotation;
1057
+ retTy = fnTy?.returnType?.[0];
1048
1058
  }
1049
1059
  else {
1050
- env.setType(nd, tgtTy);
1060
+ retTy = type_manager_1.naslAnyTy;
1051
1061
  }
1052
- // Create a mock definition for parameters
1053
- const mockConvertDef = {
1054
- params: paramTys?.map(() => ({ optional: false })) || []
1055
- };
1056
- const callInfo = (0, type_manager_1.createFunctionDef)(argTys, env.getRawType(nd), mockConvertDef, undefined);
1057
- env.resolvedCallInfo.set(nd, callInfo);
1058
- return env.getRawType(nd);
1059
1062
  }
1060
- }
1063
+ env.unifier.unify(retTy, tgtTy);
1064
+ const callInfo = (0, type_manager_1.createFunctionDef)(argTys, retTy, undefined, undefined);
1065
+ env.resolvedCallInfo.set(nd, callInfo);
1066
+ const capturedDbSqlType = env.ctxCQC?.dataSourceSqlType;
1067
+ // 剩下的需要后置处理
1068
+ const postChk = (fileNode, errBoundary, severity) => (env) => {
1069
+ const argTys = nd.arguments.map((arg) => env.getType(arg.expression));
1070
+ if (calleeName === 'CAST') {
1071
+ argTys[ovParamIdx] = (0, overload_helper_1.createCastLiteralType)(nd.arguments?.[ovParamIdx]?.expression?.value ?? '');
1072
+ }
1073
+ const ovArgTy = argTys[ovParamIdx];
1074
+ const mangledCalleeName = (0, overload_helper_1.mangleOvFnName)(calleeName, ovArgTy);
1075
+ let fnDef = mangledCalleeName ? env.quickGetLibDef(nd, mangledCalleeName, capturedDbSqlType) : undefined;
1076
+ let fnTy = fnDef?.__TypeAnnotation;
1077
+ // If no matching overload found, validate and report error
1078
+ if (!fnDef || !fnTy) {
1079
+ // Create fallback definition to prevent further errors
1080
+ const fallbackDef = (0, overload_helper_1.createFallbackOverloadDef)(calleeName, nd.calleeNamespace, nd.arguments.length);
1081
+ fnDef = fallbackDef;
1082
+ fnTy = fallbackDef.__TypeAnnotation;
1083
+ // Convert 允许接收任何类型,跳过报错(mangled name convertList convertMap 等查不到定义会产生额外错误)
1084
+ if (calleeName !== 'Convert') {
1085
+ const possibleTypes = (0, overload_helper_1.getOverloadParameterTypes)(env, nd, capturedDbSqlType);
1086
+ if (possibleTypes.length > 0) {
1087
+ const errorMsg = (0, sem_diag_1.createOverloadTypeError)(calleeName, ovArgTy, possibleTypes);
1088
+ // precise error boundary nd.arguments[i]! is not working here, why?
1089
+ env.addError(errorMsg, fileNode, errBoundary, severity);
1090
+ }
1091
+ }
1092
+ }
1093
+ // 后置类型校验,暂时都不需要,不可能报错
1094
+ // for (let i = 0; i < argTys.length && i < (fnTy?.typeArguments?.length ?? 0); ++i) {
1095
+ // const sub = argTys[i];
1096
+ // const sup = fnTy!.typeArguments![i];
1097
+ // if (!isSubTy(env, sub, sup)) { // precise error boundary nd.arguments[i]! is not working here, why?
1098
+ // env.addError(mkIncompatibleTyErr(env, sub, sup), fileNode, errBoundary, severity);
1099
+ // }
1100
+ // }
1101
+ };
1102
+ env.addPostCheckTask(nd, postChk(env.getCurFileNode(), nd, env.errSeverity));
1103
+ env.setType(nd, retTy); // 似乎不可能为空
1104
+ return env.getRawType(nd);
1105
+ };
1061
1106
  function tpCallInterface(env, nd, tgtTy) {
1062
- const qName = (0, reference_manager_1.getTokenQualifiedName)(nd);
1107
+ const qName = (0, get_q_name_1.getTokenQualifiedName)(nd);
1063
1108
  if (!qName) {
1064
1109
  env.setType(nd, type_manager_1.naslAnyTy);
1065
1110
  return type_manager_1.naslAnyTy;
@@ -1089,7 +1134,7 @@ exports.tpCallInterface = tpCallInterface;
1089
1134
  exports.tpCallAuthInterface = tpCallInterface;
1090
1135
  exports.tpCallMicroserviceInterface = tpCallInterface;
1091
1136
  exports.tpCallConnector = tpCallLogic;
1092
- function tpAnonymousFunction(env, nd, tgtTy) {
1137
+ function tpAnonymousFunction(env, nd, tgtTy, isListSort = false) {
1093
1138
  if (!tgtTy || !(0, type_predicate_2.isFuncTy)(tgtTy)) {
1094
1139
  env.setType(nd, type_manager_1.naslAnyTy);
1095
1140
  env.addError((0, sem_diag_1.mkIncompatibleTyErr)(env, '函数', tgtTy || type_manager_1.naslAnyTy));
@@ -1104,22 +1149,22 @@ function tpAnonymousFunction(env, nd, tgtTy) {
1104
1149
  const ctxParTy = tgtTy.typeArguments[idx];
1105
1150
  ctxParTy && env.setType(param, ctxParTy);
1106
1151
  });
1107
- dispatchExpr(env, nd.body, tgtTy?.returnType?.[0]);
1152
+ dispatchExpr(env, nd.body, isListSort ? undefined : tgtTy?.returnType?.[0]);
1108
1153
  env.setType(nd, (0, type_manager_1.createFnTyFromTyAnns)(// @ts-expect-error
1109
1154
  nd.params.map(env.getRawType), env.getRawType(nd.body) ?? type_manager_1.naslAnyTy));
1110
1155
  paramsArr.forEach(p => env.removeVar(p));
1111
1156
  const ndTy = env.getRawType(nd);
1112
- env.unifier.unify(ndTy, tgtTy);
1157
+ !isListSort && env.unifier.unify(ndTy, tgtTy);
1113
1158
  return ndTy;
1114
1159
  }
1115
- function tpSubLogic(env, nd, tgtTy) {
1160
+ function tpSubLogic(env, nd, tgtTy, isListSort = false) {
1116
1161
  // 若非前端,则 shallow copy,因为内部会触发 solve,会把进来前的约束清掉;
1117
1162
  // 若是前端,则无需 copy
1118
1163
  const csCopy = env.isView ? env.unifier.cs : new Map(env.unifier.cs);
1119
1164
  const subLogicVars = [...nd.params, ...nd.returns, ...nd.variables];
1120
1165
  subLogicVars.forEach(v => (0, dispatch_def_1.dispatchDef)(env, v));
1121
1166
  // 处理 tgtTy 缺失的情况
1122
- if (tgtTy && !(0, type_predicate_2.isFuncTy)(tgtTy)) {
1167
+ if (tgtTy && !(0, type_predicate_2.isFuncTy)(tgtTy) && !isListSort) {
1123
1168
  env.setType(nd, type_manager_1.naslAnyTy);
1124
1169
  env.addError((0, sem_diag_1.mkIncompatibleTyErr)(env, '函数', tgtTy));
1125
1170
  return (0, type_manager_1.createFnTyFromTyAnns)([], type_manager_1.naslAnyTy);
@@ -1137,7 +1182,7 @@ function tpSubLogic(env, nd, tgtTy) {
1137
1182
  const ndTy = (0, type_manager_1.createRefTyAnnFromDef)(nd, env);
1138
1183
  env.setType(nd, ndTy);
1139
1184
  env.unifier.cs = csCopy;
1140
- env.unifier.unify(ndTy, tgtTy); // 这里需要额外的 unify,否则 SubLogic 算出来的类型不能与外侧进来时的约束产生关系
1185
+ !isListSort && env.unifier.unify(ndTy, tgtTy); // 这里需要额外的 unify,否则 SubLogic 算出来的类型不能与外侧进来时的约束产生关系
1141
1186
  return ndTy;
1142
1187
  }
1143
1188
  function tpArgument(env, nd, tgtTy) {
@@ -1197,7 +1242,7 @@ function tpCallQueryComponent(env, nd, tgtTy) {
1197
1242
  env.setType(nd, prop.typeAnnotation);
1198
1243
  env.unifier.unify(env.getRawType(nd), tgtTy);
1199
1244
  // @ts-expect-error
1200
- nd.$propQName = (0, reference_manager_1.getPropQName)(entityQName, prop.name, 'Entity');
1245
+ nd.$propQName = (0, string_1.getPropQName)(entityQName, prop.name, 'Entity');
1201
1246
  }
1202
1247
  }
1203
1248
  }
@@ -1259,7 +1304,7 @@ function tpCallQueryComponent(env, nd, tgtTy) {
1259
1304
  if (!entityQName) {
1260
1305
  continue;
1261
1306
  }
1262
- const aggrTy = calcAggrTy((0, reference_manager_1.getPropQName)(entityQName, aggrPar.propertyName, 'Entity'), se.aggregateName);
1307
+ const aggrTy = calcAggrTy((0, string_1.getPropQName)(entityQName, aggrPar.propertyName, 'Entity'), se.aggregateName);
1263
1308
  env.setType(aggrPar, aggrTy);
1264
1309
  env.setType(se, aggrTy);
1265
1310
  se.asName && aggrAsNames.set(se.asName, aggrTy);
@@ -1285,7 +1330,7 @@ function tpCallQueryComponent(env, nd, tgtTy) {
1285
1330
  // 选了几个属性,每个属性都是一个独立的 QueryFieldExpression
1286
1331
  if (qfe.propertyName?.length > 0) {
1287
1332
  !hasAggr && (0, helper_1.createOnPush)(selMap, entityQName, qfe.propertyName);
1288
- seTy = (0, fp_macros_1.IfBind)(env.refMgr.qNameDefs.get((0, reference_manager_1.getPropQName)(entityQName, qfe.propertyName, 'Entity')))(prop => prop.typeAnnotation)((0, fp_macros_1.feed)(undefined));
1333
+ seTy = (0, fp_macros_1.IfBind)(env.refMgr.qNameDefs.get((0, string_1.getPropQName)(entityQName, qfe.propertyName, 'Entity')))(prop => prop.typeAnnotation)((0, fp_macros_1.feed)(undefined));
1289
1334
  }
1290
1335
  else { // 全选时 seTy 为 Entity 类型
1291
1336
  seTy = (0, fp_macros_1.IfBind)(env.refMgr.qNameDefs.get(`${entityQName}`))(def => env.getRawType(def))((0, fp_macros_1.feed)(undefined));
@@ -1322,12 +1367,12 @@ function tpCallQueryComponent(env, nd, tgtTy) {
1322
1367
  // const len = nd.groupBy.length + aggrAsNames.size;
1323
1368
  const allKeys = Array.from(groupByAsNames.keys()).concat(Array.from(aggrAsNames.keys()));
1324
1369
  const allTys = Array.from(groupByAsNames.values()).concat(Array.from(aggrAsNames.values()));
1325
- retTy = (0, type_manager_1.createListTyAnn)((0, type_manager_1.createAnonymousTyAnnIfNecessary)(allKeys.map(reference_manager_1.lowercaseFirstChar), allTys) ?? type_manager_1.naslAnyTy);
1370
+ retTy = (0, type_manager_1.createListTyAnn)((0, type_manager_1.createAnonymousTyAnnIfNecessary)(allKeys.map(string_1.lowercaseFirstChar), allTys) ?? type_manager_1.naslAnyTy);
1326
1371
  }
1327
1372
  else if (!hasGroupBy && hasAggr) {
1328
1373
  const aggrKeys = Array.from(aggrAsNames.keys());
1329
1374
  const aggrTys = Array.from(aggrAsNames.values());
1330
- retTy = (0, type_manager_1.createAnonymousTyAnnIfNecessary)(aggrKeys.map(reference_manager_1.lowercaseFirstChar), aggrTys);
1375
+ retTy = (0, type_manager_1.createAnonymousTyAnnIfNecessary)(aggrKeys.map(string_1.lowercaseFirstChar), aggrTys);
1331
1376
  }
1332
1377
  else {
1333
1378
  // 太乱了,之后重构
@@ -1345,13 +1390,13 @@ function tpCallQueryComponent(env, nd, tgtTy) {
1345
1390
  }
1346
1391
  else {
1347
1392
  const tyAnns = selProps.map(prop => {
1348
- const qName = (0, reference_manager_1.getPropQName)(entityQName, prop, 'Entity');
1393
+ const qName = (0, string_1.getPropQName)(entityQName, prop, 'Entity');
1349
1394
  return env.refMgr.qNameDefs.get(qName)?.typeAnnotation ?? type_manager_1.naslAnyTy;
1350
1395
  });
1351
- return (0, type_manager_1.createAnonymousTyAnn)(selProps.map(reference_manager_1.lowercaseFirstChar), tyAnns);
1396
+ return (0, type_manager_1.createAnonymousTyAnn)(selProps.map(string_1.lowercaseFirstChar), tyAnns);
1352
1397
  }
1353
1398
  });
1354
- retTy = (0, type_manager_1.createListTyAnn)((0, type_manager_1.createAnonymousTyAnn)(selShortNames.map(reference_manager_1.lowercaseFirstChar), tys));
1399
+ retTy = (0, type_manager_1.createListTyAnn)((0, type_manager_1.createAnonymousTyAnn)(selShortNames.map(string_1.lowercaseFirstChar), tys));
1355
1400
  }
1356
1401
  // 2.11 之前才有,升级脚本也没管,需要特殊处理
1357
1402
  if (nd.limit) {
@@ -1578,7 +1623,7 @@ const extractNameTyPair = (env, ty) => {
1578
1623
  return ty.properties.map((p, _) => [p.name, p.typeAnnotation]);
1579
1624
  }
1580
1625
  else if (ty) {
1581
- return (0, fp_macros_1.IfBind)((0, reference_manager_1.getTokenQualifiedName)(ty))(qName => env.refMgr.qNameDefs.get(qName)
1626
+ return (0, fp_macros_1.IfBind)((0, get_q_name_1.getTokenQualifiedName)(ty))(qName => env.refMgr.qNameDefs.get(qName)
1582
1627
  ?.properties
1583
1628
  .map((p, _) => [p.name, p.typeAnnotation ?? null]))((0, fp_macros_1.feed)([]));
1584
1629
  }
@@ -1722,7 +1767,7 @@ function tpMatch(env, nd, tgtTy) {
1722
1767
  const isRefined = shouldRefine(nd.expression);
1723
1768
  let matchedVarName = undefined;
1724
1769
  if (isRefined) {
1725
- matchedVarName = (0, reference_manager_1.getTokenQualifiedNameForMatchedExpr)(env, nd.expression);
1770
+ matchedVarName = (0, get_q_name_1.getTokenQualifiedNameForMatchedExpr)(env, nd.expression);
1726
1771
  const freshMatchedVar = nasl_concepts_1.Variable.createProtoTypeOnly({
1727
1772
  name: matchedVarName,
1728
1773
  typeAnnotation: exprRefinedTy
@@ -1809,7 +1854,7 @@ function tpEntityLogic(env, nd, tgtTy) {
1809
1854
  // 例如 app.dataSources.${dbName}.entities.${entityName}
1810
1855
  // 从 'a.b.c.logics.e' 中提取 'a.b.c'
1811
1856
  const getEntityQName = (ctxCallLogic) => {
1812
- const qualifiedNames = (0, reference_manager_1.getTokenQualifiedName)(ctxCallLogic);
1857
+ const qualifiedNames = (0, get_q_name_1.getTokenQualifiedName)(ctxCallLogic);
1813
1858
  const parts = qualifiedNames.split('.');
1814
1859
  return parts.slice(0, parts.length - 2).join('.');
1815
1860
  };
@@ -1982,7 +2027,6 @@ const tpNewStructure = (env, nd, tgtTy) => {
1982
2027
  return ndTy;
1983
2028
  };
1984
2029
  // 一个通用的方法,获取各种连线右侧的逻辑项
1985
- // calculate type of the right-hand side of each assignment line
1986
2030
  const getRightByLine = (nd, itemIdx, memIdx) => {
1987
2031
  if (memIdx !== undefined) {
1988
2032
  return toRaw(nd.rights[itemIdx].members[memIdx]);