@lcap/nasl-language-server-core 4.0.1-rc.1 → 4.0.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 +1 -1
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +24 -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 +2 -3
- package/out/reference-manager/collect-q-name.d.ts.map +1 -1
- package/out/reference-manager/collect-q-name.js +29 -28
- 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 +56 -57
- package/out/reference-manager/get-q-name.js.map +1 -1
- package/out/reference-manager/reference-manager.d.ts +21 -11
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +192 -101
- package/out/reference-manager/reference-manager.js.map +1 -1
- package/out/reference-manager/remove-q-name.d.ts +1 -2
- package/out/reference-manager/remove-q-name.d.ts.map +1 -1
- package/out/reference-manager/remove-q-name.js +33 -29
- package/out/reference-manager/remove-q-name.js.map +1 -1
- package/out/reference-manager/rename-q-name.d.ts +2 -1
- package/out/reference-manager/rename-q-name.d.ts.map +1 -1
- package/out/reference-manager/rename-q-name.js +13 -3
- package/out/reference-manager/rename-q-name.js.map +1 -1
- package/out/reference-manager/symbol-type.d.ts +5 -3
- package/out/reference-manager/symbol-type.d.ts.map +1 -1
- package/out/reference-manager/symbol-type.js +8 -3
- 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/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-def.d.ts.map +1 -1
- package/out/typer/dispatch-def.js +3 -0
- 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 +135 -100
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.d.ts.map +1 -1
- package/out/typer/dispatch-process.js +17 -5
- 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 +15 -11
- 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 +28 -44
- 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/nasl-predicate.d.ts +1 -2
- package/out/typer/nasl-predicate.d.ts.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 +4 -0
- package/out/typer/sem-diag.d.ts.map +1 -1
- package/out/typer/sem-diag.js +9 -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.d.ts.map +1 -1
- package/out/typer/subster.js +10 -5
- 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 +9 -6
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getSubViews = exports.cheapTestLocalSymbol = exports.getNamespaceWithoutLast = exports.getDatasourceQName = exports.handleEntityAutoRef = exports.isEntityLogic = exports.easyGetOldQName = exports.ReferenceManager = void 0;
|
|
4
4
|
const nasl_concepts_1 = require("@lcap/nasl-concepts");
|
|
5
|
+
const mnemonist_1 = require("mnemonist");
|
|
5
6
|
const fp_macros_1 = require("../utils/fp-macros");
|
|
6
7
|
const console_1 = require("console");
|
|
7
8
|
const builtin_q_name_1 = require("./builtin-q-name");
|
|
@@ -11,17 +12,14 @@ const type_predicate_1 = require("../typer/type-predicate");
|
|
|
11
12
|
const helper_1 = require("../typer/helper");
|
|
12
13
|
const component_def_manager_1 = require("../typer/component-def-manager/component-def-manager");
|
|
13
14
|
const get_q_name_1 = require("./get-q-name");
|
|
14
|
-
|
|
15
|
-
Object.defineProperty(exports, "getTokenQualifiedNameForMatchedExpr", { enumerable: true, get: function () { return get_q_name_1.getTokenQualifiedNameForMatchedExpr; } });
|
|
16
|
-
Object.defineProperty(exports, "getPropQName", { enumerable: true, get: function () { return get_q_name_1.getPropQName; } });
|
|
17
|
-
Object.defineProperty(exports, "prependStr", { enumerable: true, get: function () { return get_q_name_1.prependNonEmptyStr; } });
|
|
15
|
+
const string_1 = require("../utils/string");
|
|
18
16
|
const symbol_type_1 = require("./symbol-type");
|
|
19
17
|
const update_nasl_fragment_1 = require("./update-nasl-fragment");
|
|
20
18
|
const nasl_predicate_1 = require("../typer/nasl-predicate");
|
|
21
19
|
const type_manager_1 = require("../typer/type-manager");
|
|
22
20
|
const oql_1 = require("../utils/oql");
|
|
23
21
|
const parseTsClassType_1 = require("../utils/parseTsClassType");
|
|
24
|
-
const
|
|
22
|
+
const string_2 = require("../utils/string");
|
|
25
23
|
/**
|
|
26
24
|
* 考虑这样一个例子:
|
|
27
25
|
* x = f(...)
|
|
@@ -193,12 +191,6 @@ class ReferenceManager {
|
|
|
193
191
|
this.localQNameRefs = new Map();
|
|
194
192
|
// 当前文件节点
|
|
195
193
|
this.curFileNode = undefined;
|
|
196
|
-
this.buildSymbolRefsFromSymbolGraph = (symbolGraph) => {
|
|
197
|
-
const m = this.symbolRefs; // Using private property directly for internal function
|
|
198
|
-
Array.from(symbolGraph.getSymbols()).forEach(sym => sym.declaration
|
|
199
|
-
&& symbol_type_1.globalDefConcept.includes(sym.declaration.concept)
|
|
200
|
-
&& m.set(sym.declaration, new Set(sym.references)));
|
|
201
|
-
};
|
|
202
194
|
// 约 20 万节点 200ms
|
|
203
195
|
this.slowBuildSymbolRefsForApp = (env, app) => {
|
|
204
196
|
this.modeForCollect = "create" /* Operation.Create */;
|
|
@@ -256,8 +248,8 @@ class ReferenceManager {
|
|
|
256
248
|
// for (const preference of app.preferenceMap) {
|
|
257
249
|
// allRefs.push(...this.collectRefs(env, preference as any as ValidExtInp));
|
|
258
250
|
// }
|
|
259
|
-
app.integration && allRefs.push(...this.collectRefs(env, app.integration));
|
|
260
|
-
app.backend && allRefs.push(...this.collectRefs(env, app.backend));
|
|
251
|
+
app.integration && allRefs.push(...this.collectRefs(env, app.integration, false));
|
|
252
|
+
app.backend && allRefs.push(...this.collectRefs(env, app.backend, false));
|
|
261
253
|
allRefs.forEach(([ref, qName]) => {
|
|
262
254
|
if (!ref) {
|
|
263
255
|
return;
|
|
@@ -270,24 +262,11 @@ class ReferenceManager {
|
|
|
270
262
|
else {
|
|
271
263
|
// Cache reference for future relinking
|
|
272
264
|
// FIXME:这里有问题,脏脏的,比如局部变量、入参等都扔到这里面了,虽然暂时可能没有太大的正确性问题,但有内存泄漏
|
|
273
|
-
if (!cheapTestLocalSymbol(qName)) {
|
|
265
|
+
if (!(0, exports.cheapTestLocalSymbol)(qName)) {
|
|
274
266
|
(0, helper_1.createSetOnPush)(this.cachedQNameSymbolRefs, qName, ref);
|
|
275
267
|
}
|
|
276
268
|
}
|
|
277
269
|
});
|
|
278
|
-
// 如果 QA 说查找引用要能看到实体逻辑里的类型啥的,再给注释去掉
|
|
279
|
-
// 处理一下实体逻辑
|
|
280
|
-
// app.dataSources.forEach(ds => {
|
|
281
|
-
// ds.entities.forEach(e => {
|
|
282
|
-
// e.logics.forEach((l: Logic) => {
|
|
283
|
-
// const refsInLogic = this.collectRefs(env, l);
|
|
284
|
-
// refsInLogic.forEach((qName, ref) => {
|
|
285
|
-
// console.log('xx')
|
|
286
|
-
// allRefs.set(ref, qName);
|
|
287
|
-
// });
|
|
288
|
-
// });
|
|
289
|
-
// });
|
|
290
|
-
// });
|
|
291
270
|
// 暂时特殊处理一下流程,应该不会太慢
|
|
292
271
|
for (const p of app.processV2s) {
|
|
293
272
|
this.addRefsForGlobalSym(env, p);
|
|
@@ -301,7 +280,8 @@ class ReferenceManager {
|
|
|
301
280
|
}
|
|
302
281
|
for (const fe of fet.frontends) {
|
|
303
282
|
for (const v of fe.views) {
|
|
304
|
-
|
|
283
|
+
// 包括子页面
|
|
284
|
+
this.addRefsForGlobalSym(env, v, false);
|
|
305
285
|
}
|
|
306
286
|
for (const be of fe.bindEvents) {
|
|
307
287
|
this.addRefsForGlobalSym(env, be);
|
|
@@ -442,10 +422,14 @@ class ReferenceManager {
|
|
|
442
422
|
// nd = this.qNameDefs.get(getTokenQualifiedName(nd)!)!;
|
|
443
423
|
// ==> 好像也不行,很多依赖库逻辑调用又挂了,这也不行,那也不行
|
|
444
424
|
// 全局符号直接查找
|
|
445
|
-
// if (nd.concept === 'ProcessV2') {
|
|
446
|
-
// } else
|
|
447
425
|
if (isGlobalDef(nd)) {
|
|
448
|
-
res = this.getSymbolRefs(nd);
|
|
426
|
+
res = this.getSymbolRefs(nd) ?? new Set();
|
|
427
|
+
if (nd.concept === 'Entity') {
|
|
428
|
+
// 加上所有实体逻辑调用的引用(实体逻辑可看做无定义,但要修改调用处的 namespace:实体名是 namespace 的一部分)
|
|
429
|
+
for (const l of nd.logics) {
|
|
430
|
+
res = mnemonist_1.set.union(res, this.getSymbolRefs(l) ?? new Set());
|
|
431
|
+
}
|
|
432
|
+
}
|
|
449
433
|
}
|
|
450
434
|
else { // 局部符号才需要即时获取
|
|
451
435
|
const boundary = toRaw(getBoundary(nd));
|
|
@@ -460,12 +444,36 @@ class ReferenceManager {
|
|
|
460
444
|
(endTime - startTime > 200) && console.log(`Get reference: all time: ${endTime - startTime}ms`);
|
|
461
445
|
}
|
|
462
446
|
}
|
|
447
|
+
// 这个东西很特殊……查三代
|
|
448
|
+
if (nd.concept === 'BusinessLogic') {
|
|
449
|
+
// 上面已经找到了业务组件内部对业务组件逻辑的内用
|
|
450
|
+
// 现在再找出所有 业务组件逻辑 所属的业务组件的外部引用
|
|
451
|
+
const bs = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
452
|
+
if (bs?.concept === 'BusinessComponent') {
|
|
453
|
+
const bsRefs = this.getSymbolRefs(bs) ?? new Set();
|
|
454
|
+
let bsRefsRefs = new Array(); // 业务组件(在页面的引用)的引用
|
|
455
|
+
// 再对每个实例找到所有引用
|
|
456
|
+
for (const bsInst of bsRefs) {
|
|
457
|
+
bsRefsRefs.push(...this.getViewElementRefs(env, bsInst));
|
|
458
|
+
}
|
|
459
|
+
// 再从引用中过滤出找到当前业务逻辑的调用
|
|
460
|
+
res = mnemonist_1.set.union(res, new Set(bsRefsRefs.filter(r => r.concept === 'CallLogic' && r.calleeName === nd.name))); // amazing!
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// 这个东西很特殊……查三代
|
|
464
|
+
if (nd.concept === 'Connection') {
|
|
465
|
+
const conn = nd.connector;
|
|
466
|
+
const allLogics = [...conn.logics, ...conn.namespaces.flatMap(nsp => nsp.logics)];
|
|
467
|
+
for (const l of allLogics) {
|
|
468
|
+
res = mnemonist_1.set.union(res ?? new Set(), new Set(this.getReferences(env, l)));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
463
471
|
return res ? Array.from(res) : [];
|
|
464
472
|
};
|
|
465
473
|
// 建立所有局部引用,先处理上一次的缓存
|
|
466
474
|
this.clearRebuildLocalCache = (env, nd_) => {
|
|
467
475
|
this.localQNameRefs.clear();
|
|
468
|
-
return this.buildLocalQNameRefs(env, toRaw(nd_));
|
|
476
|
+
return this.buildLocalQNameRefs(env, toRaw(nd_)) ?? new Set();
|
|
469
477
|
};
|
|
470
478
|
// 给类似 FileNode 级别的定义建立局部索引
|
|
471
479
|
// 修改后:不写入 env map 了,不做缓存,直接返回数据
|
|
@@ -482,12 +490,12 @@ class ReferenceManager {
|
|
|
482
490
|
}
|
|
483
491
|
if (boundary.concept === 'View' || boundary.concept === 'BusinessComponent') {
|
|
484
492
|
viewVars = (0, nasl_concepts_1.getViewVars)(nd).map(toRaw);
|
|
485
|
-
logicVars
|
|
493
|
+
logicVars.push(...(0, nasl_concepts_1.getCtxLogicLike)(nd)?.variables?.map(toRaw) ?? []);
|
|
486
494
|
logics = (0, nasl_concepts_1.getViewLikeLogics)(nd).map(toRaw);
|
|
487
495
|
}
|
|
488
496
|
else if (boundary.concept === 'ProcessDefinitionV2') {
|
|
489
497
|
processVars = (0, nasl_concepts_1.getProcessVars)(nd).map(toRaw);
|
|
490
|
-
logicVars
|
|
498
|
+
logicVars.push(...(0, nasl_concepts_1.getCtxLogicLike)(nd)?.variables?.map(toRaw) ?? []);
|
|
491
499
|
logics = (0, nasl_concepts_1.getProcessLikeLogics)(nd).map(toRaw);
|
|
492
500
|
}
|
|
493
501
|
else if ((0, nasl_predicate_1.isCallableNaslLogic)(boundary) || (0, nasl_predicate_1.isCallableNaslInterface)(boundary)) {
|
|
@@ -501,7 +509,7 @@ class ReferenceManager {
|
|
|
501
509
|
this.localQNameRefs.set(qName, new Set());
|
|
502
510
|
}
|
|
503
511
|
});
|
|
504
|
-
let subRefs = this.collectRefs(env, boundary);
|
|
512
|
+
let subRefs = this.collectRefs(env, boundary, true);
|
|
505
513
|
this.lastBoundary = boundary;
|
|
506
514
|
subRefs?.forEach(([rf, qName]) => {
|
|
507
515
|
// 不存在则表示不是局部符号
|
|
@@ -563,7 +571,7 @@ class ReferenceManager {
|
|
|
563
571
|
return result;
|
|
564
572
|
}
|
|
565
573
|
const nd = toRaw(__nd);
|
|
566
|
-
const ctxProcLike = (0, nasl_concepts_1.getCtxProcessLike)(nd);
|
|
574
|
+
const ctxProcLike = toRaw((0, nasl_concepts_1.getCtxProcessLike)(nd));
|
|
567
575
|
if (!ctxProcLike) {
|
|
568
576
|
return result;
|
|
569
577
|
}
|
|
@@ -581,6 +589,7 @@ class ReferenceManager {
|
|
|
581
589
|
}
|
|
582
590
|
};
|
|
583
591
|
visitChildrenWith(ctxProcLike, lam);
|
|
592
|
+
// 重命名时不需要处理 sourceRef targetRef,好像其他逻辑已经处理掉了
|
|
584
593
|
return result;
|
|
585
594
|
};
|
|
586
595
|
/**
|
|
@@ -767,7 +776,7 @@ class ReferenceManager {
|
|
|
767
776
|
res.push([typeAnnotation, tyQName]);
|
|
768
777
|
const parentConcept = (0, type_predicate_1.isEntityTy)(typeAnnotation) ? 'Entity' : 'Structure';
|
|
769
778
|
for (const prop of nd.properties) {
|
|
770
|
-
const propQName = (0,
|
|
779
|
+
const propQName = (0, string_2.getPropQName)(tyQName, prop.name, parentConcept);
|
|
771
780
|
res.push([prop, propQName]);
|
|
772
781
|
}
|
|
773
782
|
};
|
|
@@ -784,7 +793,7 @@ class ReferenceManager {
|
|
|
784
793
|
}
|
|
785
794
|
const relEntityQName = `${relNsp}.${relEntity}`;
|
|
786
795
|
this.handleRefOp(env, this.modeForCollect, nd, relEntityQName);
|
|
787
|
-
const relPropQName = (0,
|
|
796
|
+
const relPropQName = (0, string_2.getPropQName)(`${relNsp}.${relEntity}`, `${relProperty}`, 'Entity');
|
|
788
797
|
this.handleRefOp(env, this.modeForCollect, nd, relPropQName);
|
|
789
798
|
};
|
|
790
799
|
this.handleBusinessComponentRefs = (env, nd) => {
|
|
@@ -797,6 +806,54 @@ class ReferenceManager {
|
|
|
797
806
|
}
|
|
798
807
|
this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(bsDef));
|
|
799
808
|
};
|
|
809
|
+
this.handleBindRoles = (env, nd) => {
|
|
810
|
+
for (const roleName of nd.bindRoles ?? nd.roles) {
|
|
811
|
+
const qName = `${symbol_type_1.roleNsp}.${roleName}`;
|
|
812
|
+
this.handleRefOp(env, this.modeForCollect, nd, qName);
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
this.handleAuthLogicRef = (env, nd) => {
|
|
816
|
+
let parent = nd.parentNode;
|
|
817
|
+
while (parent) {
|
|
818
|
+
if (parent.concept === 'App' ||
|
|
819
|
+
parent.concept === 'Connector' ||
|
|
820
|
+
parent.concept === 'Module' ||
|
|
821
|
+
parent.concept === 'Namespace') {
|
|
822
|
+
// Found the desired ancestor, stop searching
|
|
823
|
+
break;
|
|
824
|
+
}
|
|
825
|
+
parent = parent.parentNode;
|
|
826
|
+
}
|
|
827
|
+
if (!parent?.concept) {
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
// @ts-expect-error
|
|
831
|
+
parent?.interfaceDependencies?.forEach(dep => {
|
|
832
|
+
dep.interfaces.forEach(itfc => {
|
|
833
|
+
if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
|
|
834
|
+
// this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
|
|
835
|
+
const authName = itfc.authLogic;
|
|
836
|
+
parent?.authLogicsForCallInterface?.forEach(l => {
|
|
837
|
+
if (l.name === authName) {
|
|
838
|
+
this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
|
|
839
|
+
}
|
|
840
|
+
});
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
});
|
|
844
|
+
parent.interfaces?.forEach(itfc => {
|
|
845
|
+
if (itfc.concept === 'AuthInterface' && itfc.name === nd.calleeName) {
|
|
846
|
+
// this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
|
|
847
|
+
// this.handleRefOp(env, this.modeForCollect!, nd, getTokenQualifiedName(itfc)!);
|
|
848
|
+
const authName = itfc.authLogic;
|
|
849
|
+
parent?.authLogics?.forEach(l => {
|
|
850
|
+
if (l.name === authName) {
|
|
851
|
+
this.handleRefOp(env, this.modeForCollect, nd, (0, get_q_name_1.getTokenQualifiedName)(l));
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
};
|
|
800
857
|
/**
|
|
801
858
|
* 无论根节点是 ref 还是 def,都要递归收集下层所有的引用节点
|
|
802
859
|
* 会打散 a.b.c、A | B、x.a.b 等结构,并记录必要的信息
|
|
@@ -810,16 +867,35 @@ class ReferenceManager {
|
|
|
810
867
|
* @warning 此过程收集所有引用,包括全局符号和局部符号的,不会做过滤
|
|
811
868
|
* @param env semantic environment
|
|
812
869
|
* @param nd start node to collect sub refs
|
|
870
|
+
* @param skipSubView whether skip the collection for sub views
|
|
813
871
|
* @returns [ref, qName]
|
|
814
872
|
*/
|
|
815
|
-
this.collectRefs = (env, nd) => {
|
|
873
|
+
this.collectRefs = (env, nd, skipSubView = true) => {
|
|
874
|
+
// 有的 nd 没实例化,上面没有 traverseStrictChildren 方法,比如 ApplyAnnotation 大哥
|
|
875
|
+
if (nd.traverseStrictChildren === undefined) {
|
|
876
|
+
return [];
|
|
877
|
+
}
|
|
878
|
+
// extract views
|
|
879
|
+
const views = new Array();
|
|
880
|
+
nd.concept === 'View' && views.push(nd);
|
|
881
|
+
!skipSubView && views.push(...(0, exports.getSubViews)(nd));
|
|
882
|
+
if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
|
|
883
|
+
this.curFileNode = nd;
|
|
884
|
+
env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
|
|
885
|
+
}
|
|
816
886
|
const res = new Array(); // 使用数组而不是 Map
|
|
817
887
|
// specialization for speeding up
|
|
818
888
|
const normalCb = (n) => {
|
|
819
889
|
// 隐式引用 - 来自 __TypeAnnotation
|
|
820
890
|
this.handleSymbolImplicitRefs(n);
|
|
821
|
-
n.concept === 'ViewElement'
|
|
891
|
+
if (n.concept === 'ViewElement') {
|
|
892
|
+
n.tag.startsWith('bs-') && this.handleBusinessComponentRefs(env, n);
|
|
893
|
+
n.bindRoles.length && this.handleBindRoles(env, n);
|
|
894
|
+
}
|
|
895
|
+
// 都特殊,样样都特殊
|
|
822
896
|
n.concept === 'EntityProperty' && this.handleForeignKeyRef(env, n);
|
|
897
|
+
n.concept === 'AssigneeV2' && this.handleBindRoles(env, n);
|
|
898
|
+
n.concept === 'CallAuthInterface' && this.handleAuthLogicRef(env, n);
|
|
823
899
|
if (!symbol_type_1.refConcept.includes(n.concept)) {
|
|
824
900
|
return;
|
|
825
901
|
}
|
|
@@ -837,7 +913,9 @@ class ReferenceManager {
|
|
|
837
913
|
n.concept === 'OqlQueryComponent' ||
|
|
838
914
|
n.concept === 'FieldPermissionV2' ||
|
|
839
915
|
// @ts-expect-error 临时 hack,下个版本应该把左侧 concept 改一改
|
|
840
|
-
n.concept === 'NewComposite'
|
|
916
|
+
n.concept === 'NewComposite' ||
|
|
917
|
+
// 跳过子页面,但不能跳过自己
|
|
918
|
+
(skipSubView && n.concept === 'View' && n !== nd);
|
|
841
919
|
// 会终止子树迭代
|
|
842
920
|
const compositeNodeCb = (n) => {
|
|
843
921
|
let qNameRefs = new Array();
|
|
@@ -857,7 +935,7 @@ class ReferenceManager {
|
|
|
857
935
|
this.handleNewCompositeNode(n, res);
|
|
858
936
|
// 右侧构成的引用
|
|
859
937
|
qNameRefs = n.rights
|
|
860
|
-
.flatMap(r => this.collectRefs(env, r));
|
|
938
|
+
.flatMap(r => this.collectRefs(env, r, true));
|
|
861
939
|
break;
|
|
862
940
|
case 'OqlQueryComponent':
|
|
863
941
|
for (const qName of (0, oql_1.extractSymbolsFromOqlQueryComponent)(n)) {
|
|
@@ -878,8 +956,25 @@ class ReferenceManager {
|
|
|
878
956
|
res.push([ref, qName]);
|
|
879
957
|
}
|
|
880
958
|
};
|
|
881
|
-
//
|
|
882
|
-
|
|
959
|
+
// 逐个处理嵌套的页面
|
|
960
|
+
if (views.length > 0) {
|
|
961
|
+
for (const v of views) {
|
|
962
|
+
v.bindRoles.length && this.handleBindRoles(env, v);
|
|
963
|
+
const lastViewAssocProcess = env.viewAssocProcess;
|
|
964
|
+
env.viewAssocProcess = env.processV2ViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(v)) ?? null;
|
|
965
|
+
const lastCurFileNode = this.curFileNode;
|
|
966
|
+
this.curFileNode = v;
|
|
967
|
+
// @ts-expect-error contra-variance errors
|
|
968
|
+
visitChildrenWith(v, normalCb, compositeNodePred, compositeNodeCb);
|
|
969
|
+
this.curFileNode = lastCurFileNode;
|
|
970
|
+
env.viewAssocProcess = lastViewAssocProcess;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
// 处理非页面
|
|
975
|
+
// @ts-expect-error contra-variance errors
|
|
976
|
+
visitChildrenWith(nd, normalCb, compositeNodePred, compositeNodeCb);
|
|
977
|
+
}
|
|
883
978
|
// QFE 实在是没办法一致性处理
|
|
884
979
|
if (nd.concept !== 'QueryFieldExpression') {
|
|
885
980
|
// 过滤掉根节点
|
|
@@ -887,38 +982,20 @@ class ReferenceManager {
|
|
|
887
982
|
}
|
|
888
983
|
return res;
|
|
889
984
|
};
|
|
890
|
-
this.collectGlobalSubDefs = (nd) => {
|
|
891
|
-
const res = new Map();
|
|
892
|
-
res.set(nd, (0, get_q_name_1.getTokenQualifiedName)(nd));
|
|
893
|
-
const cb = (n) => {
|
|
894
|
-
if (!symbol_type_1.globalDefConcept.includes(n.concept)) {
|
|
895
|
-
return;
|
|
896
|
-
}
|
|
897
|
-
const qName = (0, get_q_name_1.getTokenQualifiedName)(n);
|
|
898
|
-
if (!qName) {
|
|
899
|
-
return;
|
|
900
|
-
}
|
|
901
|
-
res.set(n, qName);
|
|
902
|
-
};
|
|
903
|
-
visitChildrenWith(nd, cb);
|
|
904
|
-
return res;
|
|
905
|
-
};
|
|
906
985
|
/**
|
|
907
986
|
* @warning Only handle global symbols
|
|
908
987
|
* 仅清除全局符号的引用。外部优先调用此接口,不要直接调用 collectRefs
|
|
909
988
|
* 不是说输入是 global symbol,而是说对于任何输入,只移除内部对 global symbol 的引用
|
|
989
|
+
* @param skipSubView 是否跳过子页面,增量场景调用较多,增量场景默认跳过
|
|
910
990
|
*/
|
|
911
|
-
this.removeRefsForGlobalSym = (env, rmNd) => {
|
|
991
|
+
this.removeRefsForGlobalSym = (env, rmNd, skipSubView = true) => {
|
|
912
992
|
this.curFileNode = rmNd;
|
|
913
993
|
this.modeForCollect = "delete" /* Operation.Remove */;
|
|
914
|
-
if (rmNd.concept === 'View' || rmNd.concept === 'BusinessComponent') {
|
|
915
|
-
env.viewAssocProcess = env.processViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(rmNd)) ?? null;
|
|
916
|
-
}
|
|
917
994
|
if (rmNd.concept === 'ProcessV2') {
|
|
918
|
-
env.
|
|
995
|
+
env.processAssocEntity = rmNd.bind;
|
|
919
996
|
}
|
|
920
997
|
// const localVars = env.localVars.get(rmNd as any) ?? [];
|
|
921
|
-
const refAndQNames = this.collectRefs(env, rmNd);
|
|
998
|
+
const refAndQNames = this.collectRefs(env, rmNd, skipSubView);
|
|
922
999
|
for (const [ref, qName] of refAndQNames) {
|
|
923
1000
|
// if (localVars.includes(qName) || cheapTestLocalSymbol(qName)) {
|
|
924
1001
|
// continue;
|
|
@@ -939,36 +1016,31 @@ class ReferenceManager {
|
|
|
939
1016
|
else if (rmNd.concept === 'BindAttribute' && !rmNd.expression && (0, update_nasl_fragment_1.isSpecialStringRefField)(rmNd.name)) {
|
|
940
1017
|
(0, update_nasl_fragment_1.removeBindAttrRef)(this, rmNd);
|
|
941
1018
|
}
|
|
942
|
-
env.
|
|
943
|
-
env.processAssocBind = null;
|
|
1019
|
+
env.processAssocEntity = null;
|
|
944
1020
|
};
|
|
945
1021
|
/**
|
|
946
1022
|
* @warning Only handle global symbols
|
|
947
1023
|
* 仅收集全局符号的引用。外部优先调用此接口,不要直接调用 collectRefs
|
|
948
1024
|
* 不是说输入是 global symbol,而是说对于任何输入,只收集内部对 global symbol 的引用
|
|
1025
|
+
* @param skipSubView 是否跳过子页面,增量场景调用较多,增量场景默认跳过
|
|
949
1026
|
*/
|
|
950
|
-
this.addRefsForGlobalSym = (env, nd) => {
|
|
1027
|
+
this.addRefsForGlobalSym = (env, nd, skipSubView = true) => {
|
|
951
1028
|
this.curFileNode = nd;
|
|
952
1029
|
this.modeForCollect = "create" /* Operation.Create */;
|
|
953
|
-
if (nd.concept === 'View' || nd.concept === 'BusinessComponent') {
|
|
954
|
-
// 如果是 null,则设置为 null,否则会报错
|
|
955
|
-
env.viewAssocProcess = env.processViewBindings.get((0, get_q_name_1.getTokenQualifiedName)(nd)) ?? null;
|
|
956
|
-
}
|
|
957
1030
|
if (nd.concept === 'ProcessV2') {
|
|
958
|
-
env.
|
|
1031
|
+
env.processAssocEntity = nd.bind;
|
|
959
1032
|
}
|
|
960
|
-
const refAndQNames = this.collectRefs(env, nd);
|
|
1033
|
+
const refAndQNames = this.collectRefs(env, nd, skipSubView);
|
|
961
1034
|
const localVars = env.localVars.get(nd) ?? [];
|
|
962
1035
|
for (const [ref, qName] of refAndQNames) {
|
|
963
|
-
if (localVars.includes(qName) || cheapTestLocalSymbol(qName)) {
|
|
1036
|
+
if (localVars.includes(qName) || (0, exports.cheapTestLocalSymbol)(qName)) {
|
|
964
1037
|
continue;
|
|
965
1038
|
}
|
|
966
1039
|
this.handleRefOp(env, "create" /* Operation.Create */, ref, qName);
|
|
967
1040
|
}
|
|
968
1041
|
this.modeForCollect = null;
|
|
969
1042
|
this.curFileNode = undefined;
|
|
970
|
-
env.
|
|
971
|
-
env.processAssocBind = null;
|
|
1043
|
+
env.processAssocEntity = null;
|
|
972
1044
|
};
|
|
973
1045
|
this.invalidateLocalSymCache = () => {
|
|
974
1046
|
this.isLocalCacheValid = false;
|
|
@@ -1031,8 +1103,8 @@ class ReferenceManager {
|
|
|
1031
1103
|
if (qName) {
|
|
1032
1104
|
// Handle process reference in view
|
|
1033
1105
|
if (env.viewAssocProcess && env.viewAssocProcess.name === ids[0].name) {
|
|
1034
|
-
const ctxLogic = (0, nasl_concepts_1.getCtxLogicLike)(nd);
|
|
1035
|
-
const ctxViewLike = (0, nasl_concepts_1.getCtxViewLike)(nd);
|
|
1106
|
+
const ctxLogic = toRaw((0, nasl_concepts_1.getCtxLogicLike)(nd));
|
|
1107
|
+
const ctxViewLike = toRaw((0, nasl_concepts_1.getCtxViewLike)(nd));
|
|
1036
1108
|
const logicVars = env.localVars.get(ctxLogic);
|
|
1037
1109
|
const viewVars = env.localVars.get(ctxViewLike);
|
|
1038
1110
|
// 哇,是 Process.data.XXX 特殊引用 && avoid shadowing
|
|
@@ -1052,7 +1124,7 @@ class ReferenceManager {
|
|
|
1052
1124
|
}
|
|
1053
1125
|
}
|
|
1054
1126
|
}
|
|
1055
|
-
const objDefQNames = this.collectRefs(env, id0); // 第一个可能是复杂表达式,再收集一次
|
|
1127
|
+
const objDefQNames = this.collectRefs(env, id0, false); // 第一个可能是复杂表达式,再收集一次
|
|
1056
1128
|
objDefQNames.forEach(([ref, qName]) => {
|
|
1057
1129
|
// @ts-expect-error
|
|
1058
1130
|
res.push([ref, qName]);
|
|
@@ -1067,12 +1139,15 @@ class ReferenceManager {
|
|
|
1067
1139
|
// 是这样的,为了兼容 processVariable.variable1,前面的是匿名数据结构,只需要 variable1 的引用就行了
|
|
1068
1140
|
let ndDef = this.getNodeDef(ty);
|
|
1069
1141
|
if (ndDef && (ndDef.concept === 'Entity' || ndDef.concept === 'Structure' || ndDef.concept === 'Enum')) {
|
|
1070
|
-
const propQName = (0,
|
|
1142
|
+
const propQName = (0, string_2.getPropQName)(`${ty.typeNamespace}.${ty.typeName}`, ids[i + 1].name, 'Entity');
|
|
1071
1143
|
res.push([ids[i + 1], propQName]); // type reference
|
|
1072
1144
|
}
|
|
1073
1145
|
else {
|
|
1074
|
-
|
|
1075
|
-
|
|
1146
|
+
// 局部无 namespace 的定义应该不可能通过 a.x.y 这种成员访问引用到
|
|
1147
|
+
if (ty.typeNamespace && ty.typeName) {
|
|
1148
|
+
const propQName = (0, string_1.prependNonEmptyStr)((0, string_1.prependNonEmptyStr)(ty.typeNamespace, ty.typeName), ids[i + 1].name);
|
|
1149
|
+
res.push([ids[i + 1], propQName]);
|
|
1150
|
+
}
|
|
1076
1151
|
}
|
|
1077
1152
|
// update next ty and nextProp name
|
|
1078
1153
|
let nextProp = undefined;
|
|
@@ -1147,7 +1222,7 @@ class ReferenceManager {
|
|
|
1147
1222
|
const entityDef = this.qNameDefs.get(`${eNsp}.${eAsName}`);
|
|
1148
1223
|
entityDef && res.push([nd, entityQName]);
|
|
1149
1224
|
if (entityDef && pName) {
|
|
1150
|
-
const propQName = (0,
|
|
1225
|
+
const propQName = (0, string_2.getPropQName)(entityQName, pName, 'Entity');
|
|
1151
1226
|
const prop = getEntityProp(pName, entityDef);
|
|
1152
1227
|
prop && res.push([nd, propQName]);
|
|
1153
1228
|
}
|
|
@@ -1162,9 +1237,12 @@ class ReferenceManager {
|
|
|
1162
1237
|
}
|
|
1163
1238
|
return res;
|
|
1164
1239
|
};
|
|
1240
|
+
/**
|
|
1241
|
+
* FieldPermissionV2 是对 Entity 和其属性的特殊引用
|
|
1242
|
+
*/
|
|
1165
1243
|
this.splitFieldPermissionV2 = (env, nd) => {
|
|
1166
1244
|
const res = [];
|
|
1167
|
-
const bind = env.
|
|
1245
|
+
const bind = env.processAssocEntity;
|
|
1168
1246
|
if (!bind) {
|
|
1169
1247
|
return res;
|
|
1170
1248
|
}
|
|
@@ -1176,7 +1254,7 @@ class ReferenceManager {
|
|
|
1176
1254
|
? (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation) // data 是 Entity
|
|
1177
1255
|
: (0, get_q_name_1.getTokenQualifiedName)(entityRef.typeAnnotation.typeArguments[0]); // relation_data 是 List<Entity>
|
|
1178
1256
|
for (const sub of nd.subFieldPermissions) {
|
|
1179
|
-
res.push([sub, (0,
|
|
1257
|
+
res.push([sub, (0, string_2.getPropQName)(entityQName, sub.propertyName, 'Entity')]);
|
|
1180
1258
|
}
|
|
1181
1259
|
return res;
|
|
1182
1260
|
};
|
|
@@ -1263,7 +1341,7 @@ class ReferenceManager {
|
|
|
1263
1341
|
this.fastBuildQNameDefs(toRaw(app));
|
|
1264
1342
|
console.timeEnd('\x1b[44m\x1b[97m Reference manager: Build Qualified Name to Definition Map \x1b[0m');
|
|
1265
1343
|
}
|
|
1266
|
-
buildSymbolRefsForApp(env, app
|
|
1344
|
+
buildSymbolRefsForApp(env, app) {
|
|
1267
1345
|
console.time('\x1b[44m\x1b[97m Reference manager: Build Symbol to Reference Map \x1b[0m');
|
|
1268
1346
|
// symbolGraph && this.buildSymbolRefsFromSymbolGraph(symbolGraph); // 方舟的,后面可能不好修 bug 和维护
|
|
1269
1347
|
app && this.slowBuildSymbolRefsForApp(env, toRaw(app));
|
|
@@ -1410,13 +1488,6 @@ const isEntitiesLogicsPath = (str) => {
|
|
|
1410
1488
|
*/
|
|
1411
1489
|
const isEntityLogic = (nd) => nd?.concept === 'Logic' && nd.getNamespace && isEntitiesLogicsPath(nd.getNamespace());
|
|
1412
1490
|
exports.isEntityLogic = isEntityLogic;
|
|
1413
|
-
const lowercaseFirstChar = (str) => {
|
|
1414
|
-
if (str.length === 0) {
|
|
1415
|
-
return str; // Return an empty string if the input is empty
|
|
1416
|
-
}
|
|
1417
|
-
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
1418
|
-
};
|
|
1419
|
-
exports.lowercaseFirstChar = lowercaseFirstChar;
|
|
1420
1491
|
/**
|
|
1421
1492
|
* 处理 CodeWave 编译器的一些连带的自动化行为,如自动生成 { abc: Abc } 这样的匿名结构体。
|
|
1422
1493
|
* 这里实质上是否是引用?这里不是直接引用,但是 entityX 这个名字是从 EntityX 自动生成的,也可以看作是间接引用
|
|
@@ -1426,7 +1497,7 @@ exports.lowercaseFirstChar = lowercaseFirstChar;
|
|
|
1426
1497
|
const handleEntityAutoRef = (ty, nextProp, ident) => {
|
|
1427
1498
|
const nextTy = nextProp?.typeAnnotation;
|
|
1428
1499
|
if (ty.typeKind === 'anonymousStructure' &&
|
|
1429
|
-
nextProp?.name === (0,
|
|
1500
|
+
nextProp?.name === (0, string_1.lowercaseFirstChar)(nextTy?.typeName ?? '')) {
|
|
1430
1501
|
const entityQName = `${nextTy?.typeNamespace}.${nextTy?.typeName}`;
|
|
1431
1502
|
return [ident, entityQName];
|
|
1432
1503
|
}
|
|
@@ -1498,13 +1569,33 @@ const cheapTestLocalSymbol = (qName) => {
|
|
|
1498
1569
|
qName.startsWith('nasl.collection')) {
|
|
1499
1570
|
return true;
|
|
1500
1571
|
}
|
|
1501
|
-
// 页面下引用的 Process 的 qName
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1572
|
+
// 页面下引用的 Process 的 qName,一般是 Process_uniqueKey 的 hash
|
|
1573
|
+
if (qName.startsWith('Process_')) {
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1505
1576
|
if (qName.indexOf('.') === -1) {
|
|
1506
1577
|
return true;
|
|
1507
1578
|
}
|
|
1508
1579
|
return false;
|
|
1509
1580
|
};
|
|
1581
|
+
exports.cheapTestLocalSymbol = cheapTestLocalSymbol;
|
|
1582
|
+
/**
|
|
1583
|
+
* 一个 FileNode 下面还可以有其他 FileNode 哦,其实没什么神秘的。
|
|
1584
|
+
* @warning 只会返回下属的 FileNode,不包含自己
|
|
1585
|
+
* @param node
|
|
1586
|
+
* @returns 下属 FileNodes,不包含自己
|
|
1587
|
+
*/
|
|
1588
|
+
const getSubViews = (node) => {
|
|
1589
|
+
const result = [];
|
|
1590
|
+
if (node.concept === 'View') {
|
|
1591
|
+
node.children?.forEach((nd) => {
|
|
1592
|
+
if (nd.concept === 'View') {
|
|
1593
|
+
result.push(nd);
|
|
1594
|
+
result.push(...(0, exports.getSubViews)(nd));
|
|
1595
|
+
}
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
return result;
|
|
1599
|
+
};
|
|
1600
|
+
exports.getSubViews = getSubViews;
|
|
1510
1601
|
//# sourceMappingURL=reference-manager.js.map
|