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_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
93 94 95 96 97 98 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 93 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_kwrest_param(node) ⇒ Object
86 87 88 89 90 91 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 86 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
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 61 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
79 80 81 82 83 84 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 79 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
101 102 103 104 105 106 107 108 109 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 101 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
114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/syntax_tree/visitor/with_environment.rb', line 114 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 |