about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrad Sherman <bsherman1096@gmail.com>2020-01-11 13:26:25 -0600
committerBrad Sherman <bsherman1096@gmail.com>2020-01-15 21:20:51 -0600
commit237a01d116e666618ebf5cc5f5b704352c4fb276 (patch)
treea982dc62f53ff8097b83386d7aa057b996a39bd0
parentea82cbe790a706a62389d481f9927b8ced372f3b (diff)
downloadrust-237a01d116e666618ebf5cc5f5b704352c4fb276.tar.gz
rust-237a01d116e666618ebf5cc5f5b704352c4fb276.zip
Update documentation for adding new lints
- Add instructions for adding new lints with
  the new automation
-rw-r--r--doc/adding_lints.md76
1 files changed, 48 insertions, 28 deletions
diff --git a/doc/adding_lints.md b/doc/adding_lints.md
index 45b80a6b0c1..6fd052893bf 100644
--- a/doc/adding_lints.md
+++ b/doc/adding_lints.md
@@ -9,6 +9,7 @@ because that's clearly a non-descriptive name.
 
 - [Adding a new lint](#adding-a-new-lint)
   - [Setup](#setup)
+  - [Getting Started](#getting-started)
   - [Testing](#testing)
   - [Rustfix tests](#rustfix-tests)
   - [Edition 2018 tests](#edition-2018-tests)
@@ -31,6 +32,19 @@ which can change rapidly. Make sure you're working near rust-clippy's master,
 and use the `setup-toolchain.sh` script to configure the appropriate toolchain
 for the Clippy directory.
 
+### Getting Started
+
+There is a bit of boilerplate code that needs to be set up when creating a new
+lint. Fortunately, you can use the clippy dev tools to handle this for you. We
+are naming our new lint `foo_functions` (lints are generally written in snake
+case), and we don't need type information so it will have an early pass type
+(more on this later on). To get started on this lint you can run
+`./util/dev new_lint --name=foo_functions --pass=early --category=pedantic`
+(category will default to nursery if not provided). This command will create
+two files: `tests/ui/foo_functions.rs` and `clippy_lints/src/foo_functions.rs`,
+as well as run `./util/dev update_lints` to register the new lint. Next, we'll
+open up these files and add our lint!
+
 ### Testing
 
 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.
 Note that you don't have to create this file yourself, we'll get to
 generating the `.stderr` files further down.
 
-We start by creating the test file at `tests/ui/foo_functions.rs`. It doesn't
-really matter what the file is called, but it's a good convention to name it
-after the lint it is testing, so `foo_functions.rs` it is.
+We start by opening the test file created at `tests/ui/foo_functions.rs`. 
 
-Inside the file we put some examples to get started:
+Update the file with some examples to get started:
 
 ```rust
 #![warn(clippy::foo_functions)]
@@ -90,8 +102,8 @@ Once we are satisfied with the output, we need to run
 `tests/ui/update-all-references.sh` to update the `.stderr` file for our lint.
 Please note that, we should run `TESTNAME=foo_functions cargo uitest`
 every time before running `tests/ui/update-all-references.sh`.
-Running `TESTNAME=foo_functions cargo uitest` should pass then. When we
-commit our lint, we need to commit the generated `.stderr` files, too.
+Running `TESTNAME=foo_functions cargo uitest` should pass then. When we commit 
+our lint, we need to commit the generated `.stderr` files, too.
 
 ### Rustfix tests
 
@@ -121,26 +133,42 @@ With tests in place, let's have a look at implementing our lint now.
 
 ### Lint declaration
 
-We start by creating a new file in the `clippy_lints` crate. That's the crate
-where all the lint code is. We are going to call the file
-`clippy_lints/src/foo_functions.rs` and import some initial things we need:
+Let's start by opening the new file created in the `clippy_lints` crate 
+at `clippy_lints/src/foo_functions.rs`. That's the crate where all the
+lint code is. This file has already imported some initial things we will need:
 
 ```rust
-use rustc::lint::{LintArray, LintPass, EarlyLintPass};
+use rustc::lint::{LintArray, LintPass, EarlyLintPass, EarlyContext};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use syntax::ast::*;
 ```
 
-The next step is to provide a lint declaration. Lints are declared using the
-[`declare_clippy_lint!`][declare_clippy_lint] macro:
+The next step is to update the lint declaration. Lints are declared using the
+[`declare_clippy_lint!`][declare_clippy_lint] macro, and we just need to update
+the auto-generated lint declaration to have a real description, something like this:
 
 ```rust
 declare_clippy_lint! {
+    /// **What it does:**
+    ///
+    /// **Why is this bad?**
+    ///
+    /// **Known problems:** None.
+    ///
+    /// **Example:**
+    ///
+    /// ```rust
+    /// // example code
+    /// ```
     pub FOO_FUNCTIONS,
     pedantic,
     "function named `foo`, which is not a descriptive name"
 }
 ```
 
+* The section of lines prefixed with `///` constitutes the lint documentation
+section. This is the default documentation style and will be displayed at
+https://rust-lang.github.io/rust-clippy/master/index.html.
 * `FOO_FUNCTIONS` is the name of our lint. Be sure to follow the [lint naming
 guidelines][lint_naming] here when naming your lint. In short, the name should
 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
 * The last part should be a text that explains what exactly is wrong with the
   code
 
-With our lint declaration done, we will now make sure that it is assigned to a
-lint pass:
+The rest of this file contains an empty implementation for our lint pass, 
+which in this case is `EarlyLintPass` and should look like this:
 
 ```rust
 // clippy_lints/src/foo_functions.rs
@@ -166,12 +194,9 @@ impl EarlyLintPass for FooFunctions {}
 Don't worry about the `name` method here. As long as it includes the name of the
 lint pass it should be fine.
 
-Next we need to run `util/dev update_lints` to register the lint in various
-places, mainly in `clippy_lints/src/lib.rs`.
-
-While `update_lints` automates some things, it doesn't automate everything. We
-will have to register our lint pass manually in the `register_plugins` function
-in `clippy_lints/src/lib.rs`:
+The new lint automation runs `update_lints`, which automates some things, but it 
+doesn't automate everything. We will have to register our lint pass manually in
+the `register_plugins` function in `clippy_lints/src/lib.rs`:
 
 ```rust
 reg.register_early_lint_pass(box foo_functions::FooFunctions);
@@ -195,14 +220,9 @@ In short, the `LateLintPass` has access to type information while the
 `EarlyLintPass`. The `EarlyLintPass` is also faster. However linting speed
 hasn't really been a concern with Clippy so far.
 
-Since we don't need type information for checking the function name, we are
-going to use the `EarlyLintPass`. It has to be imported as well, changing our
-imports to:
-
-```rust
-use rustc::lint::{LintArray, LintPass, EarlyLintPass, EarlyContext};
-use rustc::{declare_tool_lint, lint_array};
-```
+Since we don't need type information for checking the function name, we used
+`--pass=early` when running the new lint automation and all the imports were
+added accordingly.
 
 ### Emitting a lint