Class: SyntaxTree::Statements

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

Overview

Everything that has a block of code inside of it has a list of statements. Normally we would just track those as a node that has an array body, but we have some special handling in order to handle empty statement lists. They need to have the right location information, so all of the parent node of stmts nodes will report back down the location information. We then propagate that onto void_stmt nodes inside the stmts in order to make sure all comments get printed appropriately.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parser, body:, location:, comments: []) ⇒ Statements

Returns a new instance of Statements.



10323
10324
10325
10326
10327
10328
# File 'lib/syntax_tree.rb', line 10323

def initialize(parser, body:, location:, comments: [])
  @parser = parser
  @body = body
  @location = location
  @comments = comments
end

Instance Attribute Details

#bodyObject (readonly)

Array[ untyped ]

the list of expressions contained within this node



10315
10316
10317
# File 'lib/syntax_tree.rb', line 10315

def body
  @body
end

#commentsObject (readonly)

Array[ Comment | EmbDoc ]

the comments attached to this node



10321
10322
10323
# File 'lib/syntax_tree.rb', line 10321

def comments
  @comments
end

#locationObject (readonly)

Location

the location of this node



10318
10319
10320
# File 'lib/syntax_tree.rb', line 10318

def location
  @location
end

#parserObject (readonly)

SyntaxTree

the parser that is generating this node



10312
10313
10314
# File 'lib/syntax_tree.rb', line 10312

def parser
  @parser
end

Instance Method Details

#bind(start_char, end_char) ⇒ Object



10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
# File 'lib/syntax_tree.rb', line 10330

def bind(start_char, end_char)
  @location =
    Location.new(
      start_line: location.start_line,
      start_char: start_char,
      end_line: location.end_line,
      end_char: end_char
    )

  if body[0].is_a?(VoidStmt)
    location = body[0].location
    location =
      Location.new(
        start_line: location.start_line,
        start_char: start_char,
        end_line: location.end_line,
        end_char: start_char
      )

    body[0] = VoidStmt.new(location: location)
  end

  attach_comments(start_char, end_char)
end

#bind_end(end_char) ⇒ Object



10355
10356
10357
10358
10359
10360
10361
10362
10363
# File 'lib/syntax_tree.rb', line 10355

def bind_end(end_char)
  @location =
    Location.new(
      start_line: location.start_line,
      start_char: location.start_char,
      end_line: location.end_line,
      end_char: end_char
    )
end

#child_nodesObject



10371
10372
10373
# File 'lib/syntax_tree.rb', line 10371

def child_nodes
  body
end

#empty?Boolean

Returns:

  • (Boolean)


10365
10366
10367
10368
10369
# File 'lib/syntax_tree.rb', line 10365

def empty?
  body.all? do |statement|
    statement.is_a?(VoidStmt) && statement.comments.empty?
  end
end

#format(q) ⇒ Object



10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
# File 'lib/syntax_tree.rb', line 10375

def format(q)
  line = nil

  # This handles a special case where you've got a block of statements where
  # the only value is a comment. In that case a lot of nodes like
  # brace_block will attempt to format as a single line, but since that
  # wouldn't work with a comment, we intentionally break the parent group.
  if body.length == 2 && body.first.is_a?(VoidStmt)
    q.format(body.last)
    q.break_parent
    return
  end

  body.each_with_index do |statement, index|
    next if statement.is_a?(VoidStmt)

    if line.nil?
      q.format(statement)
    elsif (statement.location.start_line - line) > 1
      q.breakable(force: true)
      q.breakable(force: true)
      q.format(statement)
    elsif statement.is_a?(AccessCtrl) || body[index - 1].is_a?(AccessCtrl)
      q.breakable(force: true)
      q.breakable(force: true)
      q.format(statement)
    elsif statement.location.start_line != line
      q.breakable(force: true)
      q.format(statement)
    elsif !q.parent.is_a?(StringEmbExpr)
      q.breakable(force: true)
      q.format(statement)
    else
      q.text("; ")
      q.format(statement)
    end

    line = statement.location.end_line
  end
end

#pretty_print(q) ⇒ Object



10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
# File 'lib/syntax_tree.rb', line 10416

def pretty_print(q)
  q.group(2, "(", ")") do
    q.text("statements")

    q.breakable
    q.seplist(body) { |statement| q.pp(statement) }

    q.pp(Comment::List.new(comments))
  end
end

#to_json(*opts) ⇒ Object



10427
10428
10429
10430
10431
# File 'lib/syntax_tree.rb', line 10427

def to_json(*opts)
  { type: :statements, body: body, loc: location, cmts: comments }.to_json(
    *opts
  )
end