Module: SyntaxTree::WithEnvironment
- Defined in:
- lib/syntax_tree/visitor/with_environment.rb
Overview
WithEnvironment is a module intended to be included in classes inheriting from Visitor. The module overrides a few visit methods to automatically keep track of local variables and arguments defined in the current environment. Example usage:
class MyVisitor < Visitor
include WithEnvironment
def visit_ident(node)
# Check if we're visiting an identifier for an argument, a local
variable or something else
local = current_environment.find_local(node)
if local.type == :argument
# handle identifiers for arguments
elsif local.type == :variable
# handle identifiers for variables
else
# handle other identifiers, such as method names
end
end
Instance Method Summary collapse
- #current_environment ⇒ Object
- #visit_blockarg(node) ⇒ Object
-
#visit_class(node) ⇒ Object
Visits for nodes that create new environments, such as classes, modules and method definitions.
- #visit_def(node) ⇒ Object
- #visit_def_endless(node) ⇒ Object
- #visit_defs(node) ⇒ Object
- #visit_kwrest_param(node) ⇒ Object
-
#visit_method_add_block(node) ⇒ Object
When we find a method invocation with a block, only the code that happens inside of the block needs a fresh environment.
- #visit_module(node) ⇒ Object
-
#visit_params(node) ⇒ Object
Visit for keeping track of local arguments, such as method and block arguments.
- #visit_rest_param(node) ⇒ Object
-
#visit_var_field(node) ⇒ Object
(also: #visit_pinned_var_ref)
Visit for keeping track of local variable definitions.
-
#visit_var_ref(node) ⇒ Object
Visits for keeping track of variable and argument usages.
- #with_new_environment ⇒ Object
Instance Method Details
#current_environment ⇒ Object
25 26 27 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 25 def current_environment @current_environment ||= Environment.new end |
#visit_blockarg(node) ⇒ Object
101 102 103 104 105 106 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 101 def visit_blockarg(node) name = node.name current_environment.add_local_definition(name, :argument) if name super end |
#visit_class(node) ⇒ Object
Visits for nodes that create new environments, such as classes, modules and method definitions
39 40 41 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 39 def visit_class(node) with_new_environment { super } end |
#visit_def(node) ⇒ Object
55 56 57 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 55 def visit_def(node) with_new_environment { super } end |
#visit_def_endless(node) ⇒ Object
63 64 65 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 63 def visit_def_endless(node) with_new_environment { super } end |
#visit_defs(node) ⇒ Object
59 60 61 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 59 def visit_defs(node) with_new_environment { super } end |
#visit_kwrest_param(node) ⇒ Object
94 95 96 97 98 99 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 94 def visit_kwrest_param(node) name = node.name current_environment.add_local_definition(name, :argument) if name super end |
#visit_method_add_block(node) ⇒ Object
When we find a method invocation with a block, only the code that happens inside of the block needs a fresh environment. The method invocation itself happens in the same environment
50 51 52 53 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 50 def visit_method_add_block(node) visit(node.call) with_new_environment { visit(node.block) } end |
#visit_module(node) ⇒ Object
43 44 45 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 43 def visit_module(node) with_new_environment { super } end |
#visit_params(node) ⇒ Object
Visit for keeping track of local arguments, such as method and block arguments
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 69 def visit_params(node) add_argument_definitions(node.requireds) node.posts.each do |param| current_environment.add_local_definition(param, :argument) end node.keywords.each do |param| current_environment.add_local_definition(param.first, :argument) end node.optionals.each do |param| current_environment.add_local_definition(param.first, :argument) end super end |
#visit_rest_param(node) ⇒ Object
87 88 89 90 91 92 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 87 def visit_rest_param(node) name = node.name current_environment.add_local_definition(name, :argument) if name super end |
#visit_var_field(node) ⇒ Object Also known as: visit_pinned_var_ref
Visit for keeping track of local variable definitions
109 110 111 112 113 114 115 116 117 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 109 def visit_var_field(node) value = node.value if value.is_a?(SyntaxTree::Ident) current_environment.add_local_definition(value, :variable) end super end |
#visit_var_ref(node) ⇒ Object
Visits for keeping track of variable and argument usages
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 122 def visit_var_ref(node) value = node.value if value.is_a?(SyntaxTree::Ident) definition = current_environment.find_local(value.value) if definition current_environment.add_local_usage(value, definition.type) end end super end |
#with_new_environment ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 29 def with_new_environment previous_environment = @current_environment @current_environment = Environment.new(previous_environment) yield ensure @current_environment = previous_environment end |