class Parser::Source::Comment::Associator
@api public
* Magic encoding comment.
* Shebang line,
namely:
Skip file processing directives disguised as comments,
@!attribute skip_directives
#
def advance_comment
def advance_comment @comment_num += 1 end
def advance_through_directives
def advance_through_directives # Skip shebang. if current_comment && current_comment.text =~ /^#!/ advance_comment end # Skip encoding line. if current_comment && current_comment.text =~ Buffer::ENCODING_RE advance_comment end end
def associate
def associate @mapping = Hash.new { |h, k| h[k] = [] } @comment_num = 0 advance_through_directives if @skip_directives process(nil, @ast) @mapping end
def associate_and_advance_comment(node)
def associate_and_advance_comment(node) @mapping[node] << current_comment advance_comment end
def current_comment
def current_comment @comments[@comment_num] end
def current_comment_between?(prev_node, next_node)
def current_comment_between?(prev_node, next_node) return false if current_comment.nil? comment_loc = current_comment.location.expression next_loc = next_node.location.expression if prev_node.nil? comment_loc.end_pos <= next_loc.begin_pos else prev_loc = prev_node.location.expression comment_loc.begin_pos >= prev_loc.end_pos && comment_loc.end_pos <= next_loc.begin_pos end end
def initialize(comments, ast)
def initialize(comments, ast) @comments = comments @ast = ast @skip_directives = true end
def process(upper_node, node)
def process(upper_node, node) if node.type == :begin prev_node, next_node = nil, upper_node else while current_comment_between?(prev_node, node) associate_and_advance_comment(node) end prev_node, next_node = nil, upper_node end node.children.each do |child| if child.is_a?(AST::Node) && child.location.expression prev_node, next_node = next_node, child process(prev_node, child) end end end