Class: Prism::ParametersNode

Inherits:
PrismNode
  • Object
show all
Defined in:
lib/prism/node.rb,
lib/prism/node_ext.rb,
ext/prism/api_node.c

Overview

Represents the list of parameters on a method, block, or lambda definition.

def a(b, c, d)
      ^^^^^^^
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(requireds, optionals, rest, posts, keywords, keyword_rest, block, location) ⇒ ParametersNode

def initialize: (requireds: Array, optionals: Array, rest: Node?, posts: Array, keywords: Array, keyword_rest: Node?, block: BlockParameterNode?, location: Location) -> void



13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
# File 'lib/prism/node.rb', line 13187

def initialize(requireds, optionals, rest, posts, keywords, keyword_rest, block, location)
  @requireds = requireds
  @optionals = optionals
  @rest = rest
  @posts = posts
  @keywords = keywords
  @keyword_rest = keyword_rest
  @block = block
  @location = location
end

Instance Attribute Details

#blockObject (readonly)

attr_reader block: BlockParameterNode?



13184
13185
13186
# File 'lib/prism/node.rb', line 13184

def block
  @block
end

#keyword_restObject (readonly)

attr_reader keyword_rest: Node?



13181
13182
13183
# File 'lib/prism/node.rb', line 13181

def keyword_rest
  @keyword_rest
end

#keywordsObject (readonly)

attr_reader keywords: Array



13178
13179
13180
# File 'lib/prism/node.rb', line 13178

def keywords
  @keywords
end

#optionalsObject (readonly)

attr_reader optionals: Array



13169
13170
13171
# File 'lib/prism/node.rb', line 13169

def optionals
  @optionals
end

#postsObject (readonly)

attr_reader posts: Array



13175
13176
13177
# File 'lib/prism/node.rb', line 13175

def posts
  @posts
end

#requiredsObject (readonly)

attr_reader requireds: Array



13166
13167
13168
# File 'lib/prism/node.rb', line 13166

def requireds
  @requireds
end

#restObject (readonly)

attr_reader rest: Node?



13172
13173
13174
# File 'lib/prism/node.rb', line 13172

def rest
  @rest
end

Class Method Details

.typeObject

Similar to #type, this method returns a symbol that you can use for splitting on the type of the node without having to do a long === chain. Note that like #type, it will still be slower than using == for a single class, but should be faster in a case statement or an array comparison.

def self.type: () -> Symbol



13300
13301
13302
# File 'lib/prism/node.rb', line 13300

def self.type
  :parameters_node
end

Instance Method Details

#accept(visitor) ⇒ Object

def accept: (visitor: Visitor) -> void



13199
13200
13201
# File 'lib/prism/node.rb', line 13199

def accept(visitor)
  visitor.visit_parameters_node(self)
end

#child_nodesObject Also known as: deconstruct

def child_nodes: () -> Array[nil | Node]



13204
13205
13206
# File 'lib/prism/node.rb', line 13204

def child_nodes
  [*requireds, *optionals, rest, *posts, *keywords, keyword_rest, block]
end

#comment_targetsObject

def comment_targets: () -> Array[Node | Location]



13222
13223
13224
# File 'lib/prism/node.rb', line 13222

def comment_targets
  [*requireds, *optionals, *rest, *posts, *keywords, *keyword_rest, *block]
end

#compact_child_nodesObject

def compact_child_nodes: () -> Array



13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
# File 'lib/prism/node.rb', line 13209

def compact_child_nodes
  compact = []
  compact.concat(requireds)
  compact.concat(optionals)
  compact << rest if rest
  compact.concat(posts)
  compact.concat(keywords)
  compact << keyword_rest if keyword_rest
  compact << block if block
  compact
end

#copy(**params) ⇒ Object

def copy: (**params) -> ParametersNode



13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
# File 'lib/prism/node.rb', line 13227

def copy(**params)
  ParametersNode.new(
    params.fetch(:requireds) { requireds },
    params.fetch(:optionals) { optionals },
    params.fetch(:rest) { rest },
    params.fetch(:posts) { posts },
    params.fetch(:keywords) { keywords },
    params.fetch(:keyword_rest) { keyword_rest },
    params.fetch(:block) { block },
    params.fetch(:location) { location },
  )
end

#deconstruct_keys(keys) ⇒ Object

def deconstruct_keys: (keys: Array) -> Hash[Symbol, nil | Node | Array | String | Token | Array | Location]



13244
13245
13246
# File 'lib/prism/node.rb', line 13244

def deconstruct_keys(keys)
  { requireds: requireds, optionals: optionals, rest: rest, posts: posts, keywords: keywords, keyword_rest: keyword_rest, block: block, location: location }
end

#inspect(inspector = NodeInspector.new) ⇒ Object

def inspect(inspector: NodeInspector) -> String



13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
# File 'lib/prism/node.rb', line 13249

def inspect(inspector = NodeInspector.new)
  inspector << inspector.header(self)
  inspector << "├── requireds: #{inspector.list("#{inspector.prefix}", requireds)}"
  inspector << "├── optionals: #{inspector.list("#{inspector.prefix}", optionals)}"
  if (rest = self.rest).nil?
    inspector << "├── rest: ∅\n"
  else
    inspector << "├── rest:\n"
    inspector << rest.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
  end
  inspector << "├── posts: #{inspector.list("#{inspector.prefix}", posts)}"
  inspector << "├── keywords: #{inspector.list("#{inspector.prefix}", keywords)}"
  if (keyword_rest = self.keyword_rest).nil?
    inspector << "├── keyword_rest: ∅\n"
  else
    inspector << "├── keyword_rest:\n"
    inspector << keyword_rest.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
  end
  if (block = self.block).nil?
    inspector << "└── block: ∅\n"
  else
    inspector << "└── block:\n"
    inspector << block.inspect(inspector.child_inspector("    ")).delete_prefix(inspector.prefix)
  end
  inspector.to_str
end

#signatureObject

Mirrors the Method#parameters method.



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/prism/node_ext.rb', line 149

def signature
  names = []

  requireds.each do |param|
    names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name])
  end

  optionals.each { |param| names << [:opt, param.name] }
  names << [:rest, rest.name || :*] if rest

  posts.each do |param|
    names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name])
  end

  # Regardless of the order in which the keywords were defined, the required
  # keywords always come first followed by the optional keywords.
  keyopt = []
  keywords.each do |param|
    if param.is_a?(OptionalKeywordParameterNode)
      keyopt << param
    else
      names << [:keyreq, param.name]
    end
  end

  keyopt.each { |param| names << [:key, param.name] }

  case keyword_rest
  when ForwardingParameterNode
    names.concat([[:rest, :*], [:keyrest, :**], [:block, :&]])
  when KeywordRestParameterNode
    names << [:keyrest, keyword_rest.name || :**]
  when NoKeywordsParameterNode
    names << [:nokey]
  end

  names << [:block, block.name || :&] if block
  names
end

#typeObject

Sometimes you want to check an instance of a node against a list of classes to see what kind of behavior to perform. Usually this is done by calling ‘[cls1, cls2].include?(node.class)` or putting the node into a case statement and doing `case node; when cls1; when cls2; end`. Both of these approaches are relatively slow because of the constant lookups, method calls, and/or array allocations.

Instead, you can call #type, which will return to you a symbol that you can use for comparison. This is faster than the other approaches because it uses a single integer comparison, but also because if you’re on CRuby you can take advantage of the fact that case statements with all symbol keys will use a jump table.

def type: () -> Symbol



13290
13291
13292
# File 'lib/prism/node.rb', line 13290

def type
  :parameters_node
end