@@ -5,22 +5,25 @@ module SyntaxTree
5
5
# from Visitor. The module overrides a few visit methods to automatically keep
6
6
# track of local variables and arguments defined in the current environment.
7
7
# Example usage:
8
- # class MyVisitor < Visitor
9
- # include WithEnvironment
10
8
#
11
- # def visit_ident(node)
12
- # # Check if we're visiting an identifier for an argument, a local
13
- # variable or something else
14
- # local = current_environment.find_local(node)
9
+ # class MyVisitor < Visitor
10
+ # include WithEnvironment
15
11
#
16
- # if local.type == :argument
17
- # # handle identifiers for arguments
18
- # elsif local.type == :variable
19
- # # handle identifiers for variables
20
- # else
21
- # # handle other identifiers, such as method names
12
+ # def visit_ident(node)
13
+ # # Check if we're visiting an identifier for an argument, a local
14
+ # # variable or something else
15
+ # local = current_environment.find_local(node)
16
+ #
17
+ # if local.type == :argument
18
+ # # handle identifiers for arguments
19
+ # elsif local.type == :variable
20
+ # # handle identifiers for variables
21
+ # else
22
+ # # handle other identifiers, such as method names
23
+ # end
22
24
# end
23
- # end
25
+ # end
26
+ #
24
27
module WithEnvironment
25
28
# The environment class is used to keep track of local variables and
26
29
# arguments inside a particular scope
@@ -37,19 +40,16 @@ class Local
37
40
# [Array[Location]] The locations of all usages of this local
38
41
attr_reader :usages
39
42
40
- # initialize: (Symbol type) -> void
41
43
def initialize ( type )
42
44
@type = type
43
45
@definitions = [ ]
44
46
@usages = [ ]
45
47
end
46
48
47
- # add_definition: (Location location) -> void
48
49
def add_definition ( location )
49
50
@definitions << location
50
51
end
51
52
52
- # add_usage: (Location location) -> void
53
53
def add_usage ( location )
54
54
@usages << location
55
55
end
@@ -62,17 +62,15 @@ def add_usage(location)
62
62
# [Environment | nil] The parent environment
63
63
attr_reader :parent
64
64
65
- # initialize: (Environment | nil parent) -> void
66
65
def initialize ( parent = nil )
67
66
@locals = { }
68
67
@parent = parent
69
68
end
70
69
71
70
# Adding a local definition will either insert a new entry in the locals
72
- # hash or append a new definition location to an existing local. Notice that
73
- # it's not possible to change the type of a local after it has been
74
- # registered
75
- # add_local_definition: (Ident | Label identifier, Symbol type) -> void
71
+ # hash or append a new definition location to an existing local. Notice
72
+ # that it's not possible to change the type of a local after it has been
73
+ # registered.
76
74
def add_local_definition ( identifier , type )
77
75
name = identifier . value . delete_suffix ( ":" )
78
76
@@ -83,8 +81,7 @@ def add_local_definition(identifier, type)
83
81
# Adding a local usage will either insert a new entry in the locals
84
82
# hash or append a new usage location to an existing local. Notice that
85
83
# it's not possible to change the type of a local after it has been
86
- # registered
87
- # add_local_usage: (Ident | Label identifier, Symbol type) -> void
84
+ # registered.
88
85
def add_local_usage ( identifier , type )
89
86
name = identifier . value . delete_suffix ( ":" )
90
87
@@ -93,8 +90,7 @@ def add_local_usage(identifier, type)
93
90
end
94
91
95
92
# Try to find the local given its name in this environment or any of its
96
- # parents
97
- # find_local: (String name) -> Local | nil
93
+ # parents.
98
94
def find_local ( name )
99
95
local = @locals [ name ]
100
96
return local unless local . nil?
@@ -116,7 +112,7 @@ def with_new_environment
116
112
end
117
113
118
114
# Visits for nodes that create new environments, such as classes, modules
119
- # and method definitions
115
+ # and method definitions.
120
116
def visit_class ( node )
121
117
with_new_environment { super }
122
118
end
@@ -127,7 +123,7 @@ def visit_module(node)
127
123
128
124
# When we find a method invocation with a block, only the code that happens
129
125
# inside of the block needs a fresh environment. The method invocation
130
- # itself happens in the same environment
126
+ # itself happens in the same environment.
131
127
def visit_method_add_block ( node )
132
128
visit ( node . call )
133
129
with_new_environment { visit ( node . block ) }
@@ -138,7 +134,7 @@ def visit_def(node)
138
134
end
139
135
140
136
# Visit for keeping track of local arguments, such as method and block
141
- # arguments
137
+ # arguments.
142
138
def visit_params ( node )
143
139
add_argument_definitions ( node . requireds )
144
140
0 commit comments