Repository navigation
Conversation
apiology
force-pushed
the
2026-10-19
branch
2 times, most recently
from
October 21, 2026 15:35
0b3a1c2 to
a04dae9
Compare
The strict-level spec for undefined calls from external sources built its ApiMap with ApiMap.load, which leaves uncached gems in unloaded_gems without loading their pins. Kramdown::Parser::GFM was only resolvable when an earlier spec (e.g. api_map_method_spec via load_with_cache) had already cached the gem, so the example failed when run alone or with a fresh SOLARGRAPH_CACHE. Cache the gem in a before hook, matching library_spec and external_spec. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn (cherry picked from commit 1b02dda)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Which gems a body of code can use is workspace data, not bench data. Collection::Gem#without_yard now catalogs the gem source with a Workspace whose gemnames are the gem and its runtime dependencies, and ApiMap#catalog gives the plugin Panel the External's configured gem names plus the bench workspace's gemnames. Bench#gem_names is removed. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
…e parser, type checker and RBS handling Resolve the Diagnostics::TypeCheck conflict by keeping this branch's workspace: keyword and the PR's 'normal' string default. Regenerate .rubocop_todo.yml. Combination fix: castwide#1245 turns MessageWorker#tick's wait into a while loop, while this branch's MessageWorker#stop (from castwide#1243) wakes the thread once and relies on it falling through. Together the worker never exits and Host#fully_stop times out, so the loop also stops waiting once stopped? is true. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Workspace.for_gem builds a workspace for the source of a gem without loading files or resolving a bundle, and Workspace#available_gem_names derives the gem and its runtime dependencies from it. This replaces the gemnames: keyword, so callers no longer compute the list, and leaves Workspace#gemnames untouched. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Workspace#initialize takes a metagem: keyword, so a workspace for the source of a gem is built through the normal constructor rather than Workspace.for_gem reaching into an instance variable. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
…typechecking in CI castwide#1240 and castwide#1245 both branch from c961a9d; castwide#1245 carries the code fixes castwide#1240 had pointed its markers at. Conflicts resolved by intent, starting from the earlier castwide#1240 merge (0b3a1c2) for the hunks castwide#1245 does not touch: keep castwide#1245's code, and keep castwide#1240's marker labels where castwide#1245 left a marker in place (host.rb predicates, node_chainer, namespace_node, resbody_node, block.rb, rbs_map/conversions.rb), plus castwide#1240's Repo#bundle_script @return tag. Keep castwide#1245's deletion of YardMap::Cache and DomainDirective. rules.rb keeps castwide#1240's @todo list plus the two castwide#1245 labels still in use. .rubocop_todo.yml regenerated with RuboCop 1.92.0. Combination markers: castwide#1240's AST::Node#children union makes child reads in castwide#1245's rewritten code fail, so those get castwide#1240's 1418/1416 child-node marker (Data/Struct assignment nodes, NodeMethods.drill_signature, CasgnNode, SendNode#process_attribute). Lines castwide#1245 rewrote get the marker castwide#1240 had on the same expression: #225 in Constants#resolve_and_cache, castwide#1223 and castwide#1259 in Library, castwide#1258 in Callable, #178 on Method's attr_writer, and castwide#1400 on uncache/load in Collection::Gem.load_all. castwide#1240's pull/1245 markers stay on CheckGemVersion's show_message, Repo's bundled_group_map and Chain::Parameter#current_index, where castwide#1245 does not clear the finding. Remove 41 markers strong reports as unneeded: 30 cite castwide#1245, whose fixes are now in; the other 11 are cleared by castwide#1245's code and castwide#1240's annotations combined. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Regenerate .rubocop_todo.yml.
…and that failed Stub unloaded_gems as a Set in the sync_catalog deadlock spec, as External#unloaded_gems returns; the merged unloaded_gems - cache_errors raises TypeError on the Array stub. Remove the @sg-ignore on the cache status check, which typecheck reports as unneeded now that it reads s&.success?. 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
This was referenced Oct 21, 2026
A plugin was recorded in the gem cache key only when the workspace config required it. A process that requires the plugin directly, such as a plugin spec suite using a workspace without config, mapped gems with the plugin loaded but read and wrote the plain gems directory, so it missed caches built by `solargraph gems` with the plugin configured. Record the gem that defines each registered convention, and key config-required plugins by gem name so both paths give the same key. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
Keep the natural Hash iteration and mark the Solargraph gap: the each_value block param is typed as the Hash pair, not the value. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
call_nodes_from skipped csend nodes, so foo&.bar was never checked:
no unresolved-call, arity or argument-type problems. A union
receiver such as String, Symbol, nil passed name&.chomp(':') even
though Symbol has no chomp. Treat csend like send, and drop nil
from the reported receiver type since &. never calls through nil.
Typechecking safe navigation calls exposes Host::Dispatch#update passing self (a Host::Dispatch) to Progress#send, whose parameter is declared as Host. Suppress it with a marker citing the fix, castwide#1440. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wo4FerFK9aaxrGrmVE9ncZ
Document return and parameter types on the plugin, panel, addon, external, node map and source map APIs so strong typecheck can follow them. In the ActiveSupport plugin, narrow the last chain link to Source::Chain::Call and guard nil closures and nodes, drop the unreachable else branch, and call panel methods directly. Qualify Chain in the NodeMethods.convert_hash return tag, which did not resolve from that namespace. Remove a stray @node_map reset from Source#code=, which has no such ivar. Mark the three remaining typecheck problems with @sg-ignore, each naming the checker gap that causes it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SEntZKsZwQHhzqcwG7MTqn
ApiMap#inner_get_methods sorted Store#get_methods results by name with Array#sort, which is not stable. Ruby on macOS reorders equal names where Linux keeps them, so get_method_stack(...).first differed by OS. On macOS bigdecimal's Integer#- (BigDecimal) -> BigDecimal came ahead of core's, and typecheck reported "Wrong argument type for Integer#-: arg_0 expected BigDecimal, received Integer" that Linux CI never saw. Break name ties by store position so every platform agrees. The position comes from an identity hash rather than sort_by.with_index or each_with_index.sort_by, because Solargraph leaves the block parameters of those Enumerator chains untyped and reports "Unresolved call to name" on them.
Use each_with_index.sort_by for the stable sort instead of an identity
hash built only to avoid a typecheck error. Solargraph leaves the
block's pin untyped ("Unresolved call to name"); castwide/solargraph
castwide#1461 clears it, so the line carries an sg-ignore citing that PR.
Regenerate .rubocop_todo.yml.
Regenerate .rubocop_todo.yml. Remove the sg-ignores the batch CI (k1463b, run 40916916729) reports Unneeded once castwide#1463 types tuple elements by position: lib/solargraph/parser/comment_ripper.rb:31, 33, 38, 40, 49 (pull/1223) lib/solargraph/position.rb:121 (pull/1223) lib/solargraph/yard_map/mapper/to_method.rb:107 (pull/1231) Remove the pending markers that now pass, in spec/source_map/clip_spec.rb: the four labeled "needs castwide#1461" and "types elements of tuples" (pended for castwide#1201).
Regenerate .rubocop_todo.yml.
Regenerate .rubocop_todo.yml. Remove the sg-ignores the merge makes Unneeded: lib/solargraph/language_server/message/base.rb:71 (cited castwide#1223) lib/solargraph/language_server/message/base.rb:73 (cited castwide#1223) lib/solargraph/language_server/message/base.rb:91 (cited castwide#1223) lib/solargraph/position.rb:121 (cited castwide#1223) lib/solargraph/type_checker/rules.rb:20 (cited castwide#1266) lib/solargraph/type_checker/rules.rb:172 (cited castwide#1266) Drop the Hash#fetch pending in strong_spec.rb citing castwide#1266, already merged here, which now passes, and the require of rbs only it used.
Regenerate .rubocop_todo.yml.
Master moved StructDefinitionNode to NodeProcessors and marked its :true check with a disable-next directive, since the old todo exclusion names the former path. Apply the same directive to the pattern-matching :true check this PR introduced. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LTpguFfufaaEmy3yWcWsUi
castwide#1223 closed without merging, so four sg-ignores cited a fix that will never land. castwide#1451 clears the three in Message::Base (nil literal vs NilClass); castwide#1463 covers the tuple index in Position.normalize. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JFJrPm9QhVqVqk5QPMD1c6
Regenerate .rubocop_todo.yml.
Typing symbol blocks makes arguments.map(&:node) nilable, matching Chain#node. simple_convert already returns nil for a non-node, so document that; its body now needs the castwide#1396 ignores, since Solargraph does not narrow on Parser.is_ast_node?, and the nil-check ignore at its call in Call becomes unneeded. Skip the chain inference when the block has no symbol name.
…n macOS and Linux Regenerate .rubocop_todo.yml. Remove the sg-ignore the merge makes Unneeded (Solargraph / strong, https://github.com/apiology/solargraph/actions/runs/40988189551/job/123844024147): lib/solargraph/api_map.rb:917 # @sg-ignore castwide#1461
The old tag omitted Integer, true, false and nil, all of which initialize assigns. The elsif pattern-capture inference gap that masked the Integer case is fixed by castwide#1416. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LTpguFfufaaEmy3yWcWsUi
Plugin::ActiveSupport added an extend of ClassMethods only for includes in workspace source maps. Since Convention::ActiveSupportConcern was removed, classes defined in gems (ActiveJob::Base, ActionController::Base, Rails::Application) lost class methods that come from concerns they include, e.g. ActiveSupport::Callbacks .define_callbacks. Load external requires before running plugins and pass the external pins to the plugin panel, so the plugin also sees includes from gems and stdlib. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
ActiveSupport::Concern extends an includer with the ClassMethods of the concern's own dependencies too: ActiveJob::Base includes ActiveJob::Callbacks, which includes ActiveSupport::Callbacks, so ActiveJob::Base gets set_callback. Plugin::ActiveSupport only extended the ClassMethods of the directly included module. Resolve each included module lexically and also extend the includer with the ClassMethods of the modules it includes, at any depth. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
ActiveSupport::Concern runs a concern's included block and class_methods block in the includer, so the includer gets the concern's class methods and extends (e.g., ActiveRecord::Core's self.configurations, ActiveSupport::Callbacks' DescendantsTracker). Copy those pins onto the includer for each concern it includes, directly or as a dependency. Extend only ClassMethods defined in the included module itself: for an include of an undefined module, the old X::ClassMethods reference resolved lexically to an enclosing namespace's ClassMethods, e.g. ActiveRecord::Base::ClassMethods with its generics unbound. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Strong typecheck inferred Array, Array<Array> for the recursive flat_map in nested_include_paths; push into a typed result array instead. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhUSLUimEYJyCZv8NdQGKb
Regenerate .rubocop_todo.yml.
OpasgnNode builds the `a + b` send for `a += b` with node.updated, so the send keeps the op_asgn's location map and its `+=` operator. assignment_syntax? then flagged it as an attribute assignment, and the local was typed as the right-hand side instead of the operator's return type. Require a setter method name as well.
…f the same name Regenerate .rubocop_todo.yml.
Parser::AST::Node#children is typed Array[self] on master but as a union of Node, Integer, Float, Rational, Complex, String, Symbol and nil where the ast RBS shim applies, so strong typecheck flags each place this PR passes a raw child where a Node (or nil) is expected. Capture receivers with 'in [::Parser::AST::Node | nil => receiver, *]' and guard the rest with is_a?(::Parser::AST::Node). Valid ASTs always have a Node or nil in these positions, so results do not change.
Regenerate .rubocop_todo.yml.
…r's return type Regenerate .rubocop_todo.yml.
…al RBS is loaded Regenerate .rubocop_todo.yml.
…rn type Regenerate .rubocop_todo.yml. Drop sg-ignores made unneeded on 2026-10-19: lib/solargraph/parser/parser_gem/node_methods.rb any_splatted_call?: # @sg-ignore castwide#1451 (added by this PR; castwide#1451 is merged here) lib/solargraph/source/chain/call.rb before named_types: # @sg-ignore Found after castwide#1418 merged node_methods.rb keeps this branch's pattern-matching bodies, so the PR's sg-ignores citing castwide#1396 (merged here) are not carried over; only its nil-accepting @PARAM tags are.
Regenerate .rubocop_todo.yml.
Regenerate .rubocop_todo.yml.
Regenerate .rubocop_todo.yml. Remove the sg-ignores citing castwide#1417: lib/solargraph/api_map.rb:206 # @sg-ignore castwide#1417 lib/solargraph/api_map.rb:210 # @sg-ignore castwide#1417 lib/solargraph/api_map.rb:680 # @sg-ignore castwide#1417 lib/solargraph/api_map.rb:699 # @sg-ignore castwide#1417 lib/solargraph/api_map.rb:712 # @sg-ignore castwide#1417 lib/solargraph/parser/node_processor.rb:21 # @sg-ignore castwide#1417 lib/solargraph/parser/node_processor.rb:24 # @sg-ignore castwide#1417 Remove the sg-ignores the merge makes Unneeded (Solargraph / strong, https://github.com/apiology/solargraph/actions/runs/41059260415/job/124074555542), with their continuation lines: lib/solargraph/type_checker.rb:689 # @sg-ignore castwide#1223 # also needs castwide#1417 lib/solargraph/type_checker.rb:692 # @sg-ignore castwide#1223 # also needs castwide#1417
Regenerate .rubocop_todo.yml.
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: This PR was written by Claude Code on behalf of @apiology.
Problem:
Open PRs are tested only one at a time:
A conflict between two of them would surface only after both merge.
Solution:
Merges every PR below into one branch so CI runs on the combination.
castwide/solargraph PRs included
superinferring the union of every ancestor's return type castwide/solargraph#1364 — Fixsuperinferring the union of every ancestor's return typeapiology/solargraph PRs included
Notes
Merge <repo>#Nmerge commit.