Class: Gauge::CodeParser Private

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

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Class Method Summary collapse

Class Method Details

.code_to_ast(code) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/code_parser.rb', line 102

def self.code_to_ast(code)
  begin
    buffer = Parser::Source::Buffer.new '(string)'
    buffer.source = code
    parser = Parser::CurrentRuby.new
  parser.parse(buffer)
  rescue Exception => e
    GaugeLog.error "Cannot translate code to ast due to [#{e.message}], ignoring. Enable gauge debug logging to see the backtrace."
    GaugeLog.debug "Backtrace:"
    e.backtrace&.each { |line| GaugeLog.debug line }
  end
end

.create_diffs(old_node, new_node) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



69
70
71
72
73
74
75
76
77
# File 'lib/code_parser.rb', line 69

def self.create_diffs(old_node, new_node)
  step_loc = old_node.children[0].children[2].loc
  step_text = new_node.children[0].children[2].children[0]
  span = Messages::Span.new(start: step_loc.begin.line,
                            end: step_loc.end.line,
                            startChar: step_loc.begin.column + 1,
                            endChar: step_loc.end.column)
  [Messages::TextDiff.new(content: step_text, span: span), create_params_diff(old_node, new_node)]
end

.create_params_diff(old_node, new_node) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/code_parser.rb', line 55

def self.create_params_diff(old_node, new_node)
  params_loc = old_node.children[1].loc
  text = Unparser.unparse new_node.children[1]
  if old_node.children[1].children.size > 1
    span = Messages::Span.new(start: params_loc.begin.line, startChar: params_loc.begin.column + 1,
                              end: params_loc.end.line, endChar: params_loc.end.column)
  else
    span = Messages::Span.new(start: old_node.loc.begin.line, startChar: old_node.loc.begin.column,
                              end: old_node.children[2].loc.line, endChar: old_node.children[2].loc.column)
    text = "do#{text.empty? ? text : " |#{text}|"}\n\t"
  end
  Messages::TextDiff.new(content: text, span: span)
end

.process_node(node, param_positions, _new_param_values, new_step_text) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/code_parser.rb', line 21

def self.process_node(node, param_positions, _new_param_values, new_step_text)
  new_params = []
  args = step_args_from_code node
  old_params = args.map { |arg| Unparser.unparse arg }
  param_positions.sort_by!(&:newPosition).each.with_index do |e, i|
    if e.oldPosition == -1
      new_params[e.newPosition] = Util.get_param_name(old_params, i)
    else
      new_params[e.newPosition] = args[e.oldPosition].children[0]
    end
  end
  args = new_params.map { |v| Parser::AST::Node.new(:arg, [v]) }
  step = [node.children[0].children[0], node.children[0].children[1], Parser::AST::Node.new(:str, [new_step_text])]
  c1 = Parser::AST::Node.new(:send, step)
  c2 = Parser::AST::Node.new(:kwargs, args)
  Parser::AST::Node.new(:block, [c1, c2, node.children[2]])
end

.refactor(step_info, param_positions, new_step) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



93
94
95
96
97
98
# File 'lib/code_parser.rb', line 93

def self.refactor(step_info, param_positions, new_step)
  ast = code_to_ast File.read(step_info[:locations][0][:file])
  refactor_args(step_info[:step_text], ast, param_positions,
                new_step.parameters,
                new_step.parameterizedStepValue)
end

.refactor_args(step_text, ast, param_positions, new_param_values, new_step_text) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/code_parser.rb', line 79

def self.refactor_args(step_text, ast, param_positions, new_param_values, new_step_text)
diffs = nil
new_ast = replace ast do |node|
  if node.children[0].children[2].children[0] == step_text
    old_node = node.clone
    node = process_node(node, param_positions, new_param_values, new_step_text)
    diffs = create_diffs(old_node, node)
  end
    node
  end
code = Unparser.unparse new_ast
{ content: code, diffs: diffs }
end

.replace(ast, &visitor) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/code_parser.rb', line 39

def self.replace(ast, &visitor)
  return ast if ast.class != Parser::AST::Node
  if ast && step_node?(ast)
    visitor.call(ast)
  else
    children = ast.children.map do |node|
      replace(node, &visitor)
    end
    return ast.updated(nil, children, nil)
  end
end

.step_args_from_code(ast) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



16
17
18
19
# File 'lib/code_parser.rb', line 16

def self.step_args_from_code(ast)
  arg_node = ast.children[1]
  arg_node.children
end

.step_node?(node) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


51
52
53
# File 'lib/code_parser.rb', line 51

def self.step_node?(node)
  node.type == :block && node.children[0].children.size > 2 && node.children[0].children[1] == :step
end