Skip to content

Split S3.7 and re-scope Step 3b into reviewable slices - #390

Merged
Firehed merged 6 commits into
mainfrom
plan/split-s3.7
Aug 3, 2026
Merged

Split S3.7 and re-scope Step 3b into reviewable slices#390
Firehed merged 6 commits into
mainfrom
plan/split-s3.7

Conversation

@Firehed

@Firehed Firehed commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Re-scopes the remaining Step 3b slices so each is reviewable as one unit, and records
two decisions found while sizing them.

Why

S3.7 was built as a single slice (#388: 622 src lines over 17 files, 30 commits) and is
too large to review as one unit. The seam it missed is already in the code: a class-like
lookup is arithmetic on the name (findFile — five lines, the old ComposerClassLocator
verbatim), while a function or constant lookup has no name→file map and must derive one
by parsing the autoload.files set. Those are two different reviews.

Sizing the rest of Step 3b against the merged slices (S3.2 +58/−40, S3.4 +171/−28,
S3.1 +305/−47) showed S3.8 and S3.9 heading the same way.

What changes

  • S3.7 → S3.7a–d. autoload.files into the autoload map; the per-file declaration
    scan; the kind-agnostic SymbolLocator with its class-like branch (behavior-preserving,
    proven by the existing golden); the derived function/constant index (new behavior, new
    fixtures). S3.7a and S3.7b are independent inputs to S3.7d.
  • S3.8 → S3.8a–c, cut by symbol namespace rather than by layer. A layer cut would land
    SymbolBackend methods no backend implements. S3.8c carries the SymbolResolver edit,
    so S4.2 now serializes against it rather than against S3.8 as a whole.
  • S3.9 → S3.9a–b, cut on provability. S3.9a widens searchClassLikes to a kind
    parameter with every Step P golden frozen; S3.9b makes the backends answer function
    search and rewrites only the function-surface golden.
  • SC.4 added. file:// conversion is hand-rolled in four live places, each differing
    in how it handles the scheme and percent-encoding. Pre-existing duplication owned by no
    step, which is what the SC.* block is for. S3.7c is gated on it rather than adding a
    fifth copy.

Decisions recorded

  • The autoload.files warm-up is declined, with numbers (0002 §3). It was never a
    correctness requirement — an unwarmed locator answers identically — so it only moves
    which message pays a one-off cost. At §8.1's measured ~4 MB/s that cost is ~35 ms here
    (~7 ms excluding PHPUnit's Assert/Functions.php, which is 111 KB of the 139 KB).
    Not worth ~105 lines, a second InitializedListener, and a non-obvious ordering rule.
    A reopen condition is named, and warm() changes no interface, so re-adding it later
    is free.
  • ConstantName is already taken by Domain\ConstantName (class constants), which
    collides with §5.3's global-constant FQN type. Flagged to be decided before S3.8b
    rather than inside it.

Also corrects the name-type JIT note: NameKind already exists, and QualifiedName
lands in S3.7c rather than S3.8.

Docs only — no src/ or tests/ changes.

@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.55%. Comparing base (7c91158) to head (2c8c8f7).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##               main     #390   +/-   ##
=========================================
  Coverage     98.55%   98.55%           
  Complexity     1753     1753           
=========================================
  Files           115      115           
  Lines          4434     4434           
=========================================
  Hits           4370     4370           
  Misses           64       64           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@Firehed
Firehed merged commit dc647dc into main Aug 3, 2026
7 checks passed
@Firehed
Firehed deleted the plan/split-s3.7 branch August 3, 2026 19:36
Firehed added a commit that referenced this pull request Aug 3, 2026
Slice **S3.7a** (#390). `ComposerAutoloadMap` gains the `autoload.files`
set — the files
Composer loads wholesale rather than by name, and the only place a
project's functions
and constants are locatable, since they have no name→file map (RFC 1 §3,
Plan 0002 §3).

- `autoloadFiles(): list<string>`, read from
`vendor/composer/autoload_files.php`.
Composer keys that file by a content hash; the paths are taken as a
plain list.
- Partitioned by vendor directory alongside the PSR-4/PSR-0/classmap
splits, so each
  `FilesystemBackend` half sees its own files (RFC 1 §5.3).
- Non-string entries are discarded — generated data from a project we do
not control.
- The fixture project declares two `files` entries, which also back
S3.7b and S3.7d.

The accessor's consumer is `ComposerSymbolLocator` in S3.7d; it is
public because that is
a different class, and caller-less until then because of the split.

Note: `tests/Fixtures` gained a `files` autoload section, so `composer
install` needs
re-running there before the suite passes.
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.

1 participant