Add EnvironmentLoader for ruby-rbs crate - #3050
Open
dak2 wants to merge 4 commits into
Open
Conversation
soutaro
reviewed
Jul 30, 2026
soutaro
reviewed
Jul 30, 2026
soutaro
reviewed
Jul 30, 2026
dak2
force-pushed
the
environment-loader-ruby-rbs-crate
branch
from
August 14, 2026 00:28
3ffad9d to
eddc09a
Compare
Contributor
Author
|
Remove Buffer. In details, 2b3df5a |
dak2
marked this pull request as ready for review
August 14, 2026 01:37
dak2
force-pushed
the
environment-loader-ruby-rbs-crate
branch
from
August 27, 2026 08:54
86f3acf to
cf765cc
Compare
A type name id means nothing without the strings it was interned against, but AstConverter takes the two interners separately and every caller has to keep them paired. Interners names that pair, so a caller passes one value and cannot mismatch the halves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Environment owns the Interners, which gives one value the role the Ruby implementation's global name pool has: names interned while loading stay resolvable for the environment's lifetime. Alongside them it collects one Source per file read -- its path, its converted directives and declarations, and the SourceKind it came from. SourceKind::Library carries the resolved directory rather than the version asked for, because the version alone cannot recover where the signatures came from. The accessors that mutate an environment are pub(crate), so only this crate's loader appends to one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A file is returned as is, a directory is searched recursively for .rbs files, and under skip_hidden the subtrees of an underscore-named directory are left out. Dot entries and symlinked directories are not traversed, as under Dir.glob. Two divergences are recorded on the function: the sort compares the platform separator rather than Ruby's `/`-joined strings, and only PermissionDenied and NotFound are swallowed where Dir.glob skips every entry it cannot open or stat, so an unreadable subdirectory is skipped instead of aborting the scan. tempfile becomes a dev-dependency for the fixture trees the tests build. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The core root, then the libraries, then the plain directories are walked in that order, each .rbs file parsed once with the first registration winning, and one Source appended per file. It resolves nothing: add_library takes a directory that already holds the library's RBS files, and manifest.yaml dependencies are not expanded -- which is also why loading core does not implicitly add stringio. load returns what this call read, so a caller loading into a non-empty environment learns what it added, the one question env.sources() cannot answer. parse_one takes only the interners so the loop can later be parallelised per worker; SignatureNode is not Send and must not escape it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
dak2
force-pushed
the
environment-loader-ruby-rbs-crate
branch
from
August 27, 2026 08:59
cf765cc to
31ff7c8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Mirrors RBS::EnvironmentLoader: resolves core, library, and explicit-directory sources in Ruby's load order, then parses each .rbs file once into an Environment.
#2954
Architecture differences from
RBS::EnvironmentLoaderEnvironmentstate instead of a process-global one.gem_sig_path/Repository, and expandsmanifest.yamldependenciesadd_library(name, path)takes an already-resolved directory; noRepository, no manifest expansion, no implicitstringioadd(path:/library:/version:)with keyword modesadd_library/add_dir, the modes separated by typelibsis aSet, to stop dependency expansion from recursingVec; with no expansion, first-wins onseen_filesis enoughTypeNameobjectsEnvironmentowns theInterners, so loaded names stay resolvable for its lifetimePathname.glob("**/*.rbs"), sorted as/-joined stringsread_dir, sorted by platform path; symlinked directories are not followed, and onlyPermissionDenied/NotFoundare skippedUsage
Register the directories on the loader, then load them into an
Environment:loadcan also fill an existingEnvironment, and returns what it read, in theorder it read it:
Notes
LoadErrorisIo { path, .. }orParse { path, message }; the sources read before the failure are already in theEnvironment.Environmentowns the interners, soenv.interners()is what resolves and displays the interned names held by the loaded declarations.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com