fix: nimcheck improvements for generics, JS operators, Python 3.10+ syntax

- Add tolerantMode for generic Nim code with < > brackets
- Fix JS ?. and ?? operator tokenization
- Add Python 3.10 match/case keywords, underscore prefix support
- Fix f-string parsing operator precedence bug
- Fix duplicate foundClosing assignments in JS/PHP tokenizers
- Treat unknown flavors as info instead of error
- Add comprehensive test coverage for all fixes
This commit is contained in:
2026-07-15 11:14:29 +02:00
parent 9f50fd7e37
commit f3ad8e64c8
16 changed files with 137 additions and 36 deletions
+3
View File
@@ -1,2 +1,5 @@
#!/usr/bin/env bash
echo "Hello, world!"
if [[ "$a" = "$b" ]]; then
echo "a equals b"
fi
+2
View File
@@ -1,3 +1,5 @@
function greet(name) {
return `Hello, ${name}!`;
}
const x = obj?.prop ?? 'default';
+14
View File
@@ -0,0 +1,14 @@
## Nim code with generics - should validate cleanly (no false "Unclosed '<'")
proc jarray[T](node: T): T =
result = node
proc pair[A, B](a: A, b: B): (A, B) =
(a, b)
proc findIf[T](items: seq[T], pred: proc(x: T): bool): Option[T] =
for item in items:
if pred(item):
return some(item)
proc compare[T](a, b: T): bool =
a < b and b > a
+9
View File
@@ -1,2 +1,11 @@
def hello(name: str) -> str:
return f"Hello, {name}!"
def process(value):
match value:
case 1:
return 'one'
case _:
return 'other'
_private_var = 42
+15
View File
@@ -144,3 +144,18 @@ suite "JavaScript Exhaustive Tests":
let src = "const big = 9007199254740991n;\n"
let result = validateSource(src, flavor = lfJavaScript)
check result.errors.len >= 0
test "nullish coalescing operator ?? working":
let src = "const x = a ?? b ?? c;\n"
let result = validateSource(src, flavor = lfJavaScript)
check result.errors.len == 0
test "optional chaining ?. operator working":
let src = "const x = obj?.prop?.nested;\n"
let result = validateSource(src, flavor = lfJavaScript)
check result.errors.len == 0
test "combined ?. and ?? operators":
let src = "const x = obj?.prop ?? 'default';\n"
let result = validateSource(src, flavor = lfJavaScript)
check result.errors.len == 0
+35
View File
@@ -164,3 +164,38 @@ suite "Nim Exhaustive Tests":
let src = "proc test() =\n ##[ this is a doc comment\n that never ends\n discard\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len >= 0 # May not detect ##[ unclosed
test "generic proc with type parameter":
let src = "proc jarray[T](node: T): T =\n result = node\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len == 0
test "generic proc with multiple type params and comparisons":
let src = "proc compare[T](a, b: T): bool =\n a < b and b > a\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len == 0
test "generic proc with Option[T]":
let src = "proc findIf[T](items: seq[T], pred: proc(x: T): bool): Option[T] =\n for item in items:\n if pred(item):\n return some(item)\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len == 0
test "template with generics":
let src = "template wrap[T](x: T): T = x\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len == 0
test "chained comparisons with < >":
let src = "let x = 1 < 2 and 3 > 2 and 4 >= 1 and 5 <= 10\n"
let result = validateSource(src, flavor = lfNim)
check result.errors.len == 0
test "valid .nim file with generics":
let result = validateFile("tests/fixtures/nim/with_generics.nim")
check result.errors.len == 0
test "tolerant mode with false angle bracket":
let opts = newValidationOptions(tolerantMode = true)
let src = "proc jarray[T](node: T): T =\n result = node\n"
let result = validateSource(src, flavor = lfNim, options = opts)
check result.errors.len == 0
+5
View File
@@ -149,3 +149,8 @@ suite "Python Exhaustive Tests":
let src = "s = \"line1\\\nline2\\\nline3\"\n"
let result = validateSource(src, flavor = lfPython)
check result.errors.len >= 0
test "underscore private convention":
let src = "_private = 42\n"
let result = validateSource(src, flavor = lfPython)
check result.errors.len == 0