@lcap/nasl-language-server-core 4.4.0-beta.3 → 4.4.0-beta.31
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 +4 -1
- package/out/checker.d.ts.map +1 -1
- package/out/checker.js +996 -96
- 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 +64 -27
- 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} +195 -23
- 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 +146 -47
- package/out/reference-manager/reference-manager.d.ts.map +1 -1
- package/out/reference-manager/reference-manager.js +632 -204
- 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 +14 -14
- 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 +9 -2
- package/out/reference-manager/symbol-type.js.map +1 -1
- package/out/reference-manager/update-nasl-fragment.d.ts +2 -2
- package/out/reference-manager/update-nasl-fragment.d.ts.map +1 -1
- package/out/reference-manager/update-nasl-fragment.js +33 -28
- package/out/reference-manager/update-nasl-fragment.js.map +1 -1
- package/out/services/bindable-logic-service.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/symbol/traverse/concepts/logic/expression/member-expression.js.map +1 -1
- package/out/typer/collectGlobalDefs.d.ts +8 -0
- package/out/typer/collectGlobalDefs.d.ts.map +1 -1
- package/out/typer/collectGlobalDefs.js +102 -54
- 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 +51 -6
- 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 +151 -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 +51 -23
- 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 +240 -199
- package/out/typer/dispatch-expr.js.map +1 -1
- package/out/typer/dispatch-process.d.ts +8 -1
- package/out/typer/dispatch-process.d.ts.map +1 -1
- package/out/typer/dispatch-process.js +37 -4
- 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 +39 -25
- 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 +87 -48
- package/out/typer/dispatch-view.js.map +1 -1
- package/out/typer/fix-use-before-assign.js.map +1 -1
- package/out/typer/get-oql-files.d.ts.map +1 -1
- package/out/typer/get-oql-files.js +3 -9
- package/out/typer/get-oql-files.js.map +1 -1
- package/out/typer/incremental-update.d.ts +14 -7
- package/out/typer/incremental-update.d.ts.map +1 -1
- package/out/typer/incremental-update.js +396 -43
- 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 +252 -37
- 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 +190 -23
- 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 +54 -31
- package/out/typer/solver.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 +251 -57
- package/out/typer/subster.js.map +1 -1
- package/out/typer/topo-sort.d.ts +38 -0
- package/out/typer/topo-sort.d.ts.map +1 -1
- package/out/typer/topo-sort.js +272 -3
- 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 +1 -0
- package/out/typer/type-predicate.d.ts.map +1 -1
- package/out/typer/type-predicate.js +83 -14
- package/out/typer/type-predicate.js.map +1 -1
- package/out/typer/typer.d.ts +51 -6
- package/out/typer/typer.d.ts.map +1 -1
- package/out/typer/typer.js +248 -46
- package/out/typer/typer.js.map +1 -1
- package/out/typer/unifier.d.ts +12 -1
- package/out/typer/unifier.d.ts.map +1 -1
- package/out/typer/unifier.js +110 -37
- package/out/typer/unifier.js.map +1 -1
- package/out/utils/debug.js.map +1 -1
- package/out/utils/type-operator.d.ts +15 -0
- package/out/utils/type-operator.d.ts.map +1 -1
- package/out/utils/type-operator.js +65 -3
- package/out/utils/type-operator.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 -164
- package/out/reference-manager/view-elem-logic.js.map +0 -1
package/out/typer/typer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { App, BaseNode, CallFunction, Logic, QueryFieldExpression, SyntaxNode, TypeAnnotation, Variable, CallQueryComponent, ProcessV2, Return, Param, type ViewElement, CallLogic, OverriddenLogic, Identifier, ProcessBindV2 } from '@lcap/nasl-concepts';
|
|
2
|
-
import { TypingEnv, ResolvedCall, TyVarSolution, TypeSubst } from './type-manager';
|
|
1
|
+
import { App, BaseNode, CallFunction, Logic, QueryFieldExpression, Structure, SyntaxNode, TypeAnnotation, Variable, CallQueryComponent, ProcessV2, Return, Param, type ViewElement, CallLogic, OverriddenLogic, Identifier, ProcessBindV2 } from '@lcap/nasl-concepts';
|
|
2
|
+
import { Constraints, TypingEnv, ResolvedCall, TyVarSolution, TypeSubst } from './type-manager';
|
|
3
3
|
import { Solver } from './solver';
|
|
4
4
|
import { ReferenceManager } from '../reference-manager/reference-manager';
|
|
5
5
|
import { type DefConcept, type RefConcept } from '../reference-manager/symbol-type';
|
|
@@ -20,6 +20,7 @@ export declare class SemEnv {
|
|
|
20
20
|
app: App | null;
|
|
21
21
|
isFirstScreenCheck: boolean;
|
|
22
22
|
strict: boolean;
|
|
23
|
+
isAIStrictMode: boolean;
|
|
23
24
|
/**
|
|
24
25
|
* 是否是前端类型检查模式
|
|
25
26
|
*
|
|
@@ -29,12 +30,19 @@ export declare class SemEnv {
|
|
|
29
30
|
isView: boolean;
|
|
30
31
|
isPlayground: boolean;
|
|
31
32
|
isInMemberExpr: boolean;
|
|
33
|
+
/** 草稿区约束单独存放,不写入 unifier.cs,从而不影响外部求解(与 withPostCheckScope 类似的作用域隔离) */
|
|
34
|
+
playgroundCs: Constraints;
|
|
32
35
|
flags: {
|
|
33
36
|
checkOQL: boolean;
|
|
34
37
|
/**
|
|
35
38
|
* 是否为智能应用生成开发模式。如果是,那么有一些特殊的类型检查规则。
|
|
36
39
|
*/
|
|
37
40
|
creatorDevMode: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* 是否启用草稿区隔离相关的额外逻辑。
|
|
43
|
+
* 仅在视图场景(env.isView=true)下生效;逻辑/流程/大 JSON 等非页面场景会自动忽略。
|
|
44
|
+
*/
|
|
45
|
+
usePlaygroundIsolation: boolean;
|
|
38
46
|
};
|
|
39
47
|
enableCheckOQL(): void;
|
|
40
48
|
enableCreatorDevMode(): void;
|
|
@@ -47,7 +55,7 @@ export declare class SemEnv {
|
|
|
47
55
|
*
|
|
48
56
|
* 页面检查会连带检查服务端逻辑,tpSolving 里简单改一下的话性能直接变慢一倍,简直是地狱
|
|
49
57
|
*/
|
|
50
|
-
allRefsInPlayground: WeakSet<
|
|
58
|
+
allRefsInPlayground: WeakSet<Identifier>;
|
|
51
59
|
varCandidateTypes: WeakMap<Variable | Return | Param, TypeAnnotation>;
|
|
52
60
|
ctxProcessV2: ProcessV2 | undefined;
|
|
53
61
|
viewAssocProcess: ProcessV2 | null;
|
|
@@ -55,10 +63,19 @@ export declare class SemEnv {
|
|
|
55
63
|
processAssocEntity: ProcessBindV2 | null;
|
|
56
64
|
typeBindings: TypingEnv;
|
|
57
65
|
private postChecksAfterResolve;
|
|
66
|
+
private currentScopeLevel;
|
|
58
67
|
matchedVars: Map<string, TypeAnnotation>;
|
|
59
68
|
allocatedVEQNames: string[];
|
|
60
69
|
allocatedVirtualNodes: Map<BaseNode, (Logic | Param | Return | Variable)[]>;
|
|
61
70
|
addPostCheckTask(nd: BaseNode, task: (env: SemEnv, pSubst: TypeSubst) => void): void;
|
|
71
|
+
private enterPostCheckScope;
|
|
72
|
+
private exitPostCheckScope;
|
|
73
|
+
/**
|
|
74
|
+
* 在 postCheck 作用域中执行函数,自动保证 enter/exit 成对调用
|
|
75
|
+
* @param fn 要在作用域中执行的函数
|
|
76
|
+
* @returns 函数返回值
|
|
77
|
+
*/
|
|
78
|
+
withPostCheckScope<T>(fn: () => T): T;
|
|
62
79
|
viewConstraintStats: Array<{
|
|
63
80
|
viewName: string;
|
|
64
81
|
stats: Array<{
|
|
@@ -70,7 +87,16 @@ export declare class SemEnv {
|
|
|
70
87
|
resolvedCallInfo: Map<BaseNode, ResolvedCall>;
|
|
71
88
|
fileNodes: SyntaxNode[];
|
|
72
89
|
errBoundary: SyntaxNode | null;
|
|
90
|
+
errBoundaryContext: Record<string, any> | null;
|
|
73
91
|
errorReportingDisableCount: number;
|
|
92
|
+
private errorDelegatee;
|
|
93
|
+
get hasErrorDelegatee(): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* 用于 OQL 类型检查,需要将其下所有节点的报错,全部委托给 errorDelegatee 处理
|
|
96
|
+
* @param x
|
|
97
|
+
*/
|
|
98
|
+
setErrorDelegatee(x: SyntaxNode): void;
|
|
99
|
+
resetErrorDelegatee(): null;
|
|
74
100
|
errSeverity: 'error' | 'warning';
|
|
75
101
|
ctxTpQFE: ((nd: QueryFieldExpression, tgtTy: TypeAnnotation | undefined) => TypeAnnotation | undefined) | undefined;
|
|
76
102
|
ctxTpEntityTy: TypeAnnotation | undefined;
|
|
@@ -92,7 +118,15 @@ export declare class SemEnv {
|
|
|
92
118
|
enableErrorReporting(): void;
|
|
93
119
|
getErrorReportingDisableCount(): number;
|
|
94
120
|
isErrorReportingDisabled(): boolean;
|
|
95
|
-
|
|
121
|
+
/**
|
|
122
|
+
* 为列表中重复出现的元素(如环展开产生的重启节点)创建报错抑制跟踪器。
|
|
123
|
+
* 非最后一次出现时自动 suppress,最后一次出现时正常报错。
|
|
124
|
+
*/
|
|
125
|
+
createDuplicateErrorGuard<T>(items: T[]): {
|
|
126
|
+
before: (item: T) => void;
|
|
127
|
+
after: (item: T) => void;
|
|
128
|
+
};
|
|
129
|
+
addError(message: string, __fileNode?: SyntaxNode, __errBoundary?: SyntaxNode, severity?: 'error' | 'warning', __context?: Record<string, any>): void;
|
|
96
130
|
/**
|
|
97
131
|
* 给节点添加错误 (只能指定错误等级为 warning 或者默认)
|
|
98
132
|
* @param message
|
|
@@ -150,7 +184,7 @@ export declare class SemEnv {
|
|
|
150
184
|
getMangledQName: (nd: CallFunction | CallLogic, mangledName: string, dsSqlType: 'mysql' | 'oracle' | 'dameng' | undefined) => string;
|
|
151
185
|
getSqlFunctionNamespace: (dsSqlType: 'mysql' | 'oracle' | 'dameng') => string;
|
|
152
186
|
private scopeStack;
|
|
153
|
-
private
|
|
187
|
+
private localDefStacks;
|
|
154
188
|
getLexicalSym: (name: string | undefined) => PossibleLocalSym | undefined;
|
|
155
189
|
/** Add a single lexical variable (shadow-safe). */
|
|
156
190
|
addLexicalSym: (nd: PossibleLocalSym & {
|
|
@@ -164,7 +198,7 @@ export declare class SemEnv {
|
|
|
164
198
|
removeLexicalVarByName: (name: string | undefined) => void;
|
|
165
199
|
getLexicalVarSize: () => number;
|
|
166
200
|
/**
|
|
167
|
-
* Enter a stored lexical scope. Variables recorded during typing are pushed onto the
|
|
201
|
+
* Enter a stored lexical scope. Variables recorded during typing are pushed onto the localDefStacks
|
|
168
202
|
* to enable identifier resolution in later phases (checker, ref collection). If the scope was not
|
|
169
203
|
* recorded (e.g. legacy / fallback), varsFallback can be provided to push & record on the fly.
|
|
170
204
|
*/
|
|
@@ -229,6 +263,8 @@ export declare class SemEnv {
|
|
|
229
263
|
removeTypes: (nd: BaseNode | undefined) => void;
|
|
230
264
|
setErrSeverity: (severity: 'error' | 'warning') => void;
|
|
231
265
|
runPostChecks: (subst: TyVarSolution) => void;
|
|
266
|
+
savePostChecksState(): Map<BaseNode, Array<(env: SemEnv, pSubst: TypeSubst) => void>>;
|
|
267
|
+
restorePostChecksState(saved: Map<BaseNode, Array<(env: SemEnv, pSubst: TypeSubst) => void>>): void;
|
|
232
268
|
printCs: () => void;
|
|
233
269
|
clearAll(): void;
|
|
234
270
|
isEq(a: TypeAnnotation, b: TypeAnnotation): boolean;
|
|
@@ -239,6 +275,15 @@ export declare class SemEnv {
|
|
|
239
275
|
[x: string]: any;
|
|
240
276
|
};
|
|
241
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* 从泛型结构体中查找属性类型,支持泛型参数替换
|
|
280
|
+
* @param env 语义环境
|
|
281
|
+
* @param genericTy 泛型类型注解
|
|
282
|
+
* @param def 结构体定义
|
|
283
|
+
* @param targetName 目标属性名称
|
|
284
|
+
* @returns 归一化后的属性类型注解,如果未找到则返回 undefined
|
|
285
|
+
*/
|
|
286
|
+
export declare function findPropertyTypeFromGeneric(env: SemEnv, genericTy: TypeAnnotation, def: Structure, targetName: string): TypeAnnotation | undefined;
|
|
242
287
|
export declare function normalize(env: SemEnv, ty: TypeAnnotation): TypeAnnotation;
|
|
243
288
|
export {};
|
|
244
289
|
//# sourceMappingURL=typer.d.ts.map
|
package/out/typer/typer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typer.d.ts","sourceRoot":"","sources":["../../src/typer/typer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,QAAQ,EAER,YAAY,EAGZ,KAAK,EACL,oBAAoB,
|
|
1
|
+
{"version":3,"file":"typer.d.ts","sourceRoot":"","sources":["../../src/typer/typer.ts"],"names":[],"mappings":"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"}
|
package/out/typer/typer.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.normalize = exports.SemEnv = void 0;
|
|
3
|
+
exports.normalize = exports.findPropertyTypeFromGeneric = exports.SemEnv = void 0;
|
|
4
4
|
const nasl_concepts_1 = require("@lcap/nasl-concepts");
|
|
5
5
|
const asserts_1 = require("@lcap/nasl-concepts/asserts");
|
|
6
6
|
const service_1 = require("@lcap/nasl-concepts/service");
|
|
7
7
|
const asserts_2 = require("@lcap/nasl-concepts/asserts");
|
|
8
8
|
const type_manager_1 = require("./type-manager");
|
|
9
9
|
const helper_1 = require("./helper");
|
|
10
|
-
const
|
|
10
|
+
const def_key_helpers_1 = require("../reference-manager/def-key-helpers");
|
|
11
11
|
const reference_manager_1 = require("../reference-manager/reference-manager");
|
|
12
12
|
const unifier_1 = require("./unifier");
|
|
13
13
|
const helper_2 = require("./helper");
|
|
@@ -29,7 +29,78 @@ class SemEnv {
|
|
|
29
29
|
}
|
|
30
30
|
// 后置的语义检查,在完全求解出类型变元后
|
|
31
31
|
addPostCheckTask(nd, task) {
|
|
32
|
-
|
|
32
|
+
const isPlaygroundSnapshot = this.isPlayground;
|
|
33
|
+
const errSeveritySnapshot = this.errSeverity;
|
|
34
|
+
const wrapped = (env, pSubst) => {
|
|
35
|
+
const prevIsPlayground = env.isPlayground;
|
|
36
|
+
const prevSeverity = env.errSeverity;
|
|
37
|
+
env.isPlayground = isPlaygroundSnapshot;
|
|
38
|
+
env.setErrSeverity(errSeveritySnapshot);
|
|
39
|
+
try {
|
|
40
|
+
task(env, pSubst);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
env.setErrSeverity(prevSeverity);
|
|
44
|
+
env.isPlayground = prevIsPlayground;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
// 记录当前作用域层级
|
|
48
|
+
const postCheckEntry = { task: wrapped, scopeLevel: this.currentScopeLevel };
|
|
49
|
+
if (this.postChecksAfterResolve.has(nd)) {
|
|
50
|
+
this.postChecksAfterResolve.get(nd).push(postCheckEntry);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.postChecksAfterResolve.set(nd, [postCheckEntry]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// 进入子作用域,增加 postChecks 作用域层级
|
|
57
|
+
enterPostCheckScope() {
|
|
58
|
+
this.currentScopeLevel++;
|
|
59
|
+
}
|
|
60
|
+
// 退出子作用域,减少 postChecks 作用域层级
|
|
61
|
+
// 添加检查防止层级不平衡
|
|
62
|
+
exitPostCheckScope() {
|
|
63
|
+
if (this.currentScopeLevel > 0) {
|
|
64
|
+
this.currentScopeLevel--;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// 层级不平衡,可能是忘记调用 enterPostCheckScope 或多次调用 exitPostCheckScope
|
|
68
|
+
if (this.isDebugMode) {
|
|
69
|
+
console.warn('postCheck scope underflow: exitPostCheckScope called without matching enterPostCheckScope');
|
|
70
|
+
}
|
|
71
|
+
// 在非调试模式下也记录,防止静默失败
|
|
72
|
+
this.currentScopeLevel = 0; // 确保不会变成负数
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 在 postCheck 作用域中执行函数,自动保证 enter/exit 成对调用
|
|
77
|
+
* @param fn 要在作用域中执行的函数
|
|
78
|
+
* @returns 函数返回值
|
|
79
|
+
*/
|
|
80
|
+
withPostCheckScope(fn) {
|
|
81
|
+
this.enterPostCheckScope();
|
|
82
|
+
try {
|
|
83
|
+
return fn();
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
this.exitPostCheckScope();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
get hasErrorDelegatee() {
|
|
90
|
+
return this.errorDelegatee !== null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 用于 OQL 类型检查,需要将其下所有节点的报错,全部委托给 errorDelegatee 处理
|
|
94
|
+
* @param x
|
|
95
|
+
*/
|
|
96
|
+
setErrorDelegatee(x) {
|
|
97
|
+
if (this.errorDelegatee) {
|
|
98
|
+
throw new Error("不支持递归设置错误委托者");
|
|
99
|
+
}
|
|
100
|
+
this.errorDelegatee = x;
|
|
101
|
+
}
|
|
102
|
+
resetErrorDelegatee() {
|
|
103
|
+
return this.errorDelegatee = null;
|
|
33
104
|
}
|
|
34
105
|
// 已废弃:localVars。请使用 refMgr.localSymBindings + enterScope/exitScope + getVisibleLocalSyms/getVisibleVars
|
|
35
106
|
// Centralized overload registry on the environment (global across a session)
|
|
@@ -51,17 +122,42 @@ class SemEnv {
|
|
|
51
122
|
isErrorReportingDisabled() {
|
|
52
123
|
return this.errorReportingDisableCount > 0;
|
|
53
124
|
}
|
|
54
|
-
|
|
125
|
+
/**
|
|
126
|
+
* 为列表中重复出现的元素(如环展开产生的重启节点)创建报错抑制跟踪器。
|
|
127
|
+
* 非最后一次出现时自动 suppress,最后一次出现时正常报错。
|
|
128
|
+
*/
|
|
129
|
+
createDuplicateErrorGuard(items) {
|
|
130
|
+
const remaining = new Map();
|
|
131
|
+
for (const item of items) {
|
|
132
|
+
remaining.set(item, (remaining.get(item) ?? 0) + 1);
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
before: (item) => {
|
|
136
|
+
if (remaining.get(item) > 1) {
|
|
137
|
+
this.suppressErrorReporting();
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
after: (item) => {
|
|
141
|
+
if (remaining.get(item) > 1) {
|
|
142
|
+
this.enableErrorReporting();
|
|
143
|
+
}
|
|
144
|
+
remaining.set(item, remaining.get(item) - 1);
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
addError(message, __fileNode, __errBoundary, severity = this.errSeverity, __context) {
|
|
55
149
|
const fileNode = __fileNode ?? this.getCurFileNode();
|
|
56
|
-
const errBoundary = __errBoundary ?? this.errBoundary;
|
|
150
|
+
const errBoundary = this.errorDelegatee ?? __errBoundary ?? this.errBoundary;
|
|
57
151
|
// discard errors
|
|
58
152
|
if (!errBoundary || this.errorReportingDisableCount > 0) {
|
|
59
153
|
return;
|
|
60
154
|
}
|
|
61
|
-
|
|
155
|
+
const context = {
|
|
62
156
|
fileNode,
|
|
63
157
|
severity: severity,
|
|
64
|
-
|
|
158
|
+
...(__context || this.errBoundaryContext || {}),
|
|
159
|
+
};
|
|
160
|
+
this.errorDiagnoser.error(errBoundary, message, context);
|
|
65
161
|
}
|
|
66
162
|
/**
|
|
67
163
|
* 给节点添加错误 (只能指定错误等级为 warning 或者默认)
|
|
@@ -80,11 +176,9 @@ class SemEnv {
|
|
|
80
176
|
}
|
|
81
177
|
resolveRef(nd) {
|
|
82
178
|
if (nd.concept === 'Identifier' && nd.namespace === 'elements.$ce.property') {
|
|
83
|
-
// @ts-expect-error 不认
|
|
84
179
|
return nd.getAncestorRaw('ViewElement');
|
|
85
180
|
}
|
|
86
181
|
else if (nd.concept === 'Identifier' && nd.name === 'elements') {
|
|
87
|
-
// @ts-expect-error 不认
|
|
88
182
|
return nd.getAncestorRaw('ViewElement');
|
|
89
183
|
}
|
|
90
184
|
else if (nd.concept === 'Identifier' && nd.namespace && nd.namespace.startsWith('elements.') && nd.namespace.endsWith('.property')) {
|
|
@@ -96,8 +190,8 @@ class SemEnv {
|
|
|
96
190
|
return undefined;
|
|
97
191
|
}
|
|
98
192
|
const componentName = nd.name;
|
|
99
|
-
const qName = `${(0,
|
|
100
|
-
return ((0, helper_1.mGetLastOne)(this.
|
|
193
|
+
const qName = `${(0, def_key_helpers_1.getGlobalDefKey)(componentLikeCtx)}.${componentName}`;
|
|
194
|
+
return ((0, helper_1.mGetLastOne)(this.localDefStacks, qName)) ?? this.refMgr.gQNameDefs.get(qName);
|
|
101
195
|
}
|
|
102
196
|
else if (nd.concept === 'CallLogic' && nd.calleeNamespace && nd.calleeNamespace.startsWith('elements.') && nd.calleeNamespace.endsWith(".logics")) {
|
|
103
197
|
// FIXME wudengke getCallNode是Theta(页面元素数量) 的方法,很慢
|
|
@@ -113,7 +207,7 @@ class SemEnv {
|
|
|
113
207
|
if (!componentLikeCtx) {
|
|
114
208
|
return undefined;
|
|
115
209
|
}
|
|
116
|
-
const qViewName = (0,
|
|
210
|
+
const qViewName = (0, def_key_helpers_1.getGlobalDefKey)(componentLikeCtx);
|
|
117
211
|
if (!qViewName) {
|
|
118
212
|
return undefined;
|
|
119
213
|
}
|
|
@@ -147,7 +241,7 @@ class SemEnv {
|
|
|
147
241
|
if (!componentLikeCtx) {
|
|
148
242
|
return undefined;
|
|
149
243
|
}
|
|
150
|
-
const qViewName = (0,
|
|
244
|
+
const qViewName = (0, def_key_helpers_1.getGlobalDefKey)(componentLikeCtx);
|
|
151
245
|
if (!qViewName) {
|
|
152
246
|
return undefined;
|
|
153
247
|
}
|
|
@@ -189,13 +283,14 @@ class SemEnv {
|
|
|
189
283
|
}
|
|
190
284
|
}
|
|
191
285
|
}
|
|
192
|
-
const qName = (0,
|
|
193
|
-
if (!qName)
|
|
286
|
+
const qName = (0, def_key_helpers_1.getGlobalDefKey)(nd);
|
|
287
|
+
if (!qName)
|
|
194
288
|
return undefined;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
289
|
+
// localDefStacks 用 getLocalDefKey 作为 key(如 logic2),需先按 localKey 查找
|
|
290
|
+
const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd);
|
|
291
|
+
const fromLexical = (localKey && (0, helper_1.mGetLastOne)(this.localDefStacks, localKey)) ?? (0, helper_1.mGetLastOne)(this.localDefStacks, qName);
|
|
292
|
+
const def = fromLexical ?? this.refMgr.gQNameDefs.get(qName);
|
|
293
|
+
return typeof def === 'string' ? undefined : def;
|
|
199
294
|
}
|
|
200
295
|
// 从 parseTs 等定义中获取定义,如果调用者需要类型,则可以从定义中获取 __TypeAnnotation
|
|
201
296
|
quickGetLibDef(nd, mangledName, dsSqlType) {
|
|
@@ -216,6 +311,8 @@ class SemEnv {
|
|
|
216
311
|
this.app = null;
|
|
217
312
|
this.isFirstScreenCheck = false;
|
|
218
313
|
this.strict = false;
|
|
314
|
+
// 针对AI应用的严格类型检查模式
|
|
315
|
+
this.isAIStrictMode = false;
|
|
219
316
|
/**
|
|
220
317
|
* 是否是前端类型检查模式
|
|
221
318
|
*
|
|
@@ -225,12 +322,19 @@ class SemEnv {
|
|
|
225
322
|
this.isView = false;
|
|
226
323
|
this.isPlayground = false;
|
|
227
324
|
this.isInMemberExpr = false;
|
|
325
|
+
/** 草稿区约束单独存放,不写入 unifier.cs,从而不影响外部求解(与 withPostCheckScope 类似的作用域隔离) */
|
|
326
|
+
this.playgroundCs = new Map();
|
|
228
327
|
this.flags = {
|
|
229
328
|
checkOQL: false,
|
|
230
329
|
/**
|
|
231
330
|
* 是否为智能应用生成开发模式。如果是,那么有一些特殊的类型检查规则。
|
|
232
331
|
*/
|
|
233
332
|
creatorDevMode: false,
|
|
333
|
+
/**
|
|
334
|
+
* 是否启用草稿区隔离相关的额外逻辑。
|
|
335
|
+
* 仅在视图场景(env.isView=true)下生效;逻辑/流程/大 JSON 等非页面场景会自动忽略。
|
|
336
|
+
*/
|
|
337
|
+
usePlaygroundIsolation: true,
|
|
234
338
|
};
|
|
235
339
|
// 指向的页面变量、局部变量、返回值、参数等,用于 Identifier 定位
|
|
236
340
|
this.idToVar = new Map();
|
|
@@ -242,7 +346,8 @@ class SemEnv {
|
|
|
242
346
|
*
|
|
243
347
|
* 页面检查会连带检查服务端逻辑,tpSolving 里简单改一下的话性能直接变慢一倍,简直是地狱
|
|
244
348
|
*/
|
|
245
|
-
//
|
|
349
|
+
// 记录所有在草稿区的 Identifier 引用
|
|
350
|
+
// 如果某个 Identifier 在这个 Set 中,说明这个引用在草稿区
|
|
246
351
|
this.allRefsInPlayground = new WeakSet();
|
|
247
352
|
// 草稿区推导出的类型,用于 一键修复类型 等功能
|
|
248
353
|
this.varCandidateTypes = new WeakMap();
|
|
@@ -255,12 +360,15 @@ class SemEnv {
|
|
|
255
360
|
// 流程关联的实体,记录这个,更方便些
|
|
256
361
|
this.processAssocEntity = null;
|
|
257
362
|
// 注意,只存放局部符号,全局符号在 gQNameDefs 中
|
|
258
|
-
// nameBindings removed: replaced by
|
|
363
|
+
// nameBindings removed: replaced by localDefStacks + refMgr.localScopeVarBindings
|
|
259
364
|
// 目前这个 env 里的类型是所有节点的类型,混合了所有局部表达式、全局符号的类型
|
|
260
365
|
// 之后再尝试分离吧
|
|
261
366
|
this.typeBindings = new Map(); // memory addr => type
|
|
262
367
|
// 后置的语义检查,在完全求解出类型变元后
|
|
368
|
+
// 存储格式:Map<BaseNode, Array<{ task: function, scopeLevel: number }>>
|
|
263
369
|
this.postChecksAfterResolve = new Map();
|
|
370
|
+
// 当前作用域层级,用于隔离不同层级的 postChecks
|
|
371
|
+
this.currentScopeLevel = 0;
|
|
264
372
|
// 给 match (a.b.c) 这种 type refinement 用的
|
|
265
373
|
this.matchedVars = new Map();
|
|
266
374
|
// 页面检查分配的 qNames
|
|
@@ -279,8 +387,11 @@ class SemEnv {
|
|
|
279
387
|
this.resolvedCallInfo = new Map();
|
|
280
388
|
this.fileNodes = [];
|
|
281
389
|
this.errBoundary = null;
|
|
390
|
+
// 当前错误相关的上下文信息(灵活扩展,可以包含连线信息等)
|
|
391
|
+
this.errBoundaryContext = null;
|
|
282
392
|
// 错误报告禁用引用计数。必须使用引用计数机制,因为 suppressErrorReporting 可能会递归调用
|
|
283
393
|
this.errorReportingDisableCount = 0;
|
|
394
|
+
this.errorDelegatee = null;
|
|
284
395
|
this.errSeverity = 'error';
|
|
285
396
|
this.ctxTpQFE = undefined; // QueryFieldExpression 用的,很烦
|
|
286
397
|
this.ctxTpEntityTy = undefined; // 实体逻辑用的,很烦
|
|
@@ -317,6 +428,7 @@ class SemEnv {
|
|
|
317
428
|
* @returns
|
|
318
429
|
*/
|
|
319
430
|
this.getRawType = (nd) => {
|
|
431
|
+
nd = (0, dispatch_stmt_1.toRaw)(nd);
|
|
320
432
|
if (!nd) {
|
|
321
433
|
return undefined;
|
|
322
434
|
}
|
|
@@ -415,36 +527,36 @@ class SemEnv {
|
|
|
415
527
|
// Internal stack tracking currently entered scopes (for restoring on exit)
|
|
416
528
|
this.scopeStack = [];
|
|
417
529
|
// Unified lexical variable storage replacing legacy nameBindings.
|
|
418
|
-
this.
|
|
530
|
+
this.localDefStacks = new Map();
|
|
419
531
|
this.getLexicalSym = (name) => {
|
|
420
532
|
if (!name)
|
|
421
533
|
return undefined;
|
|
422
|
-
return (0, helper_1.mGetLastOne)(this.
|
|
534
|
+
return (0, helper_1.mGetLastOne)(this.localDefStacks, name);
|
|
423
535
|
};
|
|
424
536
|
/** Add a single lexical variable (shadow-safe). */
|
|
425
537
|
this.addLexicalSym = (nd) => {
|
|
426
538
|
if (!nd || !nd.name)
|
|
427
539
|
return;
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
540
|
+
const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd);
|
|
541
|
+
if (localKey)
|
|
542
|
+
(0, helper_2.createOnPush)(this.localDefStacks, localKey, nd);
|
|
431
543
|
};
|
|
432
544
|
this.removeLexicalSym = (nd) => {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
545
|
+
const localKey = (0, def_key_helpers_1.getLocalDefKey)(nd);
|
|
546
|
+
if (localKey)
|
|
547
|
+
(0, helper_1.mRemoveLastOne)(this.localDefStacks, localKey);
|
|
436
548
|
// this.typeBindings.delete(nd); 这个现在不能删,以后挂到 nd.__TypeAnnotation 后才能删
|
|
437
549
|
};
|
|
438
550
|
this.removeLexicalVarByName = (name) => {
|
|
439
551
|
if (!name)
|
|
440
552
|
return;
|
|
441
|
-
(0, helper_1.mRemoveLastOne)(this.
|
|
553
|
+
(0, helper_1.mRemoveLastOne)(this.localDefStacks, name);
|
|
442
554
|
};
|
|
443
555
|
this.getLexicalVarSize = () => {
|
|
444
|
-
return this.
|
|
556
|
+
return this.localDefStacks.size;
|
|
445
557
|
};
|
|
446
558
|
/**
|
|
447
|
-
* Enter a stored lexical scope. Variables recorded during typing are pushed onto the
|
|
559
|
+
* Enter a stored lexical scope. Variables recorded during typing are pushed onto the localDefStacks
|
|
448
560
|
* to enable identifier resolution in later phases (checker, ref collection). If the scope was not
|
|
449
561
|
* recorded (e.g. legacy / fallback), varsFallback can be provided to push & record on the fly.
|
|
450
562
|
*/
|
|
@@ -571,13 +683,31 @@ class SemEnv {
|
|
|
571
683
|
}
|
|
572
684
|
};
|
|
573
685
|
// 后置的语义检查,在完全求解出类型变元后
|
|
686
|
+
// 只执行当前作用域层级及以上的 postChecks,执行后移除
|
|
574
687
|
this.runPostChecks = (subst) => {
|
|
575
688
|
// in-place 版本快很多(一倍以上),内存少 800Mb
|
|
576
689
|
const pSubst = (0, subster_1.inPlaceSubstTyAnn)(this, subst);
|
|
690
|
+
const remainingPostChecks = new Map();
|
|
577
691
|
for (const [nd, postChks] of this.postChecksAfterResolve.entries()) {
|
|
578
|
-
|
|
692
|
+
const remaining = [];
|
|
693
|
+
for (const postCheck of postChks) {
|
|
694
|
+
// 只执行当前作用域层级及以上的 postChecks
|
|
695
|
+
if (postCheck.scopeLevel >= this.currentScopeLevel) {
|
|
696
|
+
postCheck.task(this, pSubst);
|
|
697
|
+
// 执行后不保留,避免重复执行
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
// 保留父作用域的 postChecks,等待父作用域执行
|
|
701
|
+
remaining.push(postCheck);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
// 如果还有未执行的 postChecks,保留在 Map 中
|
|
705
|
+
if (remaining.length > 0) {
|
|
706
|
+
remainingPostChecks.set(nd, remaining);
|
|
707
|
+
}
|
|
579
708
|
}
|
|
580
|
-
|
|
709
|
+
// 更新为只包含未执行的 postChecks
|
|
710
|
+
this.postChecksAfterResolve = remainingPostChecks;
|
|
581
711
|
};
|
|
582
712
|
this.printCs = () => {
|
|
583
713
|
(0, helper_2.printConstraints)(this.unifier.cs);
|
|
@@ -589,7 +719,7 @@ class SemEnv {
|
|
|
589
719
|
// 需要统计的字段及其对象
|
|
590
720
|
const stats = {
|
|
591
721
|
typeBindings: this.typeBindings,
|
|
592
|
-
|
|
722
|
+
localDefStacks: this.localDefStacks,
|
|
593
723
|
};
|
|
594
724
|
const result = {
|
|
595
725
|
timestamp: new Date().toString(),
|
|
@@ -650,6 +780,17 @@ class SemEnv {
|
|
|
650
780
|
setRefMgr(refMgr) {
|
|
651
781
|
this.refMgr = refMgr;
|
|
652
782
|
}
|
|
783
|
+
// 保存后置校验状态(用于 playground 隔离,保留以兼容旧代码)
|
|
784
|
+
// 注意:使用作用域层级方案后,这个方法主要用于 playground 隔离场景
|
|
785
|
+
savePostChecksState() {
|
|
786
|
+
// 为了兼容性,返回空 Map(作用域层级方案不需要保存/恢复)
|
|
787
|
+
return new Map();
|
|
788
|
+
}
|
|
789
|
+
// 恢复后置校验状态(用于 playground 隔离,保留以兼容旧代码)
|
|
790
|
+
// 注意:使用作用域层级方案后,这个方法主要用于 playground 隔离场景
|
|
791
|
+
restorePostChecksState(saved) {
|
|
792
|
+
// 作用域层级方案不需要恢复操作,保留空实现以兼容旧代码
|
|
793
|
+
}
|
|
653
794
|
clearAll() {
|
|
654
795
|
this.typeBindings.clear();
|
|
655
796
|
this.resolvedCallInfo.clear();
|
|
@@ -659,6 +800,7 @@ class SemEnv {
|
|
|
659
800
|
this.dataSourceTyParam.clear();
|
|
660
801
|
this.scopeManager = new context_variable_query_1.ScopeManager();
|
|
661
802
|
this.unifier.cs.clear();
|
|
803
|
+
this.playgroundCs.clear();
|
|
662
804
|
this.typeHintManager = new type_hint_manager_1.TypeHintManager(this);
|
|
663
805
|
this.callLogicToElemTagCache = new WeakMap();
|
|
664
806
|
this.viewConstraintStats = [];
|
|
@@ -673,8 +815,53 @@ class SemEnv {
|
|
|
673
815
|
}
|
|
674
816
|
}
|
|
675
817
|
exports.SemEnv = SemEnv;
|
|
818
|
+
/**
|
|
819
|
+
* 从结构体属性列表中查找指定名称的属性类型
|
|
820
|
+
* @param env 语义环境
|
|
821
|
+
* @param properties 结构体属性列表
|
|
822
|
+
* @param targetName 目标属性名称
|
|
823
|
+
* @returns 归一化后的类型注解,如果未找到则返回 undefined
|
|
824
|
+
*/
|
|
825
|
+
function findPropertyType(env, properties, targetName) {
|
|
826
|
+
const pickedProperty = properties?.find((x) => x.name === targetName);
|
|
827
|
+
return pickedProperty?.typeAnnotation
|
|
828
|
+
? normalize(env, pickedProperty.typeAnnotation)
|
|
829
|
+
: undefined;
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* 从泛型结构体中查找属性类型,支持泛型参数替换
|
|
833
|
+
* @param env 语义环境
|
|
834
|
+
* @param genericTy 泛型类型注解
|
|
835
|
+
* @param def 结构体定义
|
|
836
|
+
* @param targetName 目标属性名称
|
|
837
|
+
* @returns 归一化后的属性类型注解,如果未找到则返回 undefined
|
|
838
|
+
*/
|
|
839
|
+
function findPropertyTypeFromGeneric(env, genericTy, def, targetName) {
|
|
840
|
+
const typeParams = def.typeParams ?? [];
|
|
841
|
+
const tyArgs = genericTy.typeArguments?.map((arg) => normalize(env, arg)) ?? [];
|
|
842
|
+
// 如果类型参数数量不匹配或没有类型参数,直接查找原始属性类型
|
|
843
|
+
if (typeParams.length !== tyArgs.length || typeParams.length === 0) {
|
|
844
|
+
const pickedProperty = def.properties?.find((x) => x.name === targetName);
|
|
845
|
+
if (pickedProperty?.typeAnnotation) {
|
|
846
|
+
return normalize(env, pickedProperty.typeAnnotation);
|
|
847
|
+
}
|
|
848
|
+
return undefined;
|
|
849
|
+
}
|
|
850
|
+
// 先找到目标属性,避免不必要的复制和替换
|
|
851
|
+
const pickedProperty = def.properties?.find((x) => x.name === targetName);
|
|
852
|
+
if (!pickedProperty?.typeAnnotation) {
|
|
853
|
+
return undefined;
|
|
854
|
+
}
|
|
855
|
+
// 创建类型参数到实际类型参数的映射
|
|
856
|
+
const tyParamAnns = typeParams.map((tp) => (0, type_manager_1.createTyParamAnn)(tp.name));
|
|
857
|
+
const newSubst = (0, subster_1.makeRefTySubst)(tyParamAnns, tyArgs);
|
|
858
|
+
// 替换目标属性的类型注解中的泛型参数
|
|
859
|
+
const substitutedTypeAnnotation = (0, subster_1.substTyAnn)(env, newSubst)(pickedProperty.typeAnnotation);
|
|
860
|
+
return normalize(env, substitutedTypeAnnotation);
|
|
861
|
+
}
|
|
862
|
+
exports.findPropertyTypeFromGeneric = findPropertyTypeFromGeneric;
|
|
676
863
|
function normalize(env, ty) {
|
|
677
|
-
if (
|
|
864
|
+
if ((0, type_predicate_1.isIndexedType)(ty)) {
|
|
678
865
|
// TODO wudengke 和 typePick 合并
|
|
679
866
|
const obj = normalize(env, ty.objectType);
|
|
680
867
|
const index = (ty.indexType);
|
|
@@ -689,20 +876,35 @@ function normalize(env, ty) {
|
|
|
689
876
|
return type_manager_1.naslAnyTy;
|
|
690
877
|
}
|
|
691
878
|
else if (obj.typeKind === 'anonymousStructure') {
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
if (pickedProperty?.typeAnnotation) {
|
|
696
|
-
return normalize(env, pickedProperty.typeAnnotation);
|
|
879
|
+
const result = findPropertyType(env, obj.properties, targetName);
|
|
880
|
+
if (result) {
|
|
881
|
+
return result;
|
|
697
882
|
}
|
|
883
|
+
// anonymousStructure 的属性列表是确定的,找不到说明属性不存在
|
|
884
|
+
return type_manager_1.naslAnyTy;
|
|
698
885
|
}
|
|
699
886
|
else if (obj.typeKind === 'reference') {
|
|
700
887
|
const def = env.resolveRef(obj);
|
|
701
|
-
const
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
888
|
+
const result = findPropertyType(env, def?.properties, targetName);
|
|
889
|
+
if (def) {
|
|
890
|
+
if (result) {
|
|
891
|
+
return result;
|
|
892
|
+
}
|
|
893
|
+
// 跟canDeterminePropertyExistence类似,不返回会死循环
|
|
894
|
+
return type_manager_1.naslAnyTy;
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
else if (obj.typeKind === 'generic') {
|
|
898
|
+
const def = env.resolveRef(obj);
|
|
899
|
+
if (def) {
|
|
900
|
+
const result = findPropertyTypeFromGeneric(env, obj, def, targetName);
|
|
901
|
+
if (result) {
|
|
902
|
+
return result;
|
|
903
|
+
}
|
|
904
|
+
// 跟canDeterminePropertyExistence类似,def?.concept === 'Structure' 时可以确定属性是否存在
|
|
905
|
+
if (def.concept === 'Structure') {
|
|
906
|
+
return type_manager_1.naslAnyTy;
|
|
907
|
+
}
|
|
706
908
|
}
|
|
707
909
|
}
|
|
708
910
|
// } else if(ty.typeKind === 'generic' && ty.typeName === 'SelectOverload'){
|