Class: SyntaxTree::Params

Inherits:
Node
  • Object
show all
Defined in:
lib/syntax_tree/node.rb

Overview

Params represents defining parameters on a method or lambda.

def method(param) end

Defined Under Namespace

Classes: KeywordFormatter, KeywordRestFormatter, OptionalFormatter

Instance Attribute Summary collapse

Attributes inherited from Node

#location

Instance Method Summary collapse

Methods inherited from Node

#construct_keys, #end_char, #pretty_print, #start_char, #to_json, #to_mermaid

Constructor Details

#initialize(requireds: [], optionals: [], rest: nil, posts: [], keywords: [], keyword_rest: nil, block: nil, location:) ⇒ Params

Returns a new instance of Params.



8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
# File 'lib/syntax_tree/node.rb', line 8257

def initialize(
  requireds: [],
  optionals: [],
  rest: nil,
  posts: [],
  keywords: [],
  keyword_rest: nil,
  block: nil,
  location:
)
  @requireds = requireds
  @optionals = optionals
  @rest = rest
  @posts = posts
  @keywords = keywords
  @keyword_rest = keyword_rest
  @block = block
  @location = location
  @comments = []
end

Instance Attribute Details

#blockObject (readonly)

nil | BlockArg

the optional block parameter



8252
8253
8254
# File 'lib/syntax_tree/node.rb', line 8252

def block
  @block
end

#commentsObject (readonly)

Array[ Comment | EmbDoc ]

the comments attached to this node



8255
8256
8257
# File 'lib/syntax_tree/node.rb', line 8255

def comments
  @comments
end

#keyword_restObject (readonly)

nil | :nil | ArgsForward | KwRestParam

the optional keyword rest

parameter



8249
8250
8251
# File 'lib/syntax_tree/node.rb', line 8249

def keyword_rest
  @keyword_rest
end

#keywordsObject (readonly)

Array[ [ Label, nil | Node

]] any keyword parameters and their

optional default values



8245
8246
8247
# File 'lib/syntax_tree/node.rb', line 8245

def keywords
  @keywords
end

#optionalsObject (readonly)

Array[ [ Ident, Node

]] any optional parameters and their default

values



8233
8234
8235
# File 'lib/syntax_tree/node.rb', line 8233

def optionals
  @optionals
end

#postsObject (readonly)

Array[ Ident ]

any positional parameters that exist after a rest

parameter



8241
8242
8243
# File 'lib/syntax_tree/node.rb', line 8241

def posts
  @posts
end

#requiredsObject (readonly)

Array[ Ident | MLHSParen ]

any required parameters



8229
8230
8231
# File 'lib/syntax_tree/node.rb', line 8229

def requireds
  @requireds
end

#restObject (readonly)

nil | ArgsForward | ExcessedComma | RestParam

the optional rest

parameter



8237
8238
8239
# File 'lib/syntax_tree/node.rb', line 8237

def rest
  @rest
end

Instance Method Details

#===(other) ⇒ Object



8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
# File 'lib/syntax_tree/node.rb', line 8382

def ===(other)
  other.is_a?(Params) && ArrayMatch.call(requireds, other.requireds) &&
    optionals.length == other.optionals.length &&
    optionals
      .zip(other.optionals)
      .all? { |left, right| ArrayMatch.call(left, right) } &&
    rest === other.rest && ArrayMatch.call(posts, other.posts) &&
    keywords.length == other.keywords.length &&
    keywords
      .zip(other.keywords)
      .all? { |left, right| ArrayMatch.call(left, right) } &&
    keyword_rest === other.keyword_rest && block === other.block
end

#accept(visitor) ⇒ Object



8287
8288
8289
# File 'lib/syntax_tree/node.rb', line 8287

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

#arityObject

Returns a range representing the possible number of arguments accepted by this params node not including the block. For example:

def foo(a, b = 1, c:, d: 2, &block)
  ...
end

has arity 2..4.



8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
# File 'lib/syntax_tree/node.rb', line 8405

def arity
  optional_keywords = keywords.count { |_label, value| value }

  lower_bound =
    requireds.length + posts.length + keywords.length - optional_keywords

  upper_bound =
    if keyword_rest.nil? && rest.nil?
      lower_bound + optionals.length + optional_keywords
    end

  lower_bound..upper_bound
end

#child_nodesObject Also known as: deconstruct



8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
# File 'lib/syntax_tree/node.rb', line 8291

def child_nodes
  [
    *requireds,
    *optionals.flatten(1),
    rest,
    *posts,
    *keywords.flatten(1),
    (keyword_rest if keyword_rest != :nil),
    block
  ]
end

#copy(location: nil, requireds: nil, optionals: nil, rest: nil, posts: nil, keywords: nil, keyword_rest: nil, block: nil) ⇒ Object



8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
# File 'lib/syntax_tree/node.rb', line 8303

def copy(
  location: nil,
  requireds: nil,
  optionals: nil,
  rest: nil,
  posts: nil,
  keywords: nil,
  keyword_rest: nil,
  block: nil
)
  node =
    Params.new(
      location: location || self.location,
      requireds: requireds || self.requireds,
      optionals: optionals || self.optionals,
      rest: rest || self.rest,
      posts: posts || self.posts,
      keywords: keywords || self.keywords,
      keyword_rest: keyword_rest || self.keyword_rest,
      block: block || self.block
    )

  node.comments.concat(comments.map(&:copy))
  node
end

#deconstruct_keys(_keys) ⇒ Object



8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
# File 'lib/syntax_tree/node.rb', line 8331

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

#empty?Boolean

Params nodes are the most complicated in the tree. Occasionally you want to know if they are “empty”, which means not having any parameters declared. This logic accesses every kind of parameter and determines if it’s missing.

Returns:

  • (Boolean)


8282
8283
8284
8285
# File 'lib/syntax_tree/node.rb', line 8282

def empty?
  requireds.empty? && optionals.empty? && !rest && posts.empty? &&
    keywords.empty? && !keyword_rest && !block
end

#format(q) ⇒ Object



8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
# File 'lib/syntax_tree/node.rb', line 8345

def format(q)
  parts = [
    *requireds,
    *optionals.map { |(name, value)| OptionalFormatter.new(name, value) }
  ]

  parts << rest if rest && !rest.is_a?(ExcessedComma)
  parts += [
    *posts,
    *keywords.map { |(name, value)| KeywordFormatter.new(name, value) }
  ]

  parts << KeywordRestFormatter.new(keyword_rest) if keyword_rest
  parts << block if block

  if parts.empty?
    q.nest(0) { format_contents(q, parts) }
    return
  end

  if q.parent.is_a?(DefNode)
    q.nest(0) do
      q.text("(")
      q.group do
        q.indent do
          q.breakable_empty
          format_contents(q, parts)
        end
        q.breakable_empty
      end
      q.text(")")
    end
  else
    q.nest(0) { format_contents(q, parts) }
  end
end