@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.
- package/out/checker.d.ts +1 -1
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +38 -3
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +2 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js +4 -1
- package/out/index.js.map +1 -1
- package/out/reference-manager/builtin-q-name.d.ts +1 -1
- package/out/reference-manager/builtin-q-name.d.ts.map +1 -1
- package/out/reference-manager/builtin-q-name.js +14 -10
- package/out/reference-manager/builtin-q-name.js.map +1 -1
- package/out/reference-manager/collect-q-name.d.ts.map +1 -1
- package/out/reference-manager/collect-q-name.js +15 -13
- 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 +30 -46
- package/out/reference-manager/get-q-name.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +19 -10
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +141 -101
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/remove-q-name.d.ts.map +1 -1
- package/out/reference-manager/remove-q-name.js +22 -15
- package/out/reference-manager/remove-q-name.js.map +1 -1
- package/out/reference-manager/symbol-type.d.ts +3 -2
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +7 -1
- package/out/reference-manager/symbol-type.js.map +1 -1
- package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
- package/out/reference-manager/update-nasl-fragment.js +4 -4
- package/out/reference-manager/update-nasl-fragment.js.map +1 -1
- package/out/symbol/traverse/concepts/index.d.ts +1 -1
- package/out/symbol/traverse/concepts/index.d.ts.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 +2 -2
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.js +2 -2
- package/out/typer/component-def-manager/component-def-manager.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 +2 -2
- package/out/typer/dispatch-all.js.map +1 -1
- package/out/typer/dispatch-expr.d.ts.map +1 -1
- package/out/typer/dispatch-expr.js +150 -106
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.js +1 -1
- package/out/typer/dispatch-process.js.map +1 -1
- package/out/typer/dispatch-view.d.ts +1 -1
- package/out/typer/dispatch-view.d.ts.map +1 -1
- package/out/typer/dispatch-view.js +13 -10
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +23 -39
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/index.d.ts +2 -1
- package/out/typer/index.d.ts.map +1 -1
- package/out/typer/index.js +3 -1
- package/out/typer/index.js.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 +5 -0
- package/out/typer/sem-diag.d.ts.map +1 -1
- package/out/typer/sem-diag.js +15 -1
- package/out/typer/sem-diag.js.map +1 -1
- package/out/typer/solver.d.ts +2 -2
- package/out/typer/solver.d.ts.map +1 -1
- package/out/typer/solver.js +17 -19
- package/out/typer/solver.js.map +1 -1
- package/out/typer/subster.js +3 -3
- package/out/typer/subster.js.map +1 -1
- package/out/typer/type-hint-manager/type-hint-manager.d.ts +1 -1
- package/out/typer/type-hint-manager/type-hint-manager.d.ts.map +1 -1
- package/out/typer/type-manager.d.ts.map +1 -1
- package/out/typer/type-manager.js +3 -3
- package/out/typer/type-manager.js.map +1 -1
- package/out/typer/type-predicate.js +5 -5
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +7 -4
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +24 -17
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +10 -4
- package/out/typer/unifier.js.map +1 -1
- package/out/utils/parseTsClassType.d.ts +2 -3
- package/out/utils/parseTsClassType.d.ts.map +1 -1
- package/out/utils/parseTsClassType.js +25 -58
- 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 +1 -1
- package/out/utils/type-operator.d.ts.map +1 -1
- package/out/utils/type-operator.js +12 -12
- package/out/utils/type-operator.js.map +1 -1
- 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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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(
|
|
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(
|
|
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,
|
|
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(
|
|
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(
|
|
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,
|
|
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,
|
|
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,
|
|
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]);
|