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.



8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
# File 'lib/syntax_tree/node.rb', line 8288

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



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

def block
  @block
end

#commentsObject (readonly)

Array[ Comment | EmbDoc ]

the comments attached to this node



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

def comments
  @comments
end

#keyword_restObject (readonly)

nil | :nil | ArgsForward | KwRestParam

the optional keyword rest

parameter



8280
8281
8282
# File 'lib/syntax_tree/node.rb', line 8280

def keyword_rest
  @keyword_rest
end

#keywordsObject (readonly)

Array[ [ Label, nil | Node

]] any keyword parameters and their

optional default values



8276
8277
8278
# File 'lib/syntax_tree/node.rb', line 8276

def keywords
  @keywords
end

#optionalsObject (readonly)

Array[ [ Ident, Node

]] any optional parameters and their default

values



8264
8265
8266
# File 'lib/syntax_tree/node.rb', line 8264

def optionals
  @optionals
end

#postsObject (readonly)

Array[ Ident ]

any positional parameters that exist after a rest

parameter



8272
8273
8274
# File 'lib/syntax_tree/node.rb', line 8272

def posts
  @posts
end

#requiredsObject (readonly)

Array[ Ident | MLHSParen ]

any required parameters



8260
8261
8262
# File 'lib/syntax_tree/node.rb', line 8260

def requireds
  @requireds
end

#restObject (readonly)

nil | ArgsForward | ExcessedComma | RestParam

the optional rest

parameter



8268
8269
8270
# File 'lib/syntax_tree/node.rb', line 8268

def rest
  @rest
end

Instance Method Details

#===(other) ⇒ Object



8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
# File 'lib/syntax_tree/node.rb', line 8413

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



8318
8319
8320
# File 'lib/syntax_tree/node.rb', line 8318

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.



8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
# File 'lib/syntax_tree/node.rb', line 8436

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



8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
# File 'lib/syntax_tree/node.rb', line 8322

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



8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
# File 'lib/syntax_tree/node.rb', line 8334

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



8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
# File 'lib/syntax_tree/node.rb', line 8362

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)


8313
8314
8315
8316
# File 'lib/syntax_tree/node.rb', line 8313

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

#format(q) ⇒ Object



8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
# File 'lib/syntax_tree/node.rb', line 8376

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