Mogglo

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:

Introduction

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.

Supported languages

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!

Comparison to related tools

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.

Installation

From a release

Statically-linked Linux binaries are available on the releases page.

From crates.io

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.

Build

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.

Test

Run end-to-end tests with lit and FileCheck.

sh cargo build lit --path=$PWD/test/bin --path=$PWD/target/debug test/