Class: MotionBlender::Analyzer::Parser

Inherits:
Object
  • Object
show all
Includes:
ActiveSupport::Callbacks
Defined in:
lib/motion_blender/analyzer/parser.rb

Constant Summary collapse

REQUIREMENT_TOKENS =
i(motion_require require_relative require)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ Parser

Returns a new instance of Parser.



19
20
21
22
# File 'lib/motion_blender/analyzer/parser.rb', line 19

def initialize file
  @file = file.to_s
  @requires = []
end

Instance Attribute Details

#exclude_filesObject

Returns the value of attribute exclude_files.



17
18
19
# File 'lib/motion_blender/analyzer/parser.rb', line 17

def exclude_files
  @exclude_files
end

#fileObject (readonly)

Returns the value of attribute file.



16
17
18
# File 'lib/motion_blender/analyzer/parser.rb', line 16

def file
  @file
end

#last_traceObject (readonly)

Returns the value of attribute last_trace.



16
17
18
# File 'lib/motion_blender/analyzer/parser.rb', line 16

def last_trace
  @last_trace
end

#requiresObject (readonly)

Returns the value of attribute requires.



16
17
18
# File 'lib/motion_blender/analyzer/parser.rb', line 16

def requires
  @requires
end

Instance Method Details

#parseObject



24
25
26
27
# File 'lib/motion_blender/analyzer/parser.rb', line 24

def parse
  ast = ::Parser::CurrentRuby.parse(File.read(@file))
  traverse ast if ast
end

#raketime_block?(ast) ⇒ Boolean

Returns:

  • (Boolean)


51
52
53
54
# File 'lib/motion_blender/analyzer/parser.rb', line 51

def raketime_block? ast
  (ast.type == :block) &&
    (ast.children.first.loc.expression.source == 'MotionBlender.raketime')
end

#require_command?(ast) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/motion_blender/analyzer/parser.rb', line 47

def require_command? ast
  (ast.type == :send) && REQUIREMENT_TOKENS.include?(ast.children[1])
end

#trace_for(ast) ⇒ Object



56
57
58
# File 'lib/motion_blender/analyzer/parser.rb', line 56

def trace_for ast
  "#{@file}:#{ast.loc.line}:in `#{ast.children[1]}'"
end

#traverse(ast, stack = []) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/motion_blender/analyzer/parser.rb', line 29

def traverse ast, stack = []
  @exclude_files ||= Set.new
  if require_command?(ast)
    @last_trace = trace_for ast
    Evaluator.new(@file, ast, stack).parse_args.each do |arg|
      req = Require.new(@file, ast.children[1], arg)
      next if @exclude_files.include? req.arg
      next if @exclude_files.include? req.file
      req.trace = @last_trace
      @requires << req
    end
  elsif !raketime_block?(ast)
    ast.children
      .select { |node| node.is_a?(::Parser::AST::Node) }
      .each { |node| traverse node, [*stack, ast] }
  end
end