Quick Start
You can unleash ast-grep
's power at your fingertips in a few keystrokes on the command line!
Let's see it in action by rewriting code in a moderately large codebase: TypeScript.
Our task is to rewrite old defensive code that checks nullable nested method calls to use the shiny new optional chaining operator ?.
.
Installation
First, install ast-grep
. It is distributed by npm, cargo, homebrew and macports. You can also build it from source.
# install via homebrew
brew install ast-grep
# install via MacPorts
sudo port install ast-grep
# try ast-grep in nix-shell
nix-shell -p ast-grep
# install via cargo
cargo install ast-grep --locked
# install via npm
npm i @ast-grep/cli -g
# install via pip
pip install ast-grep-cli
The binary command, ast-grep
or sg
, should be available now. Let's try it with --help
.
ast-grep --help
# if you are not on Linux
sg --help
Use sg
on Linux
Linux has a default command sg
for setgroups
. You can use the full command name ast-grep
instead of sg
. You can also use shorter alias if you want by alias sg=ast-grep
. We will use ast-grep
in the guide below.
Optionally, you can grab TypeScript source code if you want to follow the tutorial. Or you can apply the magic to your own code.
git clone git@github.com:microsoft/TypeScript.git --depth 1
Pattern
Let's search for instances of calling a method on a nested property. ast-grep
uses patterns to find similar code. Think of patterns like those in our old friend grep
, but instead of text, they match AST nodes. We can write patterns like we write ordinary code, and it will match all code that has the same syntactical structure.
For example, the following pattern code
obj.val && obj.val()
will match all the following code, regardless of white spaces or new lines.
obj.val && obj.val() // verbatim match, of course
obj.val && obj.val() // this matches, too
// this matches as well!
const result = obj.val &&
obj.val()
Exact AST matching is already powerful, but we can go further with metavariables for more flexibility. Use a metavariable to match any single AST node. Metavariables begin with $
and are typically uppercase (e.g., $PROP
). Think of it like the regex dot .
, except it matches syntax nodes, not text.
We can use the following pattern to find all property checking code.
$PROP && $PROP()
This is a valid ast-grep
pattern you can run from the command line. The --pattern
argument specifies the target. Optionally, use --lang
to specify the target language.
ast-grep --pattern '$PROP && $PROP()' --lang ts TypeScript/src
ast-grep -p '$PROP && $PROP()' -l ts TypeScript/src
# ast-grep will infer languages based on file extensions
ast-grep -p '$PROP && $PROP()' TypeScript/src
Pro Tip
The pattern must be enclosed in single quotes '
to prevent the shell from interpreting the $
sign. ast-grep -p '$PROP && $PROP()'
is okay.
With double quotes, ast-grep -p "$PROP && $PROP()"
would be interpreted as ast-grep -p " && ()"
after shell expansion.
Rewrite
Cool? Now we can use this pattern to refactor the TypeScript source!
# pattern and language argument support short form
ast-grep -p '$PROP && $PROP()' \
--rewrite '$PROP?.()' \
--interactive \
-l ts \
TypeScript/src
ast-grep
will start an interactive session to let you choose if you want to apply the patch. Press y
to accept the change!
That's it! You have refactored the TypeScript source in minutes. Congratulations!
We hope you enjoy the power of AST editing with plain programming-language patterns. Next, learn more about writing patterns.
Pattern does not work?
See our FAQ for more guidance on writing patterns.