Class: Crspec::Transpiler::Rewriter

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/crspec/transpiler/rewriter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_code) ⇒ Rewriter

Returns a new instance of Rewriter.



10
11
12
13
14
15
# File 'lib/crspec/transpiler/rewriter.rb', line 10

def initialize(source_code)
  super()
  @source_code = source_code
  @replacements = []
  @warnings = []
end

Instance Attribute Details

#transformed_codeObject (readonly)

Returns the value of attribute transformed_code.



8
9
10
# File 'lib/crspec/transpiler/rewriter.rb', line 8

def transformed_code
  @transformed_code
end

#warningsObject (readonly)

Returns the value of attribute warnings.



8
9
10
# File 'lib/crspec/transpiler/rewriter.rb', line 8

def warnings
  @warnings
end

Instance Method Details

#transpileObject



17
18
19
20
21
# File 'lib/crspec/transpiler/rewriter.rb', line 17

def transpile
  result = Prism.parse(@source_code)
  result.value.accept(self)
  apply_replacements
end

#visit_call_node(node) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/crspec/transpiler/rewriter.rb', line 23

def visit_call_node(node)
  # Convert RSpec.describe -> Crspec.describe
  if node.receiver.is_a?(Prism::ConstantReadNode) &&
     node.receiver.name == :RSpec &&
     node.name == :describe
    @replacements << {
      start_offset: node.receiver.location.start_offset,
      end_offset: node.receiver.location.end_offset,
      text: "Crspec"
    }
  end

  # Flag thread-unsafe before(:all) blocks
  if node.name == :before && node.arguments
    first_arg = node.arguments.arguments.first
    if first_arg.is_a?(Prism::SymbolNode) && first_arg.value == "all"
      @warnings << "Line #{node.location.start_line}: [Thread Safety Warning] before(:all) mutates global state across examples."
    end
  end

  super
end

#visit_constant_read_node(node) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/crspec/transpiler/rewriter.rb', line 46

def visit_constant_read_node(node)
  if node.name == :RSpec
    @replacements << {
      start_offset: node.location.start_offset,
      end_offset: node.location.end_offset,
      text: "Crspec"
    }
  end
  super
end