Replies: 3 comments 1 reply
-
I think that syntax for composing patterns is really intuitive, well done! For Biome specifically, I think we wouldn’t use the I have a slight concern regarding the callbacks with Are you planning on allowing an escape hatch that allows people to parse a GritQL pattern and use it as a (sub)pattern within this API? |
Beta Was this translation helpful? Give feedback.
-
I've used a number of AST tools (like eslint and ts-morph) but this syntax feels the most intuitive of any I've seen:
Things I really like about this:
Something I would love to use this for is a combination of deterministic + non-deterministic code generation, being able to identify the exact code I want to change across a large surface area, but then using something like GPT to adapt only that specific code to a new pattern feels like it would work really well with the
Overall I think this is great and solves several problems that today do not have great solutions! |
Beta Was this translation helpful? Give feedback.
-
Nit: Maybe it makes sense to make |
Beta Was this translation helpful? Give feedback.
-
I've heard many people are interested in using Grit from other applications, but without needing to learn the GritQL syntax.
With that in mind, I'm working on a TypeScript SDK which would allow you to interact with GritQL directly from TypeScript. I'd love early feedback on the API.
Top-level API
The main
find
method is used to execute a GritQL query. It returns a promise which can be awaited to get the results.To find matches inside a directory, you should the
find($pattern, $paths)
method. $pattern is any valid Grit query, while $paths is an array of strings representing the paths to search in.Query Builder
Queries are built by composing patterns together. All patterns are imported from a language-specific import that determines the target language.
The most basic pattern is a simple snippet pattern which can be used to match equivalent snippets of code in the target language. Snippets are created using a
js.code
template string, like this:AST Nodes
Use
js.ast.$node
to match a specific (named) AST node. An object can be passed to filter named fields of the node.For example, this pattern will find any variable assigned the value of 42:
Variables
Use
js.var.$name
to create a metavariable named$name
. This is particularly useful for binding variables to be used in other patterns.For example, this can be combined with the AST node pattern to capture the name of the variable being assigned:
Constraints
Constraints can be added to patterns by calling additional methods on the pattern.
Contains
You can use
contains
to require that a pattern contains another pattern. For example, to find a function that contains a variable assignment:Within
You can use
within
to require that a pattern is within another pattern. For example, to find a function that is within a class:Filter
The
filter
method can be used to provide a callback which will be called with each match. If the callback returnsfalse
, the match will be discarded.For example, this function will only match functions that mention the word "myFunction":
The
match
argument to the callback is an object that represents the match. You can call additional arguments on the match to get more information about the match and search for more patterns.For example, this pattern will find all functions that contain a variable assignment:
The second argument to the callback is a
context
argument that represents the context in which the match was found. This is primarily useful for retrieving variable values.For example, this can be match all functions that have a name starting with
foo
:Each
The
each
method can be used to provide a callback which will be called with each match. The callback function has the same signature as thefilter
method, but the return value is ignored.You can use this to gather information about a program. For example, this will build a list of all classes in a program:
Rewrites
The
rewrite
method can be used to rewrite any matching pattern. You should provide a replacement template string to therewrite
method.For example, this will replace all instances of
console.log
withconsole.error
:You can also replace matches inside
each
orfilter
methods. For example, this will replace all instances ofconsole.log
withconsole.error
only if the message contains the word "error":Beta Was this translation helpful? Give feedback.
All reactions