fix(amodel-gen): API 静态门方法名提取支持泛型声明(治 save.get<T> 被误判不存在)
#5 九门 gen 暴露的正交真 bug:check 的 API-存在静态门用正则 /(?:^|\n)\s*(\w+)\??\s*\(/ 抽 api.d.ts 方法名,遇泛型声明 `get<T = unknown>(` 时 \w+ 后是 `<` 非 `(`、抽不到 `get`,把真实存在(impl + api.d.ts:79 都有)的 save.get 误判"方法名幻觉不存在"→ 误杀一整类带存档持久化的游戏(高分榜等)。 修:两处方法名正则加可选泛型段 (?:<[^>]*>)?(apiMethodSet + apiVoidMethodSet)。 验证:形状门单测 11/11;针对性 check 一段同用 save.get('best',0)+sessionScore.add+ drawButton 的 game-logic → [check] PASS(三者均不再误判)。over-permissive 取向不变。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dc49f5f866
commit
13126a08ca
@ -151,14 +151,15 @@ const PLUGIN_KEY_DIR = {
|
||||
/** PluginContext(boot.ctx)真方法集 + 运行时附加 log;time/random 是属性对象(ctx.time.nowMs()/ctx.random.next() 内层 time/random≠ctx,经"非键跳过"放行)。 */
|
||||
const CTX_METHODS = new Set(['getContext2d', 'onFrame', 'getInput', 'getAudioContext', 'getEngine', 'log']);
|
||||
const _apiCache = new Map();
|
||||
/** 读某插件 api.d.ts 抽其声明的方法名集(宽松:取所有「名(」形态,over-permissive=少误报)。返回 Set|null。 */
|
||||
/** 读某插件 api.d.ts 抽其声明的方法名集(宽松:取所有「名(」形态,含泛型方法 名<T>(,over-permissive=少误报)。返回 Set|null。 */
|
||||
function apiMethodSet(dir) {
|
||||
if (_apiCache.has(dir)) return _apiCache.get(dir);
|
||||
let set = null;
|
||||
try {
|
||||
const txt = readFileSync(join(GAME_RUNTIME, 'src', 'plugins', dir, 'api.d.ts'), 'utf8');
|
||||
set = new Set();
|
||||
for (const m of txt.matchAll(/(?:^|\n)\s*(\w+)\??\s*\(/g)) set.add(m[1]);
|
||||
// 名后可带可选 ? 与泛型形参 <…>(如 save.get<T = unknown>(…)):漏认泛型会把真实方法误判"不存在"、误杀带存档的游戏。
|
||||
for (const m of txt.matchAll(/(?:^|\n)\s*(\w+)\??\s*(?:<[^>]*>)?\s*\(/g)) set.add(m[1]);
|
||||
} catch { set = null; }
|
||||
_apiCache.set(dir, set);
|
||||
return set;
|
||||
@ -177,7 +178,7 @@ function apiVoidMethodSet(dir) {
|
||||
const txt = readFileSync(join(GAME_RUNTIME, 'src', 'plugins', dir, 'api.d.ts'), 'utf8');
|
||||
set = new Set();
|
||||
// 逐行锚定:行首(可带 export declare function / readonly 修饰)的「名(…): void」;参数里的 `=> void` 不以「): void」收尾、不误收。
|
||||
for (const m of txt.matchAll(/^\s*(?:export\s+declare\s+function\s+|readonly\s+)?(\w+)\??\s*\([^\n]*\)\s*:\s*void\b/gm)) set.add(m[1]);
|
||||
for (const m of txt.matchAll(/^\s*(?:export\s+declare\s+function\s+|readonly\s+)?(\w+)\??\s*(?:<[^>]*>)?\s*\([^\n]*\)\s*:\s*void\b/gm)) set.add(m[1]);
|
||||
} catch { set = null; }
|
||||
_voidCache.set(dir, set);
|
||||
return set;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user