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