2018-11-22 09:52:00 +00:00
|
|
|
require "./util"
|
|
|
|
|
2018-05-03 15:57:47 +00:00
|
|
|
module Ameba::AST
|
|
|
|
# A generic entity to represent a branchable Crystal node.
|
|
|
|
# For example, `Crystal::If`, `Crystal::Unless`, `Crystal::While`
|
2018-11-22 08:38:32 +00:00
|
|
|
# are branchables.
|
2018-05-03 15:57:47 +00:00
|
|
|
#
|
|
|
|
# ```
|
|
|
|
# white a > 100 # Branchable A
|
|
|
|
# if b > 2 # Branchable B
|
|
|
|
# a += 1
|
|
|
|
# end
|
|
|
|
# end
|
|
|
|
# ```
|
|
|
|
class Branchable
|
2018-11-22 09:52:00 +00:00
|
|
|
include Util
|
|
|
|
|
2018-05-03 15:57:47 +00:00
|
|
|
getter branches = [] of Crystal::ASTNode
|
|
|
|
|
|
|
|
# The actual Crystal node.
|
|
|
|
getter node : Crystal::ASTNode
|
|
|
|
|
|
|
|
# Parent branchable (if any)
|
|
|
|
getter parent : Branchable?
|
|
|
|
|
|
|
|
delegate to_s, to: @node
|
|
|
|
delegate location, to: @node
|
2018-11-24 17:38:13 +00:00
|
|
|
delegate end_location, to: @node
|
2018-05-03 15:57:47 +00:00
|
|
|
|
|
|
|
# Creates a new branchable
|
|
|
|
#
|
|
|
|
# ```
|
|
|
|
# Branchable.new(node, parent_branchable)
|
|
|
|
# ```
|
|
|
|
def initialize(@node, @parent = nil)
|
|
|
|
end
|
|
|
|
|
|
|
|
# Returns true if this node or one of the parent branchables is a loop, false otherwise.
|
|
|
|
def loop?
|
2021-01-11 18:13:58 +00:00
|
|
|
loop?(node) || parent.try(&.loop?) || false
|
2018-05-03 15:57:47 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|