Repository navigation
Conversation
…de#1379) * RbsCollection * Gem caching in External spec * RbsCollection specs * Stale code * Linting
The no-YARD gem mapper lost pins that YARD used to produce: * Mixins called on an explicit receiver. Only receiverless include/extend/prepend were mapped, so ActiveSupport's `Object.prepend(self)` (which is how `require_dependency` reaches every class) and `Integer.prepend ActiveSupport::NumericWithFormat` made all the methods those modules add to core classes invisible. * ActiveSupport's `class_attribute`, whose accessors are created at run time. Rails documents them with `## :singleton-method:` comment directives that YARD turned into methods. `process_class_attribute` generates the same accessors and honors instance_accessor/instance_reader/instance_writer/instance_predicate. Fixes several solargraph-rails definitions (require_dependency on ActiveJob, Rails::Application, ActionDispatch::Routing::Mapper and ActiveRecord; ActionController callbacks; ActiveRecord::Base.enumerate_columns_in_select_statements; ActiveRecord::Base#signed_id_verifier_secret; Integer#to_formatted_s).
External now selects collection entries for the gems it loads, but the lookup expected a collection directory whose version matches the installed gem. Two kinds of signature sets were silently dropped: * Gems whose signatures are published under a different version than the gem. gem_rbs_collection ships `actionpack/6.0` for every Rails 6 and 7 release and `devise/4.9` for Devise 4 and 5, so actionpack 7.0.10 and devise 5.0.4 got no signatures at all (this is what hid the ActionController callback DSL). RbsCollection#best_key now falls back to the closest version the collection provides for that gem, preferring the highest one that does not exceed it. * Stdlib entries in the lockfile (`date/0`, `json/0`, ...). They are not associated with a gem in the bundle, and `rbs collection install` resolves them to the signatures that ship with the rbs gem instead of copying them into the collection directory, so they can never be matched by a gem lookup. RbsCollection#stdlib_names exposes them and External loads them with Collection::Stdlib, which restores e.g. `Date#xmlschema -> String`. Also guards External#rbs_collection_lockfile against a nil directory, which previously short-circuited before the collection was touched.
Gem mapping without YARD globbed only a gem's require_paths, so code
an engine autoloads from app/ was never mapped. turbo-rails defines
Turbo::Broadcastable in app/models/concerns/, which left methods like
ActiveRecord::Base#broadcast_append unresolved where YARD-based
mapping (default file set {lib,app}/**/*.rb) found them.
Map app/**/*.rb alongside the require paths. Among installed gems,
only engines ship .rb files under app/ (actionmailbox, actiontext,
activestorage, devise, importmap-rails, solid_*, turbo-rails).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
"Autoload" read as Ruby's Module#autoload; the directories matter because Rails loads them through Zeitwerk, not require. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Gem pins are mapped from gem source and serialized, so a plugin's conventions shape what lands in the gem cache. The language server caches gems by running `solargraph cache` in a subprocess, which never loaded the workspace's plugins, so the cache it wrote could differ from the one an in-process typecheck builds. `cache` and `uncache` now require the plugins configured for the directory, through a Workspace::Config#require_plugins that Workspace also delegates to. Each loaded plugin and its gem version are recorded in CacheDir, and gem_dir includes them, so loading or upgrading a plugin rebuilds the gem cache instead of reusing pins made without it. The @sg-ignore in CacheDir.add_plugin records a typecheck defect: Hash#each_value.find types the block parameter as the value type unioned with the hash itself. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Mapping app/ for every gem was Rails knowledge hard-coded in Collection::Gem, and it also mapped app/ in gems that are not engines. Behaviour outside the core language belongs in conventions. Add Convention::Base#gem_directories, empty by default, which Collection::Gem maps alongside a gem's require paths when it maps the gem from source. Convention::RailsEngine, registered like ActiveSupportConcern, returns Rails::Engine::Configuration's default autoload roots (app/* and app/*/concerns without assets and javascript, plus test/mailers/previews) for a gem whose require paths subclass Rails::Engine. Paths an engine adds through config.autoload_paths or paths.add are not read: they are Ruby expressions, usually built from __dir__, and the default roots cover the engines measured. The roots are globbed from an absolute path rather than with base:, because Dir.glob(pattern, base: dir) infers as Array<String>, nil at strong level (the block overload is not ruled out), while the same call without base: infers Array<String>. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Solargraph keeps only the generic Convention#gem_directories hook; solargraph-rails' convention supplies engine autoload roots. The RailsEngine convention, its spec and its engine-only fixtures go with it, and the Collection::Gem spec now exercises the hook through a convention registered for the example. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
"gem_directories" read as directories holding one subdirectory per gem, like GEM_PATH. The hook returns paths inside one gem, relative to its root, to map in addition to its require_paths. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Metagem is too new to expose to plugins, and conventions need only the gem root and its require paths. Keyword arguments plus ** let Solargraph pass more later without breaking plugins. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Retarget onto master now that gem-without-yard landed via castwide#1378. Resolve the Collection::Gem#without_yard conflict in favor of this branch, which adds Convention.extra_source_paths to the globbed dirs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
…s when mapping gems Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Owner
Author
|
Claude: Closing: superseded by batch b4b, which merges castwide#1407 with its fix for the 28 solargraph-rspec failures here. |
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.
Claude: CI for the castwide#1407 merge before it goes onto #213; closed once merged or superseded.