@lcap/nasl-language-server-core 4.5.0-beta.6 → 4.5.0-beta.7
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/out/checker.d.ts.map +1 -1
- package/out/checker.js +126 -19
- package/out/checker.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +13 -1
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/typer/subster.d.ts.map +1 -1
- package/out/typer/subster.js +52 -12
- package/out/typer/subster.js.map +1 -1
- package/out/typer/typer.d.ts +29 -0
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +65 -0
- package/out/typer/typer.js.map +1 -1
- package/out/utils/scope-boundary.d.ts +55 -0
- package/out/utils/scope-boundary.d.ts.map +1 -0
- package/out/utils/scope-boundary.js +79 -0
- package/out/utils/scope-boundary.js.map +1 -0
- package/out/utils/type-operator.d.ts.map +1 -1
- package/out/utils/type-operator.js +1 -1
- package/out/utils/type-operator.js.map +1 -1
- package/package.json +5 -5
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,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;
|
|
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;AAcpE,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;AAOF,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;AAmPF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCAmxKpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;iDAxzFY,GAAG,KAAG,IAAI;;iBAm0FjD,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBA9xKF,UAAU,WAAW,MAAM,YAAY,YAAY;sCAq6D/B,IAAI,GAAG,QAAQ;2CA45GxC,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
|
@@ -16,6 +16,7 @@ const helper_1 = require("./typer/helper");
|
|
|
16
16
|
const semantic_rules_1 = require("./semantic-rules");
|
|
17
17
|
const view_element_field_attrs_1 = require("@lcap/nasl-concepts/view-element-field-attrs");
|
|
18
18
|
const reference_manager_1 = require("./reference-manager/reference-manager");
|
|
19
|
+
const scope_boundary_1 = require("./utils/scope-boundary");
|
|
19
20
|
const regeExp = new nasl_utils_1.ExpressionLexer();
|
|
20
21
|
regeExp.profile = nasl_utils_1.profiles.js;
|
|
21
22
|
var Severity;
|
|
@@ -649,6 +650,16 @@ function createErrorDiagnoser(context) {
|
|
|
649
650
|
memberExpression = currentNode;
|
|
650
651
|
currentNode = currentNode.parentNode;
|
|
651
652
|
}
|
|
653
|
+
// 检查变量是否因作用域边界隔离而不可见(而非真正未定义)
|
|
654
|
+
if (env.isBlockedByScopeBoundary(name)) {
|
|
655
|
+
const bindAttr = node.getAncestor('BindAttribute');
|
|
656
|
+
const viewElement = node.getAncestor('ViewElement');
|
|
657
|
+
const compTitle = (viewElement && (0, scope_boundary_1.getCompTitle)(viewElement.tag)) ?? '当前组件';
|
|
658
|
+
const attrName = bindAttr?.name ?? '';
|
|
659
|
+
const attrHint = attrName ? `的"${attrName}"属性` : '';
|
|
660
|
+
error(memberExpression ?? node, `"${name}" 在此处不可用:${compTitle}${attrHint}不允许访问父级作用域中的变量`);
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
652
663
|
let message = `所选择的内容 ${name} 未定义`;
|
|
653
664
|
const scope = memberExpression?.constructor?.nodeTitle;
|
|
654
665
|
if (scope) {
|
|
@@ -2405,16 +2416,43 @@ function createErrorDiagnoser(context) {
|
|
|
2405
2416
|
// HACK u-table-view-expander 的BindAttribute节点存在脏的item,因此降级
|
|
2406
2417
|
const isTempWarningMode = node.parentNode?.concept === 'ViewElement' &&
|
|
2407
2418
|
node.parentNode?.tag === 'u-table-view-expander';
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2419
|
+
// 判断当前属性是否为作用域边界属性(需要隔离父级 View 变量)
|
|
2420
|
+
const parentTag = node.parentNode?.tag;
|
|
2421
|
+
const isAttrScopeBoundary = !!(parentTag && (0, scope_boundary_1.isScopeBoundaryAttr)(parentTag, node.name));
|
|
2422
|
+
// 判断当前属性是否要求表达式必须为服务端 CallLogic
|
|
2423
|
+
const backendLogicInfo = parentTag ? (0, scope_boundary_1.getBackendLogicAttrInfo)(parentTag, node.name) : undefined;
|
|
2424
|
+
// 表达式是否不符合"必须为 CallLogic"的约束(仅在有该约束时才为 true)
|
|
2425
|
+
const isNotCallLogicViolation = !!(backendLogicInfo && !(0, asserts_1.isCallLogic)(node.expression));
|
|
2426
|
+
if (isNotCallLogicViolation) {
|
|
2427
|
+
error(node, `${backendLogicInfo.compTitle}的${backendLogicInfo.attrTitle}必须是调用逻辑`);
|
|
2428
|
+
}
|
|
2429
|
+
if (isAttrScopeBoundary) {
|
|
2430
|
+
env.pushScopeBoundary();
|
|
2412
2431
|
}
|
|
2413
|
-
|
|
2414
|
-
|
|
2432
|
+
try {
|
|
2433
|
+
if (isTempWarningMode || isNotCallLogicViolation) {
|
|
2434
|
+
// isTempWarningMode:已知节点存在脏数据,降级为警告
|
|
2435
|
+
// isNotCallLogicViolation:表达式类型不符合约束,深度检查意义不大,
|
|
2436
|
+
// 降级为警告以避免产生无关噪音诊断
|
|
2437
|
+
inPlayground++;
|
|
2438
|
+
try {
|
|
2439
|
+
yield* checkNode(node.expression);
|
|
2440
|
+
}
|
|
2441
|
+
finally {
|
|
2442
|
+
inPlayground--;
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
else {
|
|
2446
|
+
yield* checkNode(node.expression);
|
|
2447
|
+
}
|
|
2448
|
+
yield* checkPlayground(node.playground);
|
|
2449
|
+
yield* checkBindExpressions(node);
|
|
2450
|
+
}
|
|
2451
|
+
finally {
|
|
2452
|
+
if (isAttrScopeBoundary) {
|
|
2453
|
+
env.popScopeBoundary();
|
|
2454
|
+
}
|
|
2415
2455
|
}
|
|
2416
|
-
yield* checkPlayground(node.playground);
|
|
2417
|
-
yield* checkBindExpressions(node);
|
|
2418
2456
|
// 检查数据源上的字段属性是否在类型上存在
|
|
2419
2457
|
// 判断条件:
|
|
2420
2458
|
// 1. 属性的 setter 是 PropertySelectSetter(从组件定义的 ViewComponentDeclaration 中获取)
|
|
@@ -3521,19 +3559,79 @@ function createErrorDiagnoser(context) {
|
|
|
3521
3559
|
const authLogic = node.getAncestor('AuthLogic');
|
|
3522
3560
|
error(authLogic, `鉴权逻辑 ${authLogic.name} 不允许调用 服务端逻辑`);
|
|
3523
3561
|
}
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3562
|
+
// 检查处于 requireBackendLogic 配置属性内的 CallLogic:
|
|
3563
|
+
// 1. 必须调用服务端逻辑
|
|
3564
|
+
// 2. 必须为 page 和 size 指定服务端入参,且不能重复
|
|
3565
|
+
const callLogicViewElement = node.getAncestor('ViewElement');
|
|
3566
|
+
const callLogicBindAttrName = node.parentNode?.name;
|
|
3567
|
+
const callLogicAttrInfo = (callLogicViewElement && callLogicBindAttrName)
|
|
3568
|
+
? (0, scope_boundary_1.getBackendLogicAttrInfo)(callLogicViewElement.tag, callLogicBindAttrName)
|
|
3569
|
+
: undefined;
|
|
3570
|
+
if (callLogicAttrInfo) {
|
|
3571
|
+
if (!node.calleeNamespace?.startsWith('app.logics')) {
|
|
3572
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}作用域下必须调用服务端逻辑`);
|
|
3573
|
+
// 已报错,跳过后续 page/size 参数检查,但仍走正常返回路径
|
|
3574
|
+
return env.getType(node);
|
|
3575
|
+
}
|
|
3576
|
+
const ref = env.resolveRef(node);
|
|
3577
|
+
const REQUIRED_PARAMS = ['page', 'size'];
|
|
3578
|
+
const definedParams = ref?.params ?? [];
|
|
3579
|
+
let hasError = false;
|
|
3580
|
+
// ── 校验 1:逻辑定义本身必须声明 page / size 参数,且类型必须为 Long ─
|
|
3581
|
+
const definedParamNames = definedParams.map(p => p?.name);
|
|
3582
|
+
const missingDefParams = REQUIRED_PARAMS.filter(p => !definedParamNames.includes(p));
|
|
3583
|
+
if (missingDefParams.length > 0) {
|
|
3584
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}调用的逻辑必须声明 ${missingDefParams.map(p => `"${p}"`).join(' 和 ')} 参数`);
|
|
3585
|
+
hasError = true;
|
|
3586
|
+
}
|
|
3587
|
+
// 类型检查:已声明的 page/size 参数类型必须是 Long
|
|
3588
|
+
for (const paramName of REQUIRED_PARAMS) {
|
|
3589
|
+
const param = definedParams.find(p => p?.name === paramName);
|
|
3590
|
+
if (!param)
|
|
3591
|
+
continue; // 缺失已由上方报错
|
|
3592
|
+
if (param.typeAnnotation?.typeName !== 'Long') {
|
|
3593
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}调用的逻辑中 "${paramName}" 参数类型必须是 整数,当前类型为 "${param.typeAnnotation?.typeName ?? '未知'}"`);
|
|
3594
|
+
hasError = true;
|
|
3532
3595
|
}
|
|
3533
|
-
});
|
|
3534
|
-
if (args.length !== values.length || new Set(values).size !== values.length) {
|
|
3535
|
-
error(node, '下载组件必须为page和size指定入参,且不能重复');
|
|
3536
3596
|
}
|
|
3597
|
+
// 校验 1 有错则定义层本身不符合要求,无需继续检查调用侧
|
|
3598
|
+
if (hasError)
|
|
3599
|
+
return env.getType(node);
|
|
3600
|
+
// ── 校验 2:调用侧必须在对应位置通过服务端入参传入 page / size ──────
|
|
3601
|
+
// 按定义位置逐一检查:arg[i].expression 必须是 namespace=backend、name=paramName 的 Identifier
|
|
3602
|
+
for (const paramName of REQUIRED_PARAMS) {
|
|
3603
|
+
const paramIdx = definedParamNames.indexOf(paramName);
|
|
3604
|
+
if (paramIdx === -1)
|
|
3605
|
+
continue; // 定义层已报错,跳过
|
|
3606
|
+
const arg = node.arguments?.[paramIdx];
|
|
3607
|
+
const expression = arg?.expression;
|
|
3608
|
+
const isValid = expression?.concept === 'Identifier'
|
|
3609
|
+
&& expression.namespace === 'backend'
|
|
3610
|
+
&& expression.name === paramName;
|
|
3611
|
+
if (isValid)
|
|
3612
|
+
continue;
|
|
3613
|
+
if (!arg || !expression) {
|
|
3614
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}缺少 "${paramName}" 参数的传入`);
|
|
3615
|
+
hasError = true;
|
|
3616
|
+
}
|
|
3617
|
+
else if (expression.namespace !== 'backend' || expression.concept !== 'Identifier') {
|
|
3618
|
+
if (isAIStrictMode) {
|
|
3619
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}的 "${paramName}" 参数必须传入服务端入参(如 $self.currentPage / $self.pageSize),不允许使用数字字面量或其他变量`);
|
|
3620
|
+
}
|
|
3621
|
+
else {
|
|
3622
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}的 "${paramName}" 参数必须通过"指定分页参数"设置,不允许使用数字字面量(如 0、1000)或其他变量`);
|
|
3623
|
+
}
|
|
3624
|
+
hasError = true;
|
|
3625
|
+
}
|
|
3626
|
+
else {
|
|
3627
|
+
// namespace=backend 但 name 对不上
|
|
3628
|
+
error(node, `${callLogicAttrInfo.compTitle}的${callLogicAttrInfo.attrTitle}的 "${paramName}" 参数传入了错误的服务端入参 "${expression.name}",期望传入 "${paramName}"`);
|
|
3629
|
+
hasError = true;
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
// 校验 2 有错则调用侧不符合要求,无需继续后续作用域校验
|
|
3633
|
+
if (hasError)
|
|
3634
|
+
return env.getType(node);
|
|
3537
3635
|
}
|
|
3538
3636
|
const map = {
|
|
3539
3637
|
frontend: {
|
|
@@ -4289,6 +4387,13 @@ function createErrorDiagnoser(context) {
|
|
|
4289
4387
|
}
|
|
4290
4388
|
return type;
|
|
4291
4389
|
}
|
|
4390
|
+
function* checkNewStructure(node) {
|
|
4391
|
+
if (node.properties?.length) {
|
|
4392
|
+
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.properties, function* (property, index) {
|
|
4393
|
+
yield* checkNode(property);
|
|
4394
|
+
});
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4292
4397
|
/**
|
|
4293
4398
|
* 获取正则表达式错误的中文消息
|
|
4294
4399
|
*/
|
|
@@ -5183,6 +5288,8 @@ function createErrorDiagnoser(context) {
|
|
|
5183
5288
|
return yield* checkNewMap(node);
|
|
5184
5289
|
case 'NewComposite':
|
|
5185
5290
|
return yield* checkNewComposite(node);
|
|
5291
|
+
case 'NewStructure':
|
|
5292
|
+
return yield* checkNewStructure(node);
|
|
5186
5293
|
case 'NewRegex':
|
|
5187
5294
|
return checkNewRegex(node);
|
|
5188
5295
|
case 'Assignment':
|