Class: AyeVar::Processor

Inherits:
Prism::Visitor
  • Object
show all
Defined in:
lib/aye_var.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeProcessor

Returns a new instance of Processor.



37
38
39
40
# File 'lib/aye_var.rb', line 37

def initialize
  @context = Set[]
  @annotations = []
end

Instance Attribute Details

#annotationsObject (readonly)

Returns the value of attribute annotations.



42
43
44
# File 'lib/aye_var.rb', line 42

def annotations
  @annotations
end

Class Method Details

.call(source) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/aye_var.rb', line 17

def self.call(source)
  visitor = new
  visitor.visit(Prism.parse(source).value)

  buffer = source.dup

  visitor.annotations.sort_by(&:first).reverse_each do |offset, action, name|
    case action
    when :start
      buffer.insert(offset, "((::Kernel.raise ::AyeVar::NameError.new('Undefined instance variable #{name}') unless defined?(#{name})); ")
    when :end
      buffer.insert(offset, ")")
    else
      raise "Invalid annotation"
    end
  end

  buffer
end

Instance Method Details

#visit_block_node(node) ⇒ Object



52
53
54
# File 'lib/aye_var.rb', line 52

def visit_block_node(node)
  new_context { super }
end

#visit_case_node(node) ⇒ Object



79
80
81
82
83
84
85
86
87
# File 'lib/aye_var.rb', line 79

def visit_case_node(node)
  visit(node.predicate)

  node.conditions.each do |condition|
    branch { visit(condition) }
  end

  branch { visit(node.else_clause) }
end

#visit_class_node(node) ⇒ Object



44
45
46
# File 'lib/aye_var.rb', line 44

def visit_class_node(node)
  new_context { super }
end

#visit_def_node(node) ⇒ Object



68
69
70
# File 'lib/aye_var.rb', line 68

def visit_def_node(node)
  new_context { super }
end

#visit_defined_node(node) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/aye_var.rb', line 60

def visit_defined_node(node)
  if Prism::InstanceVariableReadNode === node.value
    @context << node.value.name
  end

  super
end

#visit_if_node(node) ⇒ Object



72
73
74
75
76
77
# File 'lib/aye_var.rb', line 72

def visit_if_node(node)
  visit(node.predicate)

  branch { visit(node.statements) }
  branch { visit(node.subsequent) }
end

#visit_instance_variable_read_node(node) ⇒ Object



89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/aye_var.rb', line 89

def visit_instance_variable_read_node(node)
  name = node.name

  unless @context.include?(name)
    location = node.location

    @context << name

    @annotations << [location.start_character_offset, :start, name]
    @annotations << [location.end_character_offset, :end, name]
  end

  super
end

#visit_module_node(node) ⇒ Object



48
49
50
# File 'lib/aye_var.rb', line 48

def visit_module_node(node)
  new_context { super }
end

#visit_singleton_class_node(node) ⇒ Object



56
57
58
# File 'lib/aye_var.rb', line 56

def visit_singleton_class_node(node)
  new_context { super }
end