Skip to content

Commit

Permalink
Support trailing_positionals
Browse files Browse the repository at this point in the history
Closes #1172
  • Loading branch information
tk0miya committed Oct 8, 2024
1 parent 8ebbb39 commit ed1d6de
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
3 changes: 2 additions & 1 deletion lib/steep/ast/types/factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def function_1(func)
required_positionals: params.required.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
optional_positionals: params.optional.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
rest_positionals: params.rest&.yield_self {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
trailing_positionals: [],
trailing_positionals: params.trailing.map {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
required_keywords: params.required_keywords.transform_values {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
optional_keywords: params.optional_keywords.transform_values {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
rest_keywords: params.rest_keywords&.yield_self {|type| RBS::Types::Function::Param.new(name: nil, type: type_1(type)) },
Expand All @@ -263,6 +263,7 @@ def params(type)
required: type.required_positionals.map {|param| type(param.type) },
optional: type.optional_positionals.map {|param| type(param.type) },
rest: type.rest_positionals&.yield_self {|param| type(param.type) },
trailing: type.trailing_positionals.map {|param| type(param.type) },
required_keywords: type.required_keywords.transform_values {|param| type(param.type) },
optional_keywords: type.optional_keywords.transform_values {|param| type(param.type) },
rest_keywords: type.rest_keywords&.yield_self {|param| type(param.type) }
Expand Down
27 changes: 23 additions & 4 deletions lib/steep/interface/function.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,11 @@ def size
1 + (tail&.size || 0)
end

def self.build(required:, optional:, rest:)
params = rest ? self.rest(rest) : nil
def self.build(required:, optional:, rest:, trailing:)
# @type var params: Interface::Function::Params::PositionalParams?
params = nil
params = trailing.reverse_each.inject(params) {|params, type| self.required(type, params) }
params = self.rest(rest, params) if rest
params = optional.reverse_each.inject(params) {|params, type| self.optional(type, params) }
params = required.reverse_each.inject(params) {|params, type| self.required(type, params) }

Expand Down Expand Up @@ -769,11 +772,27 @@ def rest
nil
end

def trailing
array = [] #: Array[AST::Types::t]
trailing = false

positional_params&.each do |param|
case param
when PositionalParams::Required
array << param.type if trailing
when PositionalParams::Optional, PositionalParams::Rest
trailing = true
end
end

array
end

attr_reader :positional_params
attr_reader :keyword_params

def self.build(required: [], optional: [], rest: nil, required_keywords: {}, optional_keywords: {}, rest_keywords: nil)
positional_params = PositionalParams.build(required: required, optional: optional, rest: rest)
def self.build(required: [], optional: [], rest: nil, trailing: [], required_keywords: {}, optional_keywords: {}, rest_keywords: nil)
positional_params = PositionalParams.build(required: required, optional: optional, rest: rest, trailing: trailing)
keyword_params = KeywordParams.new(requireds: required_keywords, optionals: optional_keywords, rest: rest_keywords)
new(positional_params: positional_params, keyword_params: keyword_params)
end
Expand Down
6 changes: 4 additions & 2 deletions sig/steep/interface/function.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ module Steep

def size: () -> Integer

def self.build: (required: Array[AST::Types::t], optional: Array[AST::Types::t], rest: AST::Types::t?) -> PositionalParams?
def self.build: (required: Array[AST::Types::t], optional: Array[AST::Types::t], rest: AST::Types::t?, trailing: Array[AST::Types::t]) -> PositionalParams?

extend Utils

Expand Down Expand Up @@ -145,11 +145,13 @@ module Steep

%a{pure} def rest: () -> AST::Types::t?

def trailing: () -> Array[AST::Types::t]

attr_reader positional_params: PositionalParams?

attr_reader keyword_params: KeywordParams

def self.build: (?required: Array[AST::Types::t], ?optional: Array[AST::Types::t], ?rest: AST::Types::t?, ?required_keywords: ::Hash[Symbol, AST::Types::t], ?optional_keywords: ::Hash[Symbol, AST::Types::t], ?rest_keywords: AST::Types::t?) -> Params
def self.build: (?required: Array[AST::Types::t], ?optional: Array[AST::Types::t], ?rest: AST::Types::t?, ?trailing: Array[AST::Types::t], ?required_keywords: ::Hash[Symbol, AST::Types::t], ?optional_keywords: ::Hash[Symbol, AST::Types::t], ?rest_keywords: AST::Types::t?) -> Params

def initialize: (positional_params: PositionalParams?, keyword_params: KeywordParams) -> void

Expand Down
26 changes: 26 additions & 0 deletions test/type_check_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2054,6 +2054,32 @@ def f(x, y, z)
)
end

def test_method_def__trailing
run_type_check_test(
signatures: {
"a.rbs" => <<~RBS
class Hello
def f: (?untyped a, untyped b) -> void
end
RBS
},
code: {
"a.rb" => <<~RUBY
class Hello
def f(a = nil, b)
a.to_i + b
end
end
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics: []
YAML
)
end

def test_method_yield__untyped
run_type_check_test(
signatures: {
Expand Down

0 comments on commit ed1d6de

Please sign in to comment.