Mogglo is a multi-language AST-based code search and rewriting tool. Mogglo supports embedding Lua code in search patterns and replacements.
Mogglo focuses on the following features:
The following examples give a taste of Mogglo. Here's how to find pointless
assignments of an expression to itself:
sh
mogglo-rust --detail 'let $x = $x;' ./**/*.rs
The --detail
flag helps you understand why something matched, it produces
fancy output like:
╭─[./test/nonlinear.rs:4:1]
│
4 │ ╭─▶ let a =
│ │ ┬
│ │ ╰── $x
5 │ ├─▶ a;
│ │ ┬
│ │ ╰──── $x
│ │
│ ╰──────────── let $x = $x;
│
│ Note: Multiple occurrences of $x were structurally equal
───╯
Lua code is wrapped in braces. Lua can recursively match patterns with rec
.
Here's a pattern to detect out-of-bounds array accesses:
sh
mogglo-rust 'while $i <= $buf.len() { ${{ rec("$buf.get($i)") }} }' ./**/*.rs
Here's how to unroll a simple loop:
sh
mogglo-rust \
'for $i in 0..$h { $b; }' \
--where 'h_num = tonumber(h); return h_num ~= nil and h_num % 4 == 0' \
--replace 'for $i in 0..${{ string.format("%.0f", h / 4) }} { $b; $b; $b; $b; }' \
./*/**.rs
This transformation demonstrates the power of using Lua: it can't be done with
regular expression substitutions and would be very difficult with other codemod
tools.
Lua snippets can match and negate patterns, or even compose new patterns dynamically! See the guide for more detailed explanations, examples, and features.
Mogglo currently ships pre-built executables for the following languages:
Additionally, the following can be built from source or via Cargo/crates.io:
Languages are very easy to add, so file an issue or a PR if you want a new one!
Mogglo is not as polished as any of the tools mentioned in this section.
Mogglo is most similar to other multi-language code search and codemod tools.
There are many excellent language-specific code search and codemod tools; these tend to be more polished but less general than Mogglo.
Statically-linked Linux binaries are available on the releases page.
You can build a released version from crates.io. You'll need the
Rust compiler and the Cargo build tool. rustup makes it very
easy to obtain these. Then, to install Mogglo for the language <LANG>
,
run:
cargo install mogglo-<LANG>
This will install binaries in ~/.cargo/bin
by default.
To build from source, you'll need the Rust compiler and the Cargo build tool. rustup makes it very easy to obtain these. Then, get the source:
bash
git clone https://github.com/langston-barrett/mogglo
cd mogglo
Finally, build everything:
bash
cargo build --release
You can find binaries in target/release
. Run tests with cargo test
.
Run end-to-end tests with lit
and FileCheck
.
sh
cargo build
lit --path=$PWD/test/bin --path=$PWD/target/debug test/