astkit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +7 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +4 -0
  7. data/Gemfile.lock +35 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +43 -0
  10. data/Rakefile +6 -0
  11. data/astkit.gemspec +28 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/astkit.rb +703 -0
  15. data/lib/astkit/node.rb +14 -0
  16. data/lib/astkit/node/alias.rb +13 -0
  17. data/lib/astkit/node/and.rb +13 -0
  18. data/lib/astkit/node/args.rb +15 -0
  19. data/lib/astkit/node/argspush.rb +13 -0
  20. data/lib/astkit/node/array.rb +12 -0
  21. data/lib/astkit/node/attrasgn.rb +14 -0
  22. data/lib/astkit/node/back_ref.rb +12 -0
  23. data/lib/astkit/node/block.rb +12 -0
  24. data/lib/astkit/node/break.rb +9 -0
  25. data/lib/astkit/node/call.rb +14 -0
  26. data/lib/astkit/node/case.rb +13 -0
  27. data/lib/astkit/node/case2.rb +12 -0
  28. data/lib/astkit/node/cdecl.rb +14 -0
  29. data/lib/astkit/node/class.rb +14 -0
  30. data/lib/astkit/node/colon2.rb +13 -0
  31. data/lib/astkit/node/colon3.rb +12 -0
  32. data/lib/astkit/node/const.rb +12 -0
  33. data/lib/astkit/node/cvar.rb +12 -0
  34. data/lib/astkit/node/cvasgn.rb +13 -0
  35. data/lib/astkit/node/dasgn.rb +13 -0
  36. data/lib/astkit/node/dasgn_curr.rb +13 -0
  37. data/lib/astkit/node/defined.rb +12 -0
  38. data/lib/astkit/node/defn.rb +13 -0
  39. data/lib/astkit/node/defs.rb +14 -0
  40. data/lib/astkit/node/dot2.rb +13 -0
  41. data/lib/astkit/node/dot3.rb +13 -0
  42. data/lib/astkit/node/dregx.rb +13 -0
  43. data/lib/astkit/node/dstr.rb +14 -0
  44. data/lib/astkit/node/dsym.rb +13 -0
  45. data/lib/astkit/node/dvar.rb +12 -0
  46. data/lib/astkit/node/dxstr.rb +14 -0
  47. data/lib/astkit/node/ensure.rb +13 -0
  48. data/lib/astkit/node/errinfo.rb +9 -0
  49. data/lib/astkit/node/evstr.rb +12 -0
  50. data/lib/astkit/node/false.rb +12 -0
  51. data/lib/astkit/node/fcall.rb +13 -0
  52. data/lib/astkit/node/flip2.rb +13 -0
  53. data/lib/astkit/node/flip3.rb +13 -0
  54. data/lib/astkit/node/for.rb +13 -0
  55. data/lib/astkit/node/gasgn.rb +13 -0
  56. data/lib/astkit/node/gvar.rb +12 -0
  57. data/lib/astkit/node/hash.rb +12 -0
  58. data/lib/astkit/node/iasgn.rb +13 -0
  59. data/lib/astkit/node/if.rb +14 -0
  60. data/lib/astkit/node/iter.rb +13 -0
  61. data/lib/astkit/node/ivar.rb +12 -0
  62. data/lib/astkit/node/kw_arg.rb +13 -0
  63. data/lib/astkit/node/lambda.rb +12 -0
  64. data/lib/astkit/node/lasgn.rb +13 -0
  65. data/lib/astkit/node/lit.rb +12 -0
  66. data/lib/astkit/node/lvar.rb +12 -0
  67. data/lib/astkit/node/masgn.rb +14 -0
  68. data/lib/astkit/node/match.rb +12 -0
  69. data/lib/astkit/node/match2.rb +13 -0
  70. data/lib/astkit/node/match3.rb +13 -0
  71. data/lib/astkit/node/module.rb +13 -0
  72. data/lib/astkit/node/nbegin.rb +12 -0
  73. data/lib/astkit/node/next.rb +9 -0
  74. data/lib/astkit/node/nil.rb +12 -0
  75. data/lib/astkit/node/nth_ref.rb +12 -0
  76. data/lib/astkit/node/once.rb +12 -0
  77. data/lib/astkit/node/op_asgn1.rb +15 -0
  78. data/lib/astkit/node/op_asgn2.rb +15 -0
  79. data/lib/astkit/node/op_asgn_and.rb +13 -0
  80. data/lib/astkit/node/op_asgn_or.rb +13 -0
  81. data/lib/astkit/node/op_cdecl.rb +14 -0
  82. data/lib/astkit/node/opcall.rb +14 -0
  83. data/lib/astkit/node/or.rb +13 -0
  84. data/lib/astkit/node/qcall.rb +14 -0
  85. data/lib/astkit/node/redo.rb +9 -0
  86. data/lib/astkit/node/resbody.rb +14 -0
  87. data/lib/astkit/node/rescue.rb +14 -0
  88. data/lib/astkit/node/retry.rb +9 -0
  89. data/lib/astkit/node/return.rb +9 -0
  90. data/lib/astkit/node/sclass.rb +13 -0
  91. data/lib/astkit/node/scope.rb +14 -0
  92. data/lib/astkit/node/self.rb +9 -0
  93. data/lib/astkit/node/splat.rb +12 -0
  94. data/lib/astkit/node/str.rb +12 -0
  95. data/lib/astkit/node/super.rb +12 -0
  96. data/lib/astkit/node/true.rb +12 -0
  97. data/lib/astkit/node/undef.rb +12 -0
  98. data/lib/astkit/node/unless.rb +14 -0
  99. data/lib/astkit/node/until.rb +13 -0
  100. data/lib/astkit/node/valias.rb +13 -0
  101. data/lib/astkit/node/values.rb +12 -0
  102. data/lib/astkit/node/vcall.rb +12 -0
  103. data/lib/astkit/node/when.rb +14 -0
  104. data/lib/astkit/node/while.rb +13 -0
  105. data/lib/astkit/node/xstr.rb +12 -0
  106. data/lib/astkit/node/yield.rb +9 -0
  107. data/lib/astkit/node/zarray.rb +12 -0
  108. data/lib/astkit/node/zsuper.rb +9 -0
  109. data/lib/astkit/version.rb +3 -0
  110. metadata +193 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ed9c63faf78876753640c64ae29db8551a1653d4389e5a7800667f8c2fe1ed7f
4
+ data.tar.gz: 1dc9340d11c745a1920d6237facc63a5fc890a7b0a954dfbe0afff6ba927342c
5
+ SHA512:
6
+ metadata.gz: 9c0eb43c1af93b7ed58109751f2de4a24e0de2c634932a9c94577a5c8385a1e9e02b5c0204b8cb670728f13eb8629d0075086ec6fb571d61220252c3c1e30138
7
+ data.tar.gz: 65ae8173382b71d51a1160caa287810da4b543d2eb9a877d9190316a582fd87e21b05042ba8a8889aba2993c9037a0677513fc5c5d3e9f1a33944357ec5ca5bc
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.6.0
7
+ before_install: gem install bundler -v 2.0.0
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at tmshuichi@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in astkit.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ astkit (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.3)
10
+ rake (12.3.2)
11
+ rspec (3.8.0)
12
+ rspec-core (~> 3.8.0)
13
+ rspec-expectations (~> 3.8.0)
14
+ rspec-mocks (~> 3.8.0)
15
+ rspec-core (3.8.0)
16
+ rspec-support (~> 3.8.0)
17
+ rspec-expectations (3.8.2)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.8.0)
20
+ rspec-mocks (3.8.0)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.8.0)
23
+ rspec-support (3.8.0)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ astkit!
30
+ bundler (~> 1.17.2)
31
+ rake (~> 12.0)
32
+ rspec (~> 3.8)
33
+
34
+ BUNDLED WITH
35
+ 1.17.3
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Shuichi Tamayose
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # AbstractSyntaxTreeKit
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/astkit`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'astkit'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install astkit
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/astkit. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
40
+
41
+ ## Code of Conduct
42
+
43
+ Everyone interacting in the AbstractSyntaxTreeKit project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/astkit/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/astkit.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'astkit/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'astkit'
7
+ spec.version = AbstractSyntaxTreeKit::VERSION
8
+ spec.authors = ['Shuichi Tamayose']
9
+ spec.email = ['tmshuichi@gmail.com']
10
+
11
+ spec.summary = %q{TBD}
12
+ spec.description = %q{TBD}
13
+ spec.homepage = 'http://example.com'
14
+ spec.license = 'MIT'
15
+
16
+ # Specify which files should be added to the gem when it is released.
17
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
18
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ end
21
+ spec.bindir = 'exe'
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.17.2'
26
+ spec.add_development_dependency 'rake', '~> 12.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.8'
28
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'astkit'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/astkit.rb ADDED
@@ -0,0 +1,703 @@
1
+ require 'astkit/version'
2
+ require 'astkit/node'
3
+ require 'astkit/node/fcall'
4
+ require 'astkit/node/scope'
5
+ require 'astkit/node/lit'
6
+ require 'astkit/node/str'
7
+ require 'astkit/node/array'
8
+ require 'astkit/node/zarray'
9
+ require 'astkit/node/defn'
10
+ require 'astkit/node/args'
11
+ require 'astkit/node/kw_arg'
12
+ require 'astkit/node/lasgn'
13
+ require 'astkit/node/cdecl'
14
+ require 'astkit/node/colon2'
15
+ require 'astkit/node/colon3'
16
+ require 'astkit/node/const'
17
+ require 'astkit/node/call'
18
+ require 'astkit/node/opcall'
19
+ require 'astkit/node/hash'
20
+ require 'astkit/node/nil'
21
+ require 'astkit/node/true'
22
+ require 'astkit/node/false'
23
+ require 'astkit/node/or'
24
+ require 'astkit/node/and'
25
+ require 'astkit/node/lvar'
26
+ require 'astkit/node/if'
27
+ require 'astkit/node/vcall'
28
+ require 'astkit/node/nbegin'
29
+ require 'astkit/node/iter'
30
+ require 'astkit/node/dvar'
31
+ require 'astkit/node/block'
32
+ require 'astkit/node/unless'
33
+ require 'astkit/node/case'
34
+ require 'astkit/node/when'
35
+ require 'astkit/node/case2'
36
+ require 'astkit/node/for'
37
+ require 'astkit/node/dot2'
38
+ require 'astkit/node/dot3'
39
+ require 'astkit/node/masgn'
40
+ require 'astkit/node/while'
41
+ require 'astkit/node/until'
42
+ require 'astkit/node/break'
43
+ require 'astkit/node/next'
44
+ require 'astkit/node/redo'
45
+ require 'astkit/node/retry'
46
+ require 'astkit/node/rescue'
47
+ require 'astkit/node/resbody'
48
+ require 'astkit/node/errinfo'
49
+ require 'astkit/node/ensure'
50
+ require 'astkit/node/gasgn'
51
+ require 'astkit/node/module'
52
+ require 'astkit/node/class'
53
+ require 'astkit/node/iasgn'
54
+ require 'astkit/node/cvasgn'
55
+ require 'astkit/node/flip2'
56
+ require 'astkit/node/flip3'
57
+ require 'astkit/node/self'
58
+ require 'astkit/node/ivar'
59
+ require 'astkit/node/gvar'
60
+ require 'astkit/node/cvar'
61
+ require 'astkit/node/nth_ref'
62
+ require 'astkit/node/back_ref'
63
+ require 'astkit/node/qcall'
64
+ require 'astkit/node/zsuper'
65
+ require 'astkit/node/super'
66
+ require 'astkit/node/lambda'
67
+ require 'astkit/node/attrasgn'
68
+ require 'astkit/node/dsym'
69
+ require 'astkit/node/dstr'
70
+ require 'astkit/node/evstr'
71
+ require 'astkit/node/defined'
72
+ require 'astkit/node/sclass'
73
+ require 'astkit/node/match'
74
+ require 'astkit/node/match2'
75
+ require 'astkit/node/match3'
76
+ require 'astkit/node/xstr'
77
+ require 'astkit/node/return'
78
+ require 'astkit/node/values'
79
+ require 'astkit/node/yield'
80
+ require 'astkit/node/dasgn'
81
+ require 'astkit/node/dasgn_curr'
82
+ require 'astkit/node/op_asgn1'
83
+ require 'astkit/node/op_asgn2'
84
+ require 'astkit/node/op_asgn_and'
85
+ require 'astkit/node/op_asgn_or'
86
+ require 'astkit/node/op_cdecl'
87
+ require 'astkit/node/dxstr'
88
+ require 'astkit/node/once'
89
+ require 'astkit/node/dregx'
90
+ require 'astkit/node/undef'
91
+ require 'astkit/node/valias'
92
+ require 'astkit/node/alias'
93
+ require 'astkit/node/defs'
94
+ require 'astkit/node/splat'
95
+ require 'astkit/node/argspush'
96
+
97
+ class AbstractSyntaxTreeKit
98
+ HashElement = Struct.new(:key, :value)
99
+
100
+ def self.parse(src)
101
+ root = RubyVM::AbstractSyntaxTree.parse(src)
102
+ new.traverse(root)
103
+ end
104
+
105
+ def self.walk(node, &block)
106
+ yield node
107
+
108
+ case node.type
109
+ when :SCOPE
110
+ if node.body.instance_of?(Array)
111
+ node.body.each do |child|
112
+ walk(child, &block)
113
+ end
114
+ else
115
+ walk(node.body, &block)
116
+ end
117
+ when :FCALL
118
+ walk(node.arguments, &block)
119
+ when :ARRAY
120
+ when :ZARRAY
121
+ when :LIT
122
+ when :STR
123
+ when :ARGS
124
+ else
125
+ raise "Unexpected node type[#{node.type}]"
126
+ end
127
+ end
128
+
129
+ def traverse(node)
130
+ return node unless node.instance_of?(RubyVM::AbstractSyntaxTree::Node)
131
+
132
+ case node.type
133
+ when :SCOPE
134
+ Node::SCOPE.new(
135
+ node: node,
136
+ local_table: node.children[0],
137
+ arguments: traverse(node.children[1]),
138
+ body: body(node.children[2])
139
+ )
140
+ when :ARRAY
141
+ Node::ARRAY.new(
142
+ node: node,
143
+ elements: elements(node)
144
+ )
145
+ when :ZARRAY
146
+ Node::ZARRAY.new(node: node)
147
+ when :STR
148
+ Node::STR.new(
149
+ node: node,
150
+ value: node.children[0]
151
+ )
152
+ when :FCALL
153
+ Node::FCALL.new(
154
+ node: node,
155
+ method_id: node.children[0],
156
+ arguments: traverse(node.children[1])
157
+ )
158
+ when :LIT
159
+ Node::LIT.new(
160
+ node: node,
161
+ value: node.children[0]
162
+ )
163
+ when :DEFN
164
+ Node::DEFN.new(
165
+ node: node,
166
+ method_id: node.children[0],
167
+ method_definition: traverse(node.children[1])
168
+ )
169
+ when :KW_ARG
170
+ Node::KW_ARG.new(
171
+ node: node,
172
+ body: traverse(node.children[0]),
173
+ next_keyword_argument: traverse(node.children[1])
174
+ )
175
+ when :LASGN
176
+ Node::LASGN.new(
177
+ node: node,
178
+ name: node.children[0],
179
+ value: traverse(node.children[1])
180
+ )
181
+ when :ARGS
182
+ Node::ARGS.new(
183
+ node: node,
184
+ parameter_count: node.children[0],
185
+ rest_argument: node.children[6],
186
+ keyword_arguments: traverse(node.children[7]),
187
+ block_argument: node.children[9]
188
+ )
189
+ when :CDECL
190
+ if node.children[1].instance_of?(Symbol)
191
+ Node::CDECL.new(
192
+ node: node,
193
+ extension: traverse(node.children[0]),
194
+ name: node.children[1],
195
+ value: traverse(node.children[2])
196
+ )
197
+ else
198
+ Node::CDECL.new(
199
+ node: node,
200
+ name: node.children[0],
201
+ value: traverse(node.children[1])
202
+ )
203
+ end
204
+ when :COLON2
205
+ Node::COLON2.new(
206
+ node: node,
207
+ receiver: traverse(node.children[0]),
208
+ name: node.children[1]
209
+ )
210
+ when :COLON3
211
+ Node::COLON3.new(
212
+ node: node,
213
+ name: node.children[0]
214
+ )
215
+ when :CONST
216
+ Node::CONST.new(
217
+ node: node,
218
+ name: node.children[0]
219
+ )
220
+ when :CALL
221
+ Node::CALL.new(
222
+ node: node,
223
+ receiver: traverse(node.children[0]),
224
+ method_id: node.children[1],
225
+ arguments: traverse(node.children[2])
226
+ )
227
+ when :OPCALL
228
+ opcall(node)
229
+ when :HASH
230
+ hash(node)
231
+ when :NIL
232
+ Node::NIL.new(node: node)
233
+ when :TRUE
234
+ Node::TRUE.new(node: node)
235
+ when :FALSE
236
+ Node::FALSE.new(node: node)
237
+ when :OR
238
+ Node::OR.new(
239
+ node: node,
240
+ left: traverse(node.children[0]),
241
+ right: traverse(node.children[1])
242
+ )
243
+ when :AND
244
+ Node::AND.new(
245
+ node: node,
246
+ left: traverse(node.children[0]),
247
+ right: traverse(node.children[1])
248
+ )
249
+ when :LVAR
250
+ Node::LVAR.new(
251
+ node: node,
252
+ name: node.children[0]
253
+ )
254
+ when :IF
255
+ Node::IF.new(
256
+ node: node,
257
+ condition: traverse(node.children[0]),
258
+ body: traverse(node.children[1]),
259
+ els: traverse(node.children[2])
260
+ )
261
+ when :UNLESS
262
+ Node::UNLESS.new(
263
+ node: node,
264
+ condition: traverse(node.children[0]),
265
+ body: traverse(node.children[1]),
266
+ els: traverse(node.children[2])
267
+ )
268
+ when :CASE
269
+ Node::CASE.new(
270
+ node: node,
271
+ expression: traverse(node.children[0]),
272
+ case_clauses: case_clauses(node.children[1])
273
+ )
274
+ when :CASE2
275
+ Node::CASE2.new(
276
+ node: node,
277
+ case_clauses: case_clauses(node.children[1])
278
+ )
279
+ when :WHEN
280
+ if node.children[2]&.type == :WHEN
281
+ Node::WHEN.new(
282
+ node: node,
283
+ expressions: traverse(node.children[0]),
284
+ body: traverse(node.children[1])
285
+ )
286
+ else
287
+ Node::WHEN.new(
288
+ node: node,
289
+ expressions: traverse(node.children[0]),
290
+ body: traverse(node.children[1]),
291
+ els: traverse(node.children[2])
292
+ )
293
+ end
294
+ when :FOR
295
+ Node::FOR.new(
296
+ node: node,
297
+ receiver: traverse(node.children[0]),
298
+ body: traverse(node.children[1])
299
+ )
300
+ when :VCALL
301
+ vcall(node)
302
+ when :BEGIN
303
+ nbegin(node)
304
+ when :ITER
305
+ Node::ITER.new(
306
+ node: node,
307
+ receiver: traverse(node.children[0]),
308
+ body: traverse(node.children[1])
309
+ )
310
+ when :DVAR
311
+ dvar(node)
312
+ when :BLOCK
313
+ block(node)
314
+ when :DOT2
315
+ Node::DOT2.new(
316
+ node: node,
317
+ nd_begin: traverse(node.children[0]),
318
+ nd_end: traverse(node.children[1])
319
+ )
320
+ when :DOT3
321
+ Node::DOT3.new(
322
+ node: node,
323
+ nd_begin: traverse(node.children[0]),
324
+ nd_end: traverse(node.children[1])
325
+ )
326
+ when :MASGN
327
+ Node::MASGN.new(
328
+ node: node,
329
+ rhs: traverse(node.children[0]),
330
+ lhs: traverse(node.children[1]),
331
+ splat: traverse(node.children[2])
332
+ )
333
+ when :WHILE
334
+ Node::WHILE.new(
335
+ node: node,
336
+ condition: traverse(node.children[0]),
337
+ body: traverse(node.children[1])
338
+ )
339
+ when :UNTIL
340
+ Node::UNTIL.new(
341
+ node: node,
342
+ condition: traverse(node.children[0]),
343
+ body: traverse(node.children[1])
344
+ )
345
+ when :BREAK
346
+ Node::BREAK.new(node: node)
347
+ when :NEXT
348
+ Node::NEXT.new(node: node)
349
+ when :REDO
350
+ Node::REDO.new(node: node)
351
+ when :RETRY
352
+ Node::RETRY.new(node: node)
353
+ when :RESCUE
354
+ Node::RESCUE.new(
355
+ node: node,
356
+ body: traverse(node.children[0]),
357
+ rescue_body: traverse(node.children[1]),
358
+ else_body: traverse(node.children[2])
359
+ )
360
+ when :RESBODY
361
+ Node::RESBODY.new(
362
+ node: node,
363
+ exceptions: traverse(node.children[0]),
364
+ clause: traverse(node.children[1]),
365
+ next_rescue: traverse(node.children[2])
366
+ )
367
+ when :ERRINFO
368
+ Node::ERRINFO.new(node: node)
369
+ when :ENSURE
370
+ Node::ENSURE.new(
371
+ node: node,
372
+ body: traverse(node.children[0]),
373
+ clause: traverse(node.children[1])
374
+ )
375
+ when :GASGN
376
+ Node::GASGN.new(
377
+ node: node,
378
+ name: node.children[0],
379
+ value: traverse(node.children[1])
380
+ )
381
+ when :MODULE
382
+ Node::MODULE.new(
383
+ node: node,
384
+ path: traverse(node.children[0]),
385
+ body: traverse(node.children[1])
386
+ )
387
+ when :CLASS
388
+ Node::CLASS.new(
389
+ node: node,
390
+ path: traverse(node.children[0]),
391
+ superclass: traverse(node.children[1]),
392
+ body: traverse(node.children[2])
393
+ )
394
+ when :IASGN
395
+ Node::IASGN.new(
396
+ node: node,
397
+ name: node.children[0],
398
+ value: traverse(node.children[1])
399
+ )
400
+ when :CVASGN
401
+ Node::CVASGN.new(
402
+ node: node,
403
+ name: node.children[0],
404
+ value: traverse(node.children[1])
405
+ )
406
+ when :FLIP2
407
+ Node::FLIP2.new(
408
+ node: node,
409
+ nd_begin: traverse(node.children[0]),
410
+ nd_end: traverse(node.children[1])
411
+ )
412
+ when :FLIP3
413
+ Node::FLIP3.new(
414
+ node: node,
415
+ nd_begin: traverse(node.children[0]),
416
+ nd_end: traverse(node.children[1])
417
+ )
418
+ when :SELF
419
+ Node::SELF.new(node: node)
420
+ when :GVAR
421
+ Node::GVAR.new(
422
+ node: node,
423
+ name: node.children[0]
424
+ )
425
+ when :IVAR
426
+ Node::IVAR.new(
427
+ node: node,
428
+ name: node.children[0]
429
+ )
430
+ when :CVAR
431
+ Node::CVAR.new(
432
+ node: node,
433
+ name: node.children[0]
434
+ )
435
+ when :NTH_REF
436
+ Node::NTH_REF.new(
437
+ node: node,
438
+ name: node.children[0]
439
+ )
440
+ when :BACK_REF
441
+ Node::BACK_REF.new(
442
+ node: node,
443
+ name: node.children[0]
444
+ )
445
+ when :QCALL
446
+ Node::QCALL.new(
447
+ node: node,
448
+ receiver: traverse(node.children[0]),
449
+ method_id: node.children[1],
450
+ arguments: traverse(node.children[2])
451
+ )
452
+ when :ZSUPER
453
+ Node::ZSUPER.new(node: node)
454
+ when :SUPER
455
+ Node::SUPER.new(
456
+ node: node,
457
+ arguments: traverse(node.children[0])
458
+ )
459
+ when :LAMBDA
460
+ Node::LAMBDA.new(
461
+ node: node,
462
+ body: traverse(node.children[0])
463
+ )
464
+ when :ATTRASGN
465
+ Node::ATTRASGN.new(
466
+ node: node,
467
+ receiver: traverse(node.children[0]),
468
+ method_id: node.children[1],
469
+ arguments: traverse(node.children[2])
470
+ )
471
+ when :DSYM
472
+ Node::DSYM.new(
473
+ node: node,
474
+ interpolation: traverse(node.children[0]),
475
+ tail_str: traverse(node.children[1])
476
+ )
477
+ when :DSTR
478
+ Node::DSTR.new(
479
+ node: node,
480
+ pre_str: node.children[0],
481
+ interpolation: traverse(node.children[1]),
482
+ tail_str: traverse(node.children[2])
483
+ )
484
+ when :EVSTR
485
+ Node::EVSTR.new(
486
+ node: node,
487
+ body: traverse(node.children[0])
488
+ )
489
+ when :DEFINED
490
+ Node::DEFINED.new(
491
+ node: node,
492
+ expression: traverse(node.children[0])
493
+ )
494
+ when :SCLASS
495
+ Node::SCLASS.new(
496
+ node: node,
497
+ receiver: traverse(node.children[0]),
498
+ body: traverse(node.children[1])
499
+ )
500
+ when :MATCH
501
+ Node::MATCH.new(
502
+ node: node,
503
+ value: traverse(node.children[0])
504
+ )
505
+ when :MATCH2
506
+ Node::MATCH2.new(
507
+ node: node,
508
+ regexp: traverse(node.children[0]),
509
+ string: traverse(node.children[1])
510
+ )
511
+ when :MATCH3
512
+ Node::MATCH3.new(
513
+ node: node,
514
+ regexp: traverse(node.children[0]),
515
+ string: traverse(node.children[1])
516
+ )
517
+ when :XSTR
518
+ Node::XSTR.new(
519
+ node: node,
520
+ value: node.children[0]
521
+ )
522
+ when :RETURN
523
+ Node::RETURN.new(node: node)
524
+ when :VALUES
525
+ Node::VALUES.new(
526
+ node: node,
527
+ elements: elements(node)
528
+ )
529
+ when :YIELD
530
+ Node::YIELD.new(node: node)
531
+ when :DASGN
532
+ Node::DASGN.new(
533
+ node: node,
534
+ name: node.children[0],
535
+ value: traverse(node.children[1])
536
+ )
537
+ when :DASGN_CURR
538
+ Node::DASGN_CURR.new(
539
+ node: node,
540
+ name: node.children[0],
541
+ value: traverse(node.children[1])
542
+ )
543
+ when :OP_ASGN1
544
+ Node::OP_ASGN1.new(
545
+ node: node,
546
+ receiver: traverse(node.children[0]),
547
+ operator: node.children[1],
548
+ index: traverse(node.children[2]),
549
+ value: traverse(node.children[3])
550
+ )
551
+ when :OP_ASGN2
552
+ # p node.children
553
+ when :OP_ASGN_AND
554
+ Node::OP_ASGN_AND.new(
555
+ node: node,
556
+ variable: traverse(node.children[0]),
557
+ value: traverse(node.children[2])
558
+ )
559
+ when :OP_ASGN_OR
560
+ Node::OP_ASGN_OR.new(
561
+ node: node,
562
+ variable: traverse(node.children[0]),
563
+ value: traverse(node.children[2])
564
+ )
565
+ when :OP_CDECL
566
+ Node::OP_CDECL.new(
567
+ node: node,
568
+ namespace: traverse(node.children[0]),
569
+ operator: node.children[1],
570
+ value: traverse(node.children[2])
571
+ )
572
+ when :DXSTR
573
+ Node::DXSTR.new(
574
+ node: node,
575
+ pre_str: node.children[0],
576
+ interpolation: traverse(node.children[1]),
577
+ tail_str: traverse(node.children[2])
578
+ )
579
+ when :ONCE
580
+ Node::ONCE.new(
581
+ node: node,
582
+ body: traverse(node.children[0])
583
+ )
584
+ when :DREGX
585
+ Node::DREGX.new(
586
+ node: node,
587
+ interpolation: traverse(node.children[0]),
588
+ tail_str: traverse(node.children[1])
589
+ )
590
+ when :UNDEF
591
+ Node::UNDEF.new(
592
+ node: node,
593
+ old_name: traverse(node.children[0])
594
+ )
595
+ when :VALIAS
596
+ Node::VALIAS.new(
597
+ node: node,
598
+ new_name: node.children[0],
599
+ old_name: node.children[1]
600
+ )
601
+ when :ALIAS
602
+ Node::VALIAS.new(
603
+ node: node,
604
+ new_name: traverse(node.children[0]),
605
+ old_name: traverse(node.children[1])
606
+ )
607
+ when :DEFS
608
+ Node::DEFS.new(
609
+ node: node,
610
+ receiver: traverse(node.children[0]),
611
+ name: node.children[1],
612
+ body: traverse(node.children[2])
613
+ )
614
+ when :SPLAT
615
+ Node::SPLAT.new(
616
+ node: node,
617
+ element: traverse(node.children[0])
618
+ )
619
+ when :ARGSPUSH
620
+ Node::ARGSPUSH.new(
621
+ node: node,
622
+ array: traverse(node.children[0]),
623
+ element: traverse(node.children[1])
624
+ )
625
+ else
626
+ raise "Unexpected node type[#{node.type}]"
627
+ end
628
+ end
629
+
630
+ private
631
+
632
+ def opcall(node)
633
+ Node::OPCALL.new(
634
+ node: node,
635
+ receiver: traverse(node.children[0]),
636
+ method_id: node.children[1],
637
+ arguments: traverse(node.children[2])
638
+ )
639
+ end
640
+
641
+ def hash(node)
642
+ Node::HASH.new(
643
+ node: node,
644
+ elements: hash_elements(node.children[0])
645
+ )
646
+ end
647
+
648
+ def vcall(node)
649
+ Node::VCALL.new(
650
+ node: node,
651
+ name: node.children[0]
652
+ )
653
+ end
654
+
655
+ def nbegin(node)
656
+ Node::NBEGIN.new(
657
+ node: node,
658
+ body: traverse(node.children[0])
659
+ )
660
+ end
661
+
662
+ def dvar(node)
663
+ Node::DVAR.new(
664
+ node: node,
665
+ name: node.children[0]
666
+ )
667
+ end
668
+
669
+ def block(node)
670
+ Node::BLOCK.new(
671
+ node: node,
672
+ statements: statements(node.children)
673
+ )
674
+ end
675
+
676
+ def body(node)
677
+ traverse(node)
678
+ end
679
+
680
+ def elements(node)
681
+ node.children[0..-2].map { |child| traverse(child) }
682
+ end
683
+
684
+ def hash_elements(node)
685
+ node.children[0..-2].each_slice(2).map do |key_node, value_node|
686
+ HashElement.new(traverse(key_node), traverse(value_node))
687
+ end
688
+ end
689
+
690
+ def statements(list)
691
+ list.map { |l| traverse(l) }
692
+ end
693
+
694
+ def case_clauses(node)
695
+ list = [traverse(node)]
696
+
697
+ if node.children[2]&.type == :WHEN
698
+ list << case_clauses(node.children[2])
699
+ end
700
+
701
+ list.flatten
702
+ end
703
+ end