@lcap/nasl-language-server-core 4.4.0-beta.5 → 4.4.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 +3 -1
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +133 -2
- package/out/checker.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.map +1 -1
- package/out/typer/collectGlobalDefs.js +25 -2
- package/out/typer/collectGlobalDefs.js.map +1 -1
- package/out/typer/incremental-update.d.ts +10 -4
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +91 -5
- package/out/typer/incremental-update.js.map +1 -1
- package/package.json +5 -5
package/out/checker.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SyntaxNode, App, BaseNode } from '@lcap/nasl-concepts';
|
|
1
|
+
import type { SyntaxNode, Frontend, View, App, BaseNode } from '@lcap/nasl-concepts';
|
|
2
2
|
import { TypeAnnotation } from '@lcap/nasl-concepts';
|
|
3
3
|
import { type SemEnv } from './typer/typer';
|
|
4
4
|
import { Diagnostic as NaslTypeDiagnostic } from '@lcap/nasl-types';
|
|
@@ -49,6 +49,8 @@ export declare function createErrorDiagnoser(context: DiagnoseContext): {
|
|
|
49
49
|
nodeConcept: string;
|
|
50
50
|
}[];
|
|
51
51
|
error: (node: SyntaxNode, message: string, context?: ErrorContext) => void;
|
|
52
|
+
checkViewIndexPageSetting: (node: View | Frontend) => void;
|
|
53
|
+
revalidateAncestorNode: (ancestorNode: SyntaxNode, validationFn: (ancestorNode: SyntaxNode, env: SemEnv) => void, errorFilter?: (err: Diagnostic) => boolean) => NodeDiagnosticsMap | null;
|
|
52
54
|
};
|
|
53
55
|
export interface DiagnosticRecord {
|
|
54
56
|
id: string;
|
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,
|
|
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,EAET,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;AA6OF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCA2hJpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;;iBAW3B,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBA7iJF,UAAU,WAAW,MAAM,YAAY,YAAY;sCA+qD/B,IAAI,GAAG,QAAQ;2CA+5FxC,UAAU,gBACV,CAAC,YAAY,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,gBAC/C,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,KACzC,kBAAkB,GAAG,IAAI;EAgD7B;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"}
|
package/out/checker.js
CHANGED
|
@@ -14,6 +14,8 @@ 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 regeExp = new nasl_utils_1.ExpressionLexer();
|
|
18
|
+
regeExp.profile = nasl_utils_1.profiles.js;
|
|
17
19
|
var Severity;
|
|
18
20
|
(function (Severity) {
|
|
19
21
|
Severity["WARN"] = "warning";
|
|
@@ -366,7 +368,7 @@ function createErrorDiagnoser(context) {
|
|
|
366
368
|
* @returns
|
|
367
369
|
*/
|
|
368
370
|
function getError(node) {
|
|
369
|
-
const curFileNode = getCurFileNode();
|
|
371
|
+
const curFileNode = getCurFileNode() ?? node;
|
|
370
372
|
const diagnostics = diagnosticMap.get(curFileNode);
|
|
371
373
|
if (diagnostics) {
|
|
372
374
|
return diagnostics.get(node);
|
|
@@ -1935,9 +1937,39 @@ function createErrorDiagnoser(context) {
|
|
|
1935
1937
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.views, function* (node) {
|
|
1936
1938
|
yield* checkNode(node);
|
|
1937
1939
|
});
|
|
1940
|
+
checkViewIndexPageSetting(node);
|
|
1938
1941
|
}
|
|
1939
1942
|
env.exitScope();
|
|
1940
1943
|
}
|
|
1944
|
+
/**
|
|
1945
|
+
* 检查页面的首页/默认跳转页设置
|
|
1946
|
+
* 根据父级类型(Frontend 或 View)自动判断检查场景
|
|
1947
|
+
* @param node 当前页面节点
|
|
1948
|
+
*/
|
|
1949
|
+
function checkViewIndexPageSetting(node) {
|
|
1950
|
+
const isNodeFrontend = (0, asserts_1.isFrontend)(node);
|
|
1951
|
+
const children = isNodeFrontend ? node.views : node.children;
|
|
1952
|
+
// 防御性检查:确保 children 存在且是数组
|
|
1953
|
+
if (!children || !Array.isArray(children)) {
|
|
1954
|
+
return;
|
|
1955
|
+
}
|
|
1956
|
+
// 检查默认跳转页数量,只允许有一个默认跳转页
|
|
1957
|
+
const defaultViews = children.filter((view) => view.isIndex);
|
|
1958
|
+
if (defaultViews.length > 1) {
|
|
1959
|
+
// 收集所有默认跳转页的名称
|
|
1960
|
+
const defaultViewNames = defaultViews.map((view) => view.name).join('、');
|
|
1961
|
+
const typeMap = {
|
|
1962
|
+
Frontend: '首页',
|
|
1963
|
+
View: '默认跳转页',
|
|
1964
|
+
};
|
|
1965
|
+
const pageType = typeMap[node.concept] || '默认跳转页';
|
|
1966
|
+
const errorMessage = `页面 ${node.name} 只能有一个 ${pageType},目前存在 ${defaultViewNames}`;
|
|
1967
|
+
error(node, errorMessage, {
|
|
1968
|
+
fileNode: node,
|
|
1969
|
+
isIndex: true,
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1941
1973
|
/**
|
|
1942
1974
|
* 检查 页面
|
|
1943
1975
|
* @param node
|
|
@@ -1985,6 +2017,7 @@ function createErrorDiagnoser(context) {
|
|
|
1985
2017
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.children, function* (node) {
|
|
1986
2018
|
yield* checkNode(node);
|
|
1987
2019
|
});
|
|
2020
|
+
checkViewIndexPageSetting(node);
|
|
1988
2021
|
}
|
|
1989
2022
|
env.exitScope();
|
|
1990
2023
|
}
|
|
@@ -3362,6 +3395,7 @@ function createErrorDiagnoser(context) {
|
|
|
3362
3395
|
function* checkSwitchCase(node) {
|
|
3363
3396
|
if (!(0, nasl_concepts_1.isLastNode)(node)) {
|
|
3364
3397
|
if (ensureNodeKeyExists(node, 'test')) {
|
|
3398
|
+
yield* rejectNullLiteral(node.test);
|
|
3365
3399
|
yield* checkNode(node.test);
|
|
3366
3400
|
}
|
|
3367
3401
|
}
|
|
@@ -3527,7 +3561,7 @@ function createErrorDiagnoser(context) {
|
|
|
3527
3561
|
error(node, '字符串');
|
|
3528
3562
|
}
|
|
3529
3563
|
const MAX_LENGTH = 2 ** 16;
|
|
3530
|
-
if (node.value.length
|
|
3564
|
+
if (node.value.length > MAX_LENGTH) {
|
|
3531
3565
|
// 插值内部的字符串过长时要报错在插值节点上有红框
|
|
3532
3566
|
error(node.parentNode?.concept === 'StringInterpolation' ? node.parentNode : node, `存在过长文本,当前长度:${node.value.length},最大长度:${MAX_LENGTH}。建议使用变量拆分文本后再拼接。`);
|
|
3533
3567
|
}
|
|
@@ -3686,7 +3720,59 @@ function createErrorDiagnoser(context) {
|
|
|
3686
3720
|
}
|
|
3687
3721
|
return type;
|
|
3688
3722
|
}
|
|
3723
|
+
/**
|
|
3724
|
+
* 获取正则表达式错误的中文消息
|
|
3725
|
+
*/
|
|
3726
|
+
function getRegexErrorMessage(errorId) {
|
|
3727
|
+
const errors = nasl_utils_1.referenceContent?.errors;
|
|
3728
|
+
return errors?.[errorId] || `正则表达式错误: ${errorId}`;
|
|
3729
|
+
}
|
|
3730
|
+
/**
|
|
3731
|
+
* 检查正则表达式标志符
|
|
3732
|
+
*/
|
|
3733
|
+
function checkRegexFlags(flags, targetNode) {
|
|
3734
|
+
const VALID_FLAGS = new Set(['g', 'i', 'm', 's', 'u', 'y']);
|
|
3735
|
+
const flagCounts = new Map();
|
|
3736
|
+
for (const flag of flags) {
|
|
3737
|
+
if (!VALID_FLAGS.has(flag)) {
|
|
3738
|
+
error(targetNode, `正则表达式标志符 "${flag}" 无效`);
|
|
3739
|
+
continue;
|
|
3740
|
+
}
|
|
3741
|
+
const count = (flagCounts.get(flag) || 0) + 1;
|
|
3742
|
+
flagCounts.set(flag, count);
|
|
3743
|
+
if (count > 1) {
|
|
3744
|
+
error(targetNode, `正则表达式标志符 "${flag}" 重复`);
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
}
|
|
3748
|
+
/**
|
|
3749
|
+
* 检查正则表达式语法和标志符
|
|
3750
|
+
*/
|
|
3689
3751
|
function checkNewRegex(node) {
|
|
3752
|
+
// 检查正则表达式模式语法
|
|
3753
|
+
if (nasl_concepts_1.asserts.isStringLiteral(node.pattern)) {
|
|
3754
|
+
const targetNode = node.kind === 'static' ? node : node.pattern;
|
|
3755
|
+
try {
|
|
3756
|
+
regeExp.parse(`/${node.pattern.value}/`);
|
|
3757
|
+
const parseErrors = regeExp.errors;
|
|
3758
|
+
if (Array.isArray(parseErrors) && parseErrors.length > 0) {
|
|
3759
|
+
parseErrors.forEach((errToken) => {
|
|
3760
|
+
const errorId = errToken?.error?.id;
|
|
3761
|
+
if (errorId) {
|
|
3762
|
+
error(targetNode, getRegexErrorMessage(errorId));
|
|
3763
|
+
}
|
|
3764
|
+
});
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
catch (e) {
|
|
3768
|
+
error(targetNode, '正则表达式解析失败');
|
|
3769
|
+
}
|
|
3770
|
+
}
|
|
3771
|
+
// 检查正则表达式标志符
|
|
3772
|
+
if (nasl_concepts_1.asserts.isStringLiteral(node.flags)) {
|
|
3773
|
+
const targetNode = node.kind === 'static' ? node : node.flags;
|
|
3774
|
+
checkRegexFlags(node.flags.value, targetNode);
|
|
3775
|
+
}
|
|
3690
3776
|
return env.getType(node);
|
|
3691
3777
|
}
|
|
3692
3778
|
/**
|
|
@@ -4099,6 +4185,10 @@ function createErrorDiagnoser(context) {
|
|
|
4099
4185
|
*/
|
|
4100
4186
|
function* checkUnaryExpression(node) {
|
|
4101
4187
|
if (ensureNodeKeyExists(node, 'argument')) {
|
|
4188
|
+
const isCandidate = ['!'].includes(node.operator);
|
|
4189
|
+
if (isCandidate) {
|
|
4190
|
+
yield* rejectNullLiteral(node.argument);
|
|
4191
|
+
}
|
|
4102
4192
|
yield* checkNode(node.argument);
|
|
4103
4193
|
}
|
|
4104
4194
|
return env.getType(node);
|
|
@@ -4674,6 +4764,45 @@ function createErrorDiagnoser(context) {
|
|
|
4674
4764
|
});
|
|
4675
4765
|
return flattenedDiags;
|
|
4676
4766
|
}
|
|
4767
|
+
/**
|
|
4768
|
+
* 重新验证祖先节点
|
|
4769
|
+
* 用于增量更新时,当子节点变更需要重新验证祖先节点的场景
|
|
4770
|
+
* @param ancestorNode 需要重新验证的祖先节点
|
|
4771
|
+
* @param validationFn 验证函数
|
|
4772
|
+
* @param errorFilter 错误过滤函数(可选),用于保留特定的错误
|
|
4773
|
+
* @returns 新的诊断信息 Map,如果没有则返回 null
|
|
4774
|
+
*/
|
|
4775
|
+
function revalidateAncestorNode(ancestorNode, validationFn, errorFilter) {
|
|
4776
|
+
// 保存并过滤相关的错误诊断
|
|
4777
|
+
const errs = getError(ancestorNode) || [];
|
|
4778
|
+
const filteredErrs = errorFilter
|
|
4779
|
+
? errs.filter(errorFilter)
|
|
4780
|
+
: [];
|
|
4781
|
+
// 清除祖先节点的诊断信息
|
|
4782
|
+
clearDiagnostics(ancestorNode);
|
|
4783
|
+
// 恢复过滤后的错误诊断
|
|
4784
|
+
if (filteredErrs.length > 0) {
|
|
4785
|
+
filteredErrs.forEach((err) => {
|
|
4786
|
+
const { message, severity, ...context } = err;
|
|
4787
|
+
if (message) {
|
|
4788
|
+
error(ancestorNode, message, {
|
|
4789
|
+
severity: severity,
|
|
4790
|
+
...context,
|
|
4791
|
+
});
|
|
4792
|
+
}
|
|
4793
|
+
});
|
|
4794
|
+
}
|
|
4795
|
+
// 设置文件节点上下文并执行验证
|
|
4796
|
+
const cleanup = handleFileNode(ancestorNode);
|
|
4797
|
+
try {
|
|
4798
|
+
validationFn(ancestorNode, env);
|
|
4799
|
+
}
|
|
4800
|
+
finally {
|
|
4801
|
+
cleanup?.();
|
|
4802
|
+
}
|
|
4803
|
+
// 返回新的诊断信息
|
|
4804
|
+
return getDiagnostics(ancestorNode) || null;
|
|
4805
|
+
}
|
|
4677
4806
|
return {
|
|
4678
4807
|
setMetadataTypeEnable,
|
|
4679
4808
|
setLatestVersionsOfSharedApp,
|
|
@@ -4684,6 +4813,8 @@ function createErrorDiagnoser(context) {
|
|
|
4684
4813
|
getAllDiagnostics,
|
|
4685
4814
|
getDebugDiagnostics,
|
|
4686
4815
|
error,
|
|
4816
|
+
checkViewIndexPageSetting,
|
|
4817
|
+
revalidateAncestorNode,
|
|
4687
4818
|
};
|
|
4688
4819
|
}
|
|
4689
4820
|
exports.createErrorDiagnoser = createErrorDiagnoser;
|