@@ -9,6 +9,7 @@ because that's clearly a non-descriptive name.
9
9
10
10
- [ Adding a new lint] ( #adding-a-new-lint )
11
11
- [ Setup] ( #setup )
12
+ - [ Getting Started] ( #getting-started )
12
13
- [ Testing] ( #testing )
13
14
- [ Rustfix tests] ( #rustfix-tests )
14
15
- [ Edition 2018 tests] ( #edition-2018-tests )
@@ -31,6 +32,19 @@ which can change rapidly. Make sure you're working near rust-clippy's master,
31
32
and use the ` setup-toolchain.sh ` script to configure the appropriate toolchain
32
33
for the Clippy directory.
33
34
35
+ ### Getting Started
36
+
37
+ There is a bit of boilerplate code that needs to be set up when creating a new
38
+ lint. Fortunately, you can use the clippy dev tools to handle this for you. We
39
+ are naming our new lint ` foo_functions ` (lints are generally written in snake
40
+ case), and we don't need type information so it will have an early pass type
41
+ (more on this later on). To get started on this lint you can run
42
+ ` ./util/dev new_lint --name=foo_functions --pass=early --category=pedantic `
43
+ (category will default to nursery if not provided). This command will create
44
+ two files: ` tests/ui/foo_functions.rs ` and ` clippy_lints/src/foo_functions.rs ` ,
45
+ as well as run ` ./util/dev update_lints ` to register the new lint. Next, we'll
46
+ open up these files and add our lint!
47
+
34
48
### Testing
35
49
36
50
Let's write some tests first that we can execute while we iterate on our lint.
@@ -41,11 +55,9 @@ we want to check. The output of Clippy is compared against a `.stderr` file.
41
55
Note that you don't have to create this file yourself, we'll get to
42
56
generating the ` .stderr ` files further down.
43
57
44
- We start by creating the test file at ` tests/ui/foo_functions.rs ` . It doesn't
45
- really matter what the file is called, but it's a good convention to name it
46
- after the lint it is testing, so ` foo_functions.rs ` it is.
58
+ We start by opening the test file created at ` tests/ui/foo_functions.rs ` .
47
59
48
- Inside the file we put some examples to get started:
60
+ Update the file with some examples to get started:
49
61
50
62
``` rust
51
63
#![warn(clippy:: foo_functions)]
@@ -90,8 +102,8 @@ Once we are satisfied with the output, we need to run
90
102
` tests/ui/update-all-references.sh ` to update the ` .stderr ` file for our lint.
91
103
Please note that, we should run ` TESTNAME=foo_functions cargo uitest `
92
104
every time before running ` tests/ui/update-all-references.sh ` .
93
- Running ` TESTNAME=foo_functions cargo uitest ` should pass then. When we
94
- commit our lint, we need to commit the generated ` .stderr ` files, too.
105
+ Running ` TESTNAME=foo_functions cargo uitest ` should pass then. When we commit
106
+ our lint, we need to commit the generated ` .stderr ` files, too.
95
107
96
108
### Rustfix tests
97
109
@@ -121,26 +133,42 @@ With tests in place, let's have a look at implementing our lint now.
121
133
122
134
### Lint declaration
123
135
124
- We start by creating a new file in the ` clippy_lints ` crate. That's the crate
125
- where all the lint code is. We are going to call the file
126
- ` clippy_lints/src/foo_functions.rs ` and import some initial things we need:
136
+ Let's start by opening the new file created in the ` clippy_lints ` crate
137
+ at ` clippy_lints/src/foo_functions.rs ` . That's the crate where all the
138
+ lint code is. This file has already imported some initial things we will need:
127
139
128
140
``` rust
129
- use rustc :: lint :: {LintArray , LintPass , EarlyLintPass };
141
+ use rustc :: lint :: {LintArray , LintPass , EarlyLintPass , EarlyContext };
130
142
use rustc_session :: {declare_lint_pass, declare_tool_lint};
143
+ use syntax :: ast :: * ;
131
144
```
132
145
133
- The next step is to provide a lint declaration. Lints are declared using the
134
- [ ` declare_clippy_lint! ` ] [ declare_clippy_lint ] macro:
146
+ The next step is to update the lint declaration. Lints are declared using the
147
+ [ ` declare_clippy_lint! ` ] [ declare_clippy_lint ] macro, and we just need to update
148
+ the auto-generated lint declaration to have a real description, something like this:
135
149
136
150
``` rust
137
151
declare_clippy_lint! {
152
+ /// **What it does:**
153
+ ///
154
+ /// **Why is this bad?**
155
+ ///
156
+ /// **Known problems:** None.
157
+ ///
158
+ /// **Example:**
159
+ ///
160
+ /// ```rust
161
+ /// // example code
162
+ /// ```
138
163
pub FOO_FUNCTIONS ,
139
164
pedantic ,
140
165
" function named `foo`, which is not a descriptive name"
141
166
}
142
167
```
143
168
169
+ * The section of lines prefixed with ` /// ` constitutes the lint documentation
170
+ section. This is the default documentation style and will be displayed at
171
+ https://rust-lang.github.io/rust-clippy/master/index.html .
144
172
* ` FOO_FUNCTIONS ` is the name of our lint. Be sure to follow the [ lint naming
145
173
guidelines] [ lint_naming ] here when naming your lint. In short, the name should
146
174
state the thing that is being checked for and read well when used with
@@ -150,8 +178,8 @@ state the thing that is being checked for and read well when used with
150
178
* The last part should be a text that explains what exactly is wrong with the
151
179
code
152
180
153
- With our lint declaration done, we will now make sure that it is assigned to a
154
- lint pass :
181
+ The rest of this file contains an empty implementation for our lint pass,
182
+ which in this case is ` EarlyLintPass ` and should look like this :
155
183
156
184
``` rust
157
185
// clippy_lints/src/foo_functions.rs
@@ -166,12 +194,9 @@ impl EarlyLintPass for FooFunctions {}
166
194
Don't worry about the ` name ` method here. As long as it includes the name of the
167
195
lint pass it should be fine.
168
196
169
- Next we need to run ` util/dev update_lints ` to register the lint in various
170
- places, mainly in ` clippy_lints/src/lib.rs ` .
171
-
172
- While ` update_lints ` automates some things, it doesn't automate everything. We
173
- will have to register our lint pass manually in the ` register_plugins ` function
174
- in ` clippy_lints/src/lib.rs ` :
197
+ The new lint automation runs ` update_lints ` , which automates some things, but it
198
+ doesn't automate everything. We will have to register our lint pass manually in
199
+ the ` register_plugins ` function in ` clippy_lints/src/lib.rs ` :
175
200
176
201
``` rust
177
202
reg . register_early_lint_pass (box foo_functions :: FooFunctions );
@@ -195,14 +220,9 @@ In short, the `LateLintPass` has access to type information while the
195
220
` EarlyLintPass ` . The ` EarlyLintPass ` is also faster. However linting speed
196
221
hasn't really been a concern with Clippy so far.
197
222
198
- Since we don't need type information for checking the function name, we are
199
- going to use the ` EarlyLintPass ` . It has to be imported as well, changing our
200
- imports to:
201
-
202
- ``` rust
203
- use rustc :: lint :: {LintArray , LintPass , EarlyLintPass , EarlyContext };
204
- use rustc :: {declare_tool_lint, lint_array};
205
- ```
223
+ Since we don't need type information for checking the function name, we used
224
+ ` --pass=early ` when running the new lint automation and all the imports were
225
+ added accordingly.
206
226
207
227
### Emitting a lint
208
228
0 commit comments