This tool lets you make magical code changes—without AI


In the land of programming, text is king, so tools like grep, sed, and awk are fantastic companions to your compiler or interpreter. Every programmer’s toolbox can also benefit from a text-based version control system, like Git.

But these tools all work at the generic text level. While regular expressions can be incredibly powerful, they’re still not a perfect fit for the grammar of a programming language. For meaningful, semantic search, you need a different type of tool. Enter ast-grep.

What is ast-grep, and why would you need it?

Super-powered search that understands your code

Let’s say you want a list of all the function names in your codebase. A first attempt might look something like this:

grep -r 'function' ...

And then you might realize that you’re matching far too many irrelevant occurrences, so you refine your regular expression:

egrep -r '^function\W' ...

You continue in this fashion until, eventually, you realize that, no matter what you do, your search is going to match something like:

/*
The following should be:
function foo(a, b, c)
but that’s not going to work because...
*/

Tools like grep simply don’t understand the context of something that looks like a function declaration inside a comment. They work just by matching individual characters, not by considering any wider meaning that combinations of those characters may embody.

ast-grep is different. Instead of reading text character by character, line by line, it parses the text (just like a compiler) and builds an abstract syntax tree (AST) which represents your code’s actual meaning. Using that, it can then carry out semantic searches for elements like variable declarations, function calls, and so on.

Under the hood, ast-grep uses the popular Tree-sitter library, which lets it support a wide range of languages as diverse as Python, Java, and Go. ast-grep is written in Rust, so it performs well, even searching across large codebases. This is important because, since it has to fully parse files before searching them, there’s a lot more work to do than a standard text-based search.

How to search for almost anything using ast-grep

Using the command line or a web app that’s perfect for beginners

The simplest use of ast-grep uses the -p option to specify a single simple pattern.

ast-grep -p 'console.log'

Without any path arguments, ast-grep will search for files in the current directory, recursively. Unless you specify a language, ast-grep will infer it based on a file’s extension. The program will group results by file, printing details of each match, highlighting relevant parts:

Output from the ast-grep command includes a filename and several lines with the text "console.log" highlighted in red.

Note that this search returns function calls with no arguments and a reference to the method property that isn’t even a call. However, it specifically looks for an object named console, so it won’t find the following:

with (console) {
    log("Hello, world.");
}

But it will, correctly, ignore “‘console.log'” as a string and “/* console.log */” as a comment. At this point, I advise you to explore the ast-grep playground, a web app that runs ast-grep in the background and presents its results:

The ast-grep playground web app showing a pattern in the right half and matching lines in the left.

As you can see, the playground clearly indicates exactly what matched and what didn’t. This is in contrast to the command-line program, which filters input and only returns matches. I found the playground very useful when first learning about ast-grep and trying to build my own patterns.

You can use meta variables to match more dynamic content. A meta variable begins with a $ and uses only uppercase letters, along with underscores and digits. To find all calls to console.log with a single argument, use this pattern:

console.log($SINGLE_ARG)

Notice that the pattern matches calls with a single argument, not those without any or with more than one:

The ast-grep playground showing a search for calls to console.log with an argument, using a metavar.

If you want to match multiple arguments, you can use a multi meta variable, which begins with three dollar signs:

console.log($$$MULTIPLE_ARGS)

This pattern will match all calls to console.log, including those with zero or several arguments:

The ast-grep playground showing a search for calls to console.log with any number of arguments (including none), using metavars.

For more complex searches, ast-grep supports a rule syntax in YAML. You can use this to define highly-contextual searches, making full use of the AST structure.

For example, here’s a rule that matches all calls to console.log, console.debug, and console.warn, plus calls to console.error if they are not inside a catch clause:

id: no-console-except-error
language: typescript
rule:
  any:
    - pattern: console.error($$$)
      not:
        inside:
          kind: catch_clause
          stopBy: end
    - pattern: console.$METHOD($$$)
constraints:
  METHOD:
    regex: 'log|debug|warn'

Change your code without manually editing it

With careful preparation and testing, ast-grep can be a powerful automated editor

ast-grep is already a powerful tool, but it goes beyond search. With its replace feature, ast-grep lets you modify your code, too. This means you can make incredibly time-consuming changes in seconds, either automatically or interactively.

Consider the previous console.log example. Imagine one of your codebases that’s riddled with debug code that calls console.log. You decide you want something a bit more sophisticated, so you start with a bespoke function, my_logger:

function my_logger() {
    if (GLOBAL_DEBUG) {
        console.log.apply(null, arguments)
    }
}

It’s just a simple wrapper to console.log, with a global flag, for now. But the point is that you’ll need to convert each console.log() call to a my_logger one. Using ast-grep, this is a simple process. Start with a rule file, e.g., fix-logging.yml:

rule:
  pattern: console.log($$$MULTIPLE_ARGS)
fix: my_logger($$$MULTIPLE_ARGS)

Then run it like this to see the changes that would be made:

ast-grep scan --rule fix-logging.yml

If you’re happy with the results, you can get ast-grep to make these changes for you, updating files in-place with the –update-all option:

ast-grep scan --rule fix-logging.yml --update-all

There are various modes you can use to make changes, including an interactive one, which is probably the most secure way of running ast-grep while you’re getting to grips with it.


Despite the steep learning curve, mastering ast-grep will reward

There’s no doubt about it: ast-grep is a complicated program. The examples I’ve included here are at the easier end of the scale, and if you dig into the documentation further, you’ll see this tool has a lot more to offer.

While it can be daunting, the playground helps a lot, and using interactive mode to clean up your codebase is a great way to start learning ast-grep.



Source link

Leave a Reply

Subscribe to Our Newsletter

Get our latest articles delivered straight to your inbox. No spam, we promise.

Recent Reviews


Love him or hate him, Seth MacFarlane has an immovable place in the realm of TV comedy, and Ted is an excellent showcase for the writer at his best. A seasoned actor and writer of over 3 decades, he has created numerous hit productions, including adult animation tentpoles like Family Guy and American Dad!, as well as The Orville.

However, his talents have also allowed him to make the leap from television to the big screen, including his 2012 comedy Ted, which asked what would happen to a child who wished their teddy bear for life once they grew into adults.

However, in 2024, MacFarlane brought Ted to the small screen with a television series that dived into the times not seen in the 2012 movie. And I personally feel that the show has become one of MacFarlane’s finest projects to date:

How Does Ted Tie Into The Movies?

A new side of John and Ted

Ted is set between the opening 1985 sequence of the original 2012 movie and the present-day sequence, honing in on John’s teenage years at high school as Max Burkholder takes on the role. When Ted pushes things too far, he is forced to attend school with John, leading to the pair experiencing many major developmental milestones together. From falling in love to going against his parents’ wishes and trying weed for the first time, the pair take on the world together.

Alongside the main duo, Ted also shines a light on the rest of the Bennett household. Frequent MacFarlane collaborator Scott Grimes takes on the voice of John’s loudmouthed conservative father Matty, while Alanna Ubach portrays his soft-spoken, good-hearted mother Susan. The Bennett family is rounded out by Giorgia Wigham’s Blaire, John’s politically minded cousin staying with the family who is always looking out for the leading pair.

A new addition to the lore

Much like Family Guy and American Dad took on The Simpsons‘ animated family sitcom and The Orville lampooned Star Trek, Ted twists a certain style of sitcom. There have been no shortage of throwback sitcoms set in the past since the late 2010s, with The Goldbergs and Young Sheldon playing into the nostalgia people either have for that time or recognize through long-running franchises or series like Stranger Things to attract viewer attention.

In Ted, the show turns its lens to the 1990s, with Blaire being part of the youthful generation who wants to challenge the status quo. However, she butts heads with various authority figures. Plus, Matty and Jon find themselves affected by the OJ Simpson case in varying ways.

Collage featuring 1990s sitcoms around an old TV.


Go Retro and Stream These 10 Sitcoms of the 1990s

These are the 1990s prime time sitcoms that have held up better than my collection of Pogs.

Despite this setting and inevitable plays on the events of the decade, the show isn’t entirely dependent on nostalgia. Ted’s very existence already set the series up in a position where it could do anything, and MacFarlane doesn’t hold back. From new talking toys and the relatable gag about how hot McDonald’s apple pies are to an entire episode that cuts between the group playing a Dungeons and Dragons game around a table and their characters within the game’s world, the series isn’t afraid to get strange. Because of that, it is hard to find an underwhelming episode throughout its run.

Ted has a surprising amount of heart

Is this the best of Seth MacFarlane?

While MacFarlane is a seasoned comedic writer whom audiences are incredibly familiar with, from his strengths to his stylistic flaws, I do feel that Ted is, for the most part, the best of what he has to offer. The series does have the sharper edge his humor can have at times, with Ted himself having some absolutely devastating insults towards the bullies at John’s school, as well as the cast overall tiptoeing between crass humor and smartly written gags. But this is a story about a bear brought to life with a child’s wish, so there is always a good deal of heart within every episode.

Thanks to the incredible chemistry between the cast, the Bennett family unit is easy to root for. Part of the enjoyment of the show is seeing John grow into the man he was in the original movie, but it is also heartwarming to see Blaire find her place in the Bennett household, even if she butts heads with Matty. Meanwhile, even Matty has several moments of vulnerability despite his hard-headed, typically politically incorrect self, which show just why Susan, who is the delightful and lovable heart of the show, fell for him.

One week the family may be playing a Dungeons and Dragons game to replenish their stash of weed, and the next will see them dedicating themselves to fulfilling Susan’s unrealized dream or helping Matty through the stranger side of his experiences in Vietnam. Even John’s bully Clive (Jackson Seavor McDonald) gets an off-kilter spotlight where the leading pair go from pulling a horrible revenge prank on him to becoming his unlikely father figures. MacFarlane’s edge is always there, but there is always a softer side to tug at your heartstrings and cushion you if not every gag lands.​​​​​​​

Where to watch Ted

All episodes are now streaming

Ted falls out of the tumble dryer in Ted. Credit: Peacock

​​​​​​​ Both seasons of Ted are currently available in their entirety on Peacock. Season 1 consists of 7 episodes, while season 2 received a larger episode count of 8. However, even after having an overall positive response and viral attention thanks to shared and reposted clips, MacFarlane confirmed that there were no current plans for season 3, as the costs to bring Ted to life on a television budget are incredibly high.

However, as Ted said himself, “Don’t be sad because it’s over; be happy because it happened.” Even against the costs, MacFarlane set out to ensure that Ted’s surprising expansion into television would still be a fulfilling experience, ensuring that the series could at least end on a satisfying note. As such, if you wish to see just how having an irresponsible magical stuffed friend shaped John’s life ahead of the movies, you will not be disappointed.​​​​​​​



Source link