@lcap/nasl-language-server-core 4.4.0-rc.2 → 4.4.1-rc.2
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 +241 -111
- package/out/checker.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js +5 -3
- package/out/index.js.map +1 -1
- package/out/reference-manager/build-q-name-def.d.ts.map +1 -1
- package/out/reference-manager/build-q-name-def.js +11 -0
- package/out/reference-manager/build-q-name-def.js.map +1 -1
- package/out/reference-manager/builtin-q-name.js +2 -2
- package/out/reference-manager/builtin-q-name.js.map +1 -1
- package/out/reference-manager/collect-q-name.d.ts +1 -1
- package/out/reference-manager/collect-q-name.d.ts.map +1 -1
- package/out/reference-manager/collect-q-name.js +58 -24
- package/out/reference-manager/collect-q-name.js.map +1 -1
- package/out/reference-manager/def-key-helpers.d.ts +38 -0
- package/out/reference-manager/def-key-helpers.d.ts.map +1 -0
- package/out/reference-manager/{get-q-name.js → def-key-helpers.js} +183 -19
- package/out/reference-manager/def-key-helpers.js.map +1 -0
- package/out/reference-manager/helper.js +2 -2
- package/out/reference-manager/helper.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +60 -43
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +381 -146
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/remove-q-name.d.ts +1 -1
- package/out/reference-manager/remove-q-name.d.ts.map +1 -1
- package/out/reference-manager/remove-q-name.js +7 -10
- package/out/reference-manager/remove-q-name.js.map +1 -1
- package/out/reference-manager/rename-q-name.d.ts +26 -26
- package/out/reference-manager/rename-q-name.d.ts.map +1 -1
- package/out/reference-manager/rename-q-name.js +48 -167
- package/out/reference-manager/rename-q-name.js.map +1 -1
- package/out/reference-manager/symbol-type.d.ts +8 -3
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +8 -2
- package/out/reference-manager/symbol-type.js.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/typer/collectGlobalDefs.js +3 -3
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.d.ts +16 -0
- package/out/typer/component-def-manager/component-def-manager.d.ts.map +1 -1
- package/out/typer/component-def-manager/component-def-manager.js +63 -2
- package/out/typer/component-def-manager/component-def-manager.js.map +1 -1
- package/out/typer/component-def-manager/utils.d.ts.map +1 -1
- package/out/typer/component-def-manager/utils.js +26 -0
- package/out/typer/component-def-manager/utils.js.map +1 -1
- package/out/typer/dispatch-all.d.ts +3 -1
- package/out/typer/dispatch-all.d.ts.map +1 -1
- package/out/typer/dispatch-all.js +48 -5
- package/out/typer/dispatch-all.js.map +1 -1
- package/out/typer/dispatch-call.d.ts +27 -1
- package/out/typer/dispatch-call.d.ts.map +1 -1
- package/out/typer/dispatch-call.js +141 -107
- package/out/typer/dispatch-call.js.map +1 -1
- package/out/typer/dispatch-def.d.ts.map +1 -1
- package/out/typer/dispatch-def.js +3 -3
- package/out/typer/dispatch-def.js.map +1 -1
- package/out/typer/dispatch-expr.d.ts.map +1 -1
- package/out/typer/dispatch-expr.js +32 -73
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.js +3 -3
- package/out/typer/dispatch-process.js.map +1 -1
- package/out/typer/dispatch-stmt.d.ts.map +1 -1
- package/out/typer/dispatch-stmt.js +9 -11
- package/out/typer/dispatch-stmt.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 +33 -26
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/get-oql-files.js +1 -1
- package/out/typer/get-oql-files.js.map +1 -1
- package/out/typer/incremental-update.d.ts +2 -2
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +142 -30
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/overload-helper.js +2 -2
- package/out/typer/overload-helper.js.map +1 -1
- package/out/typer/solver.d.ts +8 -9
- package/out/typer/solver.d.ts.map +1 -1
- package/out/typer/solver.js +43 -32
- package/out/typer/solver.js.map +1 -1
- package/out/typer/subster.d.ts.map +1 -1
- package/out/typer/subster.js +101 -20
- package/out/typer/subster.js.map +1 -1
- package/out/typer/topo-sort.d.ts +37 -0
- package/out/typer/topo-sort.d.ts.map +1 -1
- package/out/typer/topo-sort.js +264 -5
- package/out/typer/topo-sort.js.map +1 -1
- package/out/typer/type-manager.d.ts +1 -0
- package/out/typer/type-manager.d.ts.map +1 -1
- package/out/typer/type-manager.js +14 -11
- package/out/typer/type-manager.js.map +1 -1
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +38 -16
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +19 -3
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +60 -27
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +2 -0
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +52 -27
- package/out/typer/unifier.js.map +1 -1
- package/package.json +5 -5
- package/out/reference-manager/get-q-name.d.ts +0 -9
- package/out/reference-manager/get-q-name.d.ts.map +0 -1
- package/out/reference-manager/get-q-name.js.map +0 -1
- package/out/reference-manager/view-elem-logic.d.ts +0 -44
- package/out/reference-manager/view-elem-logic.d.ts.map +0 -1
- package/out/reference-manager/view-elem-logic.js +0 -181
- package/out/reference-manager/view-elem-logic.js.map +0 -1
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;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;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;oCA2nKpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;iDAztFY,GAAG,KAAG,IAAI;;iBAouFjD,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBAxoKF,UAAU,WAAW,MAAM,YAAY,YAAY;sCA04D/B,IAAI,GAAG,QAAQ;2CAiyGxC,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;
|
|
@@ -73,6 +74,7 @@ function getExpressionNodeName(concept) {
|
|
|
73
74
|
CallMicroserviceInterface: '微服务接口',
|
|
74
75
|
CallGatewayInterface: '网关接口',
|
|
75
76
|
CallEvent: '事件',
|
|
77
|
+
Destination: '页面',
|
|
76
78
|
};
|
|
77
79
|
return expressionNodeName[concept];
|
|
78
80
|
}
|
|
@@ -254,6 +256,8 @@ function createErrorDiagnoser(context) {
|
|
|
254
256
|
let app = context.app;
|
|
255
257
|
let env = context.env;
|
|
256
258
|
let isDebug = context.debug;
|
|
259
|
+
// 严格模式
|
|
260
|
+
let isAIStrictMode = context.isAIStrictMode;
|
|
257
261
|
// 引用管理器
|
|
258
262
|
let referenceManager = env.refMgr;
|
|
259
263
|
// 检查共享数据是否有更新
|
|
@@ -266,6 +270,8 @@ function createErrorDiagnoser(context) {
|
|
|
266
270
|
let inModule = false;
|
|
267
271
|
let inPlayground = 0;
|
|
268
272
|
let inAuthLogic = false;
|
|
273
|
+
let inFrontendType = false;
|
|
274
|
+
let currentFrontendKind = '';
|
|
269
275
|
let dbType = '';
|
|
270
276
|
let curVarCounter = 0;
|
|
271
277
|
const listComponentStack = [];
|
|
@@ -313,6 +319,16 @@ function createErrorDiagnoser(context) {
|
|
|
313
319
|
diagnosticMap.set(curFileNode, diagnostics);
|
|
314
320
|
}
|
|
315
321
|
if (diagnostics) {
|
|
322
|
+
const parentKey = node?.parentKey;
|
|
323
|
+
const parentConcept = node.parentNode?.concept;
|
|
324
|
+
if (message.startsWith('类型不匹配:') &&
|
|
325
|
+
((parentKey === 'test' && parentConcept === 'IfStatement') || (parentKey === 'condition' && parentConcept === 'IfExpression'))) {
|
|
326
|
+
const map = {
|
|
327
|
+
'IfExpression': 'If表达式',
|
|
328
|
+
'IfStatement': 'If语句',
|
|
329
|
+
};
|
|
330
|
+
message = `${map[parentConcept]}条件槽位${message}`;
|
|
331
|
+
}
|
|
316
332
|
const diagnostic = {
|
|
317
333
|
message,
|
|
318
334
|
severity: inPlayground > 0 ? Severity.WARN : (severity ?? Severity.ERROR),
|
|
@@ -775,6 +791,31 @@ function createErrorDiagnoser(context) {
|
|
|
775
791
|
}
|
|
776
792
|
return false;
|
|
777
793
|
}
|
|
794
|
+
/**
|
|
795
|
+
* 获取 ViewElement 的数据源类型(T 或 T1)
|
|
796
|
+
* 参考 util.js 中的 getDataTypeOfViewElement 实现
|
|
797
|
+
*/
|
|
798
|
+
function getDataSourceTypeAnnotation(viewElement) {
|
|
799
|
+
// 向上查找定义了数据源类型的祖先组件
|
|
800
|
+
let currentNode = viewElement;
|
|
801
|
+
let depth = 0;
|
|
802
|
+
const maxSearchDepth = 5;
|
|
803
|
+
while (currentNode?.concept === 'ViewElement' && depth <= maxSearchDepth) {
|
|
804
|
+
// 使用 __ViewElementTV 获取类型,与 IDE 前端 getDataTypeOfViewElement 保持一致
|
|
805
|
+
if (currentNode.__TypeAnnotation && currentNode.__ViewElementTV?.length) {
|
|
806
|
+
// 先查找 T1(动态列),若无再查找 T(普通数据源组件)
|
|
807
|
+
const t1 = currentNode.__ViewElementTV.find((x) => x.rawName === 'T1');
|
|
808
|
+
if (t1?.renamed)
|
|
809
|
+
return t1.renamed;
|
|
810
|
+
const t = currentNode.__ViewElementTV.find((x) => x.rawName === 'T');
|
|
811
|
+
if (t?.renamed)
|
|
812
|
+
return t.renamed;
|
|
813
|
+
}
|
|
814
|
+
currentNode = currentNode.parentNode;
|
|
815
|
+
depth++;
|
|
816
|
+
}
|
|
817
|
+
return undefined;
|
|
818
|
+
}
|
|
778
819
|
/**
|
|
779
820
|
* 是否在赋值左侧
|
|
780
821
|
* @param node
|
|
@@ -857,7 +898,8 @@ function createErrorDiagnoser(context) {
|
|
|
857
898
|
if (param?.spread) {
|
|
858
899
|
continue;
|
|
859
900
|
}
|
|
860
|
-
|
|
901
|
+
// 严格模式非必填也需要有Argument占位
|
|
902
|
+
if (isAIStrictMode || !isNonRequiredParam(param)) {
|
|
861
903
|
minArgsCount++; // 如果参数有默认值,则跳过
|
|
862
904
|
}
|
|
863
905
|
}
|
|
@@ -975,7 +1017,11 @@ function createErrorDiagnoser(context) {
|
|
|
975
1017
|
error(node, `预期 ${paramsLen} 个参数,但传入了 ${argsLen} 个。`);
|
|
976
1018
|
}
|
|
977
1019
|
else if (argsLen < minArgsCount) {
|
|
978
|
-
|
|
1020
|
+
let msg = `传入参数的个数 ${argsLen} 与 ${getExpressionNodeName(node.concept)} 定义的参数个数 ${paramsLen} 不符。`;
|
|
1021
|
+
if (isAIStrictMode) {
|
|
1022
|
+
msg += `可选参数和默认值参数必须用 undefined 占位`;
|
|
1023
|
+
}
|
|
1024
|
+
error(node, msg);
|
|
979
1025
|
}
|
|
980
1026
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(args, function* (arg, index) {
|
|
981
1027
|
const param = params?.[index];
|
|
@@ -1252,6 +1298,11 @@ function createErrorDiagnoser(context) {
|
|
|
1252
1298
|
});
|
|
1253
1299
|
}
|
|
1254
1300
|
}
|
|
1301
|
+
if (node.interfaces?.length) {
|
|
1302
|
+
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.interfaces, function* (node) {
|
|
1303
|
+
yield* checkNode(node);
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1255
1306
|
yield* checkNode(node.configuration);
|
|
1256
1307
|
if (node.type === 'sharedApp') {
|
|
1257
1308
|
const status = getStatusOfSharedApp(node);
|
|
@@ -1454,7 +1505,7 @@ function createErrorDiagnoser(context) {
|
|
|
1454
1505
|
yield* checkNode(node);
|
|
1455
1506
|
});
|
|
1456
1507
|
}
|
|
1457
|
-
const dataSourceGroup = app.configuration?.getGroup('dataSource');
|
|
1508
|
+
const dataSourceGroup = app.configuration?.getGroup?.('dataSource');
|
|
1458
1509
|
if (dataSourceGroup) {
|
|
1459
1510
|
const property = dataSourceGroup.getProperty(node.name);
|
|
1460
1511
|
if (property.values?.length) {
|
|
@@ -1726,7 +1777,7 @@ function createErrorDiagnoser(context) {
|
|
|
1726
1777
|
const decimalPlaces = value?.split('.')[1]?.length || 0;
|
|
1727
1778
|
if (decimalPlaces > +scale) {
|
|
1728
1779
|
error(node, `实体字段${node.name}默认值的小数位数不能大于设置的小数位数${scale},否则将会按照小数位数自动截断`, {
|
|
1729
|
-
severity: Severity.WARN,
|
|
1780
|
+
severity: isAIStrictMode ? Severity.ERROR : Severity.WARN,
|
|
1730
1781
|
});
|
|
1731
1782
|
}
|
|
1732
1783
|
}
|
|
@@ -1976,8 +2027,10 @@ function createErrorDiagnoser(context) {
|
|
|
1976
2027
|
yield* checkNode(node);
|
|
1977
2028
|
});
|
|
1978
2029
|
}
|
|
1979
|
-
|
|
1980
|
-
|
|
2030
|
+
// 仅对内部接口(app.interfaces,由 Logic 导出)校验 originLogicName;外部接口(interfaceDependencies 等)无此字段
|
|
2031
|
+
const isInternalInterface = nasl_concepts_1.asserts.isApp(node.parentNode);
|
|
2032
|
+
if (isInternalInterface) {
|
|
2033
|
+
if (ensureNodeKeyExists(node, 'originLogicName')) {
|
|
1981
2034
|
const originLogicName = node.originLogicName;
|
|
1982
2035
|
const ref = app.logics.find((item) => item.name === originLogicName);
|
|
1983
2036
|
if (!ref) {
|
|
@@ -2349,6 +2402,31 @@ function createErrorDiagnoser(context) {
|
|
|
2349
2402
|
}
|
|
2350
2403
|
yield* checkPlayground(node.playground);
|
|
2351
2404
|
yield* checkBindExpressions(node);
|
|
2405
|
+
// 检查数据源上的字段属性是否在类型上存在
|
|
2406
|
+
// 判断条件:
|
|
2407
|
+
// 1. 属性的 setter 是 PropertySelectSetter(从组件定义的 ViewComponentDeclaration 中获取)
|
|
2408
|
+
// 2. 或者属性在 FIELD_ATTRS_BY_COMPONENT 配置中(兼容老版本组件配置)
|
|
2409
|
+
if (node.type === 'string' && typeof node.value === 'string' && node.value) {
|
|
2410
|
+
const viewElement = node.parentNode;
|
|
2411
|
+
if (viewElement?.concept === 'ViewElement') {
|
|
2412
|
+
// 优先检查组件定义中的 PropertySelectSetter
|
|
2413
|
+
const isPropertySelect = env.refMgr.compDefMgr.isPropertySelectSetter(viewElement.tag, node.name);
|
|
2414
|
+
// 同时兼容 FIELD_ATTRS_BY_COMPONENT 配置
|
|
2415
|
+
const needsFieldCheck = isPropertySelect || (0, view_element_field_attrs_1.shouldCheckFieldExists)(viewElement.tag, node.name);
|
|
2416
|
+
if (needsFieldCheck) {
|
|
2417
|
+
const dataSourceType = getDataSourceTypeAnnotation(viewElement);
|
|
2418
|
+
if (dataSourceType) {
|
|
2419
|
+
const { exists, missingField } = checkFieldExistsInType(env, dataSourceType, node.value);
|
|
2420
|
+
if (!exists && missingField) {
|
|
2421
|
+
// 优先从组件定义中获取属性标题,兜底使用硬编码配置
|
|
2422
|
+
const attrTitle = env.refMgr.compDefMgr.getPropTitle(viewElement.tag, node.name)
|
|
2423
|
+
|| (0, view_element_field_attrs_1.getFieldAttrTitle)(node.name);
|
|
2424
|
+
error(node, `${attrTitle} "${missingField}" 在数据类型上不存在`);
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2352
2430
|
// 检查不可复制属性开启双向绑定
|
|
2353
2431
|
if ((node.model || node.sync) && node.expression) {
|
|
2354
2432
|
const bindExpression = node.expression;
|
|
@@ -2444,6 +2522,11 @@ function createErrorDiagnoser(context) {
|
|
|
2444
2522
|
// 任务完成人为空会有一个提示信息
|
|
2445
2523
|
error(node, `${title}为空`);
|
|
2446
2524
|
}
|
|
2525
|
+
if (Array.isArray(node.fromLogics)) {
|
|
2526
|
+
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.fromLogics, function* (node) {
|
|
2527
|
+
yield* checkNode(node);
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2447
2530
|
}
|
|
2448
2531
|
/**
|
|
2449
2532
|
* 检查 元素指令
|
|
@@ -3017,8 +3100,8 @@ function createErrorDiagnoser(context) {
|
|
|
3017
3100
|
}
|
|
3018
3101
|
}
|
|
3019
3102
|
if (!isSame) {
|
|
3020
|
-
const
|
|
3021
|
-
const key =
|
|
3103
|
+
const matched = exportInterface.concept === 'McpInterface';
|
|
3104
|
+
const key = matched ? 'exportMcpInterface' : 'exportInterface';
|
|
3022
3105
|
error(node, `逻辑已变更,请确认请求类型无误后重新导出${'${event}'}`, {
|
|
3023
3106
|
severity: Severity.ERROR,
|
|
3024
3107
|
events: [
|
|
@@ -3278,7 +3361,7 @@ function createErrorDiagnoser(context) {
|
|
|
3278
3361
|
return;
|
|
3279
3362
|
}
|
|
3280
3363
|
yield* checkVoidCallUsedAsStatement(node);
|
|
3281
|
-
const ref = env.resolveRef(node); // 前端
|
|
3364
|
+
const ref = env.resolveRef(node) ?? env.quickGetLibDef(node, node.calleeName, undefined); // 前端
|
|
3282
3365
|
// TODO: sql 函数的 namespace 带有数据库名 nasl.sqlFunction.mysql nasl.sqlFunction.oracle ...
|
|
3283
3366
|
// 暂时不在 gQNameDefs 里,用 isBuiltInCall 简单判断了
|
|
3284
3367
|
if (!ref && !isBuiltInCall(node)) {
|
|
@@ -3379,17 +3462,30 @@ function createErrorDiagnoser(context) {
|
|
|
3379
3462
|
for (let i = 1; i < nd.arguments.length; i++) {
|
|
3380
3463
|
const expr = nd.arguments[i].expression;
|
|
3381
3464
|
let resTy;
|
|
3465
|
+
const reportArgError = (targetExpr) => {
|
|
3466
|
+
const actualTy = targetExpr ? env.getType(targetExpr) || type_manager_1.naslAnyTy : type_manager_1.naslAnyTy;
|
|
3467
|
+
error(nd.arguments[i], (0, sem_diag_1.mkIncompatibleTyErr)(env, actualTy, expectTy));
|
|
3468
|
+
};
|
|
3382
3469
|
if (expr?.concept === 'AnonymousFunction') {
|
|
3383
3470
|
resTy = env.getType(expr.body);
|
|
3384
3471
|
if (!nasl_concepts_1.asserts.isNewComposite(expr.body)) {
|
|
3385
|
-
|
|
3472
|
+
reportArgError(expr);
|
|
3386
3473
|
}
|
|
3387
3474
|
}
|
|
3388
3475
|
else if (expr?.concept === 'SubLogic') {
|
|
3389
3476
|
resTy = env.getType(expr.returns?.[0]);
|
|
3390
3477
|
}
|
|
3478
|
+
else if (expr?.concept === 'Identifier') {
|
|
3479
|
+
const ty = env.getType(expr);
|
|
3480
|
+
if ((0, type_predicate_1.isFuncTy)(ty)) {
|
|
3481
|
+
resTy = ty;
|
|
3482
|
+
}
|
|
3483
|
+
else {
|
|
3484
|
+
reportArgError(expr);
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3391
3487
|
else {
|
|
3392
|
-
|
|
3488
|
+
reportArgError(expr);
|
|
3393
3489
|
}
|
|
3394
3490
|
const byTy = resTy?.properties?.find((prop) => prop.name === 'by')?.typeAnnotation;
|
|
3395
3491
|
if (byTy?.typeKind === 'union') {
|
|
@@ -3426,6 +3522,29 @@ function createErrorDiagnoser(context) {
|
|
|
3426
3522
|
error(node, '下载组件必须为page和size指定入参,且不能重复');
|
|
3427
3523
|
}
|
|
3428
3524
|
}
|
|
3525
|
+
const map = {
|
|
3526
|
+
frontend: {
|
|
3527
|
+
scope: '前端',
|
|
3528
|
+
forbiddenScope: '服务端',
|
|
3529
|
+
forbiddenCalleeNamesMap: {
|
|
3530
|
+
'nasl.auth': ['getCurrentUser', 'generateUserId', 'validatePassword', 'encryptPassword'],
|
|
3531
|
+
},
|
|
3532
|
+
},
|
|
3533
|
+
backend: {
|
|
3534
|
+
scope: '服务端',
|
|
3535
|
+
forbiddenScope: '前端',
|
|
3536
|
+
forbiddenCalleeNamespaces: ['nasl.browser', 'nasl.io'],
|
|
3537
|
+
forbiddenCalleeNamesMap: {
|
|
3538
|
+
'nasl.auth': ['decryptByAES', 'encryptByAES', 'logout', 'hasAuth'],
|
|
3539
|
+
'nasl.configuration': ['getCurrentIp', 'getUserLanguage', 'getI18nList', 'setI18nLocale'],
|
|
3540
|
+
},
|
|
3541
|
+
},
|
|
3542
|
+
};
|
|
3543
|
+
const config = inFrontendType ? map.frontend : map.backend;
|
|
3544
|
+
const { scope, forbiddenScope, forbiddenCalleeNamespaces, forbiddenCalleeNamesMap } = config;
|
|
3545
|
+
if (forbiddenCalleeNamespaces?.includes(node.calleeNamespace) || forbiddenCalleeNamesMap?.[node.calleeNamespace]?.includes(node.calleeName)) {
|
|
3546
|
+
error(node, `不能在${scope}作用域下使用${forbiddenScope}系统逻辑`);
|
|
3547
|
+
}
|
|
3429
3548
|
return env.getType(node);
|
|
3430
3549
|
}
|
|
3431
3550
|
/**
|
|
@@ -3784,12 +3903,18 @@ function createErrorDiagnoser(context) {
|
|
|
3784
3903
|
*/
|
|
3785
3904
|
function* checkForEachStatement(node) {
|
|
3786
3905
|
env.enterScope(node);
|
|
3906
|
+
if (ensureNodeKeyExists(node, 'item')) {
|
|
3907
|
+
yield* checkNode(node.item);
|
|
3908
|
+
}
|
|
3787
3909
|
if (ensureNodeKeyExists(node, 'each')) {
|
|
3788
3910
|
yield* checkNode(node.each);
|
|
3789
3911
|
}
|
|
3790
3912
|
if (ensureNodeKeyExists(node, 'start')) {
|
|
3791
3913
|
yield* checkNode(node.start);
|
|
3792
3914
|
}
|
|
3915
|
+
if (node.end) {
|
|
3916
|
+
yield* checkNode(node.end);
|
|
3917
|
+
}
|
|
3793
3918
|
if (node.body?.length) {
|
|
3794
3919
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.body, function* (node) {
|
|
3795
3920
|
yield* checkNode(node);
|
|
@@ -3879,6 +4004,36 @@ function createErrorDiagnoser(context) {
|
|
|
3879
4004
|
scopedError(node, `${node.toNaturalTS()} 枚举类不能直接使用,请取它的枚举项`);
|
|
3880
4005
|
return errorType;
|
|
3881
4006
|
}
|
|
4007
|
+
const map = {
|
|
4008
|
+
frontend: {
|
|
4009
|
+
scope: '前端',
|
|
4010
|
+
forbiddenScope: '服务端',
|
|
4011
|
+
prefix: 'app.frontendTypes',
|
|
4012
|
+
forbiddenPrefix: 'app.backend',
|
|
4013
|
+
},
|
|
4014
|
+
backend: {
|
|
4015
|
+
scope: '服务端',
|
|
4016
|
+
forbiddenScope: '前端',
|
|
4017
|
+
prefix: 'app.backend',
|
|
4018
|
+
forbiddenPrefix: 'app.frontendTypes',
|
|
4019
|
+
forbiddenCalleeNamesMap: {
|
|
4020
|
+
'nasl.auth': ['userInfo']
|
|
4021
|
+
}
|
|
4022
|
+
},
|
|
4023
|
+
};
|
|
4024
|
+
const config = inFrontendType ? map.frontend : map.backend;
|
|
4025
|
+
const { scope, forbiddenScope, prefix, forbiddenPrefix, forbiddenCalleeNamesMap } = config;
|
|
4026
|
+
// 互斥的端类型 (pc <-> h5)
|
|
4027
|
+
const forbiddenKind = currentFrontendKind === 'pc' ? 'h5' : 'pc';
|
|
4028
|
+
if (node.namespace?.startsWith(forbiddenPrefix)) {
|
|
4029
|
+
error(node, `不能在${scope}作用域下使用${forbiddenScope}全局变量`);
|
|
4030
|
+
}
|
|
4031
|
+
else if (inFrontendType && node.namespace?.startsWith(`${prefix}.${forbiddenKind}`)) {
|
|
4032
|
+
error(node, `不能在${currentFrontendKind}作用域下使用${forbiddenKind}作用域下的前端变量`);
|
|
4033
|
+
}
|
|
4034
|
+
if (forbiddenCalleeNamesMap?.[node.namespace]?.includes(node.name)) {
|
|
4035
|
+
error(node, '不能在服务端作用域下使用前端公共变量');
|
|
4036
|
+
}
|
|
3882
4037
|
// 检查使用范围
|
|
3883
4038
|
yield* checkScopeOfUse(node, ref);
|
|
3884
4039
|
return env.getType(node);
|
|
@@ -4158,97 +4313,6 @@ function createErrorDiagnoser(context) {
|
|
|
4158
4313
|
}
|
|
4159
4314
|
return env.getType(node);
|
|
4160
4315
|
}
|
|
4161
|
-
/**
|
|
4162
|
-
* 递归检查赋值类型不兼容问题
|
|
4163
|
-
* 检查左侧类型(Decimal/Long)是否与右侧联合类型(Union<Decimal, Long>)不兼容
|
|
4164
|
-
* @param leftType 左侧类型
|
|
4165
|
-
* @param rightType 右侧类型
|
|
4166
|
-
* @param context 上下文信息,用于生成错误消息
|
|
4167
|
-
* @param allowImplicitConversion 是否允许隐式类型转换(仅对直接的基础类型赋值允许,复杂类型内部不允许)
|
|
4168
|
-
* @returns 所有类型不兼容的错误信息数组
|
|
4169
|
-
*/
|
|
4170
|
-
function checkAssignmentTypeIncompatibility(leftType, rightType, context = {}, allowImplicitConversion = true) {
|
|
4171
|
-
if (!leftType || !rightType)
|
|
4172
|
-
return [];
|
|
4173
|
-
const errors = [];
|
|
4174
|
-
// 先检查 Decimal/Long vs Union<Decimal, Long> 的情况(需要先于其他检查)
|
|
4175
|
-
// 这种情况应该报错,即使允许隐式转换
|
|
4176
|
-
if (allowImplicitConversion) {
|
|
4177
|
-
const isLeftPrimitive = leftType.typeKind === 'primitive';
|
|
4178
|
-
const isLeftDecimalOrLong = isLeftPrimitive && (leftType.typeName === 'Decimal' || leftType.typeName === 'Long');
|
|
4179
|
-
if (isLeftDecimalOrLong && (0, type_predicate_1.isDecimalUnionLongTy)(rightType)) {
|
|
4180
|
-
const prefix = context.prefix || '赋值';
|
|
4181
|
-
const fieldInfo = context.fieldName ? `字段 ${context.fieldName} ` : '';
|
|
4182
|
-
errors.push(`${prefix}:${fieldInfo}类型不匹配,不能将 ${(0, type_manager_1.showUserLevelType)(rightType)} 赋值给 ${(0, type_manager_1.showUserLevelType)(leftType)} 类型。`);
|
|
4183
|
-
return errors; // 找到基本类型错误后直接返回,不再检查嵌套
|
|
4184
|
-
}
|
|
4185
|
-
}
|
|
4186
|
-
// 检查基础类型是否严格相等(不允许隐式转换)
|
|
4187
|
-
const isLeftPrimitive = leftType.typeKind === 'primitive';
|
|
4188
|
-
const isRightPrimitive = rightType.typeKind === 'primitive';
|
|
4189
|
-
if (isLeftPrimitive && isRightPrimitive) {
|
|
4190
|
-
// 如果不允许隐式转换,则要求类型完全相等
|
|
4191
|
-
if (!allowImplicitConversion) {
|
|
4192
|
-
if (leftType.typeName !== rightType.typeName || leftType.typeNamespace !== rightType.typeNamespace) {
|
|
4193
|
-
const prefix = context.prefix || '赋值';
|
|
4194
|
-
const fieldInfo = context.fieldName ? `字段 ${context.fieldName} ` : '';
|
|
4195
|
-
errors.push(`${prefix}:${fieldInfo}类型不匹配,不能将 ${(0, type_manager_1.showUserLevelType)(rightType)} 赋值给 ${(0, type_manager_1.showUserLevelType)(leftType)} 类型。`);
|
|
4196
|
-
return errors;
|
|
4197
|
-
}
|
|
4198
|
-
// 类型完全相等,没有错误,继续检查其他情况
|
|
4199
|
-
}
|
|
4200
|
-
else {
|
|
4201
|
-
// 允许隐式转换的情况下,检查是否通过 isSubTy 检查(允许隐式转换)
|
|
4202
|
-
if ((0, type_predicate_1.isSubTy)(env, rightType, leftType)) {
|
|
4203
|
-
// 类型兼容(允许隐式转换),没有错误,继续检查其他情况
|
|
4204
|
-
}
|
|
4205
|
-
// 如果 isSubTy 返回 false,继续检查其他不兼容的情况
|
|
4206
|
-
}
|
|
4207
|
-
}
|
|
4208
|
-
// 2. 检查 List 类型(包括嵌套):List<T> vs List<Union<...>>
|
|
4209
|
-
if (leftType.typeKind === 'generic' &&
|
|
4210
|
-
leftType.typeName === 'List' &&
|
|
4211
|
-
rightType.typeKind === 'generic' &&
|
|
4212
|
-
rightType.typeName === 'List' &&
|
|
4213
|
-
leftType.typeArguments?.[0] &&
|
|
4214
|
-
rightType.typeArguments?.[0]) {
|
|
4215
|
-
// 递归检查 List 的元素类型,嵌套类型内部不允许隐式转换
|
|
4216
|
-
return checkAssignmentTypeIncompatibility(leftType.typeArguments[0], rightType.typeArguments[0], { ...context, prefix: context.prefix || '赋值' }, false // 嵌套类型内部不允许隐式转换
|
|
4217
|
-
);
|
|
4218
|
-
}
|
|
4219
|
-
// 3. 检查 Map 类型(包括嵌套):Map<K, V> vs Map<K, Union<...>>
|
|
4220
|
-
if (leftType.typeKind === 'generic' &&
|
|
4221
|
-
leftType.typeName === 'Map' &&
|
|
4222
|
-
rightType.typeKind === 'generic' &&
|
|
4223
|
-
rightType.typeName === 'Map' &&
|
|
4224
|
-
leftType.typeArguments?.length === 2 &&
|
|
4225
|
-
rightType.typeArguments?.length === 2) {
|
|
4226
|
-
// 递归检查 Map 的值类型(第二个类型参数),嵌套类型内部不允许隐式转换
|
|
4227
|
-
const valueTypeErrors = checkAssignmentTypeIncompatibility(leftType.typeArguments[1], rightType.typeArguments[1], { ...context, prefix: context.prefix || '赋值' }, false // 嵌套类型内部不允许隐式转换
|
|
4228
|
-
);
|
|
4229
|
-
errors.push(...valueTypeErrors);
|
|
4230
|
-
// 也检查键类型(第一个类型参数),嵌套类型内部不允许隐式转换
|
|
4231
|
-
const keyTypeErrors = checkAssignmentTypeIncompatibility(leftType.typeArguments[0], rightType.typeArguments[0], { ...context, prefix: context.prefix || '赋值' }, false // 嵌套类型内部不允许隐式转换
|
|
4232
|
-
);
|
|
4233
|
-
errors.push(...keyTypeErrors);
|
|
4234
|
-
return errors;
|
|
4235
|
-
}
|
|
4236
|
-
// 4. 检查匿名结构体:递归检查每个字段,收集所有字段的错误
|
|
4237
|
-
if ((0, type_predicate_1.isAnonymousTy)(leftType) && (0, type_predicate_1.isAnonymousTy)(rightType)) {
|
|
4238
|
-
const leftProps = leftType.properties ?? [];
|
|
4239
|
-
const rightProps = rightType.properties ?? [];
|
|
4240
|
-
for (const leftProp of leftProps) {
|
|
4241
|
-
const rightProp = rightProps.find(p => p.name === leftProp.name);
|
|
4242
|
-
if (rightProp && leftProp.typeAnnotation && rightProp.typeAnnotation) {
|
|
4243
|
-
// 匿名结构体的字段类型检查不允许隐式转换
|
|
4244
|
-
const fieldErrors = checkAssignmentTypeIncompatibility(leftProp.typeAnnotation, rightProp.typeAnnotation, { prefix: context.prefix || '赋值', fieldName: leftProp.name }, false // 复杂类型内部不允许隐式转换
|
|
4245
|
-
);
|
|
4246
|
-
errors.push(...fieldErrors); // 收集所有字段的错误,不提前返回
|
|
4247
|
-
}
|
|
4248
|
-
}
|
|
4249
|
-
}
|
|
4250
|
-
return errors;
|
|
4251
|
-
}
|
|
4252
4316
|
/**
|
|
4253
4317
|
* 检查 赋值语句
|
|
4254
4318
|
* @param node
|
|
@@ -4260,14 +4324,6 @@ function createErrorDiagnoser(context) {
|
|
|
4260
4324
|
if (ensureNodeKeyExists(node, 'right')) {
|
|
4261
4325
|
yield* checkNode(node.right);
|
|
4262
4326
|
}
|
|
4263
|
-
// 使用统一的类型兼容性检查
|
|
4264
|
-
const leftType = env.getType(node.left);
|
|
4265
|
-
const rightType = env.getType(node.right);
|
|
4266
|
-
const errorMessages = checkAssignmentTypeIncompatibility(leftType, rightType);
|
|
4267
|
-
// 报告所有错误
|
|
4268
|
-
errorMessages.forEach(errorMessage => {
|
|
4269
|
-
error(node, errorMessage);
|
|
4270
|
-
});
|
|
4271
4327
|
if (nasl_concepts_1.asserts.isMemberExpression(node.left)) {
|
|
4272
4328
|
reportCurrentItemModification(node.left, node);
|
|
4273
4329
|
}
|
|
@@ -4333,6 +4389,9 @@ function createErrorDiagnoser(context) {
|
|
|
4333
4389
|
error(args[i], '当前参数无效,不可用。');
|
|
4334
4390
|
}
|
|
4335
4391
|
}
|
|
4392
|
+
if (isAIStrictMode) {
|
|
4393
|
+
yield* checkCallExpressionParameters(node, ref);
|
|
4394
|
+
}
|
|
4336
4395
|
}
|
|
4337
4396
|
else {
|
|
4338
4397
|
error(node, `找不到页面${node.viewName}`);
|
|
@@ -4540,6 +4599,9 @@ function createErrorDiagnoser(context) {
|
|
|
4540
4599
|
yield* checkNode(node);
|
|
4541
4600
|
});
|
|
4542
4601
|
}
|
|
4602
|
+
else {
|
|
4603
|
+
error(node, 'Join 子句的关联关系不能为空');
|
|
4604
|
+
}
|
|
4543
4605
|
if (node.joinParts?.length) {
|
|
4544
4606
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.joinParts, function* (node) {
|
|
4545
4607
|
yield* checkNode(node);
|
|
@@ -4574,6 +4636,9 @@ function createErrorDiagnoser(context) {
|
|
|
4574
4636
|
else if (!node.asName) {
|
|
4575
4637
|
error(node, '数据查询:聚合函数别名不能为空。');
|
|
4576
4638
|
}
|
|
4639
|
+
if (node.aggregateParam) {
|
|
4640
|
+
yield* checkNode(node.aggregateParam);
|
|
4641
|
+
}
|
|
4577
4642
|
}
|
|
4578
4643
|
/**
|
|
4579
4644
|
* 检查 SQL 查询
|
|
@@ -5160,6 +5225,13 @@ function createErrorDiagnoser(context) {
|
|
|
5160
5225
|
// TODO: checkNodeIsFileModuleInIdeWithCache 也慢,后续可以优化
|
|
5161
5226
|
const isFileModule = fileNodes.length ? (0, file_node_cache_1.checkNodeIsFileModuleInIdeWithCache)(node) : true;
|
|
5162
5227
|
if (isFileModule) {
|
|
5228
|
+
// 增量更新时按文件逐个 checkNode,需重置闭包状态;若本文件在 Module 内,inModule 需为 true(否则不会经过 checkModule,inModule 会失效)
|
|
5229
|
+
inModule = !!node.getAncestor?.('Module');
|
|
5230
|
+
inPlayground = 0;
|
|
5231
|
+
inAuthLogic = false;
|
|
5232
|
+
const frontendType = node.getAncestor?.('FrontendType');
|
|
5233
|
+
inFrontendType = !!frontendType;
|
|
5234
|
+
currentFrontendKind = frontendType?.kind || '';
|
|
5163
5235
|
fileNodes.push(node);
|
|
5164
5236
|
let diagnostics = diagnosticMap.get(node);
|
|
5165
5237
|
if (!diagnostics) {
|
|
@@ -5376,6 +5448,64 @@ function createErrorDiagnoser(context) {
|
|
|
5376
5448
|
};
|
|
5377
5449
|
}
|
|
5378
5450
|
exports.createErrorDiagnoser = createErrorDiagnoser;
|
|
5451
|
+
/**
|
|
5452
|
+
* 检查字段路径是否在类型上存在
|
|
5453
|
+
* 类似于 s-component-attr-form.vue 中的 findPropertyNode 功能
|
|
5454
|
+
* @param env 语义环境
|
|
5455
|
+
* @param dataType 数据源类型
|
|
5456
|
+
* @param fieldPath 字段路径,如 "name" 或 "user.name"
|
|
5457
|
+
* @returns { exists: boolean, missingField?: string } 如果字段不存在,返回第一个不存在的字段名
|
|
5458
|
+
*/
|
|
5459
|
+
function checkFieldExistsInType(env, dataType, fieldPath) {
|
|
5460
|
+
if (!dataType || !fieldPath) {
|
|
5461
|
+
return { exists: true }; // 没有类型信息或字段路径时,跳过检查
|
|
5462
|
+
}
|
|
5463
|
+
const fieldParts = fieldPath.split('.');
|
|
5464
|
+
let currentType = dataType;
|
|
5465
|
+
for (const fieldName of fieldParts) {
|
|
5466
|
+
if (!currentType) {
|
|
5467
|
+
return { exists: false, missingField: fieldName };
|
|
5468
|
+
}
|
|
5469
|
+
// 获取类型的 properties
|
|
5470
|
+
let properties;
|
|
5471
|
+
if (currentType.typeKind === 'anonymousStructure') {
|
|
5472
|
+
properties = currentType.properties;
|
|
5473
|
+
}
|
|
5474
|
+
else if (currentType.typeKind === 'reference') {
|
|
5475
|
+
// 对于引用类型,需要解析引用
|
|
5476
|
+
const resolved = env.resolveRef(currentType);
|
|
5477
|
+
// @ts-expect-error
|
|
5478
|
+
properties = resolved?.properties;
|
|
5479
|
+
}
|
|
5480
|
+
else if (currentType.typeKind === 'generic' && currentType.typeName === 'List') {
|
|
5481
|
+
// 对于 List<T>,检查 T 的属性
|
|
5482
|
+
currentType = currentType.typeArguments?.[0];
|
|
5483
|
+
if (currentType?.typeKind === 'anonymousStructure') {
|
|
5484
|
+
properties = currentType.properties;
|
|
5485
|
+
}
|
|
5486
|
+
else if (currentType?.typeKind === 'reference') {
|
|
5487
|
+
const resolved = env.resolveRef(currentType);
|
|
5488
|
+
// @ts-expect-error
|
|
5489
|
+
properties = resolved?.properties;
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
if (!properties) {
|
|
5493
|
+
// 类型没有 properties,可能是基本类型或未解析的类型
|
|
5494
|
+
// 对于未解析的类型,跳过检查
|
|
5495
|
+
if ((0, type_predicate_1.isTyAnnTyParam)(currentType) || (0, type_predicate_1.isAnyTy)(currentType)) {
|
|
5496
|
+
return { exists: true };
|
|
5497
|
+
}
|
|
5498
|
+
return { exists: false, missingField: fieldName };
|
|
5499
|
+
}
|
|
5500
|
+
const prop = properties.find((p) => p.name === fieldName);
|
|
5501
|
+
if (!prop) {
|
|
5502
|
+
return { exists: false, missingField: fieldName };
|
|
5503
|
+
}
|
|
5504
|
+
// 继续检查下一级
|
|
5505
|
+
currentType = prop.typeAnnotation;
|
|
5506
|
+
}
|
|
5507
|
+
return { exists: true };
|
|
5508
|
+
}
|
|
5379
5509
|
function deduplicateDiagnostics(diagnostics) {
|
|
5380
5510
|
return (0, lodash_1.uniqWith)(diagnostics, (a, b) => a.node === b.node && a.message === b.message);
|
|
5381
5511
|
}
|
|
@@ -5425,7 +5555,7 @@ exports.transformDiagnosticsToRecords = transformDiagnosticsToRecords;
|
|
|
5425
5555
|
// @ts-expect-error
|
|
5426
5556
|
const toRaw = (nd) => nd.__v_raw ?? nd;
|
|
5427
5557
|
// 是否来自系统内置
|
|
5428
|
-
const isBuiltInCall = (nd) => !!nd.calleeNamespace?.startsWith('nasl.');
|
|
5558
|
+
const isBuiltInCall = (nd) => !!nd.calleeNamespace?.startsWith('nasl.') && !['nasl.auth'].includes(nd.calleeNamespace);
|
|
5429
5559
|
// 获取依赖库名
|
|
5430
5560
|
const getExtensionLibName = (nd) => nd.calleeNamespace?.startsWith('extensions.') ? nd.calleeNamespace.split('.')[1] : undefined;
|
|
5431
5561
|
//# sourceMappingURL=checker.js.map
|