Repository navigation
Conversation
Inline RBS declarations ignored the visibility of methods and attributes, so every method defined in Ruby was `public`. Detect the `public`/`private` calls in class/module bodies: - `private`/`public` without arguments is added as `AST::Ruby::Members::PrivateMember`/`PublicMember`, and switches the visibility of the instance methods and attributes defined after it, the same as `private`/`public` members in RBS - `private def foo`/`private attr_reader :foo` is recorded as the `visibility` of the `DefMember`/`AttributeMember`, the same as `private def foo: ...` in RBS `MethodBuilder` tracks the visibility members in Ruby declarations with the same loop as the RBS ones, and `DefinitionBuilder` uses the accessibility it gives instead of hardcoded `:public`. `private :foo, :bar`, `protected`, `private_class_method`, and `module_function` are out of scope and documented as limitations. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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
Inline RBS declarations ignored method visibility, so every method and attribute defined in Ruby was
public. This PR detectspublic/privatecalls in class/module bodies and applies them the same way RBS does.Approach
Two new shapes of visibility, both mirroring what RBS already has:
private/publicwithout arguments becomesAST::Ruby::Members::PrivateMember/PublicMember(subclasses ofVisibilityMember), and switches the visibility of the instance methods and attributes defined after it, likeprivate/publicmembers in RBS.private def foo/private attr_reader :foois recorded asvisibilityon theDefMember/AttributeMember, likeprivate def foo: ...in RBS. The parser keeps acurrent_visibilitywhile visiting the arguments of the call, so# @rbsannotations and#:assertions on thedefkeep working.Consumers:
MethodBuilderruns Ruby declarations through the sameeach_member_with_accessibilityloop as RBS declarations (renamed fromeach_rbs_member_with_accessibility), usingmember.visibility || accessibility.DefinitionBuilderuses the accessibilityMethodBuildercomputed instead of hardcoded:publicforDefMember, so an unannotatedprivate def foooverriding a public parent method is private.Environment#resolve_ruby_membercarriesvisibilitythrough, and passes the visibility members as they are.type_fingerprintincludes the visibility, so changing it triggers re-type-checking.As in Ruby and RBS,
privatewithout arguments does not affectdef self.methods.private def self.foois treated as a private singleton method, matching how RBS parsesprivate def self.foo: ....Out of scope
Documented as limitations in
docs/inline.md:private :foo, :bar(symbol arguments) is ignoredprotected,private_class_method, andmodule_functionVerification with Steep
Steep takes the visibility from
RBS::Definition::Method#private?, so no change on the Steep side is needed. Withcheck(inline: true)on the snippet above plus:steep checkRuby::NoMethodonFoo.new.hiddenandFoo.new.also_hiddenTests
test/rbs/inline_parser_test.rb: bareprivate/publicmembers,private def,private attr_*,@rbs skip, top-level, symbol arguments, and explicit receiver casestest/rbs/definition_builder_test.rb: accessibility of instance/singleton methods and attributes,public defin a private section, overriding a public parent method withprivate deftest/rbs/inline_type_fingerprint_test.rb: visibility changes the fingerprint🤖 Generated with Claude Code