Skip to content

Commit dfc282c

Browse files
authored
Update tutorial for rule suppression examples (#1715)
1 parent 31a9cf3 commit dfc282c

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

docs/developers/tutorial.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ In this tutorial, you will learn how to
1010
- use `SymbolInformation` to look up method signatures
1111
- use `Diagnostic` to report linter errors
1212
- use `withConfiguration` to make a rule configurable
13+
- use `atomic` to enable rule suppression
1314
- publish the rule so others can try it on their own codebase
1415

1516
We are going to implement two different rules. The first rule is a semantic
@@ -135,6 +136,7 @@ This solution is simple but it is incomplete
135136
- the rewrite triggers for any `true` literal even if it is not a function
136137
argument. For example, `val done = true` becomes
137138
`val done = isSuccess = true`.
139+
- the rewrite triggers even if rule suppression is active, i.e. `// scalafix:ok` is present.
138140

139141
The first improvement we make is to handle both `true` and `false` literals.
140142

@@ -248,14 +250,26 @@ a non-empty parameter list.
248250
+ }
249251
```
250252

251-
The final step is to extract the parameter at the index of the argument
253+
The next step is to extract the parameter at the index of the argument
252254

253255
```scala
254256
val parameter = method.parameterLists.head(i)
255257
val parameterName = parameter.displayName
256258
Patch.addLeft(t, s"$parameterName = ")
257259
```
258260

261+
We're not done quite yet, because the rule does not respect rule suppression comments like `// scalafix:ok`. Let's add a test case to reproduce this bug
262+
263+
```scala
264+
complete(false) // scalafix:ok; rule suppression
265+
```
266+
267+
We can fix this bug by specifying that `Patch.addLeft` should be `atomic`
268+
269+
```scala
270+
Patch.addLeft(t, s"$parameterName = ").atomic
271+
```
272+
259273
That completes the `NamedLiteralArguments` rule! Run all tests and we see they
260274
pass. Putting it together, the final code for the rule looks like this
261275

@@ -280,7 +294,7 @@ class NamedLiteralArguments
280294
if method.parameterLists.nonEmpty =>
281295
val parameter = method.parameterLists.head(i)
282296
val parameterName = parameter.displayName
283-
Patch.addLeft(t, s"$parameterName = ")
297+
Patch.addLeft(t, s"$parameterName = ").atomic
284298
case _ =>
285299
// Do nothing, the symbol is not a method with matching signature
286300
Patch.empty
@@ -358,6 +372,7 @@ package test
358372
class NoLiteralArguments {
359373
def complete(isSuccess: Boolean): Unit = ()
360374
complete(true) // assert: NoLiteralArguments
375+
complete(true) // scalafix:ok; should not assert
361376
}
362377
```
363378

@@ -377,7 +392,7 @@ doc.tree.collect {
377392
}.flatten.asPatch
378393
```
379394

380-
Finally, to report a diagnostic we use `Patch.lint`
395+
Finally, to report a diagnostic we use `Patch.lint` (which supports rule suppression comments out of the box)
381396

382397
```scala
383398
Patch.lint(LiteralArgument(t))
@@ -388,6 +403,7 @@ to make sure the position and message of the diagnostic make sense
388403

389404
```diff
390405
complete(true) // assert: NoLiteralArguments
406+
complete(true) // scalafix:ok; should not assert
391407
+ complete(false) /* assert: NoLiteralArguments
392408
+ ^^^^^
393409
+ Use named arguments for literals such as 'parameterName = false'
@@ -434,6 +450,7 @@ class NoLiteralArgumentsConfig {
434450
complete("done") // ok, no error message
435451
complete(42) // assert: NoLiteralArguments
436452
complete(true) // assert: NoLiteralArguments
453+
complete(true) // scalafix:ok; rule suppression
437454
}
438455
```
439456

0 commit comments

Comments
 (0)