Skip to content

Commit f1eaec1

Browse files
Add ast-grep documentation page
1 parent 1cf2b43 commit f1eaec1

File tree

3 files changed

+259
-1
lines changed

3 files changed

+259
-1
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# Editors
2+
.idea
13
# Dependencies
24
/node_modules
35

docs/integrations/ast-grep.md

+256
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
---
2+
title: Ast-Grep rules in CodeRabbit
3+
description: Integrate Ast-Grep rules with CodeRabbit
4+
sidebar_label: Ast-Grep
5+
image: "/preview_meta.jpg"
6+
---
7+
8+
<head>
9+
<meta charSet="utf-8" />
10+
<meta name="title" content="CodeRabbit integration with ast-grep rules" />
11+
<meta name="description" content="Integrate ast-grep in CodeRabbit on your own repository" />
12+
13+
<meta property="og:type" content="website" />
14+
<meta property="og:url" content="https://coderabbit.ai/" />
15+
<meta property="og:title" content="CodeRabbit integration with ast-grep rules" />
16+
<meta property="og:description" content="CodeRabbit: AI-powered Code Reviews" />
17+
<meta property="og:image" content="/preview_meta.jpg" />
18+
19+
<meta name="twitter:image" content="https://coderabbit.ai/preview_meta.jpg" />
20+
<meta name="twitter:card" content="summary_large_image" />
21+
<meta name="twitter:title" content="CodeRabbit integration with ast-grep rules" />
22+
<meta name="twitter:description" content="CodeRabbit: AI-powered Code Reviews" />
23+
</head>
24+
25+
This documentation provides guidance on integrating AST-Grep rules within the CodeRabbit platform. AST-Grep is a tool used for searching code using abstract syntax trees (AST) patterns.
26+
27+
### **Setting up AST-Grep rules**
28+
By default, users can add AST-Grep rules by following these steps:
29+
30+
1. Create a folder named `rules` in your project directory.
31+
2. Add individual `.yaml` files for each AST-Grep rule within the `rules` folder.
32+
3. Ensure each `.yaml` file contains the necessary AST-Grep rule configurations.
33+
4. Ensure that all rules contains a `message` property, that is going to be used on the review process.
34+
35+
### **The rule object**
36+
37+
Rule object is the core concept of ast-grep's rule system and every other features are built on top of it.
38+
39+
Below is the full list of fields in a rule object. Every rule field is optional and can be omitted but at least one field should be present in a rule. A node will match a rule if and only if it satisfies all fields in the rule object.
40+
```yaml
41+
rule:
42+
# atomic rule
43+
pattern: 'search.pattern'
44+
kind: 'tree_sitter_node_kind'
45+
regex: 'rust|regex'
46+
# relational rule
47+
inside: { pattern: 'sub.rule' }
48+
has: { kind: 'sub_rule' }
49+
follows: { regex: 'can|use|any' }
50+
precedes: { kind: 'multi_keys', pattern: 'in.sub' }
51+
# composite rule
52+
all: [ {pattern: 'match.all'}, {kind: 'match_all'} ]
53+
any: [ {pattern: 'match.any'}, {kind: 'match_any'} ]
54+
not: { pattern: 'not.this' }
55+
matches: 'utility-rule'
56+
```
57+
58+
### **Three Rule Categories**
59+
To summarize the rule object fields above, we have three categories of rules:
60+
61+
- Atomic Rule: the most basic rule that checks if AST nodes matches.
62+
- Relational Rule: rules that check if a node is surrounded by another node.
63+
- Composite Rule: rules that combine sub-rules together using logical operators.
64+
65+
These three categories of rules can be composed together to create more complex rules.
66+
67+
The rule object is inspired by the CSS selectors but with more composability and expressiveness. Think about how selectors in CSS works can help you understand the rule object!
68+
69+
> Read ast-grep [documentation](https://ast-grep.github.io/guide/rule-config.html) for detailed guides.
70+
71+
#### **Atomic rule**
72+
Atomic rule defines the most basic matching rule that determines whether one syntax node matches the rule or not. There are three kinds of atomic rule: `pattern`, `kind` and `regex`.
73+
74+
> Official documentation guide on [Atomic Rule](https://ast-grep.github.io/guide/rule-config/atomic-rule.html)
75+
76+
#### **Relational rule**
77+
Relational rule defines the relationship between two syntax nodes. There are four kinds of relational rule: `inside`, `has`, `follows` and `precedes`.
78+
79+
All four relational rules accept a sub rule object as their value. The sub rule will match the surrounding node while the relational rule itself will match the target node.
80+
81+
> Official documentation guide on [Relational Rule](https://ast-grep.github.io/guide/rule-config/relational-rule.html)
82+
83+
```yaml
84+
rule:
85+
pattern: await $PROMISE
86+
inside:
87+
kind: for_in_statement
88+
stopBy: end
89+
```
90+
91+
#### **Composite rule**
92+
Composite rule defines the logical relationship between multiple sub rules. There are three kinds of composite rule: `all`, `any` and `not`.
93+
94+
**all**
95+
96+
The `all` rule matches if all sub rules match.
97+
```yaml
98+
rule:
99+
all:
100+
- pattern: console.log('Hello World');
101+
- kind: expression_statement
102+
```
103+
104+
**any**
105+
106+
`any` rule matches if any sub rule matches.
107+
```yaml
108+
rule:
109+
any:
110+
- pattern: var a = $A
111+
- pattern: const a = $A
112+
- pattern: let a = $A
113+
```
114+
115+
**not**
116+
117+
`not` applies negation to a sub rule. It matches if the sub rule does not match.
118+
119+
```yaml
120+
rule:
121+
pattern: console.log($GREETING)
122+
not:
123+
pattern: console.log('Hello World')
124+
```
125+
126+
> Official documentation guide on [Composite Rule](https://ast-grep.github.io/guide/rule-config/composite-rule.html)
127+
128+
129+
## Reusing rule as utility
130+
ast-grep chooses to use YAML for rule representation. While this decision makes writing rules easier, it does impose some limitations on the rule authoring. One of the limitations is that rule objects cannot be reused.
131+
132+
#### **Local utility rule**
133+
Local utility rules are defined in the utils field of the config file. utils is a string-keyed dictionary.
134+
135+
For example, the following config file defines a local utility rule `is-literal`:
136+
137+
```yaml
138+
utils:
139+
is-literal:
140+
any:
141+
- kind: string
142+
- kind: number
143+
- kind: boolean
144+
rule:
145+
matches: is-literal
146+
```
147+
148+
#### **Global utility rule**
149+
Global utility rules are defined in a separate file. But they are available across all rule configurations in the project.
150+
151+
To create global utility rules, you need to have the `rules` folder created on the root of your project and another
152+
`utils` directory inside the root of your project.
153+
154+
```yaml
155+
my-awesome-project # project root
156+
|- rules # rule directory
157+
| |- my-rule.yml
158+
|- utils # utils directory
159+
| |- is-literal.yml
160+
```
161+
162+
```yaml
163+
# is-literal.yml
164+
id: is-literal
165+
language: TypeScript
166+
rule:
167+
any:
168+
- kind: 'false'
169+
- kind: undefined
170+
- kind: 'null'
171+
- kind: 'true'
172+
- kind: regex
173+
- kind: number
174+
- kind: string
175+
```
176+
177+
> Official documentation guide on [Utility Rule](https://ast-grep.github.io/guide/rule-config/utility-rule.html)
178+
179+
## Multiple Languages Support
180+
181+
CodeRabbit supports multiple programming languages for defining AST-Grep rules.
182+
183+
- Javascript
184+
- Typescript
185+
- C#
186+
- Golang
187+
- Java
188+
- Kotlin
189+
- Rust
190+
- Python
191+
- C
192+
193+
Below are examples of AST-Grep rules in different languages:
194+
195+
### **Javascript**
196+
#### Importing files without an extension is not allowed
197+
```yaml
198+
id: find-import-file
199+
language: js
200+
message: "Importing files without an extension is not allowed"
201+
rule:
202+
regex: "/[^.]+[^/]$"
203+
kind: string_fragment
204+
any:
205+
- inside:
206+
stopBy: end
207+
kind: import_statement
208+
- inside:
209+
stopBy: end
210+
kind: call_expression
211+
has:
212+
field: function
213+
regex: "^import$"
214+
```
215+
216+
#### No console.log allowed except console.error on the catch block
217+
```yaml
218+
id: no-console-except-error
219+
language: typescript
220+
message: "No console.log allowed except console.error on the catch block"
221+
rule:
222+
any:
223+
- pattern: console.error($$$)
224+
not:
225+
inside:
226+
kind: catch_clause
227+
stopBy: end
228+
- pattern: console.$METHOD($$$)
229+
constraints:
230+
METHOD:
231+
regex: 'log|debug|warn'
232+
```
233+
234+
### **C**
235+
In C, there is no built-in support for object-oriented programming, but some programmers use structs and function pointers to simulate classes and methods.
236+
237+
However, this style can have some drawbacks, such as:
238+
- extra memory allocation and reallocation for the struct and the function pointer.
239+
- indirection overhead when calling the function pointer.
240+
241+
A possible alternative is to use a plain function call with the struct pointer as the first argument.
242+
243+
```yaml
244+
id: method_receiver
245+
language: c
246+
rule:
247+
pattern: $R.$METHOD($$$ARGS)
248+
transform:
249+
MAYBE_COMMA:
250+
replace:
251+
source: $$$ARGS
252+
replace: '^.+'
253+
by: ', '
254+
fix:
255+
$METHOD(&$R$MAYBE_COMMA$$$ARGS)
256+
```

sidebars.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const sidebars: SidebarsConfig = {
4040
{
4141
type: "category",
4242
label: "Integrations",
43-
items: ["integrations/self-hosted-gitlab"],
43+
items: ["integrations/self-hosted-gitlab", "integrations/ast-grep"],
4444
},
4545
"faq/faq",
4646
],

0 commit comments

Comments
 (0)