Skip to content

Fix crash on executing the SaveComponentToTag predicate function to recipe items 修复对配方物品执行 SaveComponentToTag 谓词函数时发生崩溃的问题 - #112

Open
PopSlime wants to merge 1 commit into
Anvil-Dev:dev/26.1from
PopSlime:fix-item-predicate

Conversation

@PopSlime

@PopSlime PopSlime commented Sep 1, 2026

Copy link
Copy Markdown

由于先前 SaveComponentToTag 类从实现 IPredicateFunction<ItemStack> 接口改为了实现 IPredicateFunction<ItemStackTemplate> 接口,而 HasItemBase.accept 方法中的强制类型转换没有同步更改,导致对配方物品执行 SaveComponentToTag 谓词函数时抛出 ClassCastException 异常导致崩溃。该 PR 修复了上述问题。

另外,建议今后重构此处逻辑,避免使用 unsafe casting。

Fixes Anvil-Dev/AnvilCraft#4453

@Gugle2308

Copy link
Copy Markdown

所有验证完成。梳理关键结论:

  1. 修复正确性:目标分支 dev/26.1 上唯一 IPredicateFunction 实现是 SaveComponentToTag(已实现 IPredicateFunction<ItemStackTemplate>),唯一强转点就是 HasItemBase.java:79。PR 将强转从 ItemStack 改为 ItemStackTemplate 并调用 fromNonEmptyStack(...).create() 做双向转换,类型链闭合,CCE 修复完整。

  2. 空栈安全性item1.apply() 的回调参数来自 AbstractCacheElement.applyconsumer.accept(this.type),而 type = simulate.copyWithCount(1) 永不为空栈,fromNonEmptyStack 不会抛异常。✅

  3. saveComponentToTag 语义保留:原代码 function1.apply(context, itemStack) 把整个 stack(含 count)传给函数;新代码 fromNonEmptyStack 保留组件、count 设为 1(模板语义),create() 重建。对 SaveComponentToTag(只读 component)无副作用。✅

  4. 遗留问题IPredicateFunction<?> 强转仍 unsafe——若将来注册其他泛型类型的 function(如 IPredicateFunction<Integer>)会再次 CCE。PR 自己加了 // TODO: This cast is unsafe 注释,建议是好的。

  5. gh 未认证(401),无法执行 gh pr edit 修改标题。标题本身已足够准确,跳过。

给出审查意见:

代码审查摘要 — PR #112

操作: opened
范围: 1 个文件 (1 Java) / 35 行 diff
修复目标: Anvil-Dev/AnvilCraft#4453HasItemBase.accept()IPredicateFunction<ItemStack> 强转未随 SaveComponentToTag 迁移到 ItemStackTemplate 导致 ClassCastException

✅ 修复验证

目标分支 dev/26.1 交叉验证(git fetch + git show FETCH_HEAD):

检查点 结果
分支上唯一 IPredicateFunction 实现 SaveComponentToTag,已实现 IPredicateFunction<ItemStackTemplate>
分支上唯一 IPredicateFunction<ItemStack> 强转点 HasItemBase.java:79(即 PR 修改处),无其他遗漏 ✅
空栈风险 item1.apply() 回调参数来自 AbstractCacheElement.applyconsumer.accept(this.type)type = simulate.copyWithCount(1) 永不为空栈,fromNonEmptyStack 不会抛 IllegalStateException
类型链闭合 fromNonEmptyStack(itemStack)apply(...) 返回 ItemStackTemplate.create() 转回 ItemStack 赋给 itemStack,编译与运行类型匹配 ✅
语义保留 SaveComponentToTag.apply 只读 stack.get(component) 写 TagCache,模板转换(count=1)无副作用 ✅

⚠️ 警告(非阻塞)

  • HasItemBase.java:79 — unsafe cast 仍残留(IPredicateFunction<ItemStackTemplate>) function 仍是裸强转。当前只有 SaveComponentToTag 一个实现所以安全,但 functions 字段是 List<IPredicateFunction<?>>,一旦未来注册 IPredicateFunction<OtherType> 实现会再次触发 CCE。PR 已留 // TODO 注释,可考虑把 functions 类型收紧为 List<IPredicateFunction<ItemStackTemplate>>HasItemBaseHasItemHasItemIngredient 的构造器/Builder 同步调整),彻底消除强转。

💡 建议

  • 链式多 function 场景(functions 循环)中,每轮 create() 会重建 ItemStack——目前唯一实现无副作用所以安全,但若未来实现改写 count/组件的 function,需注意中间 fromNonEmptyStack 会把 count 归 1,改写 count 的函数会失效。可在注释中说明此约束。
  • @SuppressWarnings("unchecked") 目前覆盖整个 accept 方法,收紧类型后可移除。

🟢 看起来不错

  • 修复精准:只改强转点,不引入行为变化
  • fromNonEmptyStack(...).create() 往返转换完整
  • // TODO 明确标注了 unsafe cast,符合 PR 描述中的建议

📋 声称验证

声称 状态
修复 SaveComponentToTag 对配方物品执行时 CCE ✅ 强转已同步为 ItemStackTemplate
建议重构避免 unsafe casting ✅ 已加 TODO 注释(未实际重构,属建议范畴)

结论: APPROVE — 修复精准且完整,目标分支交叉验证无遗漏强转点,空栈路径安全,类型链闭合。unsafe cast 残留为已知技术债(已标注 TODO),非阻塞。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown

💾 Self-improvement review: Skill 'generic-type-cast-migration-pr-review' created.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 铁砧时移含生物的树脂块时游戏崩溃

2 participants