AI refac
Languages

بِسْمِ ٱللَّهِ ٱلرَّحْمَـٰنِ ٱلرَّحِيمِ

Kotlin / Android

Move Kotlin files and folders to another package and rename Kotlin symbols, with Java callers and Android XML kept in step.

Kotlin has two operations. Moves take a file or a folder to another package and rewrite the package line, every import, and the code that used its old package without an import. Rename changes a variable, property, function, class, or member and every reference to it, Java callers included.

The JetBrains Kotlin language server does the semantic work. It is IntelliJ without its window. refac wraps it with planning, verification, an undo log, and an Android layer for the parts the server never touches: the manifest, layouts, navigation graphs, and the implicit R and BuildConfig.

This section answers what you need to set up, how to run a first move, and what a Kotlin command costs.

What you need

NeedDetail
A Gradle project--project-path is the Gradle root, the folder with settings.gradle or settings.gradle.kts, not a module folder
JDK 17 or newerOn your PATH, for the Gradle import that the server runs
The Kotlin language serverREFAC_KOTLIN_SERVER names its folder. refac never downloads it and never guesses
An Android SDKAndroid projects only: ANDROID_HOME or local.properties, as for any Gradle build

Install the server

refac doctor kotlin prints the exact steps for the build refac was verified against: a download link, a checksum, where to unpack it, and the export line. The shape is this:

curl -LO <download link printed by refac doctor kotlin>
echo "<checksum>  <archive>" | sha256sum -c -
mkdir -p ~/.local/share/refac
tar -xzf <archive> -C ~/.local/share/refac
export REFAC_KOTLIN_SERVER=~/.local/share/refac/<unpacked folder>

Put the export line in the shell profile of whoever runs refac, an agent's environment included. The folder may be anywhere, but it must hold bin/intellij-server and a build.txt that starts with ILS-. The server is a large download, about 1.2 GB unpacked. When the variable is right, refac doctor kotlin prints [ready] with the build it found, and then you can inshallah start moving files.

A first move

Kotlin changes are made in one call, because every Kotlin command pays the server start (see Cost). Collect the files first:

refac move --project-path /path/to/gradle/root \
  --source-path app/src/main/kotlin/com/example/util/Helper.kt \
  --source-path app/src/main/kotlin/com/example/util/Format.kt \
  --target-path app/src/main/kotlin/com/example/common/Helper.kt \
  --target-path app/src/main/kotlin/com/example/common/Format.kt

The package line of both files, every import of them in Kotlin and Java, and the usages that relied on a shared package follow. A list in a file works as well, with --batch moves.json. A folder is one change that already moves all its files in one start, so it can be moved on its own.

After the move, run the project's Gradle build. It should inshallah compile without a single edit by hand, and the // Note: lines of the output name the few places refac does not edit.

Cost

Every Kotlin command starts the language server and imports the Gradle build, however few files it changes.

  • First call on a machine: about 44 seconds. The server indexes the JDK and the Kotlin libraries once.
  • Later calls: about 24 seconds. refac keeps the index (110 to 160 MB) in ~/.cache/refac, so later starts will inshallah be much faster than the first.
  • Memory while it runs: 1.3 to 1.8 GB on a small project, more on a big one.
  • After the command: nothing stays running, the Gradle daemon included.

That is why a single Kotlin move or rename is refused by default and why you put every change into one call. The options, and what to do when you have to run single changes, are on Cost and troubleshooting.

What is covered

  • Moves of .kt files and folders: the package line, imports, usages, Java callers, and Android XML. See Moves.
  • Rename of any Kotlin symbol, with the proof that the program keeps its meaning. See Rename.
  • Android and Kotlin Multiplatform projects. See Android and Multiplatform.

What is refused

Each of these stops the command before anything is changed:

  • A .java file, or a folder that contains Java sources.
  • A move between Gradle modules or between source sets, such as src/main to src/test.
  • A source or target that is not inside a source root, or that is a source root itself.
  • In a Multiplatform build, a file that declares expect or actual.

On this page