OLD | NEW |
---|---|
1 # Clang Tool Refactoring | 1 # Clang Tool Refactoring |
2 | 2 |
3 [TOC] | 3 [TOC] |
4 | 4 |
5 ## Introduction | 5 ## Introduction |
6 | 6 |
7 Clang tools can help with global refactorings of Chromium code. Clang tools can | 7 Clang tools can help with global refactorings of Chromium code. Clang tools can |
8 take advantage of clang's AST to perform refactorings that would be impossible | 8 take advantage of clang's AST to perform refactorings that would be impossible |
9 with a traditional find-and-replace regexp: | 9 with a traditional find-and-replace regexp: |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
62 ... | 62 ... |
63 | 63 |
64 ==== END EDITS ==== | 64 ==== END EDITS ==== |
65 ``` | 65 ``` |
66 | 66 |
67 The header and footer are required. Each line between the header and footer | 67 The header and footer are required. Each line between the header and footer |
68 represents one edit. Fields are separated by `:::`, and the first field must | 68 represents one edit. Fields are separated by `:::`, and the first field must |
69 be `r` (for replacement). In the future, this may be extended to handle header | 69 be `r` (for replacement). In the future, this may be extended to handle header |
70 insertion/removal. A deletion is an edit with no replacement text. | 70 insertion/removal. A deletion is an edit with no replacement text. |
71 | 71 |
72 The edits are applied by [`run_tool.py`](#Running), which understands certain | 72 The edits are applied by [`apply_edits.py`](#Running), which understands certain |
73 conventions: | 73 conventions: |
74 | 74 |
75 * The tool should munge newlines in replacement text to `\0`. The script | 75 * The tool should munge newlines in replacement text to `\0`. The script |
76 knows to translate `\0` back to newlines when applying edits. | 76 knows to translate `\0` back to newlines when applying edits. |
77 * When removing an element from a 'list' (e.g. function parameters, | 77 * When removing an element from a 'list' (e.g. function parameters, |
78 initializers), the tool should emit a deletion for just the element. The | 78 initializers), the tool should emit a deletion for just the element. The |
79 script understands how to extend the deletion to remove commas, etc. as | 79 script understands how to extend the deletion to remove commas, etc. as |
80 needed. | 80 needed. |
81 | 81 |
82 TODO: Document more about `SourceLocation` and how spelling loc differs from | 82 TODO: Document more about `SourceLocation` and how spelling loc differs from |
(...skipping 28 matching lines...) Expand all Loading... | |
111 It is important to use --bootstrap as there appear to be [bugs](https://crbug.co m/580745) | 111 It is important to use --bootstrap as there appear to be [bugs](https://crbug.co m/580745) |
112 in the clang library this script produces if you build it with gcc, which is the default. | 112 in the clang library this script produces if you build it with gcc, which is the default. |
113 | 113 |
114 ## Running | 114 ## Running |
115 First, build all Chromium targets to avoid failures due to missing dependencies | 115 First, build all Chromium targets to avoid failures due to missing dependencies |
116 that are generated as part of the build: | 116 that are generated as part of the build: |
117 | 117 |
118 ```shell | 118 ```shell |
119 ninja -C out/Debug # For non-Windows | 119 ninja -C out/Debug # For non-Windows |
120 ninja -d keeprsp -C out/Debug # For Windows | 120 ninja -d keeprsp -C out/Debug # For Windows |
121 | |
122 # experimental: | |
123 $gen_targets = $(ninja -C out/gn -t targets all \ | |
124 | grep '^gen/[^: ]*\.[ch][pc]*:' \ | |
125 | cut -f 1 -d :`) | |
126 ninja -C out/Debug $gen_targets | |
121 ``` | 127 ``` |
122 | 128 |
123 On Windows, generate the compile DB first, and after making any source changes. | 129 On Windows, generate the compile DB first, and after making any source changes. |
124 Then omit the `--generate-compdb` in later steps. | 130 Then omit the `--generate-compdb` in later steps. |
125 | 131 |
126 ```shell | 132 ```shell |
127 tools/clang/scripts/generate_win_compdb.py out/Debug | 133 tools/clang/scripts/generate_win_compdb.py out/Debug |
128 ``` | 134 ``` |
129 | 135 |
130 Then run the actual tool: | 136 Then run the actual clang tool to generate a list of edits: |
131 | 137 |
132 ```shell | 138 ```shell |
133 tools/clang/scripts/run_tool.py <toolname> \ | 139 tools/clang/scripts/run_tool.py <toolname> \ |
134 --generate-compdb | 140 --generate-compdb |
135 out/Debug <path 1> <path 2> ... | 141 out/Debug <path 1> <path 2> ... >/tmp/list-of-edits |
danakj
2016/12/23 15:45:06
suggest putting debug in the output file name for
Łukasz Anforowicz
2016/12/27 22:33:26
Done.
| |
136 ``` | 142 ``` |
137 | 143 |
138 `--generate-compdb` can be omitted if the compile DB was already generated and | 144 `--generate-compdb` can be omitted if the compile DB was already generated and |
139 the list of build flags and source files has not changed since generation. | 145 the list of build flags and source files has not changed since generation. |
140 | 146 |
141 `<path 1>`, `<path 2>`, etc are optional arguments to filter the files to run | 147 `<path 1>`, `<path 2>`, etc are optional arguments to filter the files to run |
142 the tool across. This is helpful when sharding global refactorings into smaller | 148 the tool across. This is helpful when sharding global refactorings into smaller |
143 chunks. For example, the following command will run the `empty_string` tool | 149 chunks. For example, the following command will run the `empty_string` tool |
144 across just the files in `//base`: | 150 across just the files in `//base`: |
145 | 151 |
146 ```shell | 152 ```shell |
147 tools/clang/scripts/run_tool.py empty_string \ | 153 tools/clang/scripts/run_tool.py empty_string \ |
148 --generated-compdb \ | 154 --generated-compdb \ |
149 out/Debug base | 155 out/Debug base >/tmp/list-of-edits |
danakj
2016/12/23 15:45:06
same
Łukasz Anforowicz
2016/12/27 22:33:26
Done.
| |
156 ``` | |
157 | |
158 Finally - apply the edits as follows: | |
dcheng
2016/12/27 07:30:14
Super minor nit: comma instead of a dash
Łukasz Anforowicz
2016/12/27 22:33:26
Done.
| |
159 | |
160 ```shell | |
161 cat /tmp/list-of-edits \ | |
danakj
2016/12/23 15:45:06
same
Łukasz Anforowicz
2016/12/27 22:33:26
Done.
| |
162 | tools/clang/scripts/extract_edits.py \ | |
163 | tools/clang/scripts/apply_edits.py out/Debug <optional paths to filter by> | |
danakj
2016/12/23 15:45:06
Why are there filter paths here and for run_tool.p
Łukasz Anforowicz
2016/12/27 22:33:26
I tried to explain this better in the newest patch
| |
150 ``` | 164 ``` |
151 | 165 |
152 ## Debugging | 166 ## Debugging |
153 Dumping the AST for a file: | 167 Dumping the AST for a file: |
154 | 168 |
155 ```shell | 169 ```shell |
156 clang++ -cc1 -ast-dump foo.cc | 170 clang++ -cc1 -ast-dump foo.cc |
157 ``` | 171 ``` |
158 | 172 |
159 Using `clang-query` to dynamically test matchers (requires checking out | 173 Using `clang-query` to dynamically test matchers (requires checking out |
(...skipping 20 matching lines...) Expand all Loading... | |
180 | 194 |
181 ```shell | 195 ```shell |
182 tools/clang/scripts/test_tool.py <tool name> | 196 tools/clang/scripts/test_tool.py <tool name> |
183 ``` | 197 ``` |
184 | 198 |
185 The name of the tool binary and the subdirectory for the tool in | 199 The name of the tool binary and the subdirectory for the tool in |
186 `//tools/clang` must match. The test runner finds all files that match the | 200 `//tools/clang` must match. The test runner finds all files that match the |
187 pattern `//tools/clang/<tool name>/tests/*-original.cc`, runs the tool across | 201 pattern `//tools/clang/<tool name>/tests/*-original.cc`, runs the tool across |
188 those files, and compared it to the `*-expected.cc` version. If there is a | 202 those files, and compared it to the `*-expected.cc` version. If there is a |
189 mismatch, the result is saved in `*-actual.cc`. | 203 mismatch, the result is saved in `*-actual.cc`. |
OLD | NEW |