بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ
Rename
Rename a Kotlin symbol and every reference to it, Java callers and Android XML included, with a proof that the program keeps its meaning.
refac rename on a .kt file renames one Kotlin symbol and every reference the compiler links to it: a variable, property, function, class, interface, enum entry, or member. Java callers of Kotlin code and Java accessors of renamed properties are updated too. The JetBrains Kotlin language server does the semantic part. refac plans every edit first, proves in memory that the rename keeps the meaning of the program, repairs Android XML, and only then writes, with an undo log.
Several renames in one call
A single Kotlin rename is refused by default, because every Kotlin command pays the server start (see Cost and troubleshooting). Write the renames of one project as a list:
[
{"file": "app/src/main/kotlin/com/example/util/Helper.kt", "symbol": "shout", "new_name": "yell"},
{"file": "app/src/main/kotlin/com/example/util/Format.kt", "symbol": "pad", "new_name": "padStart", "line": 12}
]refac rename --project-path /path/to/gradle/root --batch renames.jsonThe server starts once and the whole batch is all or nothing. Each entry is proven and written against the files the entry before left, so a later entry may name a file by the path that a class rename moved it to. When one change is all there is, add --allow-single:
refac rename --project-path /path/to/gradle/root \
--file app/src/main/kotlin/com/example/util/Helper.kt \
--symbol shout --new-name yell --allow-single| Flag | Meaning |
|---|---|
--project-path | The Gradle root, the folder with settings.gradle or settings.gradle.kts |
--file | A .kt file inside the project that contains the symbol, as declaration or as usage |
--symbol, --new-name | The current and the new identifier. The new name must be a plain identifier and not a Kotlin hard keyword. Names in backticks are not supported |
--line, --column | The 1-based position that picks one symbol when the name means several in the file |
--dry-run | Plan and verify, print what would change, write nothing |
--batch FILE | A JSON list of renames, - for stdin |
--json | One JSON document with per-file edit counts and notes |
Choosing the symbol
refac finds every whole-word match of --symbol in the file and asks the server what each one names. A match that the server refuses, such as text in a string or comment, a keyword, or a library symbol, is skipped. If exactly one symbol remains, it is renamed. If several remain, for example a property name and a parameter name, the command fails and lists each candidate with its line, column, and edit count, and the next call passes --line. If none remain, the command fails with the server's reason.
What is checked
- The request, before any server starts: a valid new name, a
.ktfile inside the project, and--columnonly together with--line. - The plan, without writing. A file create or delete in the server's answer stops the command.
- The proof, in memory. The server does not notice a new name that collides with something in scope, and then the rename compiles into a different program: a call that used to reach an extension reaches a member of the same name. refac gives the server the renamed text without saving it, asks for the references of the renamed declaration again, and requires exactly the places that referred to it before. A usage that was lost or gained means the meaning changed, and the rename is refused with the list of those places. A rename that cannot be proven inshallah won't be written.
- Android, when the project has an Android module. Class names in manifests, layouts, and navigation graphs follow a renamed class.
- The write. Every planned file is read again and must still read as it did when the plan was made. Edits, XML changes, and the file rename go through an undo log, and a failure restores everything.
Classes are renamed with their file
Renaming a class that is the top-level type of a file named like it also renames the file, as the IDE does: Greeter.kt becomes Welcomer.kt. The output says X is renamed to Y together with its class. Usages in Kotlin, Java, and Android XML follow.
Preview
--dry-run plans and proves the rename and prints it. A dry run of a batch with several entries runs the batch on a throw-away copy of the project, because a class rename moves its file and edits Android XML. It takes as long as the batch.
Hard failures
Each of these stops the command and leaves every file unchanged:
- No Gradle root, or the server missing, not ready, or past the timeout (
REFAC_KOTLIN_TIMEOUT_SECS, default 600). - A symbol the server will not rename: a library symbol, a keyword, or text in a string.
- An ambiguous name.
- A rename that would lose or gain usages, which is a clash or shadowing.
- A target file that already exists.
- An edit outside every reference of the symbol, and a file that changed while planning.
- Unreadable Android XML, or a missing Android namespace in a module that has a manifest.
Limits
- Coverage. Only code that the Gradle import covers is renamed. Sources of modules outside the build, generated code, and text files are not. Search for the old name afterwards and build the project, and the build should inshallah pass.
- Not edited. ProGuard and keep rules, build scripts, string literals, reflection, and resource ids. The server refuses to rename a resource id, which is the safe answer. Names left behind in such files are listed in the notes.
- False refusals. A rename onto a name that is already an alias of the same symbol changes the usage count and is refused. That is the safe direction.