Skip to content

Commit 38d1c3e

Browse files
committed
Added page on contributing to Doxide, with a walkthrough of fixing a particular issue.
1 parent bdc40ed commit 38d1c3e

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

docs/contributing.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# Contributing to Doxide
2+
3+
Contributions to Doxide are welcome via a pull request to the [GitHub repository](https://github.com/lawmurray/doxide). Similarly, bug reports and feature suggestions can be made by [opening an issue](https://github.com/lawmurray/doxide/issues), and questions asked by [starting a discussion](https://github.com/lawmurray/doxide/discussions).
4+
5+
There are many ways to contribute code to Doxide. To do so you will need knowledge of C++, and may need to learn how to use [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) to parse and query a C++ source files. A brief how-to on the latter is given here .
6+
7+
When developing Doxide, you will need to build it from source, and rebuild it from source after making any changes. See the [README.md](https://github.com/lawmurray/doxide?tab=readme-ov-file#installation) file for instructions on working from source.
8+
9+
## Using Tree-sitter
10+
11+
Install the `tree-sitter` command-line interface. This will depend on your operating system. It is widely available in Linux distributions. Once installed you may need to configure it for the first time:
12+
```
13+
tree-sitter init-config
14+
```
15+
16+
There may not be a C++ parser installed by default, and at any rate Doxide is written to a specific version of a specific parser. That parser can be found in the `contrib/tree-sitter-cuda` directory, which is a submodule tracking the [tree-sitter-cuda](https://github.com/tree-sitter-grammars/tree-sitter-cuda) CUDA parser, which is based on the [tree-sitter-cpp](https://github.com/tree-sitter/tree-sitter-cpp) C++ parser, which is based on the [tree-sitter-c](https://github.com/tree-sitter/tree-sitter-c) C parser. CUDA is a superset of C++ is sort-of-a-superset of C and so Doxide currently uses the CUDA parser.
17+
18+
From within the `contrib/tree-sitter-cuda` directory, run, for example:
19+
```
20+
tree-sitter parse ../../demo/parsing.hpp
21+
```
22+
This will parse the given file and output the parse tree to the terminal.
23+
24+
## Fixing an issue: a walkthrough
25+
26+
This is a walkthrough of fixing issue [#50](https://github.com/lawmurray/doxide/issues/50) reported on the Doxide GitHub repository. The issue was that Doxide would miss variables that had an array type:
27+
```cpp
28+
/**
29+
* Test member variable of array type.
30+
*/
31+
int arr[10];
32+
```
33+
They would not be included in the documentation, and their documentation comment would be attributed to the next entity.
34+
35+
To reproduce the issue:
36+
37+
1. Add code such as the above to `demo/parsing.hpp` as a test case.
38+
39+
2. From the root directory of the code repository, build the Doxide documentation and publish it with MkDocs:
40+
```
41+
doxide build
42+
mkdocs serve
43+
```
44+
45+
3. Point your browser to `localhost:8000`. This is actually the whole Doxide website that you see at [doxide.org](https://doxide.org). Confirm that the bug is apparent by navigating to the *Demo > Parsing* section. (Of course you won't see issue [#50](https://github.com/lawmurray/doxide/issues/50) anymore---it has been fixed!)
46+
47+
To fix the problem, we can start by seeing how Tree-sitter parses the code. Back in the `contrib/tree-sitter-cuda` directory, put the above code in a file called `test.cpp` and run:
48+
```
49+
tree-sitter parse test.cpp
50+
```
51+
The output is:
52+
```
53+
(translation_unit [0, 0] - [4, 0]
54+
(comment [0, 0] - [2, 3])
55+
(declaration [3, 0] - [3, 12]
56+
type: (primitive_type [3, 0] - [3, 3])
57+
declarator: (array_declarator [3, 4] - [3, 11]
58+
declarator: (identifier [3, 4] - [3, 7])
59+
size: (number_literal [3, 8] - [3, 10]))))
60+
```
61+
62+
!!! tip
63+
We could run `tree-sitter parse ../../demo/parsing.hpp` instead, but the parse tree is much larger, and it may be difficult to track down the specific problem that way.
64+
65+
Now, bring up the source file `src/doxide.cpp`, where Doxide's Tree-sitter queries are given as hard-coded strings in the `query_cpp` variable. These are patterns that match parse trees to select entities (e.g. types, variables, functions, macros, etc) from the source code to document. This section in particular plucks out variables and member variables:
66+
```
67+
;; variable
68+
((declaration
69+
declarator: [
70+
(identifier) @name
71+
(reference_declarator (identifier) @name)
72+
(pointer_declarator (identifier) @name)
73+
(init_declarator
74+
declarator: [
75+
(identifier) @name
76+
(reference_declarator (identifier) @name)
77+
(pointer_declarator (identifier) @name)
78+
]
79+
value: (_) @value)
80+
]
81+
default_value: (_)? @value
82+
) @variable)
83+
84+
;; member variable
85+
((field_declaration
86+
declarator: [
87+
(field_identifier) @name
88+
(reference_declarator (field_identifier) @name)
89+
(pointer_declarator (field_identifier) @name)
90+
(init_declarator
91+
declarator: [
92+
(identifier) @name
93+
(field_identifier) @name
94+
(reference_declarator (identifier) @name)
95+
(reference_declarator (field_identifier) @name)
96+
(pointer_declarator (identifier) @name)
97+
(pointer_declarator (field_identifier) @name)
98+
]
99+
value: (_) @value)
100+
]
101+
default_value: (_)? @value
102+
) @variable)
103+
```
104+
105+
!!! tip
106+
For more information on writing queries, see the Tree-sitter documentation for [Pattern Matching with Queries](https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries).
107+
108+
The query handles, among other things, `reference_declarator` and `pointer_declarator`, but we saw `array_declarator` in the parse tree above, and it does not seem to handle that. This looks like it might be the problem. So let's augment the query to handle `array_declarator`, following the same patterns as for `reference_declarator` and `pointer_declarator`:
109+
```
110+
;; variable
111+
((declaration
112+
declarator: [
113+
(identifier) @name
114+
(array_declarator (identifier) @name)
115+
(reference_declarator (identifier) @name)
116+
(pointer_declarator (identifier) @name)
117+
(init_declarator
118+
declarator: [
119+
(identifier) @name
120+
(array_declarator (identifier) @name)
121+
(reference_declarator (identifier) @name)
122+
(pointer_declarator (identifier) @name)
123+
]
124+
value: (_) @value)
125+
]
126+
default_value: (_)? @value
127+
) @variable)
128+
129+
;; member variable
130+
((field_declaration
131+
declarator: [
132+
(field_identifier) @name
133+
(array_declarator (field_identifier) @name)
134+
(reference_declarator (field_identifier) @name)
135+
(pointer_declarator (field_identifier) @name)
136+
(init_declarator
137+
declarator: [
138+
(identifier) @name
139+
(field_identifier) @name
140+
(array_declarator (identifier) @name)
141+
(array_declarator (field_identifier) @name)
142+
(reference_declarator (identifier) @name)
143+
(reference_declarator (field_identifier) @name)
144+
(pointer_declarator (identifier) @name)
145+
(pointer_declarator (field_identifier) @name)
146+
]
147+
value: (_) @value)
148+
]
149+
default_value: (_)? @value
150+
) @variable)
151+
```
152+
Now rebuild and reinstall Doxide, rerun the test above (`doxide build`, `mkdocs serve`, inspect `localhost:8000`), and verify that the bug is now fixed.
153+
154+
You can now commit the fix, including the test case added to `parsing.hpp` as a regression test for future, and submit a pull request on the [GitHub repository](https://github.com/lawmurray/doxide).

mkdocs.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,6 @@ nav:
7777
- organizing.md
7878
- parsing.md
7979
- command-line.md
80+
- contributing.md
8081
- demo/index.md
8182
- questions-and-answers.md

0 commit comments

Comments
 (0)