Skip to content

fix(detector,apex): exclude new from func_start/args return-type prefix - #1968

Merged
squid-protocol merged 1 commit into
mainfrom
fix-1963-apex-new-keyword-func-start
Aug 20, 2026
Merged

fix(detector,apex): exclude new from func_start/args return-type prefix#1968
squid-protocol merged 1 commit into
mainfrom
fix-1963-apex-new-keyword-func-start

Conversation

@squid-protocol

Copy link
Copy Markdown
Owner

Summary

Fixes #1963, found via the tri-comparison ledger sweep for apex.

  • Apex's func_start and args regexes both accepted any identifier-shaped token followed by
    whitespace at line-start as an eligible optional return-type/modifier prefix, with no exclusion
    for the new keyword.
  • A multi-line SObject-builder call (TestFactory.createSObject(\n new Account(name = 'X'),\n true\n)) had its new Account( line misparsed as a method definition named Account, with a
    bogus 1-parameter arg count.
  • tree-sitter never makes this mistake -- its grammar structurally distinguishes
    object_creation_expression from method_declaration.

Fix

(?!new\b) immediately before the optional prefix-consuming group in both func_start and
args, mirroring csharp's own GHOST ARGS SHIELD precedent -- csharp/java/groovy/dart already
exclude new from their equivalent prefix groups; apex was the one language in this family
missing it.

Verification

  • Local apex-recipes corpus: 0 remaining false positives, GitGalaxy's function count now
    matches tree-sitter exactly (38/38, zero name diffs; was 40/38 pre-fix).
  • tests/extraction/languages/test_apex.py + test_apex_strict.py: 97/97 pass.
  • crucible_check.py's ~80-repo differential scan surfaced a third, independent instance of
    the same bug (xml/apex/IterationRecipes_Tests.cls, 3 more occurrences inside a
    List<Account>{...} initializer) that neither the ledger sample nor the local corpus had
    shown -- also resolved by the same fix, confirming it generalizes correctly.
  • Golden master fixtures re-blessed via update_golden_master.py (both full-precision and
    zero-dependency modes) to reflect the intentional output change.
  • ruff_audit.py --ci / mypy_audit.py --ci: clean.

Also updates the tri-comparison ledger/chart/points-of-interest doc and
docs/language_status/apex.md's §9 to reflect the fix (previously committed as diagnosed-only).

Test plan

  • pytest tests/extraction/languages/test_apex.py tests/extraction/languages/test_apex_strict.py -- 97/97 pass
  • crucible_check.py -- both modes PASS after re-blessing
  • ruff_audit.py --ci / mypy_audit.py --ci -- clean
  • Manual verification: local corpus function count now matches tree-sitter exactly

🤖 Generated with Claude Code

…efix (#1963)

Apex's func_start and args regexes both accepted any identifier-shaped token
followed by whitespace at line-start as an eligible optional return-type/
modifier prefix, with no exclusion for the `new` keyword. A multi-line
SObject-builder call like:

    Account acct = (Account) TestFactory.createSObject(
        new Account(name = 'Original Name'),
        true
    );

had its `new Account(` line misparsed as "return type = new, function name
= Account" -- passing #1221's gate, which only checks that SOME
annotation/modifier/return-type-shaped token precedes the name, not that
the token is real. tree-sitter never makes this mistake (it structurally
distinguishes object_creation_expression from method_declaration).

Fixed with `(?!new\b)` immediately before the optional prefix-consuming
group in both regexes, mirroring csharp's own GHOST ARGS SHIELD precedent
(csharp/java/groovy/dart already exclude `new` from their equivalent
prefix groups -- apex was the one language in this family missing it).

Found via the tri-comparison ledger sweep
(apex/function/existence/agree[gitgalaxy]_vs[tree_sitter]); confirmed
against the local apex-recipes corpus (6 occurrences across 2 files).
crucible_check.py's ~80-repo differential scan surfaced a third,
independent instance (xml/apex/IterationRecipes_Tests.cls, 3 more
occurrences inside a List<Account>{...} initializer) that neither the
ledger sample nor the local corpus had shown -- also resolved by the same
fix, confirming it generalizes rather than being narrowly tailored.
GitGalaxy's function count on the local corpus now matches tree-sitter
exactly (38/38, zero name diffs; was 40/38 pre-fix).

Golden master fixtures re-blessed via update_golden_master.py to reflect
the intentional output change. Ledger, chart, points-of-interest doc, and
docs/language_status/apex.md's §9 updated to reflect the fix (was
diagnosed-only when originally committed).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@squid-protocol
squid-protocol merged commit 96e2b28 into main Aug 20, 2026
26 of 27 checks passed
@squid-protocol
squid-protocol deleted the fix-1963-apex-new-keyword-func-start branch August 20, 2026 22:58
@github-actions

Copy link
Copy Markdown
Contributor

🐦‍⬛ Muninn Security Scan

✅ No security issues found.

🐦‍⬛ Powered by Muninn · Skald Lab

squid-protocol added a commit that referenced this pull request Aug 21, 2026
…kerfile fix)

Resolves the merge conflict from #1968 landing on main after this
branch forked -- both touched golden_master_audit.json /
golden_master_zero_dep_audit.json / tri_comparison_chart.svg /
tri_comparison_ledger.json / tri_comparison_points_of_interest.md.
Regenerated fresh against the fully merged code (both apex's new
ClassName( exclusion and dockerfile's Mode A routing fix) rather than
hand-merging the generated files. crucible_check.py passes clean
(full_precision + zero_dependency) against the merged state.
squid-protocol added a commit that referenced this pull request Aug 21, 2026
…1976)

* Fix dockerfile func_start recall: route to Mode A, not brace search

Dockerfile has no ScopeParsingRegistry entry and no brace-delimited
instruction bodies at all, so it silently fell through to
Mode_B_Braces in detector.py's _function_slice -- which only produced
a named function when a literal `{` happened to appear by coincidence
within its search window (almost always an unrelated LATER
instruction's `${VAR}` template brace, not anything belonging to the
matched RUN/CMD/ENTRYPOINT/HEALTHCHECK's own body). Confirmed via
manual verification against language-crucible/data/dockerfile (dockerfile
has no tree-sitter/ctags comparison tool): the raw func_start regex was
100% correct (71/71 vs. an independent grep), but the real pipeline's
named function list only captured 15/71 of them, with bogus
body/impact numbers on top.

Routes dockerfile to Mode A (_slice_by_labels), the same
greedy-to-next-match heuristic already proven for abap/cobol/fortran/
assembly -- correct here since every Dockerfile instruction really
does end at the next instruction. Verified against the full
~80-repo crucible corpus (function_count now matches struct_func_start
exactly everywhere, including a 5th real occurrence outside the
dockerfile corpus itself), both golden masters re-blessed.

Also updates docs/self_scan/manual_verification.json,
tri_comparison_chart.svg/points_of_interest.md, and adds
docs/language_status/dockerfile.md with the full verification writeup
(including why no `class` entry was added -- named build-stage
extraction doesn't exist yet, tracked as #1974 -- and two narrower
follow-on issues found along the way, #1972 and #1973).

Fixes case found via the tri-comparison-ledger-sweep skill's
manual-verification fallback for gg-only languages.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Regenerate golden masters/chart against merged main (apex #1968 + dockerfile fix)

Resolves the merge conflict from #1968 landing on main after this
branch forked -- both touched golden_master_audit.json /
golden_master_zero_dep_audit.json / tri_comparison_chart.svg /
tri_comparison_ledger.json / tri_comparison_points_of_interest.md.
Regenerated fresh against the fully merged code (both apex's new
ClassName( exclusion and dockerfile's Mode A routing fix) rather than
hand-merging the generated files. crucible_check.py passes clean
(full_precision + zero_dependency) against the merged state.

---------

Co-authored-by: Joe Esquibel <squid-protocol@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apex func_start false-positives on new ClassName( constructor calls

1 participant