@@ -9,6 +9,7 @@ because that's clearly a non-descriptive name.
99
1010- [ Adding a new lint] ( #adding-a-new-lint )
1111 - [ Setup] ( #setup )
12+ - [ Getting Started] ( #getting-started )
1213 - [ Testing] ( #testing )
1314 - [ Rustfix tests] ( #rustfix-tests )
1415 - [ Edition 2018 tests] ( #edition-2018-tests )
@@ -31,6 +32,19 @@ which can change rapidly. Make sure you're working near rust-clippy's master,
3132and use the ` setup-toolchain.sh ` script to configure the appropriate toolchain
3233for the Clippy directory.
3334
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+
3448### Testing
3549
3650Let'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.
4155Note that you don't have to create this file yourself, we'll get to
4256generating the ` .stderr ` files further down.
4357
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 ` .
4759
48- Inside the file we put some examples to get started:
60+ Update the file with some examples to get started:
4961
5062``` rust
5163#![warn(clippy:: foo_functions)]
@@ -90,8 +102,8 @@ Once we are satisfied with the output, we need to run
90102` tests/ui/update-all-references.sh ` to update the ` .stderr ` file for our lint.
91103Please note that, we should run ` TESTNAME=foo_functions cargo uitest `
92104every 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.
95107
96108### Rustfix tests
97109
@@ -121,26 +133,42 @@ With tests in place, let's have a look at implementing our lint now.
121133
122134### Lint declaration
123135
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:
127139
128140``` rust
129- use rustc :: lint :: {LintArray , LintPass , EarlyLintPass };
141+ use rustc :: lint :: {LintArray , LintPass , EarlyLintPass , EarlyContext };
130142use rustc_session :: {declare_lint_pass, declare_tool_lint};
143+ use syntax :: ast :: * ;
131144```
132145
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:
135149
136150``` rust
137151declare_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+ /// ```
138163 pub FOO_FUNCTIONS ,
139164 pedantic ,
140165 " function named `foo`, which is not a descriptive name"
141166}
142167```
143168
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 .
144172* ` FOO_FUNCTIONS ` is the name of our lint. Be sure to follow the [ lint naming
145173guidelines] [ lint_naming ] here when naming your lint. In short, the name should
146174state 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
150178* The last part should be a text that explains what exactly is wrong with the
151179 code
152180
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 :
155183
156184``` rust
157185// clippy_lints/src/foo_functions.rs
@@ -166,12 +194,9 @@ impl EarlyLintPass for FooFunctions {}
166194Don't worry about the ` name ` method here. As long as it includes the name of the
167195lint pass it should be fine.
168196
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 ` :
175200
176201``` rust
177202reg . register_early_lint_pass (box foo_functions :: FooFunctions );
@@ -195,14 +220,9 @@ In short, the `LateLintPass` has access to type information while the
195220` EarlyLintPass ` . The ` EarlyLintPass ` is also faster. However linting speed
196221hasn't really been a concern with Clippy so far.
197222
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.
206226
207227### Emitting a lint
208228
0 commit comments