class ACLS::Parser

Public Class Methods

parse(base_dir) click to toggle source

Given a base directory, parse all Ruby source files into a custom Tree representation.

# File lib/acls/parser.rb, line 7
def parse(base_dir)
  parse_tree(Tree.new(nil, nil, base_dir), base_dir)
end

Private Class Methods

parse_ast(ast, parent, source) click to toggle source

Parse an AST Node.

# File lib/acls/parser.rb, line 43
def parse_ast(ast, parent, source)
  return if ast.nil? || !ast.is_a?(::AST::Node)

  if ast.type == :module
    parse_module(ast, parent, source)
  elsif ast.type == :class
    parse_class(ast, parent, source)
  else
    ast.children.each { |node| parse_ast(node, parent, source) }
  end

  parent
end
parse_class(ast, parent, source) click to toggle source

Parse a class. Similar to parsing a module, except you do not parse any child nodes.

# File lib/acls/parser.rb, line 38
def parse_class(ast, parent, source)
  parse_parent(ast, parent, source)
end
parse_file(tree, file) click to toggle source

Convert a source file into an AST and parse it.

# File lib/acls/parser.rb, line 58
def parse_file(tree, file)
  ast = ::Parser::CurrentRuby.parse(File.read(file))
  parse_ast(ast, tree, file)
end
parse_module(ast, parent, source) click to toggle source

Parse a module. Similar to parsing a class, except you continue to parse child nodes.

# File lib/acls/parser.rb, line 31
def parse_module(ast, parent, source)
  parent = parse_parent(ast, parent, source)
  ast.children[1..-1].map { |node| parse_ast(node, parent, source) }
end
parse_names(node, parent, source) click to toggle source

Attempt to parse a collection of module/class names to determine a fully-qualified namespace for a source module/class.

# File lib/acls/parser.rb, line 15
def parse_names(node, parent, source)
  return parent if node.nil?

  parent = parse_names(node.children.first, parent, source)
  parent.make_child(node.children.last, '', source)
end
parse_parent(ast, parent, source) click to toggle source

Parse an AST to get the top-most parent name and build a module/class chain from there.

# File lib/acls/parser.rb, line 24
def parse_parent(ast, parent, source)
  name = ast.children.first
  parse_names(name, parent, source)
end
parse_tree(tree, directory) click to toggle source
# File lib/acls/parser.rb, line 63
def parse_tree(tree, directory)
  Dir.entries(directory).each do |entry|
    next if entry[0] == '.'
    full_path = "#{directory}/#{entry}"
    if File.directory?(full_path)
      parse_tree(tree, full_path)
    elsif entry.end_with?('.rb')
      parse_file(tree, full_path)
    end
  end
  tree
end