Skip to content

Commit 00e9dc8

Browse files
bwilkersonCommit Bot
authored and
Commit Bot
committed
Add documentation on adding new diagnostics
Change-Id: Ice38a93e009cc9c07638ddce96e8960d986fa3c1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258509 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent d6ff119 commit 00e9dc8

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Adding a new diagnostic
2+
3+
This document describes the process of adding a new (non-lint) diagnostic to the
4+
analyzer.
5+
6+
## Define the diagnostic code
7+
8+
The first step is to define the code(s) associated with the diagnostic.
9+
10+
The codes are defined in the file `analyzer/messages.yaml`. There's a comment at
11+
the top of the file describing the structure of the file.
12+
13+
Every diagnostic has at least one code associated with it. A code defines the
14+
problem and correction messages that will be shown to users.
15+
16+
For most diagnostics, a single message (code) is sufficient. But sometimes it's
17+
useful to tailor the message based on the context in which the problem occurs or
18+
because the message can be made more clear. For example, it's an error to
19+
declare two or more constructors with the same name. That's true whether the
20+
name is explicit or implicit (the default constructor). In order for the message
21+
to match the user's model of the language, we define two messages for this one
22+
problem: one that refers to the constructors by their name, and one that refers
23+
to the constructors as "unnamed". The way we define two messages is by defining
24+
two codes.
25+
26+
Each code has a unique name (the key used in the map in `messages.yaml`) and can
27+
optionally define a shared name that links all the codes for a single diagnostic
28+
together. It is the shared name that is displayed to users. If a shared name
29+
isn't explicitly provided, it will default to being the same as the unique name.
30+
31+
After every edit to the `messages.yaml` file, you will need to run the utility
32+
`analyzer/tool/messages/generate.dart` to update the generated files.
33+
34+
You also need to manually add the name of the code to the list of codes in two
35+
files:
36+
- `analyzer/lib/error/error.dart`
37+
- `analysis_server/lib/src/services/correction/error_fix_status.yaml`
38+
39+
In the status file, the code should have the line
40+
```yaml
41+
status: needsEvaluation
42+
```
43+
nested under the name of the code.
44+
45+
## Write tests
46+
47+
We recommend writing the tests for a diagnostic before writing the code to
48+
generate the diagnostic. Doing so helps you think about the specific cases that
49+
the implementation code needs to handle, which can result in cleaner
50+
implementation code and fewer bugs.
51+
52+
The tests for each diagnostic code (or set of codes that have the same shared
53+
name) are in a separate file in the directory `analyzer/test/src/diagnostics`.
54+
Looking at the implementation of tests in a few of the other files can help you
55+
see the basic pattern, but all the tests essentially work by setting up the code
56+
to be analyzed, then assert that either the expected diagnostic has been
57+
produced in the expected locations or that there are no diagnostics being
58+
generated. (It's often valuable to test that the diagnostic doesn't have any
59+
false positives.)
60+
61+
## Report the diagnostic
62+
63+
The last step is to write the code to report the diagnostic. Where that code
64+
lives depends on the kind of diagnostic you're adding. If you're adding a
65+
diagnostic that's defined by the language specification (with a severity of
66+
'error'), then the best place to implement it will usually be in one of the
67+
`<node class>Resolver` classes. If you're adding a warning, then the class
68+
`BestPracticesVerifier` is usually the best place for it.

0 commit comments

Comments
 (0)