Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PATH
bundler (>= 2.2.25)
netrc (>= 0.11.0)
parallel (>= 1.21.0)
rbi (>= 0.3.7)
rbi (>= 0.4.3)
require-hooks (>= 0.2.2)
rubydex (>= 0.1.0.beta10)
sorbet-static-and-runtime (>= 0.6.12698)
Expand Down Expand Up @@ -307,7 +307,7 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.4.2)
rbi (0.4.2)
rbi (0.4.3)
prism (~> 1.0)
rbs (>= 4.0.1)
rbs (4.1.2)
Expand Down Expand Up @@ -584,7 +584,7 @@ CHECKSUMS
railties (8.1.3.1) sha256=2388a232579a00cefea4487de66c8553c3408c1300abdc6cf1799d86ffb04487
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
rbi (0.4.2) sha256=f1da92e338a6d45f9c4c1465b27a878a007fa7a0307f38abd29e6ddcb9f155b9
rbi (0.4.3) sha256=cc090ae62c3246412b992954f54077d6046c9b04f1537a4d24bfae8714503eac
rbs (4.1.2) sha256=050eb1d8b508f1233bed929c0f2c7052302f7adf295230d9cb314e9024078f48
rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
redis (5.4.0) sha256=798900d869418a9fc3977f916578375b45c38247a556b61d58cba6bb02f7d06b
Expand Down
26 changes: 2 additions & 24 deletions lib/tapioca/dsl/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,30 +161,8 @@ def compile_method_parameters_to_rbi(method_def)
parameters = method_def.parameters #: Array[[Symbol, Symbol?]]

parameters.each_with_index.map do |(type, name), index|
fallback_arg_name = "_arg#{index}"

name = name ? name.to_s : fallback_arg_name
name = fallback_arg_name unless valid_parameter_name?(name)
method_type = T.must(method_types[index])

case type
when :req
create_param(name, type: method_type)
when :opt
create_opt_param(name, type: method_type, default: "T.unsafe(nil)")
when :rest
create_rest_param(name, type: method_type)
when :keyreq
create_kw_param(name, type: method_type)
when :key
create_kw_opt_param(name, type: method_type, default: "T.unsafe(nil)")
when :keyrest
create_kw_rest_param(name, type: method_type)
when :block
create_block_param(name, type: method_type)
else
raise "Unknown type `#{type}`."
end
parameter, = create_method_parameter(type, name&.to_s, index)
create_typed_param(parameter, T.must(method_types[index]))
end
end

Expand Down
40 changes: 9 additions & 31 deletions lib/tapioca/gem/listeners/methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,8 @@ def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public

parameters = method.parameters #: Array[[Symbol, Symbol?]]

sanitized_parameters = parameters.each_with_index.map do |(type, name), index|
fallback_arg_name = "_arg#{index}"

name = if name
compiled_parameters = parameters.each_with_index.map do |(type, name), index|
parameter_name = if name
name.to_s
else
# For attr_writer methods, Sorbet signatures have the name
Expand All @@ -119,17 +117,11 @@ def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public
signature.arg_types.size == 1 &&
method_name[-1] == "="

if writer_method_with_sig
method_name.delete_suffix("=")
else
fallback_arg_name
end
method_name.delete_suffix("=") if writer_method_with_sig
end

# Sanitize param names
name = fallback_arg_name unless valid_parameter_name?(name)

[type, name]
parameter, signature_name = create_method_parameter(type, parameter_name, index)
[type, parameter, signature_name]
end

rbi_method = RBI::Method.new(
Expand All @@ -138,26 +130,12 @@ def compile_method(tree, symbol_name, constant, method, visibility = RBI::Public
visibility: visibility,
)

sanitized_parameters.each do |type, name|
case type
when :req
rbi_method << RBI::ReqParam.new(name)
when :opt
rbi_method << RBI::OptParam.new(name, "T.unsafe(nil)")
when :rest
rbi_method << RBI::RestParam.new(name)
when :keyreq
rbi_method << RBI::KwParam.new(name)
when :key
rbi_method << RBI::KwOptParam.new(name, "T.unsafe(nil)")
when :keyrest
rbi_method << RBI::KwRestParam.new(name)
when :block
rbi_method << RBI::BlockParam.new(name)
end
compiled_parameters.each do |_, parameter, _|
rbi_method << parameter
end

@pipeline.push_method(symbol_name, constant, method, rbi_method, signature, sanitized_parameters)
parameters_for_signature = compiled_parameters.map { |type, _, name| [type, name] }
@pipeline.push_method(symbol_name, constant, method, rbi_method, signature, parameters_for_signature)
tree << rbi_method
end

Expand Down
33 changes: 31 additions & 2 deletions lib/tapioca/helpers/rbi_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,43 @@ def extract_type_parameters(type_strings)
type_strings.join(", ").scan(TYPE_PARAMETER_MATCHER).flatten.uniq
end

#: (Symbol type, String? name, Integer index) -> [RBI::Param, String]
def create_method_parameter(type, name, index)
name = "_arg#{index}" unless valid_parameter_name?(name)
name = T.must(name)

parameter = case type
when :req
RBI::ReqParam.new(name)
when :opt
RBI::OptParam.new(name, "T.unsafe(nil)")
when :rest
RBI::RestParam.new(name)
when :keyreq
RBI::KwParam.new(name)
when :key
RBI::KwOptParam.new(name, "T.unsafe(nil)")
when :keyrest
RBI::KwRestParam.new(name)
when :block
RBI::BlockParam.new(name)
when :nokey
RBI::NoKwParam.new
else
Kernel.raise "Unknown type `#{type}`."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL, agent found that :nokey is a valid parameter kind for: def foo(*args, **nil). Apparently it's used to reject kwargs. It's not supported in rbi but Sorbet doesn't support it either so not raising might be enough.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will also be a :noblock version of it in Ruby 4.1: ruby/ruby@9967418

def foo(*args, &nil) = 42

method(:foo).parameters # => [[:rest, :args], [:noblock]]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support to rbi: Shopify/rbi#639

end

[parameter, name]
end

#: (String name) -> bool
def valid_method_name?(name)
Prism.parse_success?("def self.#{name}(a); end")
end

#: (String name) -> bool
#: (String? name) -> bool
def valid_parameter_name?(name)
Prism.parse_success?("def sentinel_method_name(#{name}:); end")
name ? Prism.parse_success?("def sentinel_method_name(#{name}:); end") : false
end
end
end
Loading
Loading