فهرست منبع

docs(design): Pascal/Delphi chained calls shipped (#791) — 13 languages (#750) (#792)

Updates the chained-call design doc: Pascal moves from "blocked" to covered
(#791) — the earlier "blocked" read was wrong, caused by probing only the
paren-less form. 13 languages now shipped; EXTRACTION_VERSION 16.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Colby Mchenry 1 هفته پیش
والد
کامیت
4c35b72136
1فایلهای تغییر یافته به همراه16 افزوده شده و 15 حذف شده
  1. 16 15
      docs/design/chained-call-resolution.md

+ 16 - 15
docs/design/chained-call-resolution.md

@@ -1,12 +1,11 @@
 # Design + status: chained static-factory / fluent call resolution
 
-**Status:** SHIPPED for **11 languages** (C++, C, PHP, Java, Kotlin, C#, Swift, Rust,
-Go, Scala, Dart, Objective-C) + a conformance pass. **TypeScript and Luau were evaluated
-and intentionally skipped** (both gradually typed → the mechanism is +0 / regresses on
-real code). **Pascal/Delphi** is blocked on a larger prerequisite (its method-call
-extraction is broadly incomplete). See "Full README classification" below. Tracking
-issue: **#750** (which began as "the statically-typed README languages" but that
-enumeration was incomplete — it missed ObjC / Pascal / Luau).
+**Status:** SHIPPED for **13 languages** (C++, C, PHP, Java, Kotlin, C#, Swift, Rust,
+Go, Scala, Dart, Objective-C, Pascal/Delphi) + a conformance pass. **TypeScript and Luau
+were evaluated and intentionally skipped** (both gradually typed → the mechanism is +0 /
+regresses on real code). See "Full README classification" below. Tracking issue:
+**#750** (which began as "the statically-typed README languages" but that enumeration was
+incomplete — it missed ObjC / Pascal / Luau).
 
 **Motivation:** a call whose **receiver is itself a call** — a factory / singleton /
 builder that returns an object — should produce a `calls` edge to the chained method:
@@ -75,10 +74,11 @@ walking `context.getSupertypes(...)`.
 | **Scala** | #761 | `.` | gatling **+14 / −59** | Precision win (−59 = stdlib `Option`/`Iterator` `.map`/`.flatMap` the baseline mis-tied to gatling's `Validation::*`). Companion factories + case-class `apply`. |
 | **Dart** | #762 | `.` | localsend hand-written **+17 / −10** | Precision win **+ constructors made first-class** (factory/named ctors `Foo.create()`/`Foo._()` are now indexed; unnamed `Foo()` stays `instantiates`). `dartCtorInfo` validates a ctor against the enclosing class name — handles a tree-sitter misparse where `@override (A,B) m()` makes `m()` look like a ctor. |
 | **Objective-C** | #786 | message send | SDWebImage **+35 / −75** | Precision win. Chained message send `[[Foo create] doIt]` over `message_expression`. getReturnType skips nullability qualifiers (`nonnull instancetype`). A class-message factory returns the receiver class by convention, so `[[X alloc] init]` / singleton chains resolve on `X` (validated). The −75 are wrong `init` mis-matches retargeted to the right class. |
+| **Pascal/Delphi** | #791 | `.` (`exprDot`) | PascalCoin **+19 / −18** | Precision win. `TFoo.GetInstance().DoIt()` over Pascal's `exprCall`/`exprDot`. getReturnType from the `typeref` (incl. interface returns `IFoo`). Re-encoding gated on the Delphi `TFoo`/`IFoo` type convention so capitalized *variable* chains stay bare. A constructor (no `: TBar`) or typecast `TFoo(x)` resolves on the class. 15 of the −18 are correct class→interface retargets (`GetInstance(): IAsn1OctetString`). |
 | **TypeScript** | — | `.` | typeorm +0/−6 · nest **+0/−164** | **Evaluated, NOT shipped** — gradual typing; see below. |
 | **Luau** | — | `:` / `.` | Fusion +0/−0 · matter +0/−0 | **Evaluated, NOT shipped** — gradually typed; additive-safe (missing-edge gap, no regression) but real Luau rarely annotates factory returns, so +0 on both benchmarks. Works for `Foo.create(): Bar` then `:doIt()` (synthetic). |
 
-`EXTRACTION_VERSION` is now **15** (C++→…→Dart→Objective-C). Re-index with `codegraph index -f`
+`EXTRACTION_VERSION` is now **16** (C++→…→Objective-C→Pascal). Re-index with `codegraph index -f`
 to pick up the newer extractor on an existing graph.
 
 ## Why TypeScript was skipped
@@ -108,20 +108,21 @@ declarations). Against the README's full supported-language list:
 
 | Bucket | Languages |
 |---|---|
-| **Covered** (12) | C++, C, PHP, Java, Kotlin, C#, Swift, Rust, Go, Scala, Dart, Objective-C |
+| **Covered** (13) | C++, C, PHP, Java, Kotlin, C#, Swift, Rust, Go, Scala, Dart, Objective-C, Pascal/Delphi |
 | **Evaluated, skipped** (2) | **TypeScript** — gradual typing → inference-typed factories can't be recovered; net recall regression. **Luau** — gradually typed; additive-safe but +0 on Fusion AND matter (real Luau rarely annotates factory returns). Both: the mechanism needs reliably-declared return types, which gradually-typed code too often omits. |
-| **Blocked by a prerequisite** (1) | **Pascal/Delphi** — statically typed (so the mechanism *would* pay off), but its method-call extraction from procedure bodies is broadly incomplete: paren-less calls (`TFoo.GetInstance.DoIt`) parse as a bare `exprDot` (not in `callTypes`), and even paren'd calls (`f.Regular()`) produce no edge (no receiver-type tracking for Pascal locals). Building Pascal's call graph is a substantial standalone extractor effort; the chained-call port is a small part of it. Separate follow-up. |
+| **Known limitation (not blocking)** | **Pascal/Delphi** is shipped (#791), but only the **paren'd** chain `TFoo.GetInstance().DoIt()` is covered — the **paren-less** form `TFoo.GetInstance.DoIt` parses as a bare `exprDot` (not in `callTypes`) and isn't extracted as a call at all. Emitting paren-less method calls is a separate extractor follow-up (and a broader Pascal-coverage win independent of chains). |
 | **Out of scope — no declared return types** (6) | JavaScript, Ruby, Lua, Svelte, Vue, Liquid (Liquid has no methods/chains at all) |
 | **Partial / separate** (1) | Python — only optional `-> T` hints; tracked as #578, not part of this mechanism |
 
 So #750's original framing ("the 9 statically-typed README languages") was incomplete —
-it missed three more typed languages. Resolved: **Objective-C** shipped (#786, same
-wrong-edge gap, mechanism ports directly); **Luau** evaluated and skipped (gradual
-typing → +0 on real repos, additive-safe); **Pascal** is gated on unrelated extractor
-work (its call graph is broadly incomplete).
+it missed three more typed languages, all now resolved: **Objective-C** shipped (#786,
+same wrong-edge gap, mechanism ports directly); **Pascal/Delphi** shipped (#791, a clean
+port for the paren'd chain — an initial "blocked" read was wrong, caused by probing only
+the paren-less form); **Luau** evaluated and skipped (gradual typing → +0 on real repos,
+additive-safe).
 
 The through-line: this mechanism fits languages with **reliably-declared return types**
-(the 12 shipped). Gradually-typed languages (TypeScript, Luau) omit them too often for
+(the 13 shipped). Gradually-typed languages (TypeScript, Luau) omit them too often for
 it to pay off, and dynamically-typed languages have none.
 
 ---