|
58 | 58 | val location = context.getLocation(element) |
59 | 59 | context.report(TEST_ISSUE, element, location, message) |
60 | 60 | } |
61 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 61 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
62 | 62 |
|
63 | 63 | All this simple detector does is flag any usage associated with the |
64 | 64 | given annotation, including some information about the usage. |
|
73 | 73 | @MyAnnotation fun close() = TODO() |
74 | 74 | } |
75 | 75 | operator fun Book.get(@MyAnnotation index: Int): Int = TODO() |
76 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 76 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
77 | 77 |
|
78 | 78 | ...and we then run the above detector on the following test case: |
79 | 79 |
|
|
83 | 83 | val firstWord = book[0] |
84 | 84 | book.close() |
85 | 85 | } |
86 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 86 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
87 | 87 |
|
88 | 88 | we get the following output: |
89 | 89 |
|
|
97 | 97 | src/book.kt:16: Error: METHOD_CALL usage associated with @MyAnnotation on METHOD |
98 | 98 | book.close() |
99 | 99 | ------- |
100 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 100 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
101 | 101 |
|
102 | 102 | In the first case, the infix operator “in” will call `contains` under |
103 | 103 | the hood, and here we've annotated the parameter, so lint visits the |
|
150 | 150 | open class Paperback : Book() { |
151 | 151 | override fun close() { } |
152 | 152 | } |
153 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 153 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
154 | 154 |
|
155 | 155 | then the detector will emit the following incident since the new method |
156 | 156 | overrides another method that was annotated: |
|
160 | 160 | override fun close() { } |
161 | 161 | ----- |
162 | 162 | 1 errors, 0 warnings |
163 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 163 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
164 | 164 |
|
165 | 165 | Overriding an annotated element is how the `@CallSuper` detector is |
166 | 166 | implemented, which makes sure that any method which overrides a method |
|
184 | 184 | } |
185 | 185 | } |
186 | 186 | } |
187 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 187 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
188 | 188 |
|
189 | 189 | Here, lint will flag the various exit points from the method |
190 | 190 | associated with the annotation: |
|
197 | 197 | return getDefaultCaption() |
198 | 198 | ------------------- |
199 | 199 | 2 errors, 0 warnings |
200 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 200 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
201 | 201 |
|
202 | 202 | Note also that this would have worked if the annotation had been |
203 | 203 | inherited from a super method instead of being explicitly set here. |
|
231 | 231 | return type != AnnotationUsageType.METHOD_OVERRIDE && |
232 | 232 | super.isApplicableAnnotationUsage(type) |
233 | 233 | } |
234 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 234 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
235 | 235 |
|
236 | 236 | !!! Tip |
237 | 237 | Notice how we are also calling `super` here and combining the result |
|
249 | 249 | return type != AnnotationUsageType.BINARY && |
250 | 250 | type != AnnotationUsageType.EQUALITY |
251 | 251 | } |
252 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 252 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
253 | 253 |
|
254 | 254 | These usage types apply to cases where annotated elements are |
255 | 255 | compared for equality or using other binary operators. Initially |
|
277 | 277 | src/test/pkg/HalfFloatTest.java:50: Error: Half-float type in expression widened to int [HalfFloat] |
278 | 278 | Math.round(float1); // Error: should use Half.round |
279 | 279 | ------ |
280 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 280 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
281 | 281 |
|
282 | 282 | ### Scopes |
283 | 283 |
|
|
303 | 303 | abstract override fun pop(): String |
304 | 304 | } |
305 | 305 | } |
306 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 306 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
307 | 307 |
|
308 | 308 | And the following test case: |
309 | 309 |
|
|
314 | 314 | fileStack.push("Hello") |
315 | 315 | fileStack.pop() |
316 | 316 | } |
317 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 317 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
318 | 318 |
|
319 | 319 | Here, `stack.push` call on line 2 resolves to the API method on line 7. |
320 | 320 | That method is not annotated, but it's inside a class that is annotated |
|
367 | 367 | // outer @CheckReturnValue annotation we're analyzing here |
368 | 368 | return |
369 | 369 | } |
370 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 370 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
371 | 371 |
|
372 | 372 | !!! Tip |
373 | 373 | You only have to worry about this when there are different |
|
418 | 418 | // Require restriction annotations to be annotated everywhere |
419 | 419 | return false |
420 | 420 | } |
421 | | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 421 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
422 | 422 |
|
423 | 423 | (Note that the API passes in the fully qualified name of the annotation |
424 | 424 | in question so you can control this behavior individually for each |
|
0 commit comments