Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging attributes with annotations fails #1709

Open
vinistock opened this issue Nov 6, 2023 · 5 comments
Open

Merging attributes with annotations fails #1709

vinistock opened this issue Nov 6, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@vinistock
Copy link
Member

When addressing ruby/prism#1767, I noticed that all of the type annotations associated with attr_reader were being lost. I believe we may be incorrectly merging type signatures for attributes.

Example:

# my_gem/rbi/some_file.rbi

class Foo
  sig { returns(Integer) }
  attr_reader :bar
end

When Tapioca generates the resulting RBI for my_gem, it should include the signature

# sorbet/rbi/gems/my_gem@0.1.0.rbi

class Foo
  sig { returns(Integer) } # this is missing
  def bar; end
end
@Morriar
Copy link
Collaborator

Morriar commented Nov 29, 2023

This is by design.

When trying to merge two definitions such as this:

# rbi/foo.rbi
class Foo
  attr_reader :foo; end
end

# lib/foo.rb
class Foo
  def foo; end
end

Tapioca will see that the shim says it's an attribute accessor yet the code says it's a method and will discard the shim as it indicate it may be out of date.

If the actual code uses a method the rbi file must use a method as well or the definition will be discarded.

@Morriar Morriar closed this as completed Nov 29, 2023
@vinistock
Copy link
Member Author

I'm not sure that was the exact case we were seeing in Prism. The shims under rbi were using attributes

    sig { returns(<%= field.rbi_class %>) }
    attr_reader :<%= field.name %>

And so is the actual code. Both were defined as attributes, but Tapioca seemed to be dropping them.

@Morriar
Copy link
Collaborator

Morriar commented Dec 1, 2023

Yeah, at the moment it seems that Tapioca can't see if a method comes from an attribute accessor or not.

If you look at the generated RBI for prism this attributes are actually generated as methods. I'm not sure we can easily change this behavior.

But indeed, we could be more lenient when it comes to merging and allow the merging of the signatures. This raises a question though. Should we keep the def of the attr_*? Our guideline right now is always to trust the generated RBI more than the shim but this may need to change.

@Morriar Morriar reopened this Dec 1, 2023
@paracycle
Copy link
Member

In Tapioca, we've always defaulted to generating reader/writer methods instead of attr_xxx declarations, because it is harder to figure out if a reader/writer method was defined via an attr_xxx call, but also because if Tapioca generated attr_xxx declarations, Sorbet would then do more work to turn them into reader/writer method definitions in its rewriter anyway.

Basically, you don't get any advantage from using attr_xxx declarations in RBIs, you actually get slightly worse performance because of the extra rewriter phases that need to happen.

As a result, I think we should:

  1. Merge attr_xxx declarations with the corresponding reader/writer method definitions, AND
  2. Always leave method definitions behind.

@andyw8
Copy link
Contributor

andyw8 commented Apr 19, 2024

We ran into this for Prism: Shopify/ruby-lsp#1953 (comment)

kddnewton pushed a commit to ruby/prism that referenced this issue Apr 19, 2024
Tapioca currently rewrites `attr_reader` methods in RBI files to normal
method definitions when merging signatures, but doesn't include the annotations
in the merged result.

Related issue: Shopify/tapioca#1709

This means that current methods typed with `attr_reader` in RBI files are
actually untyped in the merged RBI files. So this commit declares those
methods with normal method definitions in the RBI files to work around this
issue.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants