@lcap/nasl-language-server-core 4.4.0-beta.17 → 4.4.0-beta.19

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 (45) hide show
  1. package/out/checker.d.ts.map +1 -1
  2. package/out/checker.js +139 -2
  3. package/out/checker.js.map +1 -1
  4. package/out/reference-manager/reference-manager.d.ts +6 -1
  5. package/out/reference-manager/reference-manager.d.ts.map +1 -1
  6. package/out/reference-manager/reference-manager.js +17 -5
  7. package/out/reference-manager/reference-manager.js.map +1 -1
  8. package/out/typer/collectGlobalDefs.js +1 -1
  9. package/out/typer/collectGlobalDefs.js.map +1 -1
  10. package/out/typer/component-def-manager/component-def-manager.d.ts +16 -0
  11. package/out/typer/component-def-manager/component-def-manager.d.ts.map +1 -1
  12. package/out/typer/component-def-manager/component-def-manager.js +61 -0
  13. package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
  14. package/out/typer/component-def-manager/utils.d.ts.map +1 -1
  15. package/out/typer/component-def-manager/utils.js +25 -0
  16. package/out/typer/component-def-manager/utils.js.map +1 -1
  17. package/out/typer/dispatch-all.d.ts +3 -1
  18. package/out/typer/dispatch-all.d.ts.map +1 -1
  19. package/out/typer/dispatch-all.js +46 -3
  20. package/out/typer/dispatch-all.js.map +1 -1
  21. package/out/typer/dispatch-expr.d.ts.map +1 -1
  22. package/out/typer/dispatch-expr.js +22 -23
  23. package/out/typer/dispatch-expr.js.map +1 -1
  24. package/out/typer/incremental-update.d.ts.map +1 -1
  25. package/out/typer/incremental-update.js +21 -9
  26. package/out/typer/incremental-update.js.map +1 -1
  27. package/out/typer/solver.d.ts +8 -9
  28. package/out/typer/solver.d.ts.map +1 -1
  29. package/out/typer/solver.js +43 -32
  30. package/out/typer/solver.js.map +1 -1
  31. package/out/typer/subster.d.ts.map +1 -1
  32. package/out/typer/subster.js +35 -2
  33. package/out/typer/subster.js.map +1 -1
  34. package/out/typer/type-manager.d.ts.map +1 -1
  35. package/out/typer/type-manager.js +3 -3
  36. package/out/typer/type-manager.js.map +1 -1
  37. package/out/typer/type-predicate.js +1 -1
  38. package/out/typer/type-predicate.js.map +1 -1
  39. package/out/typer/typer.d.ts.map +1 -1
  40. package/out/typer/typer.js +14 -3
  41. package/out/typer/typer.js.map +1 -1
  42. package/out/typer/unifier.d.ts.map +1 -1
  43. package/out/typer/unifier.js +22 -22
  44. package/out/typer/unifier.js.map +1 -1
  45. package/package.json +5 -5
@@ -1 +1 @@
1
- {"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../src/checker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EAC4C,QAAQ,EAC5B,IAAI,EAQ+E,GAAG,EAMxH,QAAQ,EAGT,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;AAWpE,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;AAkPF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCA0kKpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;iDAlwFY,GAAG,KAAG,IAAI;;iBA6wFjD,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBA3lKF,UAAU,WAAW,MAAM,YAAY,YAAY;sCAm1D/B,IAAI,GAAG,QAAQ;2CA2yGxC,UAAU,gBACV,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,gBAC/C,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,qBACvB,MAAM,EAAE,oBACT,CAAC,YAAY,EAAE,UAAU,KAAK,UAAU,EAAE,KAC3D,kBAAkB,GAAG,IAAI;EAwF7B;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;AAMD,eAAO,MAAM,6BAA6B,aAC9B,UAAU,+DAGnB,MAAM,gBAAgB,CAyCxB,CAAC;AAMF,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,EAC4C,QAAQ,EAC5B,IAAI,EAQ+E,GAAG,EAMxH,QAAQ,EAGT,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;AAYpE,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;AAkPF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCAypKpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;iDA9wFY,GAAG,KAAG,IAAI;;iBAyxFjD,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBA1qKF,UAAU,WAAW,MAAM,YAAY,YAAY;sCAu3D/B,IAAI,GAAG,QAAQ;2CAs1GxC,UAAU,gBACV,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,gBAC/C,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,qBACvB,MAAM,EAAE,oBACT,CAAC,YAAY,EAAE,UAAU,KAAK,UAAU,EAAE,KAC3D,kBAAkB,GAAG,IAAI;EAwF7B;AAqED,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;AAMD,eAAO,MAAM,6BAA6B,aAC9B,UAAU,+DAGnB,MAAM,gBAAgB,CAyCxB,CAAC;AAMF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
package/out/checker.js CHANGED
@@ -14,6 +14,7 @@ const lodash_1 = require("lodash");
14
14
  const asserts_1 = require("@lcap/nasl-concepts/asserts");
15
15
  const helper_1 = require("./typer/helper");
16
16
  const semantic_rules_1 = require("./semantic-rules");
17
+ const view_element_field_attrs_1 = require("@lcap/nasl-concepts/view-element-field-attrs");
17
18
  const regeExp = new nasl_utils_1.ExpressionLexer();
18
19
  regeExp.profile = nasl_utils_1.profiles.js;
19
20
  var Severity;
@@ -775,6 +776,31 @@ function createErrorDiagnoser(context) {
775
776
  }
776
777
  return false;
777
778
  }
779
+ /**
780
+ * 获取 ViewElement 的数据源类型(T 或 T1)
781
+ * 参考 util.js 中的 getDataTypeOfViewElement 实现
782
+ */
783
+ function getDataSourceTypeAnnotation(viewElement) {
784
+ // 向上查找定义了数据源类型的祖先组件
785
+ let currentNode = viewElement;
786
+ let depth = 0;
787
+ const maxSearchDepth = 5;
788
+ while (currentNode?.concept === 'ViewElement' && depth <= maxSearchDepth) {
789
+ // 使用 __ViewElementTV 获取类型,与 IDE 前端 getDataTypeOfViewElement 保持一致
790
+ if (currentNode.__TypeAnnotation && currentNode.__ViewElementTV?.length) {
791
+ // 先查找 T1(动态列),若无再查找 T(普通数据源组件)
792
+ const t1 = currentNode.__ViewElementTV.find((x) => x.rawName === 'T1');
793
+ if (t1?.renamed)
794
+ return t1.renamed;
795
+ const t = currentNode.__ViewElementTV.find((x) => x.rawName === 'T');
796
+ if (t?.renamed)
797
+ return t.renamed;
798
+ }
799
+ currentNode = currentNode.parentNode;
800
+ depth++;
801
+ }
802
+ return undefined;
803
+ }
778
804
  /**
779
805
  * 是否在赋值左侧
780
806
  * @param node
@@ -1252,6 +1278,11 @@ function createErrorDiagnoser(context) {
1252
1278
  });
1253
1279
  }
1254
1280
  }
1281
+ if (node.interfaces?.length) {
1282
+ yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.interfaces, function* (node) {
1283
+ yield* checkNode(node);
1284
+ });
1285
+ }
1255
1286
  yield* checkNode(node.configuration);
1256
1287
  if (node.type === 'sharedApp') {
1257
1288
  const status = getStatusOfSharedApp(node);
@@ -1838,6 +1869,9 @@ function createErrorDiagnoser(context) {
1838
1869
  * @param node
1839
1870
  */
1840
1871
  function* checkEnum(node) {
1872
+ if (!node.valueType) {
1873
+ error(node, `枚举 ${node.name} 缺少值类型定义`);
1874
+ }
1841
1875
  if (node.enumItems?.length) {
1842
1876
  yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.enumItems, function* (node) {
1843
1877
  yield* checkNode(node);
@@ -1973,8 +2007,10 @@ function createErrorDiagnoser(context) {
1973
2007
  yield* checkNode(node);
1974
2008
  });
1975
2009
  }
1976
- if (ensureNodeKeyExists(node, 'originLogicName')) {
1977
- if (nasl_concepts_1.asserts.isApp(node.parentNode)) {
2010
+ // 仅对内部接口(app.interfaces,由 Logic 导出)校验 originLogicName;外部接口(interfaceDependencies 等)无此字段
2011
+ const isInternalInterface = nasl_concepts_1.asserts.isApp(node.parentNode);
2012
+ if (isInternalInterface) {
2013
+ if (ensureNodeKeyExists(node, 'originLogicName')) {
1978
2014
  const originLogicName = node.originLogicName;
1979
2015
  const ref = app.logics.find((item) => item.name === originLogicName);
1980
2016
  if (!ref) {
@@ -2346,6 +2382,31 @@ function createErrorDiagnoser(context) {
2346
2382
  }
2347
2383
  yield* checkPlayground(node.playground);
2348
2384
  yield* checkBindExpressions(node);
2385
+ // 检查数据源上的字段属性是否在类型上存在
2386
+ // 判断条件:
2387
+ // 1. 属性的 setter 是 PropertySelectSetter(从组件定义的 ViewComponentDeclaration 中获取)
2388
+ // 2. 或者属性在 FIELD_ATTRS_BY_COMPONENT 配置中(兼容老版本组件配置)
2389
+ if (node.type === 'string' && typeof node.value === 'string' && node.value) {
2390
+ const viewElement = node.parentNode;
2391
+ if (viewElement?.concept === 'ViewElement') {
2392
+ // 优先检查组件定义中的 PropertySelectSetter
2393
+ const isPropertySelect = env.refMgr.compDefMgr.isPropertySelectSetter(viewElement.tag, node.name);
2394
+ // 同时兼容 FIELD_ATTRS_BY_COMPONENT 配置
2395
+ const needsFieldCheck = isPropertySelect || (0, view_element_field_attrs_1.shouldCheckFieldExists)(viewElement.tag, node.name);
2396
+ if (needsFieldCheck) {
2397
+ const dataSourceType = getDataSourceTypeAnnotation(viewElement);
2398
+ if (dataSourceType) {
2399
+ const { exists, missingField } = checkFieldExistsInType(env, dataSourceType, node.value);
2400
+ if (!exists && missingField) {
2401
+ // 优先从组件定义中获取属性标题,兜底使用硬编码配置
2402
+ const attrTitle = env.refMgr.compDefMgr.getPropTitle(viewElement.tag, node.name)
2403
+ || (0, view_element_field_attrs_1.getFieldAttrTitle)(node.name);
2404
+ error(node, `${attrTitle} "${missingField}" 在数据类型上不存在`);
2405
+ }
2406
+ }
2407
+ }
2408
+ }
2409
+ }
2349
2410
  // 检查不可复制属性开启双向绑定
2350
2411
  if ((node.model || node.sync) && node.expression) {
2351
2412
  const bindExpression = node.expression;
@@ -2441,6 +2502,11 @@ function createErrorDiagnoser(context) {
2441
2502
  // 任务完成人为空会有一个提示信息
2442
2503
  error(node, `${title}为空`);
2443
2504
  }
2505
+ if (Array.isArray(node.fromLogics)) {
2506
+ yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.fromLogics, function* (node) {
2507
+ yield* checkNode(node);
2508
+ });
2509
+ }
2444
2510
  }
2445
2511
  /**
2446
2512
  * 检查 元素指令
@@ -3781,12 +3847,18 @@ function createErrorDiagnoser(context) {
3781
3847
  */
3782
3848
  function* checkForEachStatement(node) {
3783
3849
  env.enterScope(node);
3850
+ if (ensureNodeKeyExists(node, 'item')) {
3851
+ yield* checkNode(node.item);
3852
+ }
3784
3853
  if (ensureNodeKeyExists(node, 'each')) {
3785
3854
  yield* checkNode(node.each);
3786
3855
  }
3787
3856
  if (ensureNodeKeyExists(node, 'start')) {
3788
3857
  yield* checkNode(node.start);
3789
3858
  }
3859
+ if (node.end) {
3860
+ yield* checkNode(node.end);
3861
+ }
3790
3862
  if (node.body?.length) {
3791
3863
  yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.body, function* (node) {
3792
3864
  yield* checkNode(node);
@@ -4537,6 +4609,9 @@ function createErrorDiagnoser(context) {
4537
4609
  yield* checkNode(node);
4538
4610
  });
4539
4611
  }
4612
+ else {
4613
+ error(node, 'Join 子句的关联关系不能为空');
4614
+ }
4540
4615
  if (node.joinParts?.length) {
4541
4616
  yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.joinParts, function* (node) {
4542
4617
  yield* checkNode(node);
@@ -5157,6 +5232,10 @@ function createErrorDiagnoser(context) {
5157
5232
  // TODO: checkNodeIsFileModuleInIdeWithCache 也慢,后续可以优化
5158
5233
  const isFileModule = fileNodes.length ? (0, file_node_cache_1.checkNodeIsFileModuleInIdeWithCache)(node) : true;
5159
5234
  if (isFileModule) {
5235
+ // 增量更新时按文件逐个 checkNode,需重置闭包状态;若本文件在 Module 内,inModule 需为 true(否则不会经过 checkModule,inModule 会失效)
5236
+ inModule = !!node.getAncestor?.('Module');
5237
+ inPlayground = 0;
5238
+ inAuthLogic = false;
5160
5239
  fileNodes.push(node);
5161
5240
  let diagnostics = diagnosticMap.get(node);
5162
5241
  if (!diagnostics) {
@@ -5373,6 +5452,64 @@ function createErrorDiagnoser(context) {
5373
5452
  };
5374
5453
  }
5375
5454
  exports.createErrorDiagnoser = createErrorDiagnoser;
5455
+ /**
5456
+ * 检查字段路径是否在类型上存在
5457
+ * 类似于 s-component-attr-form.vue 中的 findPropertyNode 功能
5458
+ * @param env 语义环境
5459
+ * @param dataType 数据源类型
5460
+ * @param fieldPath 字段路径,如 "name" 或 "user.name"
5461
+ * @returns { exists: boolean, missingField?: string } 如果字段不存在,返回第一个不存在的字段名
5462
+ */
5463
+ function checkFieldExistsInType(env, dataType, fieldPath) {
5464
+ if (!dataType || !fieldPath) {
5465
+ return { exists: true }; // 没有类型信息或字段路径时,跳过检查
5466
+ }
5467
+ const fieldParts = fieldPath.split('.');
5468
+ let currentType = dataType;
5469
+ for (const fieldName of fieldParts) {
5470
+ if (!currentType) {
5471
+ return { exists: false, missingField: fieldName };
5472
+ }
5473
+ // 获取类型的 properties
5474
+ let properties;
5475
+ if (currentType.typeKind === 'anonymousStructure') {
5476
+ properties = currentType.properties;
5477
+ }
5478
+ else if (currentType.typeKind === 'reference') {
5479
+ // 对于引用类型,需要解析引用
5480
+ const resolved = env.resolveRef(currentType);
5481
+ // @ts-expect-error
5482
+ properties = resolved?.properties;
5483
+ }
5484
+ else if (currentType.typeKind === 'generic' && currentType.typeName === 'List') {
5485
+ // 对于 List<T>,检查 T 的属性
5486
+ currentType = currentType.typeArguments?.[0];
5487
+ if (currentType?.typeKind === 'anonymousStructure') {
5488
+ properties = currentType.properties;
5489
+ }
5490
+ else if (currentType?.typeKind === 'reference') {
5491
+ const resolved = env.resolveRef(currentType);
5492
+ // @ts-expect-error
5493
+ properties = resolved?.properties;
5494
+ }
5495
+ }
5496
+ if (!properties) {
5497
+ // 类型没有 properties,可能是基本类型或未解析的类型
5498
+ // 对于未解析的类型,跳过检查
5499
+ if ((0, type_predicate_1.isTyAnnTyParam)(currentType) || (0, type_predicate_1.isAnyTy)(currentType)) {
5500
+ return { exists: true };
5501
+ }
5502
+ return { exists: false, missingField: fieldName };
5503
+ }
5504
+ const prop = properties.find((p) => p.name === fieldName);
5505
+ if (!prop) {
5506
+ return { exists: false, missingField: fieldName };
5507
+ }
5508
+ // 继续检查下一级
5509
+ currentType = prop.typeAnnotation;
5510
+ }
5511
+ return { exists: true };
5512
+ }
5376
5513
  function deduplicateDiagnostics(diagnostics) {
5377
5514
  return (0, lodash_1.uniqWith)(diagnostics, (a, b) => a.node === b.node && a.message === b.message);
5378
5515
  }