Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
267 commits
Select commit Hold shift + click to select a range
698834a
Add regression specs for two more specious-inference cases
apiology Jul 31, 2026
67bd423
Simplify redundant literal items out of variable-pin unions
apiology Jul 31, 2026
edb944d
Widen tuple.rbs return types for position-shifting mutators
apiology Jul 31, 2026
8e94b1c
Check restarg argument types against the receiver's element type
apiology Aug 1, 2026
1e9556d
Fix push-argument spec to not depend on RBS param name
apiology Aug 1, 2026
5e6f8ba
Add | union and [...] grouping operators, matching YARD #1700
apiology Aug 1, 2026
c416995
Typecheck cleanup batch 1: remove stale @sg-ignore comments
apiology Aug 1, 2026
1ae1947
Typecheck cleanup batch 2: parser AST nodes, RBS translation types
apiology Aug 2, 2026
cc5087e
Typecheck cleanup batch 3: type_checker.rb, rubocop line-length fix
apiology Aug 2, 2026
3997c04
Typecheck cleanup batch 4: Pin::Method fully clean
apiology Aug 2, 2026
d133ef6
Typecheck cleanup batch 5: NodeChainer and send_node fully clean
apiology Aug 2, 2026
72b01b2
Typecheck cleanup batch 6: CommentRipper and FlowSensitiveTyping full…
apiology Aug 2, 2026
6e1affb
Typecheck cleanup batch 7: Library fully clean
apiology Aug 2, 2026
622a33c
Typecheck cleanup batch 8: ApiMap and Host fully clean
apiology Aug 2, 2026
6a220a9
Typecheck cleanup batch 9: ApiMap::Store fully clean
apiology Aug 2, 2026
78b9b04
Typecheck cleanup batch 10: Block, SclassNode, Rubocop diagnostics
apiology Aug 2, 2026
599959c
Typecheck cleanup batch 11: convention/*_node.rb fully clean
apiology Aug 2, 2026
b678187
Typecheck cleanup batch 12: DocMap, Pin::Callable, Source fully clean
apiology Aug 2, 2026
e86e7ba
Typecheck cleanup batch 13: ComplexType and UniqueType fully clean
apiology Aug 2, 2026
8fff80f
Typecheck cleanup batch 14: PinCache, Pin::Base, ToMethod, Shell
apiology Aug 2, 2026
268420d
Typecheck cleanup batch 15: ApiMap::Cache, node processors, Clip, Gem…
apiology Aug 2, 2026
4280f61
Improve overload resolution and macro handling in Chain::Call
apiology Aug 2, 2026
042459c
Typecheck cleanup batch 16: Constants, Index, Parameter, opasgn/block…
apiology Aug 2, 2026
f5ca3d1
Typecheck cleanup batch 17: NodeProcessor, ArgsNode, Chain, SourceMap…
apiology Aug 2, 2026
4529157
Typecheck cleanup batch 18 (final): strong mode fully clean, re-enabl…
apiology Aug 2, 2026
582ff2e
Typecheck cleanup batch 19: fix RBS-version-drift gap caught by clean…
apiology Aug 2, 2026
dba36ec
Add PinCache: unified gem pin caching engine
apiology Aug 2, 2026
7309146
Wire PinCache into DocMap, ApiMap, Workspace, and Library
apiology Aug 2, 2026
343d288
Update CLI cache/uncache/gems to use PinCache via Workspace
apiology Aug 2, 2026
3c45670
Typecheck cleanup batch 20: fix strong-mode drift since branch creation
apiology Aug 2, 2026
82b2542
Rebase spec performance fixes onto master
apiology Aug 1, 2026
f6c351b
Fix ApiMap#resolve_require after rebase onto master
apiology Aug 1, 2026
dc17b43
Suppress false-positive nilable-workspace typecheck nit in resolve_re…
apiology Aug 1, 2026
839ff36
Fix Thor.desc pin caching: gemspec type mismatch + test ordering
apiology Aug 2, 2026
857d8f9
Fix same cache_gem-before-catalog ordering bug in pin/base_spec.rb
apiology Aug 2, 2026
ef278e4
Note YARD version tested alongside rubocop-yard in CollectionStyle co…
apiology Aug 2, 2026
42f5643
Address PR review comments on #1223
apiology Aug 2, 2026
b061580
Widen time_limit_seconds margins after a near-miss in CI
apiology Aug 2, 2026
cf5c8c8
Fix gem_pins_spec.rb to use the renamed DocMap#cache_doc_map_gems!
apiology Aug 2, 2026
070890e
Address review comments: raise instead of sg-ignore, revert cosmetic …
apiology Aug 2, 2026
7d1a533
Link array element-type tracking pendings to castwide/solargraph#1223
apiology Aug 2, 2026
8d03dc3
Link overload-narrowing pendings to castwide/solargraph#1246
apiology Aug 2, 2026
0cd6610
Remove fork-only bundler version pin from rspec.yml
apiology Aug 2, 2026
50786d0
Revert extracted code changes; defer to #1245 via @sg-ignore
apiology Aug 2, 2026
2ac9f9a
Revert "Remove fork-only bundler version pin from rspec.yml"
apiology Aug 2, 2026
8dd1458
Refresh @sg-ignore count doc in TypeChecker::Rules
apiology Aug 2, 2026
492b000
Document the confirmed reason for pinning bundler version in CI
apiology Aug 2, 2026
954d0a6
Point sg-ignores resolvable by #1223 at that PR instead
apiology Aug 2, 2026
383660a
Avoid literal @sg-ignore substring in rules.rb doc prose
apiology Aug 2, 2026
eb4b12b
Fix Gemspecs#in_this_bundle? crash when no Gemfile is discoverable
apiology Aug 2, 2026
468ab7d
Consolidate #1245 sg-ignore reasons to a single URL reference
apiology Aug 2, 2026
8773872
Point case/when sg-ignores at issue #1241
apiology Aug 2, 2026
5443702
File and link issues for attrs/redefinition/is_a? narrowing gaps
apiology Aug 2, 2026
26a125a
Restore dropped @sg-ignore in rubocop_helpers.rb
apiology Aug 2, 2026
1feaf93
Fix @sg-ignore placement in rubocop_helpers.rb for CI
apiology Aug 2, 2026
58db074
Recognize raise/fail as compound-statement-leaving in flow-sensitive …
apiology Aug 3, 2026
7e9a53b
Handle root-scoped (::-prefixed) constants in is_a? narrowing
apiology Aug 3, 2026
f682ff4
Narrow a case/when subject to the matched class in each branch
apiology Aug 3, 2026
c2a16e5
Narrow repeated calls to the same attr_reader-style accessor
apiology Aug 3, 2026
9445d1f
Fix chain.rb nil-safety instead of suppressing the typecheck warning
apiology Aug 4, 2026
2190a35
Replace generic nil-check suppressions with real fixes/explanations
apiology Aug 4, 2026
e85bdbd
Reproduce the ||= on lvars flow-sensitive-typing gap
apiology Aug 3, 2026
b2a5b13
Narrow x ||= value on lvars and ivars to eliminate nil
apiology Aug 4, 2026
55f1c1e
Fix mislabeled sg-ignores in process_or_asgn
apiology Aug 4, 2026
c666672
Replace the last sg-ignore in OrasgnNode with a real guard
apiology Aug 4, 2026
6741f7f
Start integration testing branch 2026-08-04
apiology Aug 4, 2026
771c3d0
Merge castwide/solargraph#1223 (apiology-1196-literal-inference) into…
apiology Aug 4, 2026
6706082
Merge castwide/solargraph#1247 (pin-caching-2-chain-call-refactor) in…
apiology Aug 4, 2026
0e32e59
Unpend overload-resolution specs fixed by combining #1223 and #1247
apiology Aug 4, 2026
75868fa
Merge castwide/solargraph#1237 (speed_up_specs_master) into integrati…
apiology Aug 4, 2026
a26184f
Merge castwide/solargraph#1231 (fix-1229-intersection-types) into int…
apiology Aug 4, 2026
493a6aa
Unpend union-in-bracket spec fixed by #1231 grouping syntax
apiology Aug 4, 2026
99349d0
Merge castwide/solargraph#1252 (pin-caching-3-pincache-core) into int…
apiology Aug 4, 2026
0dc5c0b
DEBUG: print solargraph pin output for Integer#+ in CI
apiology Aug 4, 2026
9ac2040
Revert "DEBUG: print solargraph pin output for Integer#+ in CI"
apiology Aug 4, 2026
d211e10
Fix two bugs in #1223 signature-combining that dropped/mangled overloads
apiology Aug 4, 2026
d5784d3
Revert "Fix two bugs in #1223 signature-combining that dropped/mangle…
apiology Aug 4, 2026
a9b7b51
Fix Pin::Method#== and Pin::Parameter#type_arity_decl overload bugs
apiology Aug 4, 2026
cba3ca0
Merge pull request #52 from apiology/fix-integer-overload-combining-o…
apiology Aug 5, 2026
e694925
Merge castwide/solargraph#1252 update (apiology/solargraph#52 fix) in…
apiology Aug 5, 2026
866450d
Merge castwide/solargraph#1259 (worktree-fix-1254-nil-guard-narrowing…
apiology Aug 5, 2026
e831fc6
Backfill regression tests for previously-reverted/regressed behavior
apiology Aug 5, 2026
d3f5991
Describe Gem::Specification instead of a bare string in gemspec_spec
apiology Aug 5, 2026
5b06afd
Merge castwide/solargraph#1262 (worktree-backfill-regression-tests) i…
apiology Aug 5, 2026
c3cc59d
Fix Hash<K,V> tag round-trip crash and TypeChecker call-inference err…
apiology Aug 5, 2026
950adf5
Adapt #1262 DocMap#combined_pins_in_memory test to PinCache
apiology Aug 5, 2026
78a5760
Merge castwide/solargraph#1263 (fix-1259-typecheck-crash) into integr…
apiology Aug 5, 2026
99cc5bf
Merge castwide/solargraph#1258 (gh-fix-1249) into integration branch …
apiology Aug 5, 2026
b4488bb
Fix Gemspecs#resolve_require double-prefixing lib/ before find_by_path
apiology Aug 5, 2026
27f83b0
Merge castwide/solargraph#1252 update (Gemspecs#resolve_require fix) …
apiology Aug 5, 2026
d240e5d
Fix instance_double type mismatch in the new resolve_require test
apiology Aug 5, 2026
f517308
Fix blank expected-type message for untyped restarg params
apiology Aug 6, 2026
92e4f81
Merge castwide/solargraph#1223 update (restarg untyped-param message …
apiology Aug 6, 2026
bbaf7f9
Narrow bare, implicit-self attr_reader-style accessor calls
apiology Aug 6, 2026
b008207
Merge apiology/solargraph#53 (self-rooted-accessor-narrowing) into in…
apiology Aug 6, 2026
434e792
Update two FlowSensitiveTyping.new callers missed by #53
apiology Aug 6, 2026
9a7803d
Structurally verify RBS interface-typed expectations
apiology Aug 6, 2026
2a62989
Add pending specs for interface signature verification gap
apiology Aug 6, 2026
29a1887
Restore full bypass for the interface-typed expectation case
apiology Aug 6, 2026
b5cdb3f
Point the existing nil/NilClass pending spec at its tracking issue
apiology Aug 6, 2026
a26570a
Fix false positive: Struct.new(keyword_init: true) members are optional
apiology Aug 6, 2026
349cf6d
Merge castwide/solargraph#1266: structurally verify RBS interface-typ…
apiology Aug 6, 2026
2a1cfb0
Merge castwide/solargraph#1269: Struct.new(keyword_init: true) member…
apiology Aug 6, 2026
eedf506
Add pending specs for two intersection-type bugs (#1231)
apiology Aug 6, 2026
0136044
Expand intersection-type corner-case coverage from PR #1231 review
apiology Aug 6, 2026
3c30a84
Document root cause and #1266 dependency for the Hash#fetch leak
apiology Aug 6, 2026
2bb0a15
Document which pending specs are #1266-dependent vs independent
apiology Aug 6, 2026
342b11b
Fix method-call resolution on intersection-typed receivers (#1231)
apiology Aug 6, 2026
76181ad
Add pending spec for strict-union call resolution bug
apiology Aug 6, 2026
9ce3a0a
Fix Chain#nullable? leaking nil from earlier &. into later unrelated …
apiology Aug 6, 2026
8935e12
Add pending spec proving the Hash dispatch bug is union-general
apiology Aug 6, 2026
7a3a510
Correct Chain#nullable? to track self-returning calls, not just the t…
apiology Aug 6, 2026
73d3333
Merge castwide/solargraph#1271: fix Chain#nullable? nil leak
apiology Aug 6, 2026
d969a95
Fix order-dependent generic resolution for same-class union receivers
apiology Aug 6, 2026
1bea049
Merge castwide/solargraph#1273: fix order-dependent generic union res…
apiology Aug 6, 2026
c41d1a3
Recognize multi-statement raise/fail branches in flow-sensitive typing
apiology Aug 6, 2026
58a780f
Infer only the lhs type for x || raise(...) and x ||= raise(...)
apiology Aug 6, 2026
7adb5db
Fix order-dependent Hash intersection dispatch (partial, #1231)
apiology Aug 6, 2026
ecd9967
Merge latest castwide/solargraph#1259: multi-statement raise/fail, x|…
apiology Aug 6, 2026
dde1c58
Merge latest castwide/solargraph#1231: intersection-type dispatch fixes
apiology Aug 6, 2026
aba4226
Trigger CI
apiology Aug 6, 2026
10c5a55
Merge latest castwide/solargraph#1273: empty CI-retrigger commit
apiology Aug 6, 2026
922d073
Fix @generic return type lost when method also declares a block param
apiology Aug 7, 2026
0cb1a0e
Merge castwide/solargraph#1274: fix @generic return type lost with bl…
apiology Aug 7, 2026
2e0198c
Merge castwide/solargraph#1228: allow arguments to satisfy RBS interf…
apiology Aug 8, 2026
ac4eb27
Make Hash#fetch generic<X> leak spec RBS-version-aware
apiology Aug 8, 2026
dd31b94
Give RBS's bottom type its own tag instead of collapsing into undefined
apiology Aug 8, 2026
b022351
Merge castwide/solargraph#1277: give RBS bottom type its own tag
apiology Aug 8, 2026
0106b53
Drop pp gem's misdeclared ENV Class pin from YARD docs
apiology Aug 8, 2026
9a3c964
Narrow Hash intersection dispatch by _Key-shaped literal key match
apiology Aug 8, 2026
dda32df
Merge castwide/solargraph#1278: fix ENV[] typechecking
apiology Aug 8, 2026
65618b0
Make Hash#fetch generic<X> leak spec RBS-version-aware
apiology Aug 8, 2026
82f464e
Merge latest castwide/solargraph#1231: narrow Hash intersection dispa…
apiology Aug 8, 2026
92b6386
Restore version-conditional pending on #1231 _Key-narrowing specs
apiology Aug 8, 2026
71f16f8
Use skip, not pending, for the flaky #1231 _Key-narrowing specs
apiology Aug 8, 2026
83fb0ef
Resolve calls to a duck type param's own declared method
apiology Aug 11, 2026
8b97bb1
Expand RBS type aliases before conformance checks (#1255)
apiology Aug 11, 2026
d0ff6ce
Move duck type own-method regression test to alpha level
apiology Aug 11, 2026
d7e043f
Extract interface's own-declared-methods query onto ApiMap
apiology Aug 11, 2026
56e4b98
Document the generalization of key_param_index past Hash::_Key
apiology Aug 11, 2026
f729521
Fix generic return type lost on bare yield with no explicit block param
apiology Aug 11, 2026
a8970eb
Merge castwide/solargraph#1280: resolve calls to a duck type param's …
apiology Aug 11, 2026
4dae548
Merge castwide/solargraph#1281: expand RBS type aliases before confor…
apiology Aug 11, 2026
5207130
Update a parameter's flow-sensitive type after reassignment to a non-…
apiology Aug 11, 2026
368b3e0
Merge latest castwide/solargraph#1274: fix generic return type lost o…
apiology Aug 11, 2026
e40be90
Merge castwide/solargraph#1282: update a parameter's flow-sensitive t…
apiology Aug 11, 2026
b6eea57
Merge latest castwide/solargraph#1266: extract interface's own-declar…
apiology Aug 11, 2026
db2de94
Fix return type inference for methods with an ensure clause
apiology Aug 11, 2026
1c7ab6a
Merge remote-tracking branch 'origin/master' into consolidate-type-an…
apiology Aug 11, 2026
dd521f8
Fix Solargraph strong-mode gaps surfaced by CI's Ruby 4.0 + full rbs …
apiology Aug 11, 2026
78595a0
Merge castwide/solargraph#1285: fix return type inference for methods…
apiology Aug 11, 2026
d49cdab
Exclude self-referential positions from a variable's own presence
apiology Aug 11, 2026
f22dc56
Restore sg-ignore for Gem::StubSpecification unresolved on CI's exact…
apiology Aug 11, 2026
12f0a15
Move definite's long-form doc to the initializer's @param tag
apiology Aug 12, 2026
38abf73
Revert attr_reader split in Literal, use single sg-ignore instead
apiology Aug 12, 2026
47500b3
Fix generic binding through a cross-file @!parse stub
apiology Aug 12, 2026
dcab29f
Merge latest castwide/solargraph#1282: exclude self-referential posit…
apiology Aug 12, 2026
c53789b
Merge castwide/solargraph#1240: fix and re-enable strong-level typech…
apiology Aug 12, 2026
1933086
Fix Solargraph/strong and rubocop CI failures on the new hard gate
apiology Aug 12, 2026
c7ae548
Add smoke test for Store#get_methods combining many same-path pins
apiology Aug 12, 2026
cd567a0
Merge castwide/solargraph#1288: fix generic binding through a cross-f…
apiology Aug 12, 2026
0b60c02
Fix @yieldparam type lost on multi-overload block-form methods (#1289)
apiology Aug 12, 2026
2341ccc
Fix NoMethodError in Method#typify for closure-less duck-type pins
apiology Aug 12, 2026
fb7581b
Resolve type alias names against RBS core so cross-namespace aliases …
apiology Aug 12, 2026
db6a8f0
Merge castwide/solargraph#1290: fix @yieldparam type lost on multi-ov…
apiology Aug 12, 2026
8bf523c
Merge latest castwide/solargraph#1288: fix NoMethodError in Method#ty…
apiology Aug 12, 2026
a6942fc
Merge latest castwide/solargraph#1281: resolve type alias names again…
apiology Aug 12, 2026
3bedd92
Remove FileUtils @sg-ignore comments made unneeded by the latest #128…
apiology Aug 12, 2026
ce73329
Extend definite-reassignment override to local and instance variables
apiology Aug 12, 2026
b5c4dff
Match trailing keyword arguments to keyword/kwrest parameters, not by…
apiology Aug 12, 2026
97127a9
Fix Pin::Base#== missing presence, add regression coverage
apiology Aug 12, 2026
eee8ff1
Fix nil closure crash and unqualified super return type in Pin::Metho…
apiology Aug 12, 2026
4b5cc2c
Fix duck_types_match? to check the inferred type's own duck interface
apiology Aug 12, 2026
c09c1cc
Merge latest castwide/solargraph#1280: fix nil closure crash and unqu…
apiology Aug 13, 2026
aa15ca7
Merge castwide/solargraph#1295: fix duck_types_match? to check the in…
apiology Aug 13, 2026
7ffd503
Fix definite-reassignment override picking a stale pin during flow-se…
apiology Aug 13, 2026
fa659d3
Match keyword arguments by name, not by inferring the whole hash's type
apiology Aug 13, 2026
b555d1b
Narrow literal-equality (==/!=) guards against literal union members
apiology Aug 13, 2026
51cee0b
Merge latest castwide/solargraph#1282: fix definite-reassignment over…
apiology Aug 13, 2026
34a319a
Merge castwide/solargraph#1292: match trailing keyword arguments to k…
apiology Aug 13, 2026
d46c2b3
Merge castwide/solargraph#1297: narrow literal-equality (==/!=) guard…
apiology Aug 13, 2026
d791535
Fix duck-type conformance for Intersection-typed values
apiology Aug 13, 2026
b1eae2c
Remove @sg-ignore in ApiMap::Constants#resolve made unneeded by #1297
apiology Aug 13, 2026
301add9
Drop @sg-ignore for the quack nil case, guard it explicitly instead
apiology Aug 13, 2026
f1793f4
Remove 2 unneeded @sg-ignore comments in FlowSensitiveTyping#parse_li…
apiology Aug 13, 2026
8f7da39
Narrow duck-type fix back to the Intersection-only case
apiology Aug 13, 2026
dae8731
Merge latest castwide/solargraph#1231: fix duck-type conformance for …
apiology Aug 13, 2026
2034b42
Fix false Unresolved-call errors from exhaustive flow-typing exclusions
apiology Aug 13, 2026
4ad1667
Note follow-up path for #1277's bottom type
apiology Aug 13, 2026
a3ec7ba
Fix return-type inference for bang-wrapped or-expressions with flow n…
apiology Aug 13, 2026
cf003e4
Merge castwide/solargraph#1293: Fix Pin::Base#== missing presence
apiology Aug 13, 2026
c36a1cc
Merge castwide/solargraph#1277: give RBS bottom type its own tag
apiology Aug 13, 2026
a8c2669
Merge castwide/solargraph#1277: give RBS bottom type its own tag
apiology Aug 13, 2026
1dfef28
Add UniqueType::BOT constant
apiology Aug 13, 2026
bfae6eb
Merge latest castwide/solargraph#1277: add UniqueType::BOT constant
apiology Aug 13, 2026
10ab13c
Merge latest castwide/solargraph#1277: add UniqueType::BOT constant
apiology Aug 13, 2026
3e2f4b0
Resolve #1277 follow-up todo: tag exhausted exclusions as bot
apiology Aug 13, 2026
16c904d
Merge latest castwide/solargraph#1277: add UniqueType::BOT constant
apiology Aug 13, 2026
6a7c067
Merge latest castwide/solargraph#1280: no new changes beyond #1277 merge
apiology Aug 13, 2026
97b6444
Merge latest castwide/solargraph#1293: resolve #1277 follow-up todo
apiology Aug 13, 2026
c5bac5b
Fix missing closure on synthesized DuckMethod pins in Call#resolve
apiology Aug 13, 2026
1a227e9
Fix missing closure on the bot? DuckMethod pin
apiology Aug 13, 2026
c38b629
Add RBS fill for Gem::NameTuple
apiology Aug 13, 2026
c848f54
Revert "Add RBS fill for Gem::NameTuple"
apiology Aug 13, 2026
fe9c8dc
sg-ignore Gem::NameTuple gap in check_gem_version.rb
apiology Aug 13, 2026
e764484
Resolve generic type variables against union @param types
apiology Aug 14, 2026
67d86ea
Add more generic-in-union regression tests
apiology Aug 14, 2026
f7e98e1
Merge latest castwide/solargraph#1282: fix return-type inference for …
apiology Aug 14, 2026
0653590
Merge castwide/solargraph#1299: Resolve generic type variables agains…
apiology Aug 14, 2026
05aad7a
Fix Class<generic<T>>#new return type not inferring to generic<T>
apiology Aug 14, 2026
953f35e
Merge latest castwide/solargraph#1293: fix missing closure on the bot…
apiology Aug 14, 2026
f9973f0
Merge castwide/solargraph#1274: fix @generic return type lost when me…
apiology Aug 14, 2026
549b541
Override on conditional reassignment when the use site is dominated b…
apiology Aug 14, 2026
d2da7a8
Revert "Fix Class<generic<T>>#new return type not inferring to generi…
apiology Aug 14, 2026
afb58f2
Merge latest castwide/solargraph#1274: revert Class<generic<T>>#new f…
apiology Aug 14, 2026
5eb82f3
Add a CompoundStatement parent chain; derive closure as a fallback
apiology Aug 14, 2026
e324065
Rewrite override eligibility to walk the compound_statement chain
apiology Aug 14, 2026
02708aa
Merge pull request #57 from apiology/pr1-compound-statement-chain
apiology Aug 14, 2026
a1e8444
Fall back to a non-literal overload match when no literal one exists
apiology Aug 14, 2026
9fe7637
Move conditional from Region to the CompoundStatement pin itself
apiology Aug 14, 2026
1629164
Merge latest castwide/solargraph#1223: fall back to a non-literal ove…
apiology Aug 14, 2026
c5f20ea
Merge latest castwide/solargraph#1282: override on conditional reassi…
apiology Aug 14, 2026
ab0f718
Recognize RBS < 4.1's K-typed Hash key parameter
apiology Aug 14, 2026
bd9fb82
Merge latest castwide/solargraph#1231: recognize RBS < 4.1's K-typed …
apiology Aug 14, 2026
640e200
Un-skip the per-conjunct dispatch specs; the flake was a CI misread
apiology Aug 14, 2026
ce170d9
Retire the version-conditional Hash#fetch generic<X> assertion
apiology Aug 14, 2026
6cfed53
Read inline RBS superclass params only on the class line
apiology Aug 15, 2026
d645988
Merge castwide/solargraph#1301: don't let a bracketed comment in a cl…
apiology Aug 15, 2026
0b41411
Apply @!override to constants instead of crashing
apiology Aug 15, 2026
2c128cd
Index `X = Class.new(Super)` constant assignments as classes
apiology Aug 15, 2026
11e53bb
Cover duck type return tags in attached macros
apiology Aug 15, 2026
405770c
Merge castwide/solargraph#1262: backfill regression tests
apiology Aug 15, 2026
e049739
Narrow a nil-guarded default after the conditional
apiology Aug 15, 2026
cb9e7b0
Use an existing ignore category on the guarded-reassignment call
apiology Aug 15, 2026
f4cad2b
Merge castwide/solargraph#1305: apply @!override to constants instead…
apiology Aug 16, 2026
ad967a7
Merge castwide/solargraph#1306: index Class.new constant assignments …
apiology Aug 16, 2026
e52196a
Merge castwide/solargraph#1282: parameter reassignment typing and nil…
apiology Aug 16, 2026
ecc8fdd
Index gem constants defined with `Class.new`
apiology Aug 16, 2026
f3e1b54
Expire flow-sensitive narrowing at a definite reassignment
apiology Aug 16, 2026
1a9cb39
Cover coexistence with a hand-written `@!parse` stub
apiology Aug 16, 2026
3747c78
Treat a dominating reassignment as definite at that use site
apiology Aug 16, 2026
5215ce2
Narrow a variable assigned inside an if condition
apiology Aug 16, 2026
edc1648
Scrub reparsed pins by value type, not by ivar name
apiology Aug 16, 2026
cedb85d
Merge gem-pin Class.new reparse: index Class.new constants from yardoc
apiology Aug 16, 2026
2047ff5
Decouple guard-narrowing specs from falsy-type rendering
apiology Aug 16, 2026
3a424fc
Merge three flow-sensitive narrowing shapes: trailing-if, branch-loca…
apiology Aug 16, 2026
8f89ee7
Expire narrowing only when a different assignment overwrote it
apiology Aug 16, 2026
cb45cd8
Merge narrowing regression fix: expire only on a different assignment
apiology Aug 16, 2026
11e3386
Cover four-operand or-guards and their soundness controls
apiology Aug 16, 2026
b4733cf
Merge or-guard soundness controls
apiology Aug 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ jobs:
# solargraph-rails supports Ruby 3.0+
# This job uses 3.2 due to a problem compiling sqlite3 in earlier versions
ruby-version: '3.2'
bundler-cache: false
bundler-cache: true
# https://github.com/apiology/solargraph/actions/runs/19400815835/job/55508092473?pr=17
rubygems: latest
bundler: latest
Expand Down
25 changes: 20 additions & 5 deletions .github/workflows/rspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,28 @@ jobs:
# It currently 404s ("Unavailable version head for ruby"), failing CI:
# https://github.com/castwide/solargraph/actions/runs/25863741955/job/76000137015?pr=1187
ruby-version: ['3.1', '3.2', '3.3', '3.4', '4.0']
rbs-version: ['3.10.0', '4.0.0', '4.0.1', '4.0.2']
rbs-version: ['3.10.0', '4.0.3', '4.1.1']
exclude:
- ruby-version: '3.1'
rbs-version: '4.0.0'
rbs-version: '4.0.3'
- ruby-version: '3.1'
rbs-version: '4.0.1'
- ruby-version: '3.1'
rbs-version: '4.0.2'
rbs-version: '4.1.1'
steps:
- uses: actions/checkout@v3
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
# Without this pin, ruby/setup-ruby uses whatever bundler ships
# with each matrix Ruby version individually, rather than one
# consistent version across the matrix. Confirmed by removing
# it: stdlib/default-gem resolution changed enough that
# Workspace::Gemspecs#resolve_require('yaml') started returning
# nil, failing spec/api_map_method_spec.rb's YAML test across
# most of the matrix. Keep this in sync with Gemfile.lock's
# BUNDLED WITH version, and with the same pin below.
bundler: 2.5.23
- name: Set rbs version
run: echo "gem 'rbs', '${{ matrix.rbs-version }}'" >> .Gemfile
# /home/runner/.rubies/ruby-head/lib/ruby/gems/3.5.0+2/gems/rbs-3.9.4/lib/rbs.rb:11:
Expand Down Expand Up @@ -67,7 +74,15 @@ jobs:
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
# See the matching pin in the rspec matrix job above for why
# this is needed - keep both in sync with Gemfile.lock's
# BUNDLED WITH version.
bundler: 2.5.23
bundler-cache: true
- name: Install gems
run: |
bundle _2.5.23_ install
bundle update rbs # use latest available for this Ruby version
- name: Update types
run: bundle exec rbs collection update
- name: Run tests
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/typecheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,3 @@ jobs:
run: bundle exec rbs collection install
- name: Typecheck self
run: SOLARGRAPH_ASSERTS=on bundle exec solargraph typecheck --level strong
# @todo Temporary, expect to revert in 0.60
continue-on-error: true
6 changes: 6 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ Metrics/PerceivedComplexity:
Max: 40
RSpec/ExampleLength:
Max: 310
# Autocorrect mangles short-style Hash tags with nested generics/parens
# (e.g. Hash{Array(String, Array<String>) => String}) into invalid syntax.
# Confirmed broken through rubocop-yard 1.3.0 (latest as of this writing),
# against yard 0.9.45 (also latest as of this writing).
YARD/CollectionStyle:
Enabled: false

plugins:
- rubocop-rspec
Expand Down
1 change: 1 addition & 0 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Metrics/AbcSize:
Exclude:
- 'lib/solargraph/api_map/source_to_yard.rb'
- 'lib/solargraph/parser/parser_gem/node_chainer.rb'
- 'lib/solargraph/shell.rb'
- 'lib/solargraph/source/source_chainer.rb'
- 'lib/solargraph/source_map/clip.rb'
- 'lib/solargraph/source_map/mapper.rb'
Expand Down
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ source 'https://rubygems.org'
gemspec name: 'solargraph'

# Test fixture gems
# @sg-ignore Wrong argument type for Kernel#gem: arg_1 expected String, received Hash
gem 'gem-with-yard-macros', path: 'spec/fixtures/gem-with-yard-macros'

# Local gemfile for development tools, etc.
Expand Down
1 change: 0 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ task :full_spec do
FileUtils.mv('coverage/full-new', 'coverage/full')
end

# @sg-ignore #undercover return type could not be inferred
# @return [Process::Status]
def undercover
simplecov_collate
Expand Down
3 changes: 0 additions & 3 deletions lib/solargraph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,8 @@ def self.assert_or_log type, msg = nil, &block
raise "No message given for #{type.inspect}" if msg.nil?

# conditional aliases to handle compatibility corner cases
# @sg-ignore flow sensitive typing needs to handle 'raise if'
return if type == :alias_target_missing && msg.include?('highline/compatibility.rb')
# @sg-ignore flow sensitive typing needs to handle 'raise if'
return if type == :alias_target_missing && msg.include?('lib/json/add/date.rb')
# @sg-ignore flow sensitive typing needs to handle 'raise if'
return if type == :alias_target_missing && msg.include?('rubocop-ast.rbs')
# @todo :combine_with_visibility is not ready for prime time -
# lots of disagreements found in practice that heuristics need
Expand Down
87 changes: 63 additions & 24 deletions lib/solargraph/api_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ def catalog bench
end
unresolved_requires = (bench.external_requires + conventions_environ.requires + bench.workspace.config.required).to_a.compact.uniq
recreate_docmap = @unresolved_requires != unresolved_requires ||
# @sg-ignore Unresolved call to rbs_collection_path on Solargraph::Workspace, nil
workspace.rbs_collection_path != bench.workspace.rbs_collection_path ||
@doc_map.uncached_gemspecs.any?
@doc_map.any_uncached?

if recreate_docmap
@doc_map = DocMap.new(unresolved_requires, bench.workspace, out: nil) # @todo Implement gem preferences
Expand All @@ -145,10 +144,12 @@ def process_macros
closure = source_map.locate_closure_pin(node.location.line, node.location.column)
chain = Solargraph::Parser::ParserGem::NodeChainer.chain(node)
if node.children[0].nil? && store.macro_method_name_pins.key?(node.children[1].to_s)
# @sg-ignore Need to add nil check here
match = store.macro_method_name_pins[node.children[1].to_s].find do |pin|
get_complex_type_methods(closure.return_type).include?(pin)
end
if match
# @sg-ignore Need to add nil check here
match.macros.each do |macro|
macro_pins.concat macro.generate_pins_from(chain, match, source_map)
end
Expand All @@ -170,16 +171,6 @@ def uncached_gemspecs
doc_map.uncached_gemspecs || []
end

# @return [::Array<Gem::Specification>]
def uncached_rbs_collection_gemspecs
@doc_map.uncached_rbs_collection_gemspecs
end

# @return [::Array<Gem::Specification>]
def uncached_yard_gemspecs
@doc_map.uncached_yard_gemspecs
end

# @return [Enumerable<Pin::Base>]
def core_pins
@@core_map.pins
Expand All @@ -188,7 +179,6 @@ def core_pins
# @param name [String, nil]
# @return [Solargraph::YardMap::Macro, nil]
def named_macro name
# @sg-ignore Need to add nil check here
store.named_macros[name]
end

Expand All @@ -205,9 +195,11 @@ def conventions_environ
# @param filename [String]
# @param position [Position, Array(Integer, Integer)]
# @return [Source::Cursor]
# @sg-ignore Need to add nil check here
def cursor_at filename, position
position = Position.normalize(position)
raise FileNotFoundError, "File not found: #{filename}" unless source_map_hash.key?(filename)
# @sg-ignore Need to add nil check here
source_map_hash[filename].cursor_at(position)
end

Expand Down Expand Up @@ -241,7 +233,7 @@ def self.load directory, loose_unions: true
# @param rebuild [Boolean] whether to rebuild the pins even if they are cached
# @return [void]
def cache_all_for_doc_map! out: $stderr, rebuild: false
doc_map.cache_all!(out, rebuild: rebuild)
doc_map.cache_doc_map_gems!(out, rebuild: rebuild)
end

# @param gemspec [Gem::Specification]
Expand Down Expand Up @@ -416,7 +408,7 @@ def var_at_location candidates, name, closure, location
!pin.visible_at?(closure, location) && !pin.starts_at?(location)
end

vars_at_location.inject(&:combine_with)
vars_at_location.inject { |acc, pin| acc.combine_with(pin, location: location) }
end

# Get an array of class variable pins for a namespace.
Expand All @@ -442,6 +434,20 @@ def get_block_pins
store.pins_by_class(Pin::Block)
end

# Get the methods a namespace (e.g. an RBS interface) declares
# directly on itself, excluding ones inherited from Object,
# superclasses, or mixins. Useful for structural (duck-type)
# checks against an interface's own contract, e.g. whether some
# other type implements every method `Hash::_Key` itself declares
# (`#hash`, `#eql?`), independent of the interface's name.
#
# @param rooted_tag [String] The fully qualified namespace/interface to search for methods
# @param scope [Symbol] :class or :instance
# @return [Array<Solargraph::Pin::Method>]
def get_own_methods rooted_tag, scope: :instance
get_methods(rooted_tag, scope: scope).select { |pin| pin.closure&.path == rooted_tag }
end

# Get an array of methods available in a particular context.
#
# @param rooted_tag [String] The fully qualified namespace to search for methods
Expand All @@ -450,9 +456,14 @@ def get_block_pins
# @param deep [Boolean] True to include superclasses, mixins, etc.
# @return [Array<Solargraph::Pin::Method>]
def get_methods rooted_tag, scope: :instance, visibility: [:public], deep: true
if rooted_tag.start_with? 'Array('
# Array() are really tuples - use our fill, as the RBS repo
# does not give us definitions for it
rooted_tag = "Solargraph::Fills::Tuple(#{rooted_tag[6..-2]})"
end
rooted_type = ComplexType.try_parse(rooted_tag)
fqns = rooted_type.namespace
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
namespace_pin = namespace_pin_for_generics(fqns)
cached = cache.get_methods(rooted_tag, scope, visibility, deep)
return cached.clone unless cached.nil?
# @type [Array<Solargraph::Pin::Method>]
Expand Down Expand Up @@ -592,6 +603,7 @@ def get_method_stack rooted_tag, name, scope: :instance, visibility: %i[private
else
get_methods(rooted_tag, scope: scope, visibility: visibility).select { |p| p.name == name }
end
# @sg-ignore Need to add nil check here
methods = erase_generics(namespace_pin, rooted_type, methods) unless preserve_generics
methods
end
Expand Down Expand Up @@ -652,6 +664,7 @@ def query_symbols query
# @return [Array<Solargraph::Pin::Base>]
def locate_pins location
return [] if location.nil? || !source_map_hash.key?(location.filename)
# @sg-ignore Need to add nil check here
resolve_method_aliases source_map_hash[location.filename].locate_pins(location)
end

Expand All @@ -670,6 +683,7 @@ def clip cursor
# @return [Array<Pin::Symbol>]
def document_symbols filename
return [] unless source_map_hash.key?(filename) # @todo Raise error?
# @sg-ignore Need to add nil check here
resolve_method_aliases source_map_hash[filename].document_symbols
end

Expand All @@ -682,6 +696,7 @@ def source_maps
#
# @param filename [String]
# @return [SourceMap]
# @sg-ignore Need to add nil check here
def source_map filename
raise FileNotFoundError, "Source map for `#{filename}` not found" unless source_map_hash.key?(filename)
source_map_hash[filename]
Expand All @@ -706,14 +721,12 @@ def super_and_sub? sup, sub
# @todo If two literals are different values of the same type, it would
# make more sense for super_and_sub? to return true, but there are a
# few callers that currently expect this to be false.
# @sg-ignore flow-sensitive typing should be able to handle redefinition
return false if sup.literal? && sub.literal? && sup.to_s != sub.to_s
# @sg-ignore flow sensitive typing should be able to handle redefinition
sup = sup.simplify_literals.to_s
# @sg-ignore flow sensitive typing should be able to handle redefinition
sub = sub.simplify_literals.to_s
return true if sup == sub
sc_fqns = sub
# @sg-ignore flow sensitive typing unions rather than overrides types across multiple sequential reassignments
while (sc = store.get_superclass(sc_fqns))
# @sg-ignore flow sensitive typing needs to handle "if foo = bar"
sc_new = store.constants.dereference(sc)
Expand Down Expand Up @@ -750,10 +763,10 @@ def resolve_method_aliases pins, visibility = %i[public private protected]
logger.debug do
"ApiMap#resolve_method_aliases(pins=#{pins.map(&:name)}, visibility=#{visibility}) => #{with_resolved_aliases.map(&:name)}"
end
with_resolved_aliases
GemPins.combine_method_pins_by_path(with_resolved_aliases)
end

# @return [Workspace, nil]
# @return [Workspace]
def workspace
doc_map.workspace
end
Expand Down Expand Up @@ -783,9 +796,10 @@ def inner_get_methods_from_reference fq_reference_tag, namespace_pin, type, scop
# @todo Can inner_get_methods be cached? Lots of lookups of base types going on.
methods = inner_get_methods(resolved_reference_type.tag, scope, visibility, deep, skip, no_core)
if namespace_pin && !resolved_reference_type.all_params.empty?
reference_pin = store.get_path_pins(resolved_reference_type.name).select { |p| p.is_a?(Pin::Namespace) }.first
reference_pin = namespace_pin_for_generics(resolved_reference_type.name)
# logger.debug { "ApiMap#add_methods_from_reference(type=#{type}) - resolving generics with #{reference_pin.generics}, #{resolved_reference_type.rooted_tags}" }
methods = methods.map do |method_pin|
# @sg-ignore Need to add nil check here
method_pin.resolve_generics(reference_pin, resolved_reference_type)
end
end
Expand All @@ -799,6 +813,15 @@ def qualify_superclass fq_sub_tag
store.qualify_superclass fq_sub_tag
end

# @param require_path [String]
#
# @return [Array<Gem::Specification>, nil]
def resolve_require require_path
raise "Unable to resolve require '#{require_path}' without a workspace" if workspace.nil?

Workspace::Gemspecs.new(workspace.directory).resolve_require require_path
end

private

# A hash of source maps with filename keys.
Expand All @@ -811,6 +834,21 @@ def store
@store ||= Store.new
end

# Get the namespace pin that should be used to resolve generic type
# parameters for a fully qualified namespace. Multiple pins can
# exist for the same namespace (e.g., a gem's own class definition
# plus a `@!parse` stub in a different file that adds `@generic`
# tags); the one that actually declares the generics must be used,
# regardless of load order.
#
# @param fqns [String]
# @return [Pin::Namespace, nil]
def namespace_pin_for_generics fqns
# @type [Array<Pin::Namespace>]
candidates = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }
candidates.find { |p| !p.generics.empty? } || candidates.first
end

# @return [Solargraph::ApiMap::Cache]
attr_reader :cache

Expand All @@ -826,7 +864,7 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
rooted_type = ComplexType.parse(rooted_tag).force_rooted
fqns = rooted_type.namespace
rooted_type.all_params
namespace_pin = store.get_path_pins(fqns).select { |p| p.is_a?(Pin::Namespace) }.first
namespace_pin = namespace_pin_for_generics(fqns)
return [] if no_core && fqns =~ /^(Object|BasicObject|Class|Module)$/
reqstr = "#{fqns}|#{scope}|#{visibility.sort}|#{deep}"
return [] if skip.include?(reqstr)
Expand Down Expand Up @@ -867,6 +905,7 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
end
rooted_sc_tag = qualify_superclass(rooted_tag)
unless rooted_sc_tag.nil?
# @sg-ignore Need to add nil check here
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
visibility, true, skip, no_core)
end
Expand All @@ -880,6 +919,7 @@ def inner_get_methods rooted_tag, scope, visibility, deep, skip, no_core = false
end
rooted_sc_tag = qualify_superclass(rooted_tag)
unless rooted_sc_tag.nil?
# @sg-ignore Need to add nil check here
result.concat inner_get_methods_from_reference(rooted_sc_tag, namespace_pin, rooted_type, scope,
visibility, true, skip, true)
end
Expand Down Expand Up @@ -973,7 +1013,6 @@ def resolve_method_alias alias_pin
# :nocov:
end

# @sg-ignore ignore `received nil` for original
create_resolved_alias_pin(alias_pin, original)
end

Expand Down
Loading
Loading