kotlin-tooling-immutable-collections-0-5-x-migration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesekotlinx.collections.immutable 0.5.x Migration
kotlinx.collections.immutable 0.5.x 迁移指南
The 0.5.x line renames every copy-returning method on the persistent collections to a
participial form (per [KEEP-0459]) and deprecates the old names at level with a
hint. Migrating is a mechanical, binary-compatible, semantics-preserving
call-site rename — same parameters, order, and return type; only the name changes.
WARNINGReplaceWithDrive it from the compiler: bump the version, recompile, and fix each deprecation warning —
the warning names the replacement. Source of truth: [].
0.5.0-MIGRATION.md0.5.x 系列根据 [KEEP-0459] 提案,将持久化集合上所有返回副本的方法重命名为分词形式,并将旧方法标记为 WARNING 级别的废弃,同时附带 ReplaceWith 提示。迁移过程是机械性的、二进制兼容且语义一致的调用点重命名——参数、顺序和返回类型均保持不变,仅方法名称变更。
迁移由编译器驱动:升级版本、重新编译,然后修复每个废弃警告——警告信息会指明替代方法。权威参考:[]。
0.5.0-MIGRATION.mdWhen it applies
适用场景
Check the version the project currently uses:
- 0.3.x or 0.4.x (any pre-0.5.0) → run the migration below.
- On 0.5.x but not the latest → set the version to the latest 0.5.x and stop. All 0.5.x releases share the same renames, so a within-line bump adds no new deprecations and needs no recompile.
- On the latest 0.5.x, or on 0.6.x and later → nothing to do.
检查项目当前使用的版本:
- 0.3.x 或 0.4.x(任何 0.5.0 之前的版本)→ 执行以下迁移步骤。
- 已使用 0.5.x 但非最新版本→ 将版本设置为最新的 0.5.x 即可停止操作。所有 0.5.x 版本共享相同的重命名规则,因此同系列内升级不会新增废弃警告,无需重新编译。
- 已使用最新 0.5.x 或 0.6.x 及更高版本→ 无需任何操作。
Migration
迁移步骤
1. Find the build command
1. 确定构建命令
Check , , or for how the project builds; if it isn't
written down, infer it from the build files — Gradle (), Maven (, or the
wrapper), Bazel
(a wrapper), or a custom script. Record the compile command (and the test command).
In a multi-module project you only need the modules that use the library, plus any you
change — not a whole-repo build.
README.mdCLAUDE.mdAGENTS.md./gradlewmvn./mvnwbazel查看 、 或 了解项目构建方式;若未记录,可从构建文件推断——Gradle()、Maven( 或 包装器)、Bazel( 包装器)或自定义脚本。记录编译命令(以及测试命令)。在多模块项目中,仅需处理使用该库的模块及变更模块——无需全仓库构建。
README.mdCLAUDE.mdAGENTS.md./gradlewmvn./mvnwbazel2. Baseline compile
2. 基准编译
Compile on the current version and confirm it's green. If it doesn't build now, you can't
tell post-migration errors from pre-existing ones — get a working compile command first.
使用当前版本编译并确认构建成功。若当前无法构建,则无法区分迁移后错误与原有错误——需先确保编译命令可正常运行。
3. Bump to the latest 0.5.x
3. 升级至最新 0.5.x 版本
Find where the version is pinned — across the build
files finds it (version catalog, build script, , , …) — and set
it to the latest 0.5.x on [Maven Central] (a is fine). If the build pins artifact
hashes (e.g. ), update those too — the cheapest fix is to
copy the new artifact's checksum straight from the dependency-verification failure message
and add just that one entry, rather than regenerating the whole metadata file. The bump is
binary-compatible; old code keeps compiling with warnings. (If the dependency fails to
resolve with a Kotlin metadata-version error, the project's Kotlin is too old for the 0.5.x
artifact — bump Kotlin first.)
grep -rn kotlinx-collections-immutablegradle.propertiespom.xml-betagradle/verification-metadata.xml查找版本固定位置——在构建文件中执行 可找到(版本目录、构建脚本、、 等),并将其设置为 [Maven Central] 上最新的 0.5.x 版本( 版本也可)。若构建固定了 artifact 哈希值(如 ),也需更新这些哈希值——最简单的修复方式是直接从依赖验证失败消息中复制新 artifact 的校验和并添加单个条目,而非重新生成整个元数据文件。版本升级是二进制兼容的;旧代码仍可编译,但会出现警告。(若依赖解析时出现 Kotlin 元数据版本错误,说明项目的 Kotlin 版本过旧,无法适配 0.5.x 版本——需先升级 Kotlin。)
grep -rn kotlinx-collections-immutablegradle.propertiespom.xml-betagradle/verification-metadata.xml4. Recompile and fix the warnings
4. 重新编译并修复警告
Recompile. Each renamed method carries , so the
compiler emits one warning per call site naming the replacement (e.g. "Use removingAll()
instead"). Apply that rename. Repeat compile → fix until no
deprecation warnings remain. (For multiplatform, one target compile surfaces the shared call
sites. Pre-existing factory deprecations such as →
appear the same way — apply those too.) A recompile that fails right after the bump is
failing on these deprecations (plus, if hashes are pinned, a one-time dependency-verification
error) — keep applying the renames the warnings name; don't re-run dependency-resolution or
metadata-regeneration commands to try to clear it.
@Deprecated(WARNING, ReplaceWith(...))kotlinx.collections.immutableimmutableListOfpersistentListOfTrust the compiler — never find/replace by name. The same method names exist on
/ / and on the types, which mutate in
place and are not deprecated. Only the sites the compiler flags (receiver statically
) get renamed; if it didn't flag it, leave it.
MutableListMutableMapMutableSet.BuilderPersistent*An after a rename means the participial name isn't on that
receiver — you've split a rename. A rename only compiles if the declaration and every
call site move together. The library already did that for the kotlinx types, so renaming
their call sites just works — but it doesn't hold for anything else that merely shares the
names. When a renamed call won't resolve, there are two cases:
Unresolved reference- The receiver is unrelated to this library (a , a
Mutable*, a same-named method on some other type) — the rename was wrong; revert that site..Builder - The receiver is a project type the codebase is itself migrating — it implements a
, or it's the project's own wrapper whose methods echo these names and get renamed to match. The rename is right but half-done: rename the declaration and its other callers too, so the call resolves. (Deprecated overrides on an implementer are step 5.)
Persistent*
Decide by the receiver's declared type, never the method name — a -named
field may hold another type. This matters most when you can't lean on a fast recompile and
are renaming from reading the source.
Persistent*Java callers. The recompile flags them only if the build reports javac deprecation
warnings (, usually off). If it doesn't, grep the files that
import the library for the old names and rename the calls whose receiver is a
type.
-Xlint:deprecation.javaPersistent*After the renames, the compiler may report some as having no
effect — remove those (re-read the region first, in case it still covers something else).
@Suppress("DEPRECATION")重新编译。每个重命名的方法都带有 注解,因此编译器会为每个调用点生成一条警告,指明替代方法(例如:"Use removingAll() instead")。根据提示进行重命名。重复编译→修复流程,直至不再出现 的废弃警告。(对于多平台项目,单个目标编译即可显示共享调用点。原有的工厂方法废弃提示,如 → ,也会以相同方式显示——同样需进行重命名。)升级后立即编译失败通常是因为这些废弃警告(加上哈希值固定时的一次性依赖验证错误)——持续根据警告提示进行重命名即可;无需重新运行依赖解析或元数据生成命令来尝试清除错误。
@Deprecated(WARNING, ReplaceWith(...))kotlinx.collections.immutableimmutableListOfpersistentListOf信任编译器——切勿通过名称查找替换。 / / 以及 类型上存在相同的方法名称,这些方法是原地修改的,不会被废弃。仅编译器标记的调用点(接收者静态类型为 )需要重命名;若未标记,则保留原样。
MutableListMutableMapMutableSet.BuilderPersistent*重命名后出现 错误,说明分词形式的方法不存在于该接收者上——你拆分了重命名操作。 只有当声明和所有调用点同时迁移时,重命名才能编译通过。该库已针对 kotlinx 类型完成此操作,因此重命名其调用点即可正常工作——但对于其他仅共享名称的类型则不适用。当重命名后的调用无法解析时,有两种情况:
Unresolved reference- 接收者与该库无关(、
Mutable*、其他类型上的同名方法)——重命名错误;恢复该调用点。.Builder - 接收者是代码库自身正在迁移的项目类型——它实现了 ,或者是项目自己的包装类,其方法名称与这些方法一致,需要同步重命名。重命名是正确的但未完成:同时重命名声明及其其他调用者,使调用可解析。(实现类上的废弃重写见步骤5。)
Persistent*
根据接收者的声明类型判断,切勿仅根据方法名称——名为 的字段可能持有其他类型。当无法依赖快速重新编译而只能通过阅读源码进行重命名时,这一点尤为重要。
Persistent*Java 调用者。 只有当构建报告 javac 废弃警告(,通常默认关闭)时,编译器才会标记这些调用点。若未开启,需在导入该库的 文件中搜索旧方法名称,并对接收者为 类型的调用进行重命名。
-Xlint:deprecation.javaPersistent*重命名后,编译器可能会报告某些 注解无效——移除这些注解(先重新阅读相关区域,确保其未覆盖其他内容)。
@Suppress("DEPRECATION")5. Custom implementers
5. 自定义实现类
If the project has classes that implement / /
/ , their deprecated overrides need migrating too.
Find them:
PersistentListPersistentMapPersistentSetPersistentCollectionbash
grep -rnE --include='*.kt' \
'(class|object|interface)\s+\w[^:]*:\s*[^{]*\b(PersistentList|PersistentMap|PersistentSet|PersistentCollection)\s*<' .On Windows PowerShell, is the equivalent:
Select-Stringgreppowershell
Get-ChildItem -Recurse -Filter *.kt |
Select-String '(class|object|interface)\s+\w[^:]*:\s*[^{]*\b(PersistentList|PersistentMap|PersistentSet|PersistentCollection)\s*<'(Confirm a match really lists the interface as a supertype, not just a field type or type
argument.) For each, move the implementation into the new participial method and have the
deprecated override delegate to it:
kotlin
override fun adding(element: E): MyList<E> = /* real implementation */
@Suppress("OVERRIDE_DEPRECATION")
override fun add(element: E): MyList<E> = adding(element)If the participial methods call each other, route those calls through participial siblings,
not the deprecated names. (Add to the suppress only when an override body
itself still calls a deprecated member.) Doing this now matters: at 0.6.0 the old names
become compile errors, and at 0.7.0 they are removed. See [] for the
upstream implementer guidance.
"DEPRECATION"0.5.0-MIGRATION.md若项目中有实现 / / / 的类,其废弃的重写方法也需要迁移。查找这些类:
PersistentListPersistentMapPersistentSetPersistentCollectionbash
grep -rnE --include='*.kt' \\
'(class|object|interface)\\s+\\w[^:]*:\\s*[^{]*\\b(PersistentList|PersistentMap|PersistentSet|PersistentCollection)\\s*<' .在 Windows PowerShell 中, 等同于 :
Select-Stringgreppowershell
Get-ChildItem -Recurse -Filter *.kt |
Select-String '(class|object|interface)\\s+\\w[^:]*:\\s*[^{]*\\b(PersistentList|PersistentMap|PersistentSet|PersistentCollection)\\s*<'(确认匹配结果确实将该接口列为父类型,而非仅字段类型或类型参数。)对于每个匹配类,将实现逻辑迁移至新的分词形式方法,并让废弃的重写方法委托给新方法:
kotlin
override fun adding(element: E): MyList<E> = /* 实际实现逻辑 */
@Suppress("OVERRIDE_DEPRECATION")
override fun add(element: E): MyList<E> = adding(element)若分词形式方法之间相互调用,应通过分词形式的兄弟方法进行路由,而非调用废弃名称。(仅当重写方法体本身仍调用废弃成员时,才在抑制注解中添加 。)现在完成此步骤至关重要:在 0.6.0 版本中,旧方法名称将变为编译错误,而在 0.7.0 版本中会被移除。有关上游实现者指南,请参阅 []。
"DEPRECATION"0.5.0-MIGRATION.md6. Run any documented follow-up steps
6. 执行文档中记录的后续步骤
Do this after the renames compile clean, so that if you run low on time the call-site work
is already done. Some projects document steps to run after a dependency change that the
compiler won't surface — most commonly regenerating dependency-verification metadata (the
hashes from step 3). Usually the single-entry fix from
step 3 is all you need; only fall back to the project's documented full-regeneration procedure
(in / / / ) if that one entry isn't
enough. Run it once — a full / "resolve all dependencies"
pass re-resolves the entire graph and is slow, and repeating it rarely changes the outcome.
Then re-confirm the build is clean.
gradle/verification-metadata.xmlREADME.mdCONTRIBUTING.mdCLAUDE.mdAGENTS.md--write-verification-metadata在重命名后编译通过再执行此步骤,这样即使时间不足,调用点的修改工作也已完成。部分项目会记录依赖变更后的后续步骤,这些步骤不会被编译器提示——最常见的是重新生成依赖验证元数据(步骤3中的 哈希值)。通常步骤3中的单条目修复即可满足需求;仅当该条目不足时,才回退到项目文档中记录的完整生成流程( / / / )。仅执行一次——完整的 / "解析所有依赖" 过程会重新解析整个依赖图,速度较慢,重复执行几乎不会改变结果。然后再次确认构建成功。
gradle/verification-metadata.xmlREADME.mdCONTRIBUTING.mdCLAUDE.mdAGENTS.md--write-verification-metadataRename reference
重命名参考
- —
PersistentCollection→add,adding→addAll,addingAll→remove,removing→removeAll,removingAll→retainAll,retainingAll→clearcleared - (the above, plus) —
PersistentList→add(i, e),addingAt→addAll(i, c),addingAllAt→set(i, e),replacingAt→removeAtremovingAt - —
PersistentMap→put,putting→putAll,puttingAll→remove(k),removing→remove(k, v),removing→clearcleared
Builders (, etc.) are not renamed — they mutate in place, so
their imperative names stay.
PersistentList.Builder- —
PersistentCollection→add、adding→addAll、addingAll→remove、removing→removeAll、removingAll→retainAll、retainingAll→clearcleared - (包含上述方法,新增)——
PersistentList→add(i, e)、addingAt→addAll(i, c)、addingAllAt→set(i, e)、replacingAt→removeAtremovingAt - —
PersistentMap→put、putting→putAll、puttingAll→remove(k)、removing→remove(k, v)、removing→clearcleared
构建器( 等)不会被重命名——它们是原地修改的,因此保留命令式名称。
PersistentList.BuilderLinks
链接
- — upstream guide (source of truth, incl. implementer details)
0.5.0-MIGRATION.md - KEEP-0459 — naming rationale
- — 上游指南(权威参考,包含实现者细节)
0.5.0-MIGRATION.md - KEEP-0459 — 命名依据
",