What
func_start's method-shorthand branch (the one that matches ES6/Java/C#-style bare name(...) { method definitions with no leading keyword) has no requirement that the match is actually followed by {. Any statement that merely starts a line with identifier( -- i.e. any bare function call used as a statement -- matches as if it were a function/method definition.
This is the exact defect class the args regex's own comment already names and fixed for several of these same languages (see javascript's args rule in language_standards.py):
FIX 1 (Invocation Shield): Injected (?=[ \t\n]*\{) at the end of the class method branch, demanding structural proof that the signature opens a logic block.
func_start's equivalent branch never got the same treatment, so it's still open to the false-positive args was explicitly hardened against.
Repro (regex-level, works for any of the 7 affected languages)
from gitgalaxy.standards.language_standards import LANGUAGE_DEFINITIONS
fs = LANGUAGE_DEFINITIONS["javascript"]["rules"]["func_start"]
fs.search("next();").group(0) # -> 'next' (should be None -- this is a call, not a definition)
fs.search(" next();").group(0) # -> ' next' (same, indented)
javascript's current func_start pattern (method-shorthand branch is the last alternative):
(?:\b(?:async\s+)?function\s*\*?\s+[a-zA-Z_$][\w$]*(?=\s*\()|\b[a-zA-Z_$][\w$]*(?=[ \t\n]*=[ \t\n]*(?:async\s*)?(?:function(?:\s*\*)?\b|\([^)]*\)[ \t\n]*=>|[a-zA-Z_$][\w$]*[ \t\n]*=>))|^[ \t]*[a-zA-Z_$][\w$]*(?=[ \t\n]*:[ \t\n]*(?:async\s*)?(?:function(?:\s*\*)?\b|\([^)]*\)[ \t\n]*=>|[a-zA-Z_$][\w$]*[ \t\n]*=>))|^[ \t]*(?:static[ \t\n]+)?(?:async[ \t\n]+)?(?:get\s+|set\s+)?\*?(?!(?:if|for|while|switch|catch|return|throw|new|typeof|jQuery|function)\b|\$)#?[a-zA-Z_$][\w$]*(?=\s*\())
Note the final alternative's lookahead is just (?=\s*\() -- no trailing { requirement, unlike args' equivalent branch which has (?=[ \t\n]*\{).
Confirmed on real production code, not just synthetic snippets
Building a tree-sitter-based ground-truth accuracy pass for JavaScript (mirroring ast_accuracy_audit.py's Python methodology, #1200) against expressjs/express (v5.2.1, full repo, 43 JS files): 9 of 59 "functions" GitGalaxy reported (≈15%) were phantom call-sites, not real definitions -- found_functions=50, extra_functions=9, i.e. function precision ≈84.7% on this corpus. Every single extra was a bare-call statement whose name happened to start a line:
benchmarks/middleware.js, examples/auth/index.js, examples/error/index.js, examples/params/index.js, examples/route-middleware/index.js, examples/route-separation/user.js -- all report a phantom function named next, from the extremely common Express middleware idiom next(); as a statement (see e.g. examples/auth/index.js:38,77).
examples/auth/index.js also reports a phantom function named hash, from hash({ password: 'foobar' }, function (err, pass, salt, hash) { (examples/auth/index.js:50) -- a call to a require()'d function that starts the line.
examples/view-constructor/index.js reports a phantom fn.
Because next(...)/similar callback-invocation idioms are near-universal in real JS/TS/Java/C#/Groovy/Dart/Apex code (any statement-position function or method call, not just Express middleware), this is not an edge case -- it's a systemic precision hit on any real corpus in the affected languages.
Affected languages (confirmed via the same regex-level repro)
Checked every language with a func_start rule; these 7 all match next(); where they shouldn't:
javascript, typescript, java, csharp, apex, dart, groovy
Not affected (their method-shorthand branch, if present, already requires more structural proof, or they don't have this branch shape at all): c, cpp, rust, go, php, ruby, perl, lua, solidity, powershell, kotlin, scala, swift.
Note this affected-language list is a different grouping than #1209's (which was about the args regex's missing capture group) -- e.g. ruby/powershell had the args bug but don't have this one; apex/dart didn't have the args bug in this form but do have this one. Different defect, different structural precondition (whether func_start's method-shorthand branch has a trailing-brace lookahead), just the same underlying category of bug (a signature-shaped call site vs. a real definition) and the same proven fix shape already sitting in this codebase's own args regex.
Suggested fix
For each of the 7 languages, add the same (?=[ \t\n]*\{) (or language-appropriate equivalent, e.g. Java/C# also allow a leading throws/generic-bounds clause before {) to the end of func_start's method-shorthand branch, mirroring args' own "Invocation Shield" fix in the same file. Needs the usual per-language care this repo's func_start changes get: verify against real one-liner/multi-line legitimate method definitions in each language aren't broken by the added lookahead (e.g. Java/C# methods can have a throws/where clause between ) and {), a ReDoS scaling sweep on the changed branch, and a golden-master diff via crucible_check.py per the Differential Scan protocol before merging.
Not in scope here
What
func_start's method-shorthand branch (the one that matches ES6/Java/C#-style barename(...) {method definitions with no leading keyword) has no requirement that the match is actually followed by{. Any statement that merely starts a line withidentifier(-- i.e. any bare function call used as a statement -- matches as if it were a function/method definition.This is the exact defect class the
argsregex's own comment already names and fixed for several of these same languages (see javascript'sargsrule inlanguage_standards.py):func_start's equivalent branch never got the same treatment, so it's still open to the false-positiveargswas explicitly hardened against.Repro (regex-level, works for any of the 7 affected languages)
javascript's current
func_startpattern (method-shorthand branch is the last alternative):Note the final alternative's lookahead is just
(?=\s*\()-- no trailing{requirement, unlikeargs' equivalent branch which has(?=[ \t\n]*\{).Confirmed on real production code, not just synthetic snippets
Building a tree-sitter-based ground-truth accuracy pass for JavaScript (mirroring
ast_accuracy_audit.py's Python methodology, #1200) againstexpressjs/express(v5.2.1, full repo, 43 JS files): 9 of 59 "functions" GitGalaxy reported (≈15%) were phantom call-sites, not real definitions --found_functions=50, extra_functions=9, i.e. function precision ≈84.7% on this corpus. Every single extra was a bare-call statement whose name happened to start a line:benchmarks/middleware.js,examples/auth/index.js,examples/error/index.js,examples/params/index.js,examples/route-middleware/index.js,examples/route-separation/user.js-- all report a phantom function namednext, from the extremely common Express middleware idiomnext();as a statement (see e.g.examples/auth/index.js:38,77).examples/auth/index.jsalso reports a phantom function namedhash, fromhash({ password: 'foobar' }, function (err, pass, salt, hash) {(examples/auth/index.js:50) -- a call to arequire()'d function that starts the line.examples/view-constructor/index.jsreports a phantomfn.Because
next(...)/similar callback-invocation idioms are near-universal in real JS/TS/Java/C#/Groovy/Dart/Apex code (any statement-position function or method call, not just Express middleware), this is not an edge case -- it's a systemic precision hit on any real corpus in the affected languages.Affected languages (confirmed via the same regex-level repro)
Checked every language with a
func_startrule; these 7 all matchnext();where they shouldn't:javascript,typescript,java,csharp,apex,dart,groovyNot affected (their method-shorthand branch, if present, already requires more structural proof, or they don't have this branch shape at all):
c,cpp,rust,go,php,ruby,perl,lua,solidity,powershell,kotlin,scala,swift.Note this affected-language list is a different grouping than #1209's (which was about the
argsregex's missing capture group) -- e.g.ruby/powershellhad the args bug but don't have this one;apex/dartdidn't have the args bug in this form but do have this one. Different defect, different structural precondition (whetherfunc_start's method-shorthand branch has a trailing-brace lookahead), just the same underlying category of bug (a signature-shaped call site vs. a real definition) and the same proven fix shape already sitting in this codebase's ownargsregex.Suggested fix
For each of the 7 languages, add the same
(?=[ \t\n]*\{)(or language-appropriate equivalent, e.g. Java/C# also allow a leadingthrows/generic-bounds clause before{) to the end offunc_start's method-shorthand branch, mirroringargs' own "Invocation Shield" fix in the same file. Needs the usual per-language care this repo'sfunc_startchanges get: verify against real one-liner/multi-line legitimate method definitions in each language aren't broken by the added lookahead (e.g. Java/C# methods can have athrows/whereclause between)and{), a ReDoS scaling sweep on the changed branch, and a golden-master diff viacrucible_check.pyper the Differential Scan protocol before merging.Not in scope here
argsregex itself is unaffected (it already has this shield for these languages, per fix(core): args regex capture group missing in 25 languages (regression from #1199 Python fix) #1209's own commit history) -- args-count accuracy for functions GitGalaxy did correctly find was 100% exact-match in the same express measurement pass, no issue there.func_startboundary/entity-extraction precision, a different failure mode than prism.py's line_exclusive comment stripper treats bare ';' and '%' as comment starts for every language in the family, not just the ones that use them #1193 (which is aboutcode_streamcorruption from comment-stripping) -- distinct root cause, filed separately.