ast 2.4.0 → 2.4.2
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 +5 -5
- data/lib/ast/node.rb +13 -3
- data/lib/ast/processor/mixin.rb +1 -1
- metadata +10 -63
- data/.gitignore +0 -8
- data/.travis.yml +0 -14
- data/.yardopts +0 -1
- data/CHANGELOG.md +0 -9
- data/Gemfile +0 -4
- data/README.md +0 -23
- data/Rakefile +0 -19
- data/ast.gemspec +0 -29
- data/test/helper.rb +0 -17
- data/test/test_ast.rb +0 -271
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8210d16488dff96abdba806c27ddc7d9640e737050096441ec93dcff222b624c
|
4
|
+
data.tar.gz: e01089e2ec37377bf49160eebd8a277c4f481877e9cdfc4af977d860e7b516f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc8e13d06da136e8de38ce6446f9260b35a1dbde3da47b558a256827df93a5d1bfa1130b07bc4fc326a0ac96dbdd112b330ec4b79a47cff647f7b48182803b65
|
7
|
+
data.tar.gz: 6afd93b25aa0d9061fdee5cebdd732303535107ecab668cc8dc37a49a0ee209d0906a9b8a415e1d4b62d4a5fd2b0f7da3263665a156aa9a57c24dd2f5ad89075
|
data/lib/ast/node.rb
CHANGED
@@ -140,7 +140,9 @@ module AST
|
|
140
140
|
properties.nil?
|
141
141
|
self
|
142
142
|
else
|
143
|
-
|
143
|
+
copy = original_dup
|
144
|
+
copy.send :initialize, new_type, new_children, new_properties
|
145
|
+
copy
|
144
146
|
end
|
145
147
|
end
|
146
148
|
|
@@ -227,9 +229,9 @@ module AST
|
|
227
229
|
def to_ast
|
228
230
|
self
|
229
231
|
end
|
230
|
-
|
232
|
+
|
231
233
|
# Converts `self` to an Array where the first element is the type as a Symbol,
|
232
|
-
# and subsequent elements are the same representation of its children.
|
234
|
+
# and subsequent elements are the same representation of its children.
|
233
235
|
#
|
234
236
|
# @return [Array<Symbol, [...Array]>]
|
235
237
|
def to_sexp_array
|
@@ -244,6 +246,14 @@ module AST
|
|
244
246
|
[type, *children_sexp_arrs]
|
245
247
|
end
|
246
248
|
|
249
|
+
# Enables matching for Node, where type is the first element
|
250
|
+
# and the children are remaining items.
|
251
|
+
#
|
252
|
+
# @return [Array]
|
253
|
+
def deconstruct
|
254
|
+
[type, *children]
|
255
|
+
end
|
256
|
+
|
247
257
|
protected
|
248
258
|
|
249
259
|
# Returns `@type` with all underscores replaced by dashes. This allows
|
data/lib/ast/processor/mixin.rb
CHANGED
@@ -23,7 +23,7 @@ module AST
|
|
23
23
|
# into a variable named `<string-literal>`,
|
24
24
|
# * `(load <string-literal>)`: loads value of a variable named
|
25
25
|
# `<string-literal>`,
|
26
|
-
# * `(each <node> ...)
|
26
|
+
# * `(each <node> ...)`: computes each of the `<node>`s and
|
27
27
|
# prints the result.
|
28
28
|
#
|
29
29
|
# All AST nodes have the same Ruby class, and therefore they don't
|
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.4.
|
4
|
+
version: 2.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- whitequark
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '12.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '12.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bacon
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -68,60 +68,18 @@ dependencies:
|
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: coveralls
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: json_pure
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: mime-types
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '1.25'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '1.25'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rest-client
|
113
71
|
requirement: !ruby/object:Gem::Requirement
|
114
72
|
requirements:
|
115
73
|
- - "~>"
|
116
74
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
75
|
+
version: 0.8.23
|
118
76
|
type: :development
|
119
77
|
prerelease: false
|
120
78
|
version_requirements: !ruby/object:Gem::Requirement
|
121
79
|
requirements:
|
122
80
|
- - "~>"
|
123
81
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
82
|
+
version: 0.8.23
|
125
83
|
- !ruby/object:Gem::Dependency
|
126
84
|
name: yard
|
127
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -157,28 +115,18 @@ executables: []
|
|
157
115
|
extensions: []
|
158
116
|
extra_rdoc_files: []
|
159
117
|
files:
|
160
|
-
- ".gitignore"
|
161
|
-
- ".travis.yml"
|
162
|
-
- ".yardopts"
|
163
|
-
- CHANGELOG.md
|
164
|
-
- Gemfile
|
165
118
|
- LICENSE.MIT
|
166
119
|
- README.YARD.md
|
167
|
-
- README.md
|
168
|
-
- Rakefile
|
169
|
-
- ast.gemspec
|
170
120
|
- lib/ast.rb
|
171
121
|
- lib/ast/node.rb
|
172
122
|
- lib/ast/processor.rb
|
173
123
|
- lib/ast/processor/mixin.rb
|
174
124
|
- lib/ast/sexp.rb
|
175
|
-
- test/helper.rb
|
176
|
-
- test/test_ast.rb
|
177
125
|
homepage: https://whitequark.github.io/ast/
|
178
126
|
licenses:
|
179
127
|
- MIT
|
180
128
|
metadata: {}
|
181
|
-
post_install_message:
|
129
|
+
post_install_message:
|
182
130
|
rdoc_options: []
|
183
131
|
require_paths:
|
184
132
|
- lib
|
@@ -193,9 +141,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
193
141
|
- !ruby/object:Gem::Version
|
194
142
|
version: '0'
|
195
143
|
requirements: []
|
196
|
-
|
197
|
-
|
198
|
-
signing_key:
|
144
|
+
rubygems_version: 3.2.3
|
145
|
+
signing_key:
|
199
146
|
specification_version: 4
|
200
147
|
summary: A library for working with Abstract Syntax Trees.
|
201
148
|
test_files: []
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
data/.yardopts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
-r README.YARD.md -m markdown --protected
|
data/CHANGELOG.md
DELETED
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
# AST
|
2
|
-
|
3
|
-
[](https://travis-ci.org/whitequark/ast)
|
4
|
-
[](https://codeclimate.com/github/whitequark/ast)
|
5
|
-
[](https://coveralls.io/r/whitequark/ast)
|
6
|
-
|
7
|
-
AST is a small library for working with immutable abstract syntax trees.
|
8
|
-
|
9
|
-
## Installation
|
10
|
-
|
11
|
-
$ gem install ast
|
12
|
-
|
13
|
-
## Usage
|
14
|
-
|
15
|
-
See the documentation at [GitHub](http://whitequark.github.com/ast/frames.html) or [rdoc.info](http://rdoc.info/gems/ast).
|
16
|
-
|
17
|
-
## Contributing
|
18
|
-
|
19
|
-
1. Fork it
|
20
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
21
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
22
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
23
|
-
5. Create new Pull Request
|
data/Rakefile
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'bundler/setup'
|
3
|
-
|
4
|
-
task :default => :test
|
5
|
-
|
6
|
-
desc "Run test suite"
|
7
|
-
task :test do
|
8
|
-
sh "bacon -Itest -a"
|
9
|
-
end
|
10
|
-
|
11
|
-
PAGES_REPO = 'git@github.com:whitequark/ast'
|
12
|
-
|
13
|
-
desc "Build and deploy documentation to GitHub pages"
|
14
|
-
task :pages do
|
15
|
-
system "git clone #{PAGES_REPO} gh-temp/ -b gh-pages; rm gh-temp/* -rf; touch gh-temp/.nojekyll" or abort
|
16
|
-
system "yardoc -o gh-temp/;" or abort
|
17
|
-
system "cd gh-temp/; git add -A; git commit -m 'Updated pages.'; git push -f origin gh-pages" or abort
|
18
|
-
FileUtils.rm_rf 'gh-temp'
|
19
|
-
end
|
data/ast.gemspec
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = 'ast'
|
3
|
-
s.version = '2.4.0'
|
4
|
-
s.license = 'MIT'
|
5
|
-
s.authors = ["whitequark"]
|
6
|
-
s.email = ["whitequark@whitequark.org"]
|
7
|
-
s.homepage = "https://whitequark.github.io/ast/"
|
8
|
-
s.summary = %q{A library for working with Abstract Syntax Trees.}
|
9
|
-
s.description = s.summary
|
10
|
-
|
11
|
-
s.files = `git ls-files`.split("\n")
|
12
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
14
|
-
s.require_paths = ["lib"]
|
15
|
-
|
16
|
-
s.add_development_dependency 'rake', '~> 10.0'
|
17
|
-
|
18
|
-
s.add_development_dependency 'bacon', '~> 1.2'
|
19
|
-
s.add_development_dependency 'bacon-colored_output'
|
20
|
-
s.add_development_dependency 'simplecov'
|
21
|
-
|
22
|
-
s.add_development_dependency 'coveralls'
|
23
|
-
s.add_development_dependency 'json_pure' # for coveralls on 1.9.2
|
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
|
26
|
-
|
27
|
-
s.add_development_dependency 'yard'
|
28
|
-
s.add_development_dependency 'kramdown'
|
29
|
-
end
|
data/test/helper.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'bacon'
|
2
|
-
require 'bacon/colored_output'
|
3
|
-
|
4
|
-
require 'simplecov'
|
5
|
-
require 'coveralls'
|
6
|
-
|
7
|
-
SimpleCov.start do
|
8
|
-
self.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
9
|
-
SimpleCov::Formatter::HTMLFormatter,
|
10
|
-
Coveralls::SimpleCov::Formatter
|
11
|
-
])
|
12
|
-
|
13
|
-
# Exclude the testsuite itself.
|
14
|
-
add_filter "/test/"
|
15
|
-
end
|
16
|
-
|
17
|
-
require 'ast'
|
data/test/test_ast.rb
DELETED
@@ -1,271 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
describe AST::Node do
|
4
|
-
extend AST::Sexp
|
5
|
-
|
6
|
-
class MetaNode < AST::Node
|
7
|
-
attr_reader :meta
|
8
|
-
end
|
9
|
-
|
10
|
-
before do
|
11
|
-
@node = AST::Node.new(:node, [ 0, 1 ])
|
12
|
-
@metanode = MetaNode.new(:node, [ 0, 1 ], :meta => 'value')
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'should have accessors for type and children' do
|
16
|
-
@node.type.should.equal :node
|
17
|
-
@node.children.should.equal [0, 1]
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should set metadata' do
|
21
|
-
@metanode.meta.should.equal 'value'
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'should be frozen' do
|
25
|
-
@node.frozen?.should.be.true
|
26
|
-
@node.children.frozen?.should.be.true
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should return self when duping' do
|
30
|
-
@node.dup.should.equal? @node
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should return self when cloning' do
|
34
|
-
@node.clone.should.equal? @node
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should return an updated node, but only if needed' do
|
38
|
-
@node.updated().should.be.identical_to @node
|
39
|
-
@node.updated(:node).should.be.identical_to @node
|
40
|
-
@node.updated(nil, [0, 1]).should.be.identical_to @node
|
41
|
-
|
42
|
-
updated = @node.updated(:other_node)
|
43
|
-
updated.should.not.be.identical_to @node
|
44
|
-
updated.type.should.equal :other_node
|
45
|
-
updated.children.should.equal @node.children
|
46
|
-
|
47
|
-
updated.frozen?.should.be.true
|
48
|
-
|
49
|
-
updated = @node.updated(nil, [1, 1])
|
50
|
-
updated.should.not.be.identical_to @node
|
51
|
-
updated.type.should.equal @node.type
|
52
|
-
updated.children.should.equal [1, 1]
|
53
|
-
|
54
|
-
updated = @metanode.updated(nil, nil, :meta => 'other_value')
|
55
|
-
updated.meta.should.equal 'other_value'
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'should format to_sexp correctly' do
|
59
|
-
AST::Node.new(:a, [ :sym, [ 1, 2 ] ]).to_sexp.should.equal '(a :sym [1, 2])'
|
60
|
-
AST::Node.new(:a, [ :sym, @node ]).to_sexp.should.equal "(a :sym\n (node 0 1))"
|
61
|
-
AST::Node.new(:a, [ :sym,
|
62
|
-
AST::Node.new(:b, [ @node, @node ])
|
63
|
-
]).to_sexp.should.equal "(a :sym\n (b\n (node 0 1)\n (node 0 1)))"
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'should format to_s correctly' do
|
67
|
-
AST::Node.new(:a, [ :sym, [ 1, 2 ] ]).to_s.should.equal '(a :sym [1, 2])'
|
68
|
-
AST::Node.new(:a, [ :sym, @node ]).to_s.should.equal "(a :sym\n (node 0 1))"
|
69
|
-
AST::Node.new(:a, [ :sym,
|
70
|
-
AST::Node.new(:b, [ @node, @node ])
|
71
|
-
]).to_s.should.equal "(a :sym\n (b\n (node 0 1)\n (node 0 1)))"
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'should format inspect correctly' do
|
75
|
-
AST::Node.new(:a, [ :sym, [ 1, 2 ] ]).inspect.should.equal "s(:a, :sym, [1, 2])"
|
76
|
-
AST::Node.new(:a, [ :sym,
|
77
|
-
AST::Node.new(:b, [ @node, @node ])
|
78
|
-
]).inspect.should.equal "s(:a, :sym,\n s(:b,\n s(:node, 0, 1),\n s(:node, 0, 1)))"
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'should recreate inspect output' do
|
82
|
-
simple_node = AST::Node.new(:a, [ :sym, [ 1, 2 ] ])
|
83
|
-
eval(simple_node.inspect).should.equal simple_node
|
84
|
-
complex_node = s(:a , :sym, s(:b, s(:node, 0, 1), s(:node, 0, 1)))
|
85
|
-
eval(complex_node.inspect).should.equal complex_node
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'should return self in to_ast' do
|
89
|
-
@node.to_ast.should.be.identical_to @node
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'should produce to_sexp_array correctly' do
|
93
|
-
AST::Node.new(:a, [ :sym, [ 1, 2 ] ]).to_sexp_array.should.equal [:a, :sym, [1, 2]]
|
94
|
-
AST::Node.new(:a, [ :sym,
|
95
|
-
AST::Node.new(:b, [ @node, @node ])
|
96
|
-
]).to_sexp_array.should.equal [:a, :sym, [:b, [:node, 0, 1], [:node, 0, 1]]]
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should only use type and children to compute #hash' do
|
100
|
-
@node.hash.should.equal([@node.type, @node.children, @node.class].hash)
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'should only use type and children in #eql? comparisons' do
|
104
|
-
# Not identical but equivalent
|
105
|
-
@node.eql?(AST::Node.new(:node, [0, 1])).should.be.true
|
106
|
-
# Not identical and not equivalent
|
107
|
-
@node.eql?(AST::Node.new(:other, [0, 1])).should.be.false
|
108
|
-
# Not identical and not equivalent because of differend class
|
109
|
-
@node.eql?(@metanode).should.be.false
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'should only use type and children in #== comparisons' do
|
113
|
-
@node.should.equal @node
|
114
|
-
@node.should.equal @metanode
|
115
|
-
@node.should.not.equal :foo
|
116
|
-
|
117
|
-
mock_node = Object.new.tap do |obj|
|
118
|
-
def obj.to_ast
|
119
|
-
self
|
120
|
-
end
|
121
|
-
|
122
|
-
def obj.type
|
123
|
-
:node
|
124
|
-
end
|
125
|
-
|
126
|
-
def obj.children
|
127
|
-
[ 0, 1 ]
|
128
|
-
end
|
129
|
-
end
|
130
|
-
@node.should.equal mock_node
|
131
|
-
end
|
132
|
-
|
133
|
-
it 'should allow to decompose nodes with a, b = *node' do
|
134
|
-
node = s(:gasgn, :$foo, s(:integer, 1))
|
135
|
-
|
136
|
-
var_name, value = *node
|
137
|
-
var_name.should.equal :$foo
|
138
|
-
value.should.equal s(:integer, 1)
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'should concatenate with arrays' do
|
142
|
-
node = s(:gasgn, :$foo)
|
143
|
-
(node + [s(:integer, 1)]).
|
144
|
-
should.equal s(:gasgn, :$foo, s(:integer, 1))
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'should append elements' do
|
148
|
-
node = s(:array)
|
149
|
-
(node << s(:integer, 1) << s(:string, "foo")).
|
150
|
-
should.equal s(:array, s(:integer, 1), s(:string, "foo"))
|
151
|
-
end
|
152
|
-
|
153
|
-
begin
|
154
|
-
eval <<-CODE
|
155
|
-
it 'should not trigger a rubinius bug' do
|
156
|
-
bar = [ s(:bar, 1) ]
|
157
|
-
baz = s(:baz, 2)
|
158
|
-
s(:foo, *bar, baz).should.equal s(:foo, s(:bar, 1), s(:baz, 2))
|
159
|
-
end
|
160
|
-
CODE
|
161
|
-
rescue SyntaxError
|
162
|
-
# Running on 1.8, ignore.
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
describe AST::Processor do
|
167
|
-
extend AST::Sexp
|
168
|
-
|
169
|
-
def have_sexp(text)
|
170
|
-
text = text.lines.map { |line| line.sub /^ +\|(.+)/, '\1' }.join.rstrip
|
171
|
-
lambda { |ast| ast.to_sexp == text }
|
172
|
-
end
|
173
|
-
|
174
|
-
class MockProcessor < AST::Processor
|
175
|
-
attr_reader :counts
|
176
|
-
|
177
|
-
def initialize
|
178
|
-
@counts = Hash.new(0)
|
179
|
-
end
|
180
|
-
|
181
|
-
def on_root(node)
|
182
|
-
count_node(node)
|
183
|
-
node.updated(nil, process_all(node.children))
|
184
|
-
end
|
185
|
-
alias on_body on_root
|
186
|
-
|
187
|
-
def on_def(node)
|
188
|
-
count_node(node)
|
189
|
-
name, arglist, body = node.children
|
190
|
-
node.updated(:def, [ name, process(arglist), process(body) ])
|
191
|
-
end
|
192
|
-
|
193
|
-
def handler_missing(node)
|
194
|
-
count_node(node)
|
195
|
-
end
|
196
|
-
|
197
|
-
def count_node(node)
|
198
|
-
@counts[node.type] += 1; nil
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
before do
|
203
|
-
@ast = AST::Node.new(:root, [
|
204
|
-
AST::Node.new(:def, [ :func,
|
205
|
-
AST::Node.new(:arglist, [ :foo, :bar ]),
|
206
|
-
AST::Node.new(:body, [
|
207
|
-
AST::Node.new(:invoke, [ :puts, "Hello world" ])
|
208
|
-
])
|
209
|
-
]),
|
210
|
-
AST::Node.new(:invoke, [ :func ])
|
211
|
-
])
|
212
|
-
|
213
|
-
@processor = MockProcessor.new
|
214
|
-
end
|
215
|
-
|
216
|
-
it 'should visit every node' do
|
217
|
-
@processor.process(@ast).should.equal @ast
|
218
|
-
@processor.counts.should.equal({
|
219
|
-
:root => 1,
|
220
|
-
:def => 1,
|
221
|
-
:arglist => 1,
|
222
|
-
:body => 1,
|
223
|
-
:invoke => 2,
|
224
|
-
})
|
225
|
-
end
|
226
|
-
|
227
|
-
it 'should be able to replace inner nodes' do
|
228
|
-
def @processor.on_arglist(node)
|
229
|
-
node.updated(:new_fancy_arglist)
|
230
|
-
end
|
231
|
-
|
232
|
-
@processor.process(@ast).should have_sexp(<<-SEXP)
|
233
|
-
|(root
|
234
|
-
| (def :func
|
235
|
-
| (new-fancy-arglist :foo :bar)
|
236
|
-
| (body
|
237
|
-
| (invoke :puts "Hello world")))
|
238
|
-
| (invoke :func))
|
239
|
-
SEXP
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'should build sexps' do
|
243
|
-
s(:add,
|
244
|
-
s(:integer, 1),
|
245
|
-
s(:multiply,
|
246
|
-
s(:integer, 2),
|
247
|
-
s(:integer, 3))).should have_sexp(<<-SEXP)
|
248
|
-
|(add
|
249
|
-
| (integer 1)
|
250
|
-
| (multiply
|
251
|
-
| (integer 2)
|
252
|
-
| (integer 3)))
|
253
|
-
SEXP
|
254
|
-
end
|
255
|
-
|
256
|
-
it 'should return nil if passed nil' do
|
257
|
-
@processor.process(nil).should == nil
|
258
|
-
end
|
259
|
-
|
260
|
-
it 'should refuse to process non-nodes' do
|
261
|
-
lambda { @processor.process([]) }.should.raise NoMethodError, %r|to_ast|
|
262
|
-
end
|
263
|
-
|
264
|
-
it 'should allow to visit nodes with process_all(node)' do
|
265
|
-
@processor.process_all s(:foo, s(:bar), s(:integer, 1))
|
266
|
-
@processor.counts.should.equal({
|
267
|
-
:bar => 1,
|
268
|
-
:integer => 1,
|
269
|
-
})
|
270
|
-
end
|
271
|
-
end
|