Skip to content

SYSTEM Cited by 1 source

Kotlinator

Kotlinator is Meta's internal end-to-end pipeline for automated Java-to-Kotlin translation of the Android codebase at monorepo scale (~10M lines, ~100K files). It wraps JetBrains' J2K with Meta-specific pre- and post- processing, a linter pass, and a build-error-driven fix loop.

Architecture — six phases

  1. Deep build — build the file being translated so the IDE can resolve all its symbols (third-party deps, generated code, etc.) before conversion runs.
  2. Preprocessing (~50 steps) — Java-to-Java transformations on top of Meta's Editus metaprogramming tool: nullability fixes, J2K-workaround edits, accommodations for Meta's custom DI framework.
  3. Headless J2K — the JetBrains IDE converter, run from an IntelliJ plugin whose class extends ApplicationStarter and calls JavaToKotlinConverter directly. See concepts/headless-ide-inspection.
  4. Postprocessing (~150 steps) — Kotlin-to-Kotlin transforms on the just-machine-translated Kotlin: Android-specific tweaks, further nullability fixes, idiomaticity polishing. Runs on code that frequently does not compile yet — enabled by PSI- based metaprogramming that isn't a compiler plugin.
  5. Linters with autofixes — the existing Meta linter stack with its autofix rules applied.
  6. Build-error-based fixes — the Kotlinator attempts to build the just-translated code, parses compiler errors, and applies targeted edits (missing imports, inserted !!, etc.). See concepts/build-error-driven-fix-loop.

Scale + throughput

  • ~10,000,000 Java LOC in the starting codebase.
  • ~100,000 files to convert.
  • >40,000 conversions shipped by 2024-12 ("well past the halfway point").
  • ~30 minutes per-file remote conversion (versus the couple-minutes local-IDE-button baseline — the trade was total time up, developer time down to zero).
  • >200 total custom steps across preprocessing, postprocessing, and build-error-based fixes.

Invocation surfaces

  • Daily diff cron — an internal cron system ( pattern page) produces a daily batch of diffs against user-defined selection criteria, auto-routes to reviewers, runs tests, ships on approval. Functionally a PR bot, embedded in Meta's diff-review infrastructure.
  • On-demand web UI — a web UI for developers to trigger remote conversion of a specific file or module. Runs the same Kotlinator pipeline.

Open-sourcing

A subset of postprocessing transformations is open-sourced at github.com/fbsamples/kotlin_ast_tools. Full open-sourcing is gated on porting Editus-based steps to the new J2K client hooks Meta co-designed with JetBrains during the 2024 K2-compiler port of J2K — moving off Meta's custom symbol resolution onto J2K's more precise resolution makes the Android-specific steps donatable.

Why a pipeline, not a single converter

J2K alone produces non-building code on the vast majority of Meta files: "Due to the size of our codebase and the custom frameworks we use, the vast majority of conversion diffs produced by the vanilla J2K would not build." The open-ended-pass pipeline shape is the architectural solution: each named step closes one class of J2K shortcoming; over time, the sum hits the long tail.

Why automate even unnecessary fixes

Meta "automates [some] fixes as part of postprocessing, even though they aren't strictly necessary" to minimise human-intervention risk. Canonical named case: condensing long chains of null checks — correctness-equivalent but "less susceptible to a well-meaning developer accidentally dropping a negation." See concepts/bot-safer-than-human.

Seen in

Last updated · 319 distilled / 1,201 read