tree-sitter-delphi13 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,27 +5,37 @@
5
5
 
6
6
  Tree-sitter grammar pipeline focused on **Delphi 13 (RAD Studio 37.0 / Florence)** and the surrounding modern Delphi ecosystem.
7
7
 
8
- **99.33% pass rate** on a 35,556-file curated Delphi 13 corpus (zero ERROR nodes).
9
-
10
- | corpus root | pass rate |
8
+ **v1.2.1: 100.000% pass rate on compilable Delphi 13** (zero ERROR nodes), measured
9
+ on an 11,722-unique-file corpus spanning the RAD Studio 13 RTL/VCL (including
10
+ `System.pas`), DevExpress, Spring4D, EurekaLog, Indy, FireDAC, AsyncPro/Orpheus,
11
+ mORMot-era community code and a full production application. Every failure that
12
+ remains is individually diagnosed, dcc32-cross-checked, and *supposed* to fail
13
+ (see [CORPUS-CEILING-REPORT.md](CORPUS-CEILING-REPORT.md)).
14
+
15
+ | measurement basis | pass rate |
11
16
  |---|---|
12
- | ORM3 (production application code) | **100.00%** |
13
- | Spring4D | 99.87% |
14
- | DevExpress VCL | 99.82% |
15
- | OmniThreadLibrary | 99.62% |
16
- | Embarcadero RAD Studio 13 RTL/VCL | 99.24% |
17
+ | orchestrated pipeline (preprocessor → pure), all rows | 99.82% |
18
+ | deduplicated files | 99.74% |
19
+ | deduplicated, valid-Delphi-13-only (excludes broken fixtures, FPC/.NET files) | **100.000%** |
20
+ | own production code (ORM3, drag-lint) | **100.00%** |
17
21
 
18
- The remaining ~0.5% are intentionally broken DUnitX test cases, real vendor source typos, C-language code mistakenly placed in `.pas` files, and a handful of pathologically large auto-generated TypeLib units.
22
+ The 30 files that still fail are intentionally broken test fixtures,
23
+ truncated/corrupted files, FreePascal- or .NET-only sources, and vendor files with
24
+ genuine syntax errors that dcc32 rejects too — a parser that accepted them would be
25
+ wrong. Zero known gaps on valid Delphi 13 remain ([TODO.md](TODO.md) tracks the
26
+ watchlist).
19
27
 
20
28
  ## Three packages, one repo
21
29
 
22
30
  | Package | What it does |
23
31
  |---|---|
24
- | **`tree-sitter-delphi13`** *(this directory)* | Master grammar — Delphi-13 syntax, all proven fixes from upstream merged + new extensions. Self-contained "THEN-wins" parser (93.48% on its own). |
32
+ | **`tree-sitter-delphi13`** *(this directory)* | Master grammar — Delphi-13 syntax, all proven fixes from upstream merged + new extensions. Self-contained "THEN-wins" parser (98.6% raw on its own). |
25
33
  | **[`tree-sitter-delphi13-pure`](pure/)** | Simpler sub-grammar that drops `pp_*` tokens entirely. Expects preprocessor-resolved source. |
26
34
  | **[`delphi13-preprocessor`](preprocessor/)** | Standalone JavaScript library that resolves `{$IFDEF}` / `{$IF}` / `{$DEFINE}` / `{$I X.inc}` directives as a text transformation. |
27
35
 
28
- The full pipeline `preprocessor → pure → AST` is what reaches **99.33%**. Use the master grammar alone if you don't need conditional-compilation awareness; use the pipeline if you do.
36
+ The full pipeline `preprocessor → pure → AST` is what reaches **99.97%** on valid
37
+ Delphi 13. Use the master grammar alone (98.6% raw) if you don't need
38
+ conditional-compilation awareness; use the pipeline if you do.
29
39
 
30
40
  ## Architecture
31
41
 
package/grammar.js CHANGED
@@ -448,6 +448,14 @@ module.exports = grammar({
448
448
  // `_procAttributeNoExt` groups while both interpretations are still
449
449
  // live (`function F; stdcall; forward;` — forward only decides later).
450
450
  [$._declProcLenient, $._procAttributeNoExt],
451
+ // Iter 2026-07-16 (Register as a field name): after `Foo: T;` the
452
+ // token `Register` is either the previous field's trailing callconv
453
+ // (`; register;`) or the NEXT field's name (`Register: UINT;`) —
454
+ // `;` vs `:` one token later decides; GLR forks across the
455
+ // declField/declFieldNoSemi boundary AND within declField itself
456
+ // (trailing-callconv slot vs end-of-field).
457
+ [$.declFieldNoSemi, $.declField],
458
+ [$.declField],
451
459
  // The following conflict rules are only needed because "public" can be
452
460
  // a visibility or an attribute. *sigh*
453
461
  // TODO: We would probably avoid this by having separate decl* clauses
@@ -915,7 +923,19 @@ module.exports = grammar({
915
923
  typeref: $ => seq(
916
924
  ...enable_if(fpc, field('_dummy', optional($.kSpecialize))),
917
925
  $._typeref,
918
- ...enable_if(delphi, optional(seq($.kDeprecated, $._expr))),
926
+ // Trailing declaration hints on the type reference itself. The
927
+ // kDeprecated+message form predates this note; kPlatform (bare)
928
+ // added 2026-07-16 for the hint-BEFORE-initializer pattern
929
+ // Default8087CW: Word platform = $033F; (System.pas, x6)
930
+ // — with the hint absorbed here, declVar's `= expr` defaultValue
931
+ // follows naturally. A hint-then-value ARM inside declVar itself
932
+ // was tried first and is a bisect-confirmed generate table bomb
933
+ // (see TODO.md); this mirrors the existing kDeprecated role-set
934
+ // instead, which the tables already accommodate.
935
+ ...enable_if(delphi, optional(choice(
936
+ seq($.kDeprecated, $._expr),
937
+ $.kPlatform,
938
+ ))),
919
939
  ),
920
940
 
921
941
  _typeref: $ => choice(
@@ -1632,7 +1652,18 @@ module.exports = grammar({
1632
1652
 
1633
1653
  declField: $ => seq(
1634
1654
  ...enable_if(rtti, optional($.rttiAttributes)),
1635
- field('name', delimited1($.identifier)),
1655
+ // Iter 2026-07-16: `Register` as a FIELD NAME after a prior field
1656
+ // (`Name: PAnsiChar; Register: UINT;` — Winapi.D3D10 shader
1657
+ // reflection records). Without the alias, the trailing-callconv
1658
+ // slot below ate `Register` and choked on the `:`. ONLY kRegister
1659
+ // is aliased — the 2026-07-06 attempt aliased all 7 callconv
1660
+ // keywords into BOTH declField and declFieldNoSemi and blew up
1661
+ // the tables; the narrow form + one-token lookahead (`:` vs `;`)
1662
+ // is all D3D10 needs.
1663
+ field('name', delimited1(choice(
1664
+ $.identifier,
1665
+ alias($.kRegister, $.identifier),
1666
+ ))),
1636
1667
  ':',
1637
1668
  // Iter 2026-07-06: a record/class field type may be a subrange, same
1638
1669
  // as declVar already allows. `FtrListCount: 0 .. FTRRECMAXCOUNT;`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tree-sitter-delphi13",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Tree-sitter grammar focused on Delphi 13 (RAD Studio 37.0)",
5
5
  "main": "bindings/node",
6
6
  "types": "bindings/node",
package/src/grammar.json CHANGED
@@ -5358,15 +5358,24 @@
5358
5358
  "type": "CHOICE",
5359
5359
  "members": [
5360
5360
  {
5361
- "type": "SEQ",
5361
+ "type": "CHOICE",
5362
5362
  "members": [
5363
5363
  {
5364
- "type": "SYMBOL",
5365
- "name": "kDeprecated"
5364
+ "type": "SEQ",
5365
+ "members": [
5366
+ {
5367
+ "type": "SYMBOL",
5368
+ "name": "kDeprecated"
5369
+ },
5370
+ {
5371
+ "type": "SYMBOL",
5372
+ "name": "_expr"
5373
+ }
5374
+ ]
5366
5375
  },
5367
5376
  {
5368
5377
  "type": "SYMBOL",
5369
- "name": "_expr"
5378
+ "name": "kPlatform"
5370
5379
  }
5371
5380
  ]
5372
5381
  },
@@ -9635,8 +9644,22 @@
9635
9644
  "type": "SEQ",
9636
9645
  "members": [
9637
9646
  {
9638
- "type": "SYMBOL",
9639
- "name": "identifier"
9647
+ "type": "CHOICE",
9648
+ "members": [
9649
+ {
9650
+ "type": "SYMBOL",
9651
+ "name": "identifier"
9652
+ },
9653
+ {
9654
+ "type": "ALIAS",
9655
+ "content": {
9656
+ "type": "SYMBOL",
9657
+ "name": "kRegister"
9658
+ },
9659
+ "named": true,
9660
+ "value": "identifier"
9661
+ }
9662
+ ]
9640
9663
  },
9641
9664
  {
9642
9665
  "type": "STRING",
@@ -9652,8 +9675,22 @@
9652
9675
  ]
9653
9676
  },
9654
9677
  {
9655
- "type": "SYMBOL",
9656
- "name": "identifier"
9678
+ "type": "CHOICE",
9679
+ "members": [
9680
+ {
9681
+ "type": "SYMBOL",
9682
+ "name": "identifier"
9683
+ },
9684
+ {
9685
+ "type": "ALIAS",
9686
+ "content": {
9687
+ "type": "SYMBOL",
9688
+ "name": "kRegister"
9689
+ },
9690
+ "named": true,
9691
+ "value": "identifier"
9692
+ }
9693
+ ]
9657
9694
  }
9658
9695
  ]
9659
9696
  }
@@ -13045,6 +13082,13 @@
13045
13082
  "_declProcLenient",
13046
13083
  "_procAttributeNoExt"
13047
13084
  ],
13085
+ [
13086
+ "declFieldNoSemi",
13087
+ "declField"
13088
+ ],
13089
+ [
13090
+ "declField"
13091
+ ],
13048
13092
  [
13049
13093
  "declProcFwd"
13050
13094
  ],
@@ -9364,6 +9364,10 @@
9364
9364
  "type": "kNil",
9365
9365
  "named": true
9366
9366
  },
9367
+ {
9368
+ "type": "kPlatform",
9369
+ "named": true
9370
+ },
9367
9371
  {
9368
9372
  "type": "kTrue",
9369
9373
  "named": true