Skip to content
This repository has been archived by the owner on Jul 5, 2023. It is now read-only.

rails_rbi:jobs raise unknown prefix error #538

Open
boiiiboi opened this issue Jan 19, 2023 · 2 comments · May be fixed by #543
Open

rails_rbi:jobs raise unknown prefix error #538

boiiiboi opened this issue Jan 19, 2023 · 2 comments · May be fixed by #543
Labels
bug Something isn't working

Comments

@boiiiboi
Copy link

Describe the bug:

After running rails_rbi:jobs, following error occured.

-- Generate sigs for ActiveJob ActiveStorage::BaseJob --
rails aborted!
unknown prefix

Steps to reproduce:

  1. Run rails_rbi:jobs

Expected behavior:

Expect to generate sigs successfully.

Versions:

  • Ruby: ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22]
  • Rails: Rails 7.0.4.1
  • Sorbet: Sorbet typechecker 0.5.10626 git 1204e682b8e83a919d8ec8a0753022f241f393ee debug_symbols=true clean=1
  • Sorbet-Rails: 0.7.34
@boiiiboi boiiiboi added the bug Something isn't working label Jan 19, 2023
@supersam654
Copy link

I'm running into this too while upgrading to Ruby 3.2.

  • Ruby: ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
  • Rails: Rails 7.0.4.1
  • Sorbet: Sorbet typechecker 0.5.10595 git cb7684fdb328e6e6d5f3f2687a3073f680f97df7 debug_symbols=true clean=0
  • Sorbet-Rails: 0.7.34

After poking around a bit, it looks like the "unknown prefix" error is coming from Parlour:

https://github.com/AaronC81/parlour/blob/baddfc5d9dbfcde15aebe88b2bff89b200ecb137/lib/parlour/rbi_generator/parameter.rb#L75-L82

Parlour appears to be struggling with "forward everything arguments" (https://bugs.ruby-lang.org/issues/16253) which ActiveJob uses for perform_now and perform_later. Notably, this syntax was introduced in Ruby 2.7.

https://github.com/rails/rails/blob/23e0345fe900dfd7edd6e8e5a7a6bd54b2a7d2ed/activejob/lib/active_job/enqueuing.rb#L28

https://github.com/rails/rails/blob/23e0345fe900dfd7edd6e8e5a7a6bd54b2a7d2ed/activejob/lib/active_job/execution.rb#L17

The method Parlour is generating RBI for is re-constructed in sorbet-rails around:

def self.parameters_from_method_def(method_def)
signature = T::Private::Methods.signature_for_method(method_def)
method_def = signature.nil? ? method_def : signature.method
parameters_with_type = signature.nil? ?
method_def.parameters.map { |p|
ParsedParamDef.new(
name: p.size == 1 ? :_ : p[1], # give param without name default name _
kind: p[0], # append untyped as type of each param
type_str: 'T.untyped',
)
} :
get_ordered_parameters_with_type(signature)
# add prefix & suffix
parameters_with_type.each do |param_def|
param_def.prefix =
case param_def.kind
when :rest; '*'
when :keyrest; '**'
when :block; '&'
# being comprehensive
when :req, :opt; ''
when :key, :keyreq; ''
else nil
end
param_def.suffix =
case param_def.kind
when :key, :keyreq; ':'
else nil
end
end
extract_default_value_for_params!(
parameters_with_type,
method_def,
)
parameters_with_type.map do |param_def|
::Parlour::RbiGenerator::Parameter.new(
"#{param_def.prefix}#{param_def.name}#{param_def.suffix}",
type: param_def.type_str,
default: param_def.default,
)
end
end

That method is generating invalid Parlour Parameters:

# run with `rails runner repro.rb`

class Foo
  def m(...); end
end

method_def = Foo.instance_method(:m)
params = SorbetRails::SorbetUtils.parameters_from_method_def(method_def)
params.each { |param| pp param }

Prints:

Warning: unable to parse the source of m
#<Parlour::RbiGenerator::Parameter:0x00007fc43a24d758
 @default=nil,
 @kind=:double_splat,
 @name="**",
 @type="T.untyped">
#<Parlour::RbiGenerator::Parameter:0x00007fc43a24d1b8
 @default=nil,
 @kind=:double_splat,
 @name="****",
 @type="T.untyped">
#<Parlour::RbiGenerator::Parameter:0x00007fc43a24cf38
 @default=nil,
 @kind=:block,
 @name="&&",
 @type="T.untyped">

This fix (which I'm hoping to have a PR for today if I don't get terribly sidetracked) appears to be updating parameters_from_method_def so it generates Parlour Parameters with valid names.

@supersam654 supersam654 linked a pull request Feb 24, 2023 that will close this issue
@simoleone
Copy link

This also happens when alias and alias_method are used because recent versions of ruby seem to use forward everything on the alias.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants