Skip to content
This repository was archived by the owner on Aug 16, 2025. It is now read-only.

restructure existing blog posts #19

Merged
merged 24 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
5179dea
format blog file
harjotgill Mar 2, 2024
c0e81f1
format all blog files
harjotgill Mar 2, 2024
f777247
hide version 1 schema
harjotgill Mar 1, 2024
26799b5
Update faq.md
guritfaq Mar 7, 2024
2ba4987
Fix images for light and dark mode. Made improvements to docs (#22)
karan925 Mar 12, 2024
a059d97
Add ast-grep documentation page
petrisorcoderabbit Mar 8, 2024
9941a21
Update the ast-grep documentation to include the coderabbit config fi…
petrisorcoderabbit Mar 8, 2024
82d7eed
Fix language review
petrisorcoderabbit Mar 11, 2024
02189bf
Update coderabbit.yaml schema for ast-grep tool naming
petrisorcoderabbit Mar 12, 2024
98f0ef6
Update coderabbig guide page with new coderabbit.yaml changes
petrisorcoderabbit Mar 12, 2024
d705086
Update 2023-11-13-boosting-engineering-efficiency.md
guritfaq Mar 12, 2024
d0bd7ba
Move ast-grep documentation under the prompt-customization page
petrisorcoderabbit Mar 13, 2024
00e15a3
Change ast-grep naming
petrisorcoderabbit Mar 13, 2024
c59229f
Correct grammar for ast-grep documentation
petrisorcoderabbit Mar 13, 2024
c154d61
update faqs
karan925 Mar 12, 2024
8b47f3f
Update Discord link in Footer component (#25)
karan925 Mar 15, 2024
dd21258
restructure existing blog posts
harjotgill Mar 17, 2024
2cbb989
merge
harjotgill Mar 17, 2024
a5adb95
restructure existing docs
harjotgill Mar 17, 2024
82aa358
restructure existing docs
harjotgill Mar 17, 2024
6a91e80
review feedback
harjotgill Mar 17, 2024
3dc4177
add preview image
harjotgill Mar 17, 2024
0cb9eb9
use directory instead of folder terminology
harjotgill Mar 17, 2024
6c75ada
nit
harjotgill Mar 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move ast-grep documentation under the prompt-customization page
  • Loading branch information
petrisorcoderabbit authored and harjotgill committed Mar 17, 2024
commit d0bd7ba043e950a9e50da89cb7250b3357479f11
264 changes: 264 additions & 0 deletions docs/guides/prompt-customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,267 @@ Descriptive test names are used to clearly convey the intent of each test.
- Test the review feedback on pull requests and tailor as necessary.

:::

## Abstract Syntax Tree (AST) instructions

:::note
**Deep dive into AST patterns and AST-Grep rules**
- AST patterns [wikipedia](https://en.wikipedia.org/wiki/Abstract_syntax_tree)
- AST-grep [official documentation](https://ast-grep.github.io/guide/rule-config.html) for detailed guides.
:::

This section explains how to add custom code review instructions using AST-Grep rules. AST-Grep is a tool used for searching code using abstract syntax trees (AST) patterns.

By default, you can add AST-Grep rules by following these steps:
1. Create a folder that keeps all the ast-grep rules in your project directory.
2. Add individual `.yaml` files for each AST-Grep rule within the newly created folder.
3. Ensure that each `.yaml` file contains the necessary AST-Grep rule configurations.
4. Ensure that all rules contains a `message` property, that will be used in the review process.
5. Add the rules folder to the `.coderabbit.yml` file under `tools.ast-grep` configuration.

```yaml
#...
reviews:
#...
tools:
ast-grep:
rules_folder: "custom-name"
#...
```

### The rule object

Rule object is the core concept of ast-grep's rule system and every other features are built on top of it.

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.
```yaml
rule:
# atomic rule
pattern: 'search.pattern'
kind: 'tree_sitter_node_kind'
regex: 'rust|regex'
# relational rule
inside: { pattern: 'sub.rule' }
has: { kind: 'sub_rule' }
follows: { regex: 'can|use|any' }
precedes: { kind: 'multi_keys', pattern: 'in.sub' }
# composite rule
all: [ {pattern: 'match.all'}, {kind: 'match_all'} ]
any: [ {pattern: 'match.any'}, {kind: 'match_any'} ]
not: { pattern: 'not.this' }
matches: 'utility-rule'
```

### Three Rule Categories
To summarize the rule object fields above, we have three categories of rules:

- **Atomic Rule:** the most basic rule that checks if AST nodes matches.
- **Relational Rule:** rules that check if a node is surrounded by another node.
- **Composite Rule:** rules that combine sub-rules together using logical operators.

These three categories of rules can be composed together to create more complex rules.

The rule object is inspired by the CSS selectors but with more composability and expressiveness.
Thinking about how selectors in CSS works can help you understand the rule object!

> Read ast-grep [documentation](https://ast-grep.github.io/guide/rule-config.html) for detailed guides.

#### Atomic rule
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`.

> Official documentation guide on [Atomic Rule](https://ast-grep.github.io/guide/rule-config/atomic-rule.html)

#### Relational rule
Relational rule defines the relationship between two syntax nodes. There are four kinds of relational rule: `inside`, `has`, `follows` and `precedes`.

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.

> Official documentation guide on [Relational Rule](https://ast-grep.github.io/guide/rule-config/relational-rule.html)

```yaml
rule:
pattern: await $PROMISE
inside:
kind: for_in_statement
stopBy: end
```

#### Composite rule
Composite rule defines the logical relationship between multiple sub-rules. There are three kinds of composite rule: `all`, `any` and `not`.

**all**

The `all` rule matches if all sub-rules match.
```yaml
rule:
all:
- pattern: console.log('Hello World');
- kind: expression_statement
```

**any**

`any` rule matches if any sub-rule matches.
```yaml
rule:
any:
- pattern: var a = $A
- pattern: const a = $A
- pattern: let a = $A
```

**not**

`not` applies negation to a sub-rule. It matches if the sub-rule does not match.

```yaml
rule:
pattern: console.log($GREETING)
not:
pattern: console.log('Hello World')
```

> Official documentation guide on [Composite Rule](https://ast-grep.github.io/guide/rule-config/composite-rule.html)


### Reusing rule as utility
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.

#### Local utility rule
Local utility rules are defined in the utils field of the config file. utils is a string-keyed dictionary.

For example, the following config file defines a local utility rule `is-literal`:

```yaml
utils:
is-literal:
any:
- kind: string
- kind: number
- kind: boolean
rule:
matches: is-literal
```

#### Global utility rule
Global utility rules are defined in a separate file. But they are available across all rule configurations in the project.

To create global utility rules, you need to have the `rules` folder created on the root of your project and another
`utils` directory inside the root of your project.

```yaml
my-awesome-project # project root
|- rules # rule directory
| |- my-rule.yml
|- utils # utils directory
| |- is-literal.yml
```

>Also, you need to add the `rules` and `utils` folders to the `.coderabbit.yml` file under `tools.ast-grep` configuration.

```yaml
#...
reviews:
#...
tools:
ast-grep:
rules_folder: "rules"
utils_folder: "utils"
#...
```

```yaml
# is-literal.yml
id: is-literal
language: TypeScript
rule:
any:
- kind: 'false'
- kind: undefined
- kind: 'null'
- kind: 'true'
- kind: regex
- kind: number
- kind: string
```

> Official documentation guide on [Utility Rule](https://ast-grep.github.io/guide/rule-config/utility-rule.html)

### Multiple Languages Support

CodeRabbit supports multiple programming languages for defining AST-Grep rules.

- JavaScript
- Typescript
- C#
- Golang
- Java
- Kotlin
- Rust
- Python
- C

Below are examples of AST-Grep rules in different languages:

#### JavaScript
**Importing files without an extension is not allowed**
```yaml
id: find-import-file
language: js
message: "Importing files without an extension is not allowed"
rule:
regex: "/[^.]+[^/]$"
kind: string_fragment
any:
- inside:
stopBy: end
kind: import_statement
- inside:
stopBy: end
kind: call_expression
has:
field: function
regex: "^import$"
```

**No console.log allowed except console.error on the catch block**
```yaml
id: no-console-except-error
language: typescript
message: "No console.log allowed except console.error on the catch block"
rule:
any:
- pattern: console.error($$$)
not:
inside:
kind: catch_clause
stopBy: end
- pattern: console.$METHOD($$$)
constraints:
METHOD:
regex: 'log|debug|warn'
```

#### C
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.

However, this style can have some drawbacks, such as:
- extra memory allocation and reallocation for the struct and the function pointer.
- indirection overhead when calling the function pointer.

A possible alternative is to use a plain function call with the struct pointer as the first argument.

```yaml
id: method_receiver
language: c
rule:
pattern: $R.$METHOD($$$ARGS)
transform:
MAYBE_COMMA:
replace:
source: $$$ARGS
replace: '^.+'
by: ', '
fix:
$METHOD(&$R$MAYBE_COMMA$$$ARGS)
```
Loading