ast 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b74cff86763a30c7b0b92c2aae6467d904ad2c4
4
- data.tar.gz: f829d02411d598e5b470ad57cf726d342349ff07
3
+ metadata.gz: 2e3398752b5d18c8a0d8d92566ddb560f35391bc
4
+ data.tar.gz: 1d08b307064106e701044d3f640c5cac033148c6
5
5
  SHA512:
6
- metadata.gz: 51d6106feef1199a6ae5f347c9121303479d155d13291292a0c733884fd88579f56be461237fd8d21551305649e85c9d556791aab1deaf45bee66ad387bb954c
7
- data.tar.gz: a310e6c19a8b83477e855b8fa9d95c1c1de9398b2308d91a84cbf1b84a52004c5193a10ac522474e9ee20f058c469c4e4de38369df2d2d21114b4afc62d196ce
6
+ metadata.gz: 2dfe3fe6af1cbfc6c4ce5dde12c8c285c10a4249779e8442ecbe1a9a73301dcb7e5b6028ccf4e7a4c7686b353762475103f85c1216f7ee4a69a55d8d8b6a3169
7
+ data.tar.gz: 752a64d60bf8b65c20782343a653958458f224fb4b124d258e1edef86e2c7acbd95fc9c5eebabbd7ebe4ced860e6fd0280412d180a896aabe8320ec3dfdc7a30
@@ -8,5 +8,5 @@ This is a design choice. It does create some pressure on
8
8
  garbage collector, but completely eliminates all concurrency
9
9
  and aliasing problems.
10
10
 
11
- See also {AST::Node}, {AST::Processor} and {AST::Sexp} for additional
12
- recommendations and design patterns.
11
+ See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for
12
+ additional recommendations and design patterns.
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ast'
3
- s.version = '2.0.0'
3
+ s.version = '2.1.0'
4
4
  s.license = 'MIT'
5
- s.authors = ["Peter Zotov"]
5
+ s.authors = ["whitequark"]
6
6
  s.email = ["whitequark@whitequark.org"]
7
7
  s.homepage = "https://whitequark.github.io/ast/"
8
8
  s.summary = %q{A library for working with Abstract Syntax Trees.}
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.add_development_dependency 'coveralls'
23
23
  s.add_development_dependency 'json_pure' # for coveralls on 1.9.2
24
24
  s.add_development_dependency 'mime-types', '~> 1.25' # for coveralls on 1.8.7
25
+ s.add_development_dependency 'rest-client', '~> 1.6.7' # 1.8.7
25
26
 
26
27
  s.add_development_dependency 'yard'
27
28
  s.add_development_dependency 'kramdown'
data/lib/ast.rb CHANGED
@@ -7,8 +7,8 @@
7
7
  # garbage collector, but completely eliminates all concurrency
8
8
  # and aliasing problems.
9
9
  #
10
- # See also {AST::Node}, {AST::Processor} and {AST::Sexp} for additional
11
- # recommendations and design patterns.
10
+ # See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for
11
+ # additional recommendations and design patterns.
12
12
  #
13
13
  module AST
14
14
  require 'ast/node'
@@ -1,266 +1,12 @@
1
1
  module AST
2
- # Processor is a class which helps transforming one AST into another.
3
- # In a nutshell, the {#process} method accepts a {Node} and dispatches
4
- # it to a handler corresponding to its type, and returns a (possibly)
5
- # updated variant of the node.
2
+ # This class includes {AST::Processor::Mixin}; however, it is
3
+ # deprecated, since the module defines all of the behaviors that
4
+ # the processor includes. Any new libraries should use
5
+ # {AST::Processor::Mixin} instead of subclassing this.
6
6
  #
7
- # Processor has a set of associated design patterns. They are best
8
- # explained with a concrete example. Let's define a simple arithmetic
9
- # language and an AST format for it:
10
- #
11
- # Terminals (AST nodes which do not have other AST nodes inside):
12
- #
13
- # * `(integer <int-literal>)`,
14
- #
15
- # Nonterminals (AST nodes with other nodes as children):
16
- #
17
- # * `(add <node> <node>)`,
18
- # * `(multiply <node> <node>)`,
19
- # * `(divide <node> <node>)`,
20
- # * `(negate <node>)`,
21
- # * `(store <node> <string-literal>)`: stores value of `<node>` into a variable named `<string-literal>`,
22
- # * `(load <string-literal>)`: loads value of a variable named `<string-literal>`,
23
- # * `(each <node> ...): computes each of the `<node>`s and prints the result.
24
- #
25
- # All AST nodes have the same Ruby class, and therefore they don't
26
- # know how to traverse themselves. (A solution which dynamically checks the
27
- # type of children is possible, but is slow and error-prone.) So, a subclass
28
- # of Processor which knows how to traverse the entire tree should be defined.
29
- # Such subclass has a handler for each nonterminal node which recursively
30
- # processes children nodes:
31
- #
32
- # require 'ast'
33
- #
34
- # class ArithmeticsProcessor < AST::Processor
35
- # # This method traverses any binary operators such as (add) or (multiply).
36
- # def process_binary_op(node)
37
- # # Children aren't decomposed automatically; it is suggested to use Ruby
38
- # # multiple assignment expansion, as it is very convenient here.
39
- # left_expr, right_expr = *node
40
- #
41
- # # AST::Node#updated won't change node type if nil is passed as a first
42
- # # argument, which allows to reuse the same handler for multiple node types
43
- # # using `alias' (below).
44
- # node.updated(nil, [
45
- # process(left_expr),
46
- # process(right_expr)
47
- # ])
48
- # end
49
- # alias on_add process_binary_op
50
- # alias on_multiply process_binary_op
51
- # alias on_divide process_binary_op
52
- #
53
- # def on_negate(node)
54
- # # It is also possible to use #process_all for more compact code
55
- # # if every child is a Node.
56
- # node.updated(nil, process_all(node))
57
- # end
58
- #
59
- # def on_store(node)
60
- # expr, variable_name = *node
61
- #
62
- # # Note that variable_name is not a Node and thus isn't passed to #process.
63
- # node.updated(nil, [
64
- # process(expr),
65
- # variable_name
66
- # ])
67
- # end
68
- #
69
- # # (load) is effectively a terminal node, and so it does not need
70
- # # an explicit handler, as the following is the default behavior.
71
- # def on_load(node)
72
- # nil
73
- # end
74
- #
75
- # def on_each(node)
76
- # node.updated(nil, process_all(node))
77
- # end
78
- # end
79
- #
80
- # Let's test our ArithmeticsProcessor:
81
- #
82
- # include AST::Sexp
83
- # expr = s(:add, s(:integer, 2), s(:integer, 2))
84
- #
85
- # p ArithmeticsProcessor.new.process(expr) == expr # => true
86
- #
87
- # As expected, it does not change anything at all. This isn't actually
88
- # very useful, so let's now define a Calculator, which will compute the
89
- # expression values:
90
- #
91
- # # This Processor folds nonterminal nodes and returns an (integer)
92
- # # terminal node.
93
- # class ArithmeticsCalculator < ArithmeticsProcessor
94
- # def compute_op(node)
95
- # # First, node children are processed and then unpacked to local
96
- # # variables.
97
- # nodes = process_all(node)
98
- #
99
- # if nodes.all? { |node| node.type == :integer }
100
- # # If each of those nodes represents a literal, we can fold this
101
- # # node!
102
- # values = nodes.map { |node| node.children.first }
103
- # AST::Node.new(:integer, [
104
- # yield(values)
105
- # ])
106
- # else
107
- # # Otherwise, we can just leave the current node in the tree and
108
- # # only update it with processed children nodes, which can be
109
- # # partially folded.
110
- # node.updated(nil, nodes)
111
- # end
112
- # end
113
- #
114
- # def on_add(node)
115
- # compute_op(node) { |left, right| left + right }
116
- # end
117
- #
118
- # def on_multiply(node)
119
- # compute_op(node) { |left, right| left * right }
120
- # end
121
- # end
122
- #
123
- # Let's check:
124
- #
125
- # p ArithmeticsCalculator.new.process(expr) # => (integer 4)
126
- #
127
- # Excellent, the calculator works! Now, a careful reader could notice that
128
- # the ArithmeticsCalculator does not know how to divide numbers. What if we
129
- # pass an expression with division to it?
130
- #
131
- # expr_with_division = \
132
- # s(:add,
133
- # s(:integer, 1),
134
- # s(:divide,
135
- # s(:add, s(:integer, 8), s(:integer, 4)),
136
- # s(:integer, 3))) # 1 + (8 + 4) / 3
137
- #
138
- # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
139
- # p folded_expr_with_division
140
- # # => (add
141
- # # (integer 1)
142
- # # (divide
143
- # # (integer 12)
144
- # # (integer 3)))
145
- #
146
- # As you can see, the expression was folded _partially_: the inner `(add)` node which
147
- # could be computed was folded to `(integer 12)`, the `(divide)` node is left as-is
148
- # because there is no computing handler for it, and the root `(add)` node was also left
149
- # as it is because some of its children were not literals.
150
- #
151
- # Note that this partial folding is only possible because the _data_ format, i.e.
152
- # the format in which the computed values of the nodes are represented, is the same as
153
- # the AST itself.
154
- #
155
- # Let's extend our ArithmeticsCalculator class further.
156
- #
157
- # class ArithmeticsCalculator
158
- # def on_divide(node)
159
- # compute_op(node) { |left, right| left / right }
160
- # end
161
- #
162
- # def on_negate(node)
163
- # # Note how #compute_op works regardless of the operator arity.
164
- # compute_op(node) { |value| -value }
165
- # end
166
- # end
167
- #
168
- # Now, let's apply our renewed ArithmeticsCalculator to a partial result of previous
169
- # evaluation:
170
- #
171
- # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
172
- #
173
- # Five! Excellent. This is also pretty much how CRuby 1.8 executed its programs.
174
- #
175
- # Now, let's do some automated bug searching. Division by zero is an error, right?
176
- # So if we could detect that someone has divided by zero before the program is even
177
- # run, that could save some debugging time.
178
- #
179
- # class DivisionByZeroVerifier < ArithmeticsProcessor
180
- # class VerificationFailure < Exception; end
181
- #
182
- # def on_divide(node)
183
- # # You need to process the children to handle nested divisions
184
- # # such as:
185
- # # (divide
186
- # # (integer 1)
187
- # # (divide (integer 1) (integer 0))
188
- # left, right = process_all(node)
189
- #
190
- # if right.type == :integer &&
191
- # right.children.first == 0
192
- # raise VerificationFailure, "Ouch! This code divides by zero."
193
- # end
194
- # end
195
- #
196
- # def divides_by_zero?(ast)
197
- # process(ast)
198
- # false
199
- # rescue VerificationFailure
200
- # true
201
- # end
202
- # end
203
- #
204
- # nice_expr = \
205
- # s(:divide,
206
- # s(:add, s(:integer, 10), s(:integer, 2)),
207
- # s(:integer, 4))
208
- #
209
- # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
210
- # # => false. Good.
211
- #
212
- # bad_expr = \
213
- # s(:add, s(:integer, 10),
214
- # s(:divide, s(:integer, 1), s(:integer, 0)))
215
- #
216
- # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
217
- # # => true. WHOOPS. DO NOT RUN THIS.
218
- #
219
- # Of course, this won't detect more complex cases... unless you use some partial
220
- # evaluation before! The possibilites are endless. Have fun.
7
+ # @deprecated Use {AST::Processor::Mixin} instead.
221
8
  class Processor
222
- # Dispatches `node`. If a node has type `:foo`, then a handler named
223
- # `on_foo` is invoked with one argument, the `node`; if there isn't
224
- # such a handler, {#handler_missing} is invoked with the same argument.
225
- #
226
- # If the handler returns `nil`, `node` is returned; otherwise, the return
227
- # value of the handler is passed along.
228
- #
229
- # @param [AST::Node, nil] node
230
- # @return [AST::Node, nil]
231
- def process(node)
232
- return if node.nil?
233
-
234
- node = node.to_ast
235
-
236
- # Invoke a specific handler
237
- on_handler = :"on_#{node.type}"
238
- if respond_to? on_handler
239
- new_node = send on_handler, node
240
- else
241
- new_node = handler_missing(node)
242
- end
243
-
244
- node = new_node if new_node
245
-
246
- node
247
- end
248
-
249
- # {#process}es each node from `nodes` and returns an array of results.
250
- #
251
- # @param [Array<AST::Node>] nodes
252
- # @return [Array<AST::Node>]
253
- def process_all(nodes)
254
- nodes.to_a.map do |node|
255
- process node
256
- end
257
- end
258
-
259
- # Default handler. Does nothing.
260
- #
261
- # @param [AST::Node] node
262
- # @return [AST::Node, nil]
263
- def handler_missing(node)
264
- end
9
+ require 'ast/processor/mixin'
10
+ include Mixin
265
11
  end
266
12
  end
@@ -0,0 +1,288 @@
1
+ module AST
2
+ class Processor
3
+ # The processor module is a module which helps transforming one
4
+ # AST into another. In a nutshell, the {#process} method accepts
5
+ # a {Node} and dispatches it to a handler corresponding to its
6
+ # type, and returns a (possibly) updated variant of the node.
7
+ #
8
+ # The processor module has a set of associated design patterns.
9
+ # They are best explained with a concrete example. Let's define a
10
+ # simple arithmetic language and an AST format for it:
11
+ #
12
+ # Terminals (AST nodes which do not have other AST nodes inside):
13
+ #
14
+ # * `(integer <int-literal>)`,
15
+ #
16
+ # Nonterminals (AST nodes with other nodes as children):
17
+ #
18
+ # * `(add <node> <node>)`,
19
+ # * `(multiply <node> <node>)`,
20
+ # * `(divide <node> <node>)`,
21
+ # * `(negate <node>)`,
22
+ # * `(store <node> <string-literal>)`: stores value of `<node>`
23
+ # into a variable named `<string-literal>`,
24
+ # * `(load <string-literal>)`: loads value of a variable named
25
+ # `<string-literal>`,
26
+ # * `(each <node> ...): computes each of the `<node>`s and
27
+ # prints the result.
28
+ #
29
+ # All AST nodes have the same Ruby class, and therefore they don't
30
+ # know how to traverse themselves. (A solution which dynamically
31
+ # checks the type of children is possible, but is slow and
32
+ # error-prone.) So, a class including the module which knows how
33
+ # to traverse the entire tree should be defined. Such classes
34
+ # have a handler for each nonterminal node which recursively
35
+ # processes children nodes:
36
+ #
37
+ # require 'ast'
38
+ #
39
+ # class ArithmeticsProcessor
40
+ # include AST::Processor::Module
41
+ # # This method traverses any binary operators such as (add)
42
+ # # or (multiply).
43
+ # def process_binary_op(node)
44
+ # # Children aren't decomposed automatically; it is
45
+ # # suggested to use Ruby multiple assignment expansion,
46
+ # # as it is very convenient here.
47
+ # left_expr, right_expr = *node
48
+ #
49
+ # # AST::Node#updated won't change node type if nil is
50
+ # # passed as a first argument, which allows to reuse the
51
+ # # same handler for multiple node types using `alias'
52
+ # # (below).
53
+ # node.updated(nil, [
54
+ # process(left_expr),
55
+ # process(right_expr)
56
+ # ])
57
+ # end
58
+ # alias_method :on_add, :process_binary_op
59
+ # alias_method :on_multiply, :process_binary_op
60
+ # alias_method :on_divide, :process_binary_op
61
+ #
62
+ # def on_negate(node)
63
+ # # It is also possible to use #process_all for more
64
+ # # compact code if every child is a Node.
65
+ # node.updated(nil, process_all(node))
66
+ # end
67
+ #
68
+ # def on_store(node)
69
+ # expr, variable_name = *node
70
+ #
71
+ # # Note that variable_name is not a Node and thus isn't
72
+ # # passed to #process.
73
+ # node.updated(nil, [
74
+ # process(expr),
75
+ # variable_name
76
+ # ])
77
+ # end
78
+ #
79
+ # # (load) is effectively a terminal node, and so it does
80
+ # # not need an explicit handler, as the following is the
81
+ # # default behavior. Essentially, for any nodes that don't
82
+ # # have a defined handler, the node remains unchanged.
83
+ # def on_load(node)
84
+ # nil
85
+ # end
86
+ #
87
+ # def on_each(node)
88
+ # node.updated(nil, process_all(node))
89
+ # end
90
+ # end
91
+ #
92
+ # Let's test our ArithmeticsProcessor:
93
+ #
94
+ # include AST::Sexp
95
+ # expr = s(:add, s(:integer, 2), s(:integer, 2))
96
+ #
97
+ # p ArithmeticsProcessor.new.process(expr) == expr # => true
98
+ #
99
+ # As expected, it does not change anything at all. This isn't
100
+ # actually very useful, so let's now define a Calculator, which
101
+ # will compute the expression values:
102
+ #
103
+ # # This Processor folds nonterminal nodes and returns an
104
+ # # (integer) terminal node.
105
+ # class ArithmeticsCalculator < ArithmeticsProcessor
106
+ # def compute_op(node)
107
+ # # First, node children are processed and then unpacked
108
+ # # to local variables.
109
+ # nodes = process_all(node)
110
+ #
111
+ # if nodes.all? { |node| node.type == :integer }
112
+ # # If each of those nodes represents a literal, we can
113
+ # # fold this node!
114
+ # values = nodes.map { |node| node.children.first }
115
+ # AST::Node.new(:integer, [
116
+ # yield(values)
117
+ # ])
118
+ # else
119
+ # # Otherwise, we can just leave the current node in the
120
+ # # tree and only update it with processed children
121
+ # # nodes, which can be partially folded.
122
+ # node.updated(nil, nodes)
123
+ # end
124
+ # end
125
+ #
126
+ # def on_add(node)
127
+ # compute_op(node) { |left, right| left + right }
128
+ # end
129
+ #
130
+ # def on_multiply(node)
131
+ # compute_op(node) { |left, right| left * right }
132
+ # end
133
+ # end
134
+ #
135
+ # Let's check:
136
+ #
137
+ # p ArithmeticsCalculator.new.process(expr) # => (integer 4)
138
+ #
139
+ # Excellent, the calculator works! Now, a careful reader could
140
+ # notice that the ArithmeticsCalculator does not know how to
141
+ # divide numbers. What if we pass an expression with division to
142
+ # it?
143
+ #
144
+ # expr_with_division = \
145
+ # s(:add,
146
+ # s(:integer, 1),
147
+ # s(:divide,
148
+ # s(:add, s(:integer, 8), s(:integer, 4)),
149
+ # s(:integer, 3))) # 1 + (8 + 4) / 3
150
+ #
151
+ # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
152
+ # p folded_expr_with_division
153
+ # # => (add
154
+ # # (integer 1)
155
+ # # (divide
156
+ # # (integer 12)
157
+ # # (integer 3)))
158
+ #
159
+ # As you can see, the expression was folded _partially_: the inner
160
+ # `(add)` node which could be computed was folded to
161
+ # `(integer 12)`, the `(divide)` node is left as-is because there
162
+ # is no computing handler for it, and the root `(add)` node was
163
+ # also left as it is because some of its children were not
164
+ # literals.
165
+ #
166
+ # Note that this partial folding is only possible because the
167
+ # _data_ format, i.e. the format in which the computed values of
168
+ # the nodes are represented, is the same as the AST itself.
169
+ #
170
+ # Let's extend our ArithmeticsCalculator class further.
171
+ #
172
+ # class ArithmeticsCalculator
173
+ # def on_divide(node)
174
+ # compute_op(node) { |left, right| left / right }
175
+ # end
176
+ #
177
+ # def on_negate(node)
178
+ # # Note how #compute_op works regardless of the operator
179
+ # # arity.
180
+ # compute_op(node) { |value| -value }
181
+ # end
182
+ # end
183
+ #
184
+ # Now, let's apply our renewed ArithmeticsCalculator to a partial
185
+ # result of previous evaluation:
186
+ #
187
+ # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
188
+ #
189
+ # Five! Excellent. This is also pretty much how CRuby 1.8 executed
190
+ # its programs.
191
+ #
192
+ # Now, let's do some automated bug searching. Division by zero is
193
+ # an error, right? So if we could detect that someone has divided
194
+ # by zero before the program is even run, that could save some
195
+ # debugging time.
196
+ #
197
+ # class DivisionByZeroVerifier < ArithmeticsProcessor
198
+ # class VerificationFailure < Exception; end
199
+ #
200
+ # def on_divide(node)
201
+ # # You need to process the children to handle nested divisions
202
+ # # such as:
203
+ # # (divide
204
+ # # (integer 1)
205
+ # # (divide (integer 1) (integer 0))
206
+ # left, right = process_all(node)
207
+ #
208
+ # if right.type == :integer &&
209
+ # right.children.first == 0
210
+ # raise VerificationFailure, "Ouch! This code divides by zero."
211
+ # end
212
+ # end
213
+ #
214
+ # def divides_by_zero?(ast)
215
+ # process(ast)
216
+ # false
217
+ # rescue VerificationFailure
218
+ # true
219
+ # end
220
+ # end
221
+ #
222
+ # nice_expr = \
223
+ # s(:divide,
224
+ # s(:add, s(:integer, 10), s(:integer, 2)),
225
+ # s(:integer, 4))
226
+ #
227
+ # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
228
+ # # => false. Good.
229
+ #
230
+ # bad_expr = \
231
+ # s(:add, s(:integer, 10),
232
+ # s(:divide, s(:integer, 1), s(:integer, 0)))
233
+ #
234
+ # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
235
+ # # => true. WHOOPS. DO NOT RUN THIS.
236
+ #
237
+ # Of course, this won't detect more complex cases... unless you
238
+ # use some partial evaluation before! The possibilites are
239
+ # endless. Have fun.
240
+ module Mixin
241
+ # Dispatches `node`. If a node has type `:foo`, then a handler
242
+ # named `on_foo` is invoked with one argument, the `node`; if
243
+ # there isn't such a handler, {#handler_missing} is invoked
244
+ # with the same argument.
245
+ #
246
+ # If the handler returns `nil`, `node` is returned; otherwise,
247
+ # the return value of the handler is passed along.
248
+ #
249
+ # @param [AST::Node, nil] node
250
+ # @return [AST::Node, nil]
251
+ def process(node)
252
+ return if node.nil?
253
+
254
+ node = node.to_ast
255
+
256
+ # Invoke a specific handler
257
+ on_handler = :"on_#{node.type}"
258
+ if respond_to? on_handler
259
+ new_node = send on_handler, node
260
+ else
261
+ new_node = handler_missing(node)
262
+ end
263
+
264
+ node = new_node if new_node
265
+
266
+ node
267
+ end
268
+
269
+ # {#process}es each node from `nodes` and returns an array of
270
+ # results.
271
+ #
272
+ # @param [Array<AST::Node>] nodes
273
+ # @return [Array<AST::Node>]
274
+ def process_all(nodes)
275
+ nodes.to_a.map do |node|
276
+ process node
277
+ end
278
+ end
279
+
280
+ # Default handler. Does nothing.
281
+ #
282
+ # @param [AST::Node] node
283
+ # @return [AST::Node, nil]
284
+ def handler_missing(node)
285
+ end
286
+ end
287
+ end
288
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ast
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Peter Zotov
7
+ - whitequark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-21 00:00:00.000000000 Z
11
+ date: 2015-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '1.25'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rest-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.6.7
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 1.6.7
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: yard
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +170,7 @@ files:
156
170
  - lib/ast.rb
157
171
  - lib/ast/node.rb
158
172
  - lib/ast/processor.rb
173
+ - lib/ast/processor/mixin.rb
159
174
  - lib/ast/sexp.rb
160
175
  - test/helper.rb
161
176
  - test/test_ast.rb
@@ -179,7 +194,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
194
  version: '0'
180
195
  requirements: []
181
196
  rubyforge_project:
182
- rubygems_version: 2.2.2
197
+ rubygems_version: 2.4.1
183
198
  signing_key:
184
199
  specification_version: 4
185
200
  summary: A library for working with Abstract Syntax Trees.