yutu 0.1.1

Modern Lua linter
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# Lints

| code | default level | category | message |
|---|---|---|---|
| [`almost-swap`]#almost-swap |`deny` | `correctness` | code sequence almost implements a swap |
| [`approx-pi`]#approx-pi | ⚠️ `warn` | `correctness` | numeric literal is approximatly pi |
| [`bool-compare`]#bool-compare | ⚠️ `warn` | `complexity` | comparison with bool constant can be simplfied |
| [`cyclomatic-complexity`]#cyclomatic-complexity | ⚠️ `warn` | `restriction` | cyclomatic complexity of function is too high |
| [`empty-block`]#empty-block | ⚠️ `warn` | `suspicious` | empty block in control flow statement |
| [`empty-statement`]#empty-statement | ⚠️ `warn` | `style` | empty statement |
| [`error-prone-negation`]#error-prone-negation | ⚠️ `warn` | `suspicious` | negation is executed before relational operator |
| [`hex-int-overflow`]#hex-int-overflow | ⚠️ `warn` | `complexity` | overflow in integer literal |
| [`inconsistent-indentation`]#inconsistent-indentation | ⚠️ `warn` | `restriction` | indentation contains tabs after spaces |
| [`inexact-hex-float`]#inexact-hex-float | ⚠️ `warn` | `correctness` | cannot exactly represent hexadecimal float in 64 bit |
| [`invisible-characters`]#invisible-characters |`deny` | `suspicious` | code contains invisible Unicode characters |
| [`line-too-long`]#line-too-long | ⚠️ `warn` | `restriction` | line is too long |
| [`lower-case-global`]#lower-case-global | ⚠️ `warn` | `suspicious` | global variable in lower-case initial |
| [`next-line-args`]#next-line-args | ⚠️ `warn` | `suspicious` | arguments of called function start in next line |
| [`non-ascii-literal`]#non-ascii-literal |`allow` | `restriction` | string literal contains non-ASCII character |
| [`octal-confusion`]#octal-confusion | ⚠️ `warn` | `complexity` | zero prefixed integer can be confused as octal number |
| [`only-whitespace`]#only-whitespace | ℹ️ `hint` | `style` | line contains only whitespace |
| [`redefined-local`]#redefined-local |`allow` | `pedantic` | redefined local |
| [`redundant-local`]#redundant-local | ⚠️ `warn` | `suspicious` | redundant redefinition of a local |
| [`redundant-parentheses`]#redundant-parentheses | ⚠️ `warn` | `complexity` | expression contains redundant parentheses |
| [`rounds-int-part`]#rounds-int-part | ⚠️ `warn` | `correctness` | integral part of numeric literal will be rounded |
| [`rounds-to-inf`]#rounds-to-inf | ⚠️ `warn` | `correctness` | numeric literal rounds to infinity |
| [`shadowing-local`]#shadowing-local |`allow` | `pedantic` | shadowing local |
| [`too-many-lines`]#too-many-lines | ⚠️ `warn` | `complexity` | function contains too many lines |
| [`too-many-parameters`]#too-many-parameters | ⚠️ `warn` | `complexity` | function has too many parameters |
| [`trailing-whitespace`]#trailing-whitespace | ℹ️ `hint` | `style` | line contains trailing whitespace |
| [`unbalanced-assignment`]#unbalanced-assignment | ⚠️ `warn` | `suspicious` | unexpected number of expressions on right side of assignment |
| [`unbalanced-initialization`]#unbalanced-initialization | ⚠️ `warn` | `suspicious` | unexpected number of expressions on right side of initialization |
| [`unconditional-recursion`]#unconditional-recursion |`deny` | `correctness` | unconditional recursion in function |
| [`unicode-code-point-is-surrogate`]#unicode-code-point-is-surrogate | ⚠️ `warn` | `correctness` | Unicode code point is a surrogate |
| [`unicode-code-point-too-large`]#unicode-code-point-too-large | ⚠️ `warn` | `correctness` | Unicode code point is too large |
| [`unnecessary-negation`]#unnecessary-negation | ⚠️ `warn` | `complexity` | negation of relational expression can be simplified |
| [`unreachable-code`]#unreachable-code | ⚠️ `warn` | `suspicious` | unreachable code |
| [`unused-label`]#unused-label | ⚠️ `warn` | `suspicious` | unused label |
| [`unused-local`]#unused-local | ⚠️ `warn` | `suspicious` | unused local |
| [`unused-loopvar`]#unused-loopvar | ⚠️ `warn` | `suspicious` | unused loop variable |
| [`unused-parameter`]#unused-parameter | ⚠️ `warn` | `suspicious` | unused parameter |
| [`unused-vararg`]#unused-vararg | ⚠️ `warn` | `suspicious` | unused variable length argument |
| [`used-despite-unused-hint`]#used-despite-unused-hint | ⚠️ `warn` | `suspicious` | used declaration with unused hint |

## almost-swap
❌ `deny` - `correctness`
### What it does
Checks for code that almost implements a swap operation.

### Why restrict this?
This is most likely a mistake as the second assignment serves no purpose.

### Example
The following code does not swap `a` and `b`.
```lua
a = b
b = a
```
Use this code instead.
```lua
a, b = b, a
```

## approx-pi
⚠️ `warn` - `correctness`
### What it does
Checks for floating point literals that approximate pi (π), which is already defined in `math`.

### Why restrict this?
Usually the standard library definition is more precise.

### Example
```lua
local radius = 42
local area = 3.141 * radius ^ 2
```
Use this code instead.
```lua
local radius = 42
local area = math.pi * radius ^ 2
```

## bool-compare
⚠️ `warn` - `complexity`
### What it does
Checks if a boolean value is compared to a boolean literal.

### Why restrict this?
It is usually clearer to just use the boolean value or its negation.

### Example
```lua
local is_ok = true
if is_ok == true then
    -- do something
end
```
Use this code instead.
```lua
local is_ok = true
if is_ok then
    -- do something
end
```

## cyclomatic-complexity
⚠️ `warn` - `restriction`
### What it does
Checks if the cyclomatic complexity of a function exceeds the threshold configured in `cyclomatic_complexity_threshold`.

### Why restrict this?
Functions with high cyclomatic complexity can be hard to understand and may be candidates for a refactoring.

### Known problems
Due to missing switch statements Lua code sometimes requires long `if`-`elseif` chains. Such chains can be easy to understand, if the structure is very regular, but they would still result in a high cyclomatic complexity.

### Example
```lua
function foo()
    if x1 == 0 then
        -- do something
    end
    if x2 == 0 then
        -- do something
    end
    -- ...
    if x100 == 0 then
        -- do something
    end
end
```

## empty-block
⚠️ `warn` - `suspicious`
### What it does
Checks if a block contains no statements.

### Why restrict this?
It usually makes sense to at least explain why a block is empty. Otherwise it could indicate that this was a mistake.

The warning can be suppressed by adding a comment inside the block.

### Example
```lua
if a then
else
    print(42)
end
```

## empty-statement
⚠️ `warn` - `style`
### What it does
Checks for consecutive semicolons.

### Why restrict this?
This is most likely a typing mistake.

### Example
```lua
print("hello");;
```

## error-prone-negation
⚠️ `warn` - `suspicious`
### What it does
Checks for combinations of negations and relational expressions which are likely unintended.

### Why restrict this?
Negation has a higher precedence than binary operators. Omitting parentheses is likely a mistake, as boolean expressions usually require no comparisons.

### Example
```lua
if not a > b then
    -- do something
end
```

## hex-int-overflow
⚠️ `warn` - `complexity`
### What it does
Checks if a hexadecimal integer literal is too large for a signed 64 bit integer value.

### Why restrict this?
In Lua hexadecimal integer literals are truncated if they are too large.

### Example
```lua
local _ = 0x10000000000000000 -- actual value is 0
```

## inconsistent-indentation
⚠️ `warn` - `restriction`
### What it does
Checks for tabs after spaces.

### Why restrict this?
Using tabs after spaces is not useful.

## inexact-hex-float
⚠️ `warn` - `correctness`
### What it does
Checks if a hexadecimal float literal can be represented exactly as a 64 bit IEEE-754 float value.

### Why restrict this?
This is very likely unintended behavior, as the main use case of hexadecimal float literals is to exactly specify values.

### Example
```lua
local _ = 0x1.p9999
```

## invisible-characters
❌ `deny` - `suspicious`
### What it does
Checks for invisible Unicode characters in the code.

### Why restrict this?
There is no valid use case for invisible Unicode characters in your code.

## line-too-long
⚠️ `warn` - `restriction`
### What it does
Checks if the number of columns in a line exceeds the threshold configured in `line_length_threshold `.

### Why restrict this?
Lines that are to long are hard to understand.

## lower-case-global
⚠️ `warn` - `suspicious`
### What it does
Checks for global variables with lower-case initial letter.

### Why restrict this?
By convention in Lua globals start with an upper-case letter.

### Example
```lua
a = 42
```

## next-line-args
⚠️ `warn` - `suspicious`
### What it does
Checks if the argument list of a function calls start in the next line.

### Why restrict this?
Lua requires no semicolons between statements, so some opening parentheses can unexpectedly be interpreted as the start of the argument list of a function call.

### Example
```lua
a = b + c
(print or io.write)('done')
```

## non-ascii-literal
✅ `allow` - `restriction`
### What it does
Checks for non-ASCII characters in string literals.

### Why restrict this?
Some editors may not work well with certain Unicode symbols, so using escape sequences instead could be useful.

### Example
```lua
local _ = "€"
```
Use this code instead.
```lua
local _ = "\u{20ac}"
```

## octal-confusion
⚠️ `warn` - `complexity`
### What it does
Checks if a decimal integer literal has a leading zero.

### Why restrict this?
In C such literals are octal numbers, so some people may expect the same to be true in Lua. As there is no use for such a prefix, it can safely be removed to avoid confusion.

### Example
```lua
local _ = 042
```

## only-whitespace
ℹ️ `hint` - `style`
### What it does
Checks if a line only contains whitespaces.

### Why restrict this?
Lines with only whitespaces serve no purpose. They are most likely added due to a typing or editing mistake.

## redefined-local
✅ `allow` - `pedantic`
### What it does
Checks for redefinitions of local variables.

### Why restrict this?
Redefinitions of local variables can make it harder to understand the code.

### Known problems
There are commonly used patterns that will result in warnings.

```lua
local val, err = foo();
if err then
    print(err)
end

local val, err = bar(); -- redefined local
if err then
    print(err)
end
```

### Example
```lua
local a = 42
print(a)

local a = 100 -- redefined local
print(a)
```

## redundant-local
⚠️ `warn` - `suspicious`
### What it does
Checks for redundant redefinitions of local variables.

### Why restrict this?
Redundant redefinitions of local variables have no effect and are thus likely to be unintended.

### Example
```lua
local a = 0;
local a = a;
```

## redundant-parentheses
⚠️ `warn` - `complexity`
### What it does
Checks for parentheses inside of parentheses.

### Why restrict this?
Double parentheses indicate that there might be a mistake. They can be removed without changing the semantics of the code.

### Example
```lua
local _ = ((20 + 1)) * 2
```

## rounds-int-part
⚠️ `warn` - `correctness`
### What it does
Checks if the value of a numeric literal is too large for its integral part to be represented exactly as a 64 bit IEEE-754 float value.

### Why restrict this?
This is very likely unintended behavior and may result in logic bugs.

### Example
```lua
local a = 100000000000000000000000 -- the actual value is 99999999999999991611392.0
local b = 100000000000000000000001 -- rounded to same value
print(a < b) -- false
```

## rounds-to-inf
⚠️ `warn` - `correctness`
### What it does
Checks if the value of a numeric literal is so large that it would be rounded to infinity.

### Why restrict this?
Using the standard library definition is more clear.

### Example
```lua
local inf = 2e1000
```
Use this code instead.
```lua
local inf = math.huge
```

## shadowing-local
✅ `allow` - `pedantic`
### What it does
Checks for locals that shadow locals in a surrounding scope.

### Why restrict this?
This can lead to confusion, when one tries to change the other variable in the inner scope.

### Known problems
Like with [redefined-local](#redefined-local) there are some commonly used patterns that will result in warnings.

### Example
```lua
local a = 0
if b then
    -- ...
    local a = 0 -- shadowing local
    -- ...
    a = 100
end
print(a)
```

## too-many-lines
⚠️ `warn` - `complexity`
### What it does
Checks if the number of lines in a function exceeds the threshold configured in `function_line_threshold`.

### Why restrict this?
Functions with too many lines can be hard to understand.

### Example
```lua
function foo()
    local a
    -- 1000 more lines which may modify a
    print(a)
end
```

## too-many-parameters
⚠️ `warn` - `complexity`
### What it does
Checks if the number of function parameters exceeds the threshold configured in `parameter_threshold`.

### Why restrict this?
Functions with too many parameters can be hard to understand.

### Example
```lua
function foo(a, b, c, d, e, f, g, h, i, j)
    print(a, b, c, d, e, f, g, h, i, j)
end
```

## trailing-whitespace
ℹ️ `hint` - `style`
### What it does
Checks for trailing whitespaces in a line.

### Why restrict this?
Trailing whitespaces serve no purpose. They are most likely added due to a typing or editing mistake.

## unbalanced-assignment
⚠️ `warn` - `suspicious`
### What it does
Checks if the left and right side of an assignment have the same number of expressions.

### Why restrict this?
Extra left-hand side values will be assigned `nil` which might be unintended. Extra right-hand side values will be ignored which indicates a mistake.

### Example
```lua
A, B = 42 -- B is assigned nil
C, D = 1, 2, 3 -- 3 is ignored
```

## unbalanced-initialization
⚠️ `warn` - `suspicious`
### What it does
Checks if the left and right side of an assignment have the same number of names and expressions.

### Why restrict this?
Extra left-hand side values will be assigned `nil` which might be unintended. Extra right-hand side values will be ignored which indicates a mistake.

### Example
```lua
local a, b = 42 -- b is assigned nil
local c, d = 1, 2, 3 -- 3 is ignored
```

## unconditional-recursion
❌ `deny` - `correctness`
### What it does
Checks for functions that are unconditionally recursive.

### Why restrict this?
Such functions will never return and may overflow the stack, which is most likely unintended.

### Example
```lua
local function foo()
    foo()
end
foo()
```

## unicode-code-point-is-surrogate
⚠️ `warn` - `correctness`
### What it does
Checks for Unicode escape sequences with values between `0xD800` and `0xDFFF`.

### Why restrict this?
Lua allows unpaired surrogates. As these are invalid Unicode scalar values they should usually be avoided.

### Example
```lua
local _ = "\u{D800}"
```

## unicode-code-point-too-large
⚠️ `warn` - `correctness`
### What it does
Checks for Unicode escape sequences with values larger than `0x10FFFF`.

### Why restrict this?
Lua allows such invalid Unicode code points. As these are however not mapped to a valid Unicode scalar value they should usually be avoided.

### Example
```lua
local _ = "\u{110000}"
```

## unnecessary-negation
⚠️ `warn` - `complexity`
### What it does
Checks for combinations of negations and relational expressions which can be simplified.

### Why restrict this?
This makes the code more readable.

### Known problems
If one operand is a NaN value the simplification is not always correct.

### Example
```lua
if not (a > b) then
    -- do something
end
```
Use this code instead.
```lua
if a <= b then
    -- do something
end
```

## unreachable-code
⚠️ `warn` - `suspicious`
### What it does
Checks for code that can never be reached during execution.

### Why restrict this?
Unreachable code can be removed without changing the semantics of the code.

### Example
```lua
goto bar
print("foo") -- unreachable code
::bar::
print("bar")
```

## unused-label
⚠️ `warn` - `suspicious`
### What it does
Checks for labels that are never used by a `goto` statement.

### Why restrict this?
This is likely due to a mistake or refactoring. The label can be removed without changing the semantics of the code.

### Example
```lua
function loop()
    local i = 0;
    ::foo::
    print(i)
    i = i + 1
    if i == 100 then
        -- forgot to use label
    end
    goto foo
    ::bar:: -- unused label
    return
end
```

## unused-local
⚠️ `warn` - `suspicious`
### What it does
Checks for locals that are never used.

### Why restrict this?
An unused local indicates, that it was either unknowingly unused or later became unused due to a refactoring. It can be safely be removed without changing the semantics of the code.

The warning can be locally ignored by adding a `_` prefix if `allow_local_unused_hint` is configured as `true`. Otherwise it can also be ignored by using `_` as the name.

### Example
```lua
local a = 42
```

## unused-loopvar
⚠️ `warn` - `suspicious`
### What it does
Checks for loop variables that are never used.

### Why restrict this?
An unused loop variable indicates, that it was either unknowingly unused or later became unused due to a refactoring.

The warning can be locally ignored by adding a `_` prefix if `allow_loopvar_unused_hint` is configured as `true`. Otherwise it can also be ignored by using `_` as the name.

### Example
```lua
for i = 0, 10 do
    print(42)
end
```

## unused-parameter
⚠️ `warn` - `suspicious`
### What it does
Checks for parameters that are never used.

### Why restrict this?
An unused parameter indicates, that it was either unknowingly unused or later became unused due to a refactoring.

The warning can be locally ignored by adding a `_` prefix.

### Example
```lua
function foo(a, b)
    print(a)
end
```

## unused-vararg
⚠️ `warn` - `suspicious`
### What it does
Checks for unused variable length arguments.

### Why restrict this?
This is likely a mistake, as there is otherwise no reason to add the `...` parameter.

### Example
```lua
function foo(a, ...)
    print(a)
end
```

## used-despite-unused-hint
⚠️ `warn` - `suspicious`
### What it does
Checks if a declaration with an unused hint (`_` prefix) was used.

### Why restrict this?
If a variable is actually used, the hint should be removed, so mistakes in later changes can be detected.

### Example
```lua
local _a = 42
print(_a)
```