codemodsquad / astx

Super powerful structural search and replace for JavaScript and TypeScript to automate your refactoring
MIT License
90 stars 6 forks source link

when to use astx codemod engine? #18

Open alexbit-codemod opened 1 year ago

alexbit-codemod commented 1 year ago

great work @jedwards1211 here.

which use cases cannot be handled by astx? have you heard about semgrep? (they have data flow analysis, and built on top of tree-sitter) also grit.io is building some awesome stuff. their pattern language reminded of your work.

at intuita, we are building a community of codemod champions like you. would love to have you there and exchange notes. also if interested, we can chat about adding astx support to our codemod.studio (we have visual codemod builder and some LLM helpers to build codemods faster)

jedwards1211 commented 1 year ago

Hi @alex-from-intuita, thanks for reaching out! Your codemod studio is cool!

Yeah semgrep has a similar pattern language, it seems like it doesn't allow you to replace with patterns or do any codemodding in general though?

grit.io is interesting, I'll have to read more about it. It seems like they need to devote more attention to making a syntax for capturing zero or more AST nodes into a metavariable like astx's $$a (ordered sibling AST nodes) and $$$a (unordered sibling AST nodes). Maybe they have a way to do stuff like that, I don't immediately see one though...

The fact that they have a pattern language that's not just JS/TS is good, there are limitations to defining patterns as pure JS/TS statements or expressions, ideally you want a grammar that's a superset of the programming language's grammar where you can use special pattern language constructs in place of any grammar symbol...

It's hard to say exactly which use cases can't be handled by astx, there's a basic mode where you just find one pattern and replace with another pattern that's obviously fairly limited, but I've put a lot of work into making patterns as powerful as possible. But it also has an API you can use with arbitrary code, here's a basic example and a very complex example. I've put a lot of work into making that API as straightforward to use as I can as well. Theoretically you can do anything with this API but of course it's a question of how easy or difficult it is.

One big limitation is you can't make patterns that only match identifiers of a given TypeScript type, for example $a + $b where $a is a string...that's something I find myself wishing for, and I'm not sure I'd be able to implement anytime soon.

The biggest problem I've run into with JSCodeshift is that recast constantly lags behind the latest language features...for instance I saw recast barf on code that had a TSInstantiationExpression, which is rather new. I've been experimenting with other ways to preserve formatting without using recast, I have a branch that hijacks internal @babel/generator API to do that. I also want to experiment with using a custom Prettier printer to preserve formatting of unmodified nodes. Basically I want something that's guaranteed to just work as long as the backend (Babel or whatever) can parse your code, and I've pretty much given up on having that guarantee with recast.

jedwards1211 commented 1 year ago

But yeah astx was inspired by jscodeshift and is basically intended to be a much easier-to-use version of it, in all my own codemodding work I use astx instead of jscodeshift now.

Another limitation of the API is you can only search for nodes via patterns right now, I need to add a method to get all nodes of a given type (you can then .filter) so no edge cases are more tricky than using JSCodeshift's API.