ast 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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.