fix(rules): make magic-number detection far less noisy

Real-world test on a 321-file TS/Svelte monorepo flagged 454 magic-number
findings, ~82% of them noise: literals already assigned to a named const/field
and numbers merely buried under a binary expression (e.g. a call arg inside a
string concat). Tighten all 5 languages to: (1) require the literal be a DIRECT
operand of a binary/comparison expression, and (2) exclude initializers of a
named binding (const/var/let/field). Cuts magic-number ~67% with no loss on
fixtures (each language still detects its genuine `x > 5000` case).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Giancarmine Salucci
2026-06-23 01:32:33 +02:00
co-authored by Claude Opus 4.8
parent 6fb2210bbe
commit 8324dde1a2
6 changed files with 41 additions and 38 deletions
+7 -6
View File
@@ -30,9 +30,10 @@ language: Go
severity: info
message: "Magic number in an expression — consider a named constant."
rule:
kind: int_literal
not:
regex: "^(0|1|2|10|100|1000)$"
inside:
kind: binary_expression
stopBy: end
all:
- kind: int_literal
- not: { regex: "^(0|1|2|10|100|1000)$" }
- inside: { kind: binary_expression }
# Skip literals already named via const/var declaration.
- not: { inside: { kind: const_spec, stopBy: end } }
- not: { inside: { kind: var_spec, stopBy: end } }
+6 -6
View File
@@ -30,9 +30,9 @@ language: Java
severity: info
message: "Magic number in an expression — consider a named constant."
rule:
kind: decimal_integer_literal
not:
regex: "^(0|1|2|10|100|1000)$"
inside:
kind: binary_expression
stopBy: end
all:
- kind: decimal_integer_literal
- not: { regex: "^(0|1|2|10|100|1000)$" }
- inside: { kind: binary_expression }
# Skip literals already named via field/variable declaration.
- not: { inside: { kind: variable_declarator, stopBy: end } }
+6 -6
View File
@@ -30,9 +30,9 @@ language: JavaScript
severity: info
message: "Magic number in an expression — consider a named constant."
rule:
kind: number
not:
regex: "^(0|1|2|-1|10|100|1000)$"
inside:
kind: binary_expression
stopBy: end
all:
- kind: number
- not: { regex: "^(0|1|2|-1|10|100|1000)$" }
- inside: { kind: binary_expression }
- not: { inside: { kind: variable_declarator, stopBy: end } }
- not: { inside: { kind: field_definition, stopBy: end } }
+6 -8
View File
@@ -33,11 +33,9 @@ language: Python
severity: info
message: "Magic number in an expression — consider a named constant."
rule:
kind: integer
not:
regex: "^(0|1|2|10|100|1000)$"
inside:
any:
- kind: binary_operator
- kind: comparison_operator
stopBy: end
all:
- kind: integer
- not: { regex: "^(0|1|2|10|100|1000)$" }
- inside: { any: [{ kind: binary_operator }, { kind: comparison_operator }] }
# Skip literals already named via assignment (e.g. `RETRIES = 5`).
- not: { inside: { kind: assignment, stopBy: end } }
+7 -6
View File
@@ -31,9 +31,10 @@ language: Rust
severity: info
message: "Magic number in an expression — consider a named constant."
rule:
kind: integer_literal
not:
regex: "^(0|1|2|10|100|1000)$"
inside:
kind: binary_expression
stopBy: end
all:
- kind: integer_literal
- not: { regex: "^(0|1|2|10|100|1000)$" }
- inside: { kind: binary_expression }
# Skip literals already named via `let`/`const`/`static` declaration.
- not: { inside: { kind: let_declaration, stopBy: end } }
- not: { inside: { kind: const_item, stopBy: end } }
+9 -6
View File
@@ -38,9 +38,12 @@ severity: info
message: "Magic number in an expression — consider a named constant."
metadata: { pattern: magic-number, apply_track: llm, difficulty: semantic }
rule:
kind: number
not:
regex: "^(0|1|2|-1|10|100|1000)$"
inside:
kind: binary_expression
stopBy: end
all:
- kind: number
- not: { regex: "^(0|1|2|-1|10|100|1000)$" }
# Must be a DIRECT operand of a comparison/arithmetic expression (e.g. `x > 5000`),
# not just buried under one (avoids flagging call args inside a concat, etc.).
- inside: { kind: binary_expression }
# Skip literals that already have a name: the value of `const X = ...` or a class field.
- not: { inside: { kind: variable_declarator, stopBy: end } }
- not: { inside: { kind: public_field_definition, stopBy: end } }