From 8324dde1a274d2618ad5315b4a8c960ce4306e83 Mon Sep 17 00:00:00 2001 From: Giancarmine Salucci Date: Tue, 23 Jun 2026 01:32:33 +0200 Subject: [PATCH] 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) --- rules/go/complexity.yml | 13 +++++++------ rules/java/complexity.yml | 12 ++++++------ rules/javascript/complexity.yml | 12 ++++++------ rules/python/complexity.yml | 14 ++++++-------- rules/rust/complexity.yml | 13 +++++++------ rules/typescript/complexity.yml | 15 +++++++++------ 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/rules/go/complexity.yml b/rules/go/complexity.yml index bf99931..39c4066 100644 --- a/rules/go/complexity.yml +++ b/rules/go/complexity.yml @@ -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 } } diff --git a/rules/java/complexity.yml b/rules/java/complexity.yml index 70e2c3d..505e9c6 100644 --- a/rules/java/complexity.yml +++ b/rules/java/complexity.yml @@ -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 } } diff --git a/rules/javascript/complexity.yml b/rules/javascript/complexity.yml index 980d606..402aa16 100644 --- a/rules/javascript/complexity.yml +++ b/rules/javascript/complexity.yml @@ -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 } } diff --git a/rules/python/complexity.yml b/rules/python/complexity.yml index 559904d..78e23b4 100644 --- a/rules/python/complexity.yml +++ b/rules/python/complexity.yml @@ -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 } } diff --git a/rules/rust/complexity.yml b/rules/rust/complexity.yml index 8745376..b96c800 100644 --- a/rules/rust/complexity.yml +++ b/rules/rust/complexity.yml @@ -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 } } diff --git a/rules/typescript/complexity.yml b/rules/typescript/complexity.yml index 0c8cd39..cacd7e2 100644 --- a/rules/typescript/complexity.yml +++ b/rules/typescript/complexity.yml @@ -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 } }