mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-24 06:53:52 +08:00
The Pascal grammar's parameter rule takes no RTTI attribute, so a
declaration like `procedure WithRef(const [ref] AValue: Integer; ...)` or
DelphiMVCFramework's `function CreatePerson([MVCFromBody] const Person:
TPerson)` broke the parse at the `[`. The method was lost, the parameter
after the attribute became a field of the class, every member declared
after it went missing until the next class, and in an implementation the
routine's locals became unit variables and its calls were credited to the
file node.
The Pascal extractor now has an offset-preserving preParse that blanks an
attribute group at the start of a routine parameter, before or after its
modifier (const/var/out/constref), in any routine header, procedural type
or anonymous method (`operator` counts only after `class`, since Delphi
doesn't reserve it). It is a linear hand-written scanner that skips
strings, comments and directives, reads generic and qualified routine
names, and leaves every other bracket alone (set defaults, array types,
member and method attributes, property index lists, code). A new
LanguageExtractor flag, signatureAsWritten, lets Pascal signatures read
the source as written, so `(const [MVCFromBody] Person: TPerson)` keeps
its attribute instead of showing blank space. Only Pascal sets the flag.
Validation:
- New __tests__/pascal-param-attributes.test.ts (8 tests, the issue's unit
included): 6 fail on main's wiring, all pass with the fix.
- A/B against main 5a6917b4, both arms built from their own sources:
SynEdit, HeidiSQL and DWScript (2,497 files) are byte-identical, as is
mORMot2 (its two `[ref] const` signatures keep the attribute).
DelphiMVCFramework (32 files changed by the preParse, 150 attributes):
4 nodes recovered (2 methods, a function and a constant), 10 removed,
all misparses (9 method locals hoisted to unit variables and a
parameter read as a field), 18 methods get a correct signature, end
line and return type; edges -39 +90: 29 calls move from the file node
or the wrong method to the method making them, 60 new edges come from
bodies and declarations main lost, 10 contains edges went with the
misparsed nodes. Every changed edge was triaged.
- Controls leveldb (C++, kernel) and SDWebImage (Objective-C, wasm with
its own preParse) are byte-identical in dump-graph.
- Cost: the preParse takes about 4 ms per MB (95 ms on mORMot2's 25 MB);
index time is within noise (3 interleaved rounds, medians: HeidiSQL
6.53 to 6.47 s, mORMot2 16.7 to 17.2 s, DWScript 16.3 to 16.1 s wall).
- The shipped scanner matches the prototype used for triage on all 4,578
Pascal files of the five repos, with lengths and newlines kept.
Fixes #2545
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>