Class: Steep::TypeInference::SendArgs::PositionalArgs

Inherits:
Object
  • Object
show all
Defined in:
lib/steep/type_inference/send_args.rb

Defined Under Namespace

Classes: MissingArg, NodeParamPair, NodeTypePair, SplatArg, UnexpectedArg

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args:, index:, positional_params:, uniform: false) ⇒ PositionalArgs

Returns a new instance of PositionalArgs.



79
80
81
82
83
84
# File 'lib/steep/type_inference/send_args.rb', line 79

def initialize(args:, index:, positional_params:, uniform: false)
  @args = args
  @index = index
  @positional_params = positional_params
  @uniform = uniform
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



74
75
76
# File 'lib/steep/type_inference/send_args.rb', line 74

def args
  @args
end

#indexObject (readonly)

Returns the value of attribute index.



75
76
77
# File 'lib/steep/type_inference/send_args.rb', line 75

def index
  @index
end

#positional_paramsObject (readonly)

Returns the value of attribute positional_params.



76
77
78
# File 'lib/steep/type_inference/send_args.rb', line 76

def positional_params
  @positional_params
end

#uniformObject (readonly)

Returns the value of attribute uniform.



77
78
79
# File 'lib/steep/type_inference/send_args.rb', line 77

def uniform
  @uniform
end

Instance Method Details

#consume(n, node:) ⇒ Object



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/steep/type_inference/send_args.rb', line 153

def consume(n, node:)
  # @type var ps: Array[Interface::Function::Params::PositionalParams::param]
  ps = []
  params = consume0(n, node: node, params: positional_params, ps: ps)
  case params
  when UnexpectedArg
    [
      params,
      update(index: index+1, positional_params: nil)
    ]
  else
    [ps, update(index: index+1, positional_params: params)]
  end
end

#consume0(n, node:, params:, ps:) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/steep/type_inference/send_args.rb', line 168

def consume0(n, node:, params:, ps:)
  case n
  when 0
    params
  else
    head = params&.head
    case head
    when nil
      UnexpectedArg.new(node: node)
    when Interface::Function::Params::PositionalParams::Required, Interface::Function::Params::PositionalParams::Optional
      ps << head
      consume0(n-1, node: node, params: params&.tail, ps: ps)
    when Interface::Function::Params::PositionalParams::Rest
      ps << head
      consume0(n-1, node: node, params: params, ps: ps)
    end
  end
end

#following_argsObject



90
91
92
# File 'lib/steep/type_inference/send_args.rb', line 90

def following_args
  args[index..] or raise
end

#nextObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/steep/type_inference/send_args.rb', line 102

def next()
  case
  when node && node.type == :forwarded_args
    # If the node is a `:forwarded_args`, abort
    nil
  when !node && param.is_a?(Interface::Function::Params::PositionalParams::Required)
    [
      MissingArg.new(params: positional_params),
      update(index: index, positional_params: nil)
    ]
  when !node && param.is_a?(Interface::Function::Params::PositionalParams::Optional)
    nil
  when !node && param.is_a?(Interface::Function::Params::PositionalParams::Rest)
    nil
  when !node && !param
    nil
  when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Required)
    [
      NodeParamPair.new(node: node, param: param),
      update(index: index+1, positional_params: positional_params&.tail)
    ]
  when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Optional)
    [
      NodeParamPair.new(node: node, param: param),
      update(index: index+1, positional_params: positional_params&.tail)
    ]
  when node && node.type != :splat && param.is_a?(Interface::Function::Params::PositionalParams::Rest)
    [
      NodeParamPair.new(node: node, param: param),
      update(index: index+1)
    ]
  when node && node.type != :splat && !param
    [
      UnexpectedArg.new(node: node),
      update(index: index + 1)
    ]
  when node && node.type == :splat
    [
      SplatArg.new(node: node),
      self
    ]
  end
end

#nodeObject



86
87
88
# File 'lib/steep/type_inference/send_args.rb', line 86

def node
  args[index]
end

#paramObject



94
95
96
# File 'lib/steep/type_inference/send_args.rb', line 94

def param
  positional_params&.head
end

#uniform_typeObject



146
147
148
149
150
151
# File 'lib/steep/type_inference/send_args.rb', line 146

def uniform_type
  return nil unless positional_params
  if positional_params.each.any? {|param| param.is_a?(Interface::Function::Params::PositionalParams::Rest) }
    AST::Types::Intersection.build(types: positional_params.each.map(&:type))
  end
end

#update(index: self.index, positional_params: self.positional_params, uniform: self.uniform) ⇒ Object



98
99
100
# File 'lib/steep/type_inference/send_args.rb', line 98

def update(index: self.index, positional_params: self.positional_params, uniform: self.uniform)
  PositionalArgs.new(args: args, index: index, positional_params: positional_params, uniform: uniform)
end