修复游戏脚本构造继承与可调用身份

补齐显式和隐式派生构造、直接类表达式与继承成员查找。

区分普通函数和箭头函数的 this 词法所有者。

支持赋值函数、本地别名与 bind 结果的调用边。

区分业务 call apply bind 方法与 Function.prototype 调用。

新增六组失败回归并同步技术方案与项目决策。
This commit is contained in:
2026-08-04 13:16:17 +08:00
parent 149b21622d
commit 3863d95456
3 changed files with 512 additions and 43 deletions
@@ -5984,6 +5984,8 @@
- JavaScript / ESM alias 与 receiver 补充:imported member 作为参数时只允许受控的 callback API 建立执行 demand,普通日志或元数据传参不得推断为调用。普通 member alias 同时支持声明 initializer 与后续赋值,`new ns.Game()` 等完整 constructor path 必须传播到实例 alias。局部对象、class、实例、`this``super` 的方法调用统一按 semantic receiver owner 匹配,禁止再按末级方法名跨 owner 扩散到同名 decoy。
- JavaScript / ESM 控制流身份补充:member alias、局部 receiver 与动态 namespace 的赋值必须保存 assignment position 和 enclosing function scope;函数体使用按真实 invocation position 选择当时事件,多次调用跨越赋值边界时合并可能 owner,恒假分支、未调用函数或调用之后的赋值不得覆盖更早使用点。导出的 function 与 class/object member 额外以模块初始化结束作为潜在外部调用点,使声明后生效的顶层赋值进入 demand,同时保留更早本地调用状态。动态依赖传播以原始 owner 模块 AST span 为权威,不因投影重排声明或省略独立赋值语句重算 alias。class method owner 进一步区分 static / instanceclass expression 与实例化 alias 使用同一 owner 图。callback API 只接受 semantic 未解析的已知全局调度函数,以及可由 AST 证明的 literal array / dynamic import 调用;被用户定义或遮蔽的同名 `setTimeout / map / then` 不得推断执行参数。
- JavaScript / ESM 深层可达性补充:constructor、`.call/.apply` 与受控 inline callback 建立真实 invocation;具名 function expression 不再生成遮蔽外层 binding 的重叠节点,普通 inline function / arrow 未被执行时保持不可达。受控 callback API 名大小写敏感,并以精确参数索引建立执行边:timer、microtask、RAF、Promise 与数组迭代取第一个参数,`addEventListener` 取第二个参数,delay、initial value、event type、options 和额外参数保持普通值。条件/循环赋值合并执行与跳过状态,conditional expression 合并各 owner,未知确定赋值显式 invalidation;已调用函数对外层 alias 的副作用按调用位置传播,`super` owner 固定在 class 定义点。恒假扫描先屏蔽 parser 识别的注释和 literal;恒假分支区间随单次函数可达性 analysis 预计算、排序合并并以借用二分索引查询,不再使用 thread-local 完整源码 key 或命中时 clone ranges。投影 canonical 根名避让两侧全部非 import bindingdynamic shorthand 保留原键,循环模块按相同原始声明去重,同名 dynamic export 不得拉入无引用本地声明。
- JavaScript / ESM 深层可达性补充:constructor、`.call/.apply` 与受控 inline callback 建立真实 invocation;具名 function expression 不再生成遮蔽外层 binding 的重叠节点,普通 inline function / arrow 未被执行时保持不可达。条件/循环赋值合并执行与跳过状态,conditional expression 合并各 owner,未知确定赋值显式 invalidation;已调用函数对外层 alias 的副作用按调用位置传播,`super` owner 固定在 class 定义点。恒假扫描先屏蔽 parser 识别的注释和 literal。投影 canonical 根名避让两侧全部非 import bindingdynamic shorthand 保留原键,循环模块按相同原始声明去重,同名 dynamic export 不得拉入无引用本地声明。
- JavaScript / ESM 构造、继承与 callable 补充:`new` 沿冻结的 class owner 图执行本类显式 constructor、显式 `super()` 或隐式 derived constructor,并支持直接 class expressioninstance / static 成员未 override 时继续沿 `extends` 链查找。普通嵌套 function 不继承 class `this`arrow 保持词法 owner。`let binding; binding = function/arrow`、本地 function alias 和 Function.prototype `.bind()` 结果都建立 callable identity`.call/.apply/.bind` 只有在 receiver 可解析为 callable 时采用 Function.prototype 语义,业务对象同名方法仍作为普通 receiver method 执行。
- 浏览器因果:状态证据仍只冻结 trusted input listener 及其点击派生微任务内的变化;完整手势身份改由宿主在成功完成 Chromium 元素鼠标输入后调用隔离世界 finish。更早注册的 `window` capture listener 即使调用 `stopImmediatePropagation()` 也不能阻断探针自身的完成身份,页面脚本不能伪造 host finishRAF / timer 继续不计入动作结果。
- 验证边界:Linux 定向回归覆盖目录相对读写与清理、祖先 symlink、CAS 安装后错误、九文件混合快照、Tetris AST 反例和七项真实 Chrome generic 试玩。Windows cfg 代码必须继续在真实 Windows CI / 发布构建验证;本地缺少 MinGW C compiler 时,安装了 Rust target 也不能把交叉 `cargo check` 失败误报为源码失败。
- JavaScript / ESM 循环与体积补充:投影声明按 `(origin module, original root binding)` 保存身份,canonical 重命名不能改写原始身份;删除回流声明前先把引用改接到 importer 已有 canonical,有界轮次未收敛时失败关闭。inline module 与外部脚本共同占用累计 `2 MiB` 源码预算。
@@ -835,6 +835,7 @@ game-project/
- dynamic import demand 必须以 source 与 import occurrence position 联合作为身份,同 source 的可达裸 import 不得继承不可达 occurrence 的 export。动态 namespace 在首段 export 之后继续保留完整 member path,声明 initializer 与后续赋值式 `await import` 都必须绑定 semantic symbol。named / namespace 成员作为回调参数、对象解构 alias、实例 alias 与下游 wrapper 时继续按真实调用 span 传播 demand。constructor、`new Game().method()` 和实例 alias 分别形成精确成员根,`this.method()` 只匹配相同 class / object owner;顶层声明位置只使用 Oxc span,禁止以源码文本 `find` 反查。受控 callback API 名严格大小写敏感,调用图只读取真实 callback 参数位:timer、microtask、RAF、Promise 与数组迭代 API 取第一个参数,`addEventListener` 取第二个参数,delay、initial value、event type、options 和其它额外参数都不得建立执行边。恒假分支区间由单次函数可达性 analysis 预计算、排序合并并借用二分索引,不得使用 thread-local 完整源码 key 或在每个位置查询时复制区间、重扫整份源码。
- imported member 只有作为受控 callback API 的参数时才建立执行 demand;日志、注册元数据等普通传参不能被当作调用。普通 member alias 必须同时支持声明 initializer 与后续赋值,`new ns.Game()` 的完整 constructor path 继续传播到实例 alias。局部对象、class、实例、`this``super` 的方法调用统一按 semantic receiver owner 匹配,禁止按末级方法名跨 owner 选中同名 decoy。
- member alias、局部 receiver 与动态 namespace 的 assignment 必须保留赋值位置和 enclosing function scope;函数体内的使用必须按真实 invocation position 选择当时已生效的事件,多次调用跨过赋值边界时合并全部可能 owner,恒假分支、未调用函数或调用之后的赋值不能倒灌覆盖更早使用点。`receiver = source` 必须冻结赋值完成时的 source owner,source 后续重赋值不能反向改写 receiver;调用事件按 JavaScript 的 callee、参数 / RHS、内层调用、外层调用 / 赋值顺序生效,`outer(inner())``receiver = mutate()` 不得按 AST 先序颠倒副作用。未知条件、循环以及 `switch case/default` 内赋值保留执行与跳过状态,conditional expression 保留全部可解析 owner,无法解析的确定重赋值显式 invalidation;已调用函数对外层 alias 的最终副作用按调用位置回写,但普通函数体内无条件 `return / throw` 之后的事件必须截断。被导出的 function、class/object member 还必须把模块初始化完成视为潜在外部调用时点,使声明之后生效的顶层赋值进入 demand,同时保留此前本地调用的旧状态。动态依赖传播继续以原始 owner 模块 AST span 为权威,不得因投影重排声明或省略独立赋值语句而重算出相反 alias。class owner 必须继续区分 static / instanceclass expression 与实例化 alias 进入相同 receiver 图,`super` 的 parent owner 在 class 定义位置冻结。constructor、`.call()``.apply()` 都是实际 invocation;具名 function expression 只保留外层 binding 对应的单一 range,未被受控 API 执行的 inline function / arrow 保持不可达。恒真 / 恒假关键字只按 JavaScript 大小写识别,局部或参数遮蔽的 `undefined` 不得当作恒假;恒假分支识别必须先用 parser trivia 屏蔽注释和非执行 literal。callback API 只接受 semantic 未解析的已知全局调度函数或 AST 可证明的 literal array / dynamic import 调用;用户定义、导入或遮蔽的同名 `setTimeout / map / then` 不能触发参数执行推断。
- member alias、局部 receiver 与动态 namespace 的 assignment 必须保留赋值位置和 enclosing function scope;函数体内的使用必须按真实 invocation position 选择当时已生效的事件,多次调用跨过赋值边界时合并全部可能 owner,恒假分支、未调用函数或调用之后的赋值不能倒灌覆盖更早使用点。未知条件或循环内赋值保留执行与跳过两种状态,conditional expression 保留全部可解析 owner,无法解析的确定重赋值显式 invalidation;已调用函数对外层 alias 的最终副作用按调用位置回写,不能被 scope 隔离丢失。被导出的 function、class/object member 还必须把模块初始化完成视为潜在外部调用时点,使声明之后生效的顶层赋值进入 demand,同时保留此前本地调用的旧状态。动态依赖传播继续以原始 owner 模块 AST span 为权威,不得因投影重排声明或省略独立赋值语句而重算出相反 alias。class owner 必须继续区分 static / instanceclass expression 与实例化 alias 进入相同 receiver 图,`super` 的 parent owner 在 class 定义位置冻结;`new` 必须覆盖显式 `super()`、隐式 derived constructor 和直接 class expression,未 override 的 instance / static 方法沿冻结的 `extends` 链查找。普通嵌套 function 拥有独立 `this`,只有 arrow 词法继承外层 owner。声明后通过 assignment 安装的 function / arrow、以及本地 function alias 和 `.bind()` 结果必须保留 callable identity。constructor、真正 Function.prototype 的 `.call()` / `.apply()` / `.bind()` 都是实际 invocation,但业务对象同名方法仍按 receiver method 解析;具名 function expression 只保留外层 binding 对应的单一 range,未被受控 API 执行的 inline function / arrow 保持不可达。恒假分支识别必须先用 parser trivia 屏蔽注释和非执行 literal。callback API 只接受 semantic 未解析的已知全局调度函数或 AST 可证明的 literal array / dynamic import 调用;用户定义、导入或遮蔽的同名 `setTimeout / map / then` 不能触发参数执行推断。
- 泥点不足是确定性业务中断,不是瞬态 Provider 故障或未知副作用。钱包的 `泥点余额不足``可消费泥点不足:...` 两种领域文案统一映射为稳定原因 `mud-points-insufficient`,不得自动重试;即使 External Generation durable ledger 已存在,也必须落为 `failed`,不能误入 `needs-reconciliation`。game-chat 顶部状态、持久失败对话与 `【Supervisor 阶段记录】` 统一显示“泥点余额不足,本轮游戏生成已中断。请充值后发送“继续”,系统会从当前项目进度接着完成。”,并禁止透传 operationId、URL、路径、密钥或任意上游正文。
- tool-plan 成功响应落账前,对内置 Runtime 原生函数与 legacy wrapper 的合法、无重复 key JSON arguments 按工具 schema 的精确位置做项目路径 canonicalization`file.*.path``project.patchset.changes[*].path``project.git_commit.paths[*]``command.*.cwd``image.inspect.paths[*]``canvas.asset_generate.outputPath` 若是当前项目根目录内的完整绝对路径,转换为 `/` 分隔的项目相对路径后再校验、持久化并执行;源码/叙述字段、任务产物描述、动态 MCP arguments 和项目外绝对路径不得改写,后两者继续由绝对路径门禁失败关闭。项目根只允许搜索/列举范围与命令 cwd 规范化为 `.`,不能成为文件目标。当前进程与重启恢复都必须从同一份规范化 handoff 重放,禁止分别执行原响应和持久响应。