@lcap/nasl-language-server-core 4.4.0-beta.4 → 4.4.0-beta.6
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 +156 -3
- package/out/checker.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +2 -2
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +2 -2
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/view-elem-logic.d.ts +3 -3
- package/out/reference-manager/view-elem-logic.d.ts.map +1 -1
- package/out/reference-manager/view-elem-logic.js +17 -0
- package/out/reference-manager/view-elem-logic.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/dispatch-call.d.ts.map +1 -1
- package/out/typer/dispatch-call.js +6 -0
- 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 -1
- package/out/typer/dispatch-def.js.map +1 -1
- package/out/typer/dispatch-expr.d.ts +2 -1
- package/out/typer/dispatch-expr.d.ts.map +1 -1
- package/out/typer/dispatch-expr.js +95 -21
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-stmt.d.ts.map +1 -1
- package/out/typer/dispatch-stmt.js +29 -15
- package/out/typer/dispatch-stmt.js.map +1 -1
- package/out/typer/dispatch-view.d.ts.map +1 -1
- package/out/typer/dispatch-view.js +0 -4
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/incremental-update.d.ts +10 -0
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +167 -2
- package/out/typer/incremental-update.js.map +1 -1
- package/out/typer/oql-checker/chain-call-transformer.d.ts.map +1 -1
- package/out/typer/oql-checker/chain-call-transformer.js +17 -4
- package/out/typer/oql-checker/chain-call-transformer.js.map +1 -1
- package/out/typer/oql-checker/ts-parser.d.ts.map +1 -1
- package/out/typer/oql-checker/ts-parser.js +157 -21
- package/out/typer/oql-checker/ts-parser.js.map +1 -1
- package/out/typer/overload-helper.d.ts.map +1 -1
- package/out/typer/overload-helper.js +5 -0
- package/out/typer/overload-helper.js.map +1 -1
- package/out/typer/subster.d.ts +1 -1
- package/out/typer/subster.d.ts.map +1 -1
- package/out/typer/subster.js +7 -3
- package/out/typer/subster.js.map +1 -1
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +38 -2
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +22 -2
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +117 -16
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +1 -1
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +8 -4
- package/out/typer/unifier.js.map +1 -1
- package/package.json +6 -6
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;AAOpE,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;AA4OF;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe;oCA49IpB,OAAO;sDAPW,gBAAgB,EAAE;;;;sBAhBjD,UAAU,GAAG,SAAS;;;8BA4Df,UAAU;2BAyBb,UAAU;;;iBAW3B,MAAM;kBACL,MAAM;kBACN,MAAM;qBACH,MAAM;;kBA/+IF,UAAU,WAAW,MAAM,YAAY,YAAY;sCA+qD/B,IAAI,GAAG,QAAQ;2CAi2FxC,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
|
@@ -10,8 +10,8 @@ const sem_diag_1 = require("./typer/sem-diag");
|
|
|
10
10
|
const type_predicate_1 = require("./typer/type-predicate");
|
|
11
11
|
const type_manager_1 = require("./typer/type-manager");
|
|
12
12
|
const service_2 = require("@lcap/nasl-concepts/service");
|
|
13
|
-
const asserts_1 = require("@lcap/nasl-concepts/asserts");
|
|
14
13
|
const lodash_1 = require("lodash");
|
|
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
17
|
var Severity;
|
|
@@ -321,7 +321,30 @@ function createErrorDiagnoser(context) {
|
|
|
321
321
|
}
|
|
322
322
|
const finalNode = memberExpression ?? node;
|
|
323
323
|
(0, helper_1.createOnPush)(diagnostics, finalNode, diagnostic);
|
|
324
|
-
|
|
324
|
+
const aggregationFields = {
|
|
325
|
+
assignmentLine: 'assignmentLines',
|
|
326
|
+
};
|
|
327
|
+
const nodeDiagnostics = diagnostics.get(finalNode);
|
|
328
|
+
if (nodeDiagnostics && nodeDiagnostics.length > 0) {
|
|
329
|
+
// 构建最终的 tsErrorDetail,合并所有上下文信息
|
|
330
|
+
const aggregatedContext = {};
|
|
331
|
+
// 对每个需要聚合的字段进行收集
|
|
332
|
+
for (const [singleField, arrayField] of Object.entries(aggregationFields)) {
|
|
333
|
+
const values = nodeDiagnostics
|
|
334
|
+
.map(d => d[singleField])
|
|
335
|
+
.filter((val) => val !== undefined);
|
|
336
|
+
if (values.length > 0) {
|
|
337
|
+
aggregatedContext[arrayField] = values;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
finalNode.tsErrorDetail = {
|
|
341
|
+
...diagnostic,
|
|
342
|
+
...aggregatedContext,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
finalNode.tsErrorDetail = diagnostic;
|
|
347
|
+
}
|
|
325
348
|
}
|
|
326
349
|
else { }
|
|
327
350
|
}
|
|
@@ -343,7 +366,7 @@ function createErrorDiagnoser(context) {
|
|
|
343
366
|
* @returns
|
|
344
367
|
*/
|
|
345
368
|
function getError(node) {
|
|
346
|
-
const curFileNode = getCurFileNode();
|
|
369
|
+
const curFileNode = getCurFileNode() ?? node;
|
|
347
370
|
const diagnostics = diagnosticMap.get(curFileNode);
|
|
348
371
|
if (diagnostics) {
|
|
349
372
|
return diagnostics.get(node);
|
|
@@ -1912,9 +1935,39 @@ function createErrorDiagnoser(context) {
|
|
|
1912
1935
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.views, function* (node) {
|
|
1913
1936
|
yield* checkNode(node);
|
|
1914
1937
|
});
|
|
1938
|
+
checkViewIndexPageSetting(node);
|
|
1915
1939
|
}
|
|
1916
1940
|
env.exitScope();
|
|
1917
1941
|
}
|
|
1942
|
+
/**
|
|
1943
|
+
* 检查页面的首页/默认跳转页设置
|
|
1944
|
+
* 根据父级类型(Frontend 或 View)自动判断检查场景
|
|
1945
|
+
* @param node 当前页面节点
|
|
1946
|
+
*/
|
|
1947
|
+
function checkViewIndexPageSetting(node) {
|
|
1948
|
+
const isNodeFrontend = (0, asserts_1.isFrontend)(node);
|
|
1949
|
+
const children = isNodeFrontend ? node.views : node.children;
|
|
1950
|
+
// 防御性检查:确保 children 存在且是数组
|
|
1951
|
+
if (!children || !Array.isArray(children)) {
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
// 检查默认跳转页数量,只允许有一个默认跳转页
|
|
1955
|
+
const defaultViews = children.filter((view) => view.isIndex);
|
|
1956
|
+
if (defaultViews.length > 1) {
|
|
1957
|
+
// 收集所有默认跳转页的名称
|
|
1958
|
+
const defaultViewNames = defaultViews.map((view) => view.name).join('、');
|
|
1959
|
+
const typeMap = {
|
|
1960
|
+
Frontend: '首页',
|
|
1961
|
+
View: '默认跳转页',
|
|
1962
|
+
};
|
|
1963
|
+
const pageType = typeMap[node.concept] || '默认跳转页';
|
|
1964
|
+
const errorMessage = `页面 ${node.name} 只能有一个 ${pageType},目前存在 ${defaultViewNames}`;
|
|
1965
|
+
error(node, errorMessage, {
|
|
1966
|
+
fileNode: node,
|
|
1967
|
+
isIndex: true,
|
|
1968
|
+
});
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1918
1971
|
/**
|
|
1919
1972
|
* 检查 页面
|
|
1920
1973
|
* @param node
|
|
@@ -1962,6 +2015,7 @@ function createErrorDiagnoser(context) {
|
|
|
1962
2015
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.children, function* (node) {
|
|
1963
2016
|
yield* checkNode(node);
|
|
1964
2017
|
});
|
|
2018
|
+
checkViewIndexPageSetting(node);
|
|
1965
2019
|
}
|
|
1966
2020
|
env.exitScope();
|
|
1967
2021
|
}
|
|
@@ -2941,15 +2995,27 @@ function createErrorDiagnoser(context) {
|
|
|
2941
2995
|
}
|
|
2942
2996
|
return type;
|
|
2943
2997
|
function checkListSort(nd) {
|
|
2998
|
+
const parTy = env.getType(nd.arguments?.[0]);
|
|
2999
|
+
let paramType = '未知类型';
|
|
3000
|
+
if (parTy?.typeName === 'List') {
|
|
3001
|
+
paramType = (0, type_manager_1.showUserLevelType)(parTy.typeArguments?.[0] || type_manager_1.naslAnyTy);
|
|
3002
|
+
}
|
|
3003
|
+
const expectTy = `{ by: (item: ${paramType}) => 未知类型, asc: 布尔值 }`;
|
|
2944
3004
|
for (let i = 1; i < nd.arguments.length; i++) {
|
|
2945
3005
|
const expr = nd.arguments[i].expression;
|
|
2946
3006
|
let resTy;
|
|
2947
3007
|
if (expr?.concept === 'AnonymousFunction') {
|
|
2948
3008
|
resTy = env.getType(expr.body);
|
|
3009
|
+
if (!nasl_concepts_1.asserts.isNewComposite(expr.body)) {
|
|
3010
|
+
error(nd.arguments[i], (0, sem_diag_1.mkIncompatibleTyErr)(env, env.getType(expr) || type_manager_1.naslAnyTy, expectTy));
|
|
3011
|
+
}
|
|
2949
3012
|
}
|
|
2950
3013
|
else if (expr?.concept === 'SubLogic') {
|
|
2951
3014
|
resTy = env.getType(expr.returns?.[0]);
|
|
2952
3015
|
}
|
|
3016
|
+
else {
|
|
3017
|
+
error(nd.arguments[i], (0, sem_diag_1.mkIncompatibleTyErr)(env, env.getType(expr) || type_manager_1.naslAnyTy, expectTy));
|
|
3018
|
+
}
|
|
2953
3019
|
const byTy = resTy?.properties?.find((prop) => prop.name === 'by')?.typeAnnotation;
|
|
2954
3020
|
if (byTy?.typeKind === 'union') {
|
|
2955
3021
|
// 这里使用 node.arguments[i] 则无红框,猜测是 ListSort 的特殊交互导致的问题
|
|
@@ -3031,6 +3097,7 @@ function createErrorDiagnoser(context) {
|
|
|
3031
3097
|
*/
|
|
3032
3098
|
function* checkIfStatement(node) {
|
|
3033
3099
|
if (ensureNodeKeyExists(node, 'test')) {
|
|
3100
|
+
yield* rejectNullLiteral(node.test);
|
|
3034
3101
|
yield* checkNode(node.test);
|
|
3035
3102
|
}
|
|
3036
3103
|
// then
|
|
@@ -3046,12 +3113,32 @@ function createErrorDiagnoser(context) {
|
|
|
3046
3113
|
});
|
|
3047
3114
|
}
|
|
3048
3115
|
}
|
|
3116
|
+
/**
|
|
3117
|
+
* 检查 条件表达式
|
|
3118
|
+
* @param node
|
|
3119
|
+
*/
|
|
3120
|
+
function* checkIfExpression(node) {
|
|
3121
|
+
if (ensureNodeKeyExists(node, 'condition')) {
|
|
3122
|
+
yield* rejectNullLiteral(node.condition);
|
|
3123
|
+
yield* checkNode(node.condition);
|
|
3124
|
+
}
|
|
3125
|
+
// then
|
|
3126
|
+
if (ensureNodeKeyExists(node, 'consequent')) {
|
|
3127
|
+
yield* checkNode(node.consequent);
|
|
3128
|
+
}
|
|
3129
|
+
// else
|
|
3130
|
+
if (ensureNodeKeyExists(node, 'alternate')) {
|
|
3131
|
+
yield* checkNode(node.alternate);
|
|
3132
|
+
}
|
|
3133
|
+
return env.getType(node);
|
|
3134
|
+
}
|
|
3049
3135
|
/**
|
|
3050
3136
|
* 检查 匹配
|
|
3051
3137
|
* @param node
|
|
3052
3138
|
*/
|
|
3053
3139
|
function* checkMatch(node) {
|
|
3054
3140
|
if (ensureNodeKeyExists(node, 'expression')) {
|
|
3141
|
+
yield* rejectNullLiteral(node.expression);
|
|
3055
3142
|
yield* checkNode(node.expression);
|
|
3056
3143
|
}
|
|
3057
3144
|
if (node.cases?.length) {
|
|
@@ -3350,6 +3437,7 @@ function createErrorDiagnoser(context) {
|
|
|
3350
3437
|
*/
|
|
3351
3438
|
function* checkWhileStatement(node) {
|
|
3352
3439
|
if (ensureNodeKeyExists(node, 'test')) {
|
|
3440
|
+
yield* rejectNullLiteral(node.test);
|
|
3353
3441
|
yield* checkNode(node.test);
|
|
3354
3442
|
}
|
|
3355
3443
|
if (node.body?.length) {
|
|
@@ -3469,6 +3557,11 @@ function createErrorDiagnoser(context) {
|
|
|
3469
3557
|
if (typeof node.value !== 'string') {
|
|
3470
3558
|
error(node, '字符串');
|
|
3471
3559
|
}
|
|
3560
|
+
const MAX_LENGTH = 2 ** 16;
|
|
3561
|
+
if (node.value.length >= MAX_LENGTH) {
|
|
3562
|
+
// 插值内部的字符串过长时要报错在插值节点上有红框
|
|
3563
|
+
error(node.parentNode?.concept === 'StringInterpolation' ? node.parentNode : node, `存在过长文本,当前长度:${node.value.length},最大长度:${MAX_LENGTH}。建议使用变量拆分文本后再拼接。`);
|
|
3564
|
+
}
|
|
3472
3565
|
return env.getType(node);
|
|
3473
3566
|
}
|
|
3474
3567
|
/**
|
|
@@ -4003,10 +4096,17 @@ function createErrorDiagnoser(context) {
|
|
|
4003
4096
|
*/
|
|
4004
4097
|
function* checkBinaryExpression(node) {
|
|
4005
4098
|
yield* semantic_rules_1.ExtraSemanticRules.rejectFileTypes(node, env, error);
|
|
4099
|
+
const isCandidate = ['+', '-', '*', '/', '%', '>', '<', '>=', '<='].includes(node.operator);
|
|
4006
4100
|
if (ensureNodeKeyExists(node, 'left')) {
|
|
4101
|
+
if (isCandidate) {
|
|
4102
|
+
yield* rejectNullLiteral(node.left);
|
|
4103
|
+
}
|
|
4007
4104
|
yield* checkNode(node.left);
|
|
4008
4105
|
}
|
|
4009
4106
|
if (ensureNodeKeyExists(node, 'right')) {
|
|
4107
|
+
if (isCandidate) {
|
|
4108
|
+
yield* rejectNullLiteral(node.right);
|
|
4109
|
+
}
|
|
4010
4110
|
yield* checkNode(node.right);
|
|
4011
4111
|
}
|
|
4012
4112
|
return env.getType(node);
|
|
@@ -4019,6 +4119,7 @@ function createErrorDiagnoser(context) {
|
|
|
4019
4119
|
error(node, '表达式不能为空!');
|
|
4020
4120
|
}
|
|
4021
4121
|
yield* (0, nasl_utils_1.wrapForEachToGenerator)(node.expressions, function* (node) {
|
|
4122
|
+
yield* rejectNullLiteral(node);
|
|
4022
4123
|
yield* checkNode(node);
|
|
4023
4124
|
});
|
|
4024
4125
|
return env.getType(node);
|
|
@@ -4208,6 +4309,15 @@ function createErrorDiagnoser(context) {
|
|
|
4208
4309
|
error(node, `无返回值的${node?.constructor?.nodeTitle}${node.calleeName} 不能在${parentNode?.constructor?.nodeTitle}中作为表达式使用。`);
|
|
4209
4310
|
}
|
|
4210
4311
|
}
|
|
4312
|
+
/**
|
|
4313
|
+
* 检查 不允许使用 null 字面量
|
|
4314
|
+
* @param node
|
|
4315
|
+
*/
|
|
4316
|
+
function* rejectNullLiteral(node) {
|
|
4317
|
+
if (node.concept === 'NullLiteral') {
|
|
4318
|
+
error(node, `此处不允许使用 null`);
|
|
4319
|
+
}
|
|
4320
|
+
}
|
|
4211
4321
|
function* dispatchNode(node) {
|
|
4212
4322
|
try {
|
|
4213
4323
|
// 调用表达式
|
|
@@ -4354,6 +4464,8 @@ function createErrorDiagnoser(context) {
|
|
|
4354
4464
|
return yield* checkBlock(node);
|
|
4355
4465
|
case 'IfStatement':
|
|
4356
4466
|
return yield* checkIfStatement(node);
|
|
4467
|
+
case 'IfExpression':
|
|
4468
|
+
return yield* checkIfExpression(node);
|
|
4357
4469
|
case 'Match':
|
|
4358
4470
|
return yield* checkMatch(node);
|
|
4359
4471
|
case 'MatchCase':
|
|
@@ -4593,6 +4705,45 @@ function createErrorDiagnoser(context) {
|
|
|
4593
4705
|
});
|
|
4594
4706
|
return flattenedDiags;
|
|
4595
4707
|
}
|
|
4708
|
+
/**
|
|
4709
|
+
* 重新验证祖先节点
|
|
4710
|
+
* 用于增量更新时,当子节点变更需要重新验证祖先节点的场景
|
|
4711
|
+
* @param ancestorNode 需要重新验证的祖先节点
|
|
4712
|
+
* @param validationFn 验证函数
|
|
4713
|
+
* @param errorFilter 错误过滤函数(可选),用于保留特定的错误
|
|
4714
|
+
* @returns 新的诊断信息 Map,如果没有则返回 null
|
|
4715
|
+
*/
|
|
4716
|
+
function revalidateAncestorNode(ancestorNode, validationFn, errorFilter) {
|
|
4717
|
+
// 保存并过滤相关的错误诊断
|
|
4718
|
+
const errs = getError(ancestorNode) || [];
|
|
4719
|
+
const filteredErrs = errorFilter
|
|
4720
|
+
? errs.filter(errorFilter)
|
|
4721
|
+
: [];
|
|
4722
|
+
// 清除祖先节点的诊断信息
|
|
4723
|
+
clearDiagnostics(ancestorNode);
|
|
4724
|
+
// 恢复过滤后的错误诊断
|
|
4725
|
+
if (filteredErrs.length > 0) {
|
|
4726
|
+
filteredErrs.forEach((err) => {
|
|
4727
|
+
const { message, severity, ...context } = err;
|
|
4728
|
+
if (message) {
|
|
4729
|
+
error(ancestorNode, message, {
|
|
4730
|
+
severity: severity,
|
|
4731
|
+
...context,
|
|
4732
|
+
});
|
|
4733
|
+
}
|
|
4734
|
+
});
|
|
4735
|
+
}
|
|
4736
|
+
// 设置文件节点上下文并执行验证
|
|
4737
|
+
const cleanup = handleFileNode(ancestorNode);
|
|
4738
|
+
try {
|
|
4739
|
+
validationFn(ancestorNode, env);
|
|
4740
|
+
}
|
|
4741
|
+
finally {
|
|
4742
|
+
cleanup?.();
|
|
4743
|
+
}
|
|
4744
|
+
// 返回新的诊断信息
|
|
4745
|
+
return getDiagnostics(ancestorNode) || null;
|
|
4746
|
+
}
|
|
4596
4747
|
return {
|
|
4597
4748
|
setMetadataTypeEnable,
|
|
4598
4749
|
setLatestVersionsOfSharedApp,
|
|
@@ -4603,6 +4754,8 @@ function createErrorDiagnoser(context) {
|
|
|
4603
4754
|
getAllDiagnostics,
|
|
4604
4755
|
getDebugDiagnostics,
|
|
4605
4756
|
error,
|
|
4757
|
+
checkViewIndexPageSetting,
|
|
4758
|
+
revalidateAncestorNode,
|
|
4606
4759
|
};
|
|
4607
4760
|
}
|
|
4608
4761
|
exports.createErrorDiagnoser = createErrorDiagnoser;
|