jruby-parser 0.3 → 0.4
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.
- data/lib/jruby-parser.jar +0 -0
- data/lib/jruby-parser/version.rb +1 -1
- data/spec/helpers/node_helpers.rb +113 -1
- data/spec/helpers/parser_helpers.rb +13 -0
- data/spec/jruby-parser/find_scopes_spec.rb +31 -0
- data/spec/jruby-parser/find_spec.rb +9 -7
- data/spec/jruby-parser/get_node_at_spec.rb +18 -0
- data/spec/jruby-parser/is_block_parameter_spec.rb +38 -0
- data/spec/jruby-parser/is_method_parameter_spec.rb +35 -0
- data/spec/jruby-parser/rewriting_spec.rb +14 -14
- data/spec/jruby-parser/static_analysis_spec.rb +171 -0
- data/spec/positions/arg_spec.rb +18 -1
- data/spec/positions/attr_asgn_spec.rb +15 -0
- data/spec/positions/call_spec.rb +6 -0
- metadata +38 -41
- data/bin/generate_parser +0 -46
- data/bin/optimize_parser.rb +0 -106
- data/bin/patch_parser.rb +0 -105
data/lib/jruby-parser.jar
CHANGED
Binary file
|
data/lib/jruby-parser/version.rb
CHANGED
@@ -110,11 +110,123 @@ module HaveArgCounts
|
|
110
110
|
ArgCountsMatcher.new(*args)
|
111
111
|
end
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
|
+
class HaveParametersMatcher
|
115
|
+
def initialize(*list)
|
116
|
+
@with_decorations = []
|
117
|
+
@without_decorations = []
|
118
|
+
list.each do |e1, e2|
|
119
|
+
@without_decorations << e1
|
120
|
+
@with_decorations << (e2 || e1)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def matches?(args)
|
125
|
+
@actual_with = args.get_normative_parameter_name_list(false).to_a
|
126
|
+
@actual_without = args.get_normative_parameter_name_list(true).to_a
|
127
|
+
@with_decorations == @actual_with && @without_decorations == @actual_without
|
128
|
+
end
|
129
|
+
|
130
|
+
def failure_message
|
131
|
+
error = ""
|
132
|
+
if @with_decorations != @actual_with
|
133
|
+
error << %[expected #{@actual_with.inspect} to have #{@with_decorations.inspect}.]
|
134
|
+
end
|
135
|
+
|
136
|
+
if @without_decorations != @actual_without
|
137
|
+
error << %[ expected #{@actual_without.inspect} to have #{@without_decorations.inspect}.]
|
138
|
+
end
|
139
|
+
error
|
140
|
+
end
|
141
|
+
|
142
|
+
def negative_failure_message
|
143
|
+
error = ""
|
144
|
+
if @with_decorations != @actual_with
|
145
|
+
error << %[expected #{@actual_with.inspect} to not have #{@with_decorations.inspect}.]
|
146
|
+
end
|
147
|
+
|
148
|
+
if @without_decorations != @actual_without
|
149
|
+
error << %[ expected #{@actual_without.inspect} to not have #{@without_decorations.inspect}.]
|
150
|
+
end
|
151
|
+
error
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
module HaveParameters
|
156
|
+
def have_parameters(*args)
|
157
|
+
HaveParametersMatcher.new(*args)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
class HaveStaticAssignmentsMatcher
|
162
|
+
java_import org.jrubyparser.ast.FixnumNode
|
163
|
+
java_import org.jrubyparser.ast.ListNode
|
164
|
+
|
165
|
+
def initialize(list)
|
166
|
+
@list = list
|
167
|
+
end
|
168
|
+
|
169
|
+
def matches?(args)
|
170
|
+
@actual_list = args.calculateStaticAssignments.to_a
|
171
|
+
@failures_var_names = []
|
172
|
+
@failures_var_values = []
|
173
|
+
|
174
|
+
@list.each_with_index do |arr, i|
|
175
|
+
node_pair = @actual_list[i]
|
176
|
+
expected_var, expected_value = arr[0].to_s, arr[1]
|
177
|
+
actual_var, actual_value = node_pair.first.name, value_for(node_pair.second)
|
178
|
+
|
179
|
+
@failures_var_names << [expected_var, actual_var] if expected_var != actual_var
|
180
|
+
@failures_var_values << [expected_value, actual_value] if expected_value != actual_value
|
181
|
+
|
182
|
+
end
|
183
|
+
|
184
|
+
@failures_var_names.size == 0 && @failures_var_values.size == 0
|
185
|
+
end
|
186
|
+
|
187
|
+
def value_for(node)
|
188
|
+
if node.kind_of? FixnumNode
|
189
|
+
node.value
|
190
|
+
elsif node.kind_of? ListNode
|
191
|
+
node.child_nodes.map {|e| value_for(e)}
|
192
|
+
else
|
193
|
+
node
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def failure_message
|
198
|
+
names = @failures_var_names.inject("names: ") do |s, e|
|
199
|
+
s << "#{e[0]} != #{e[1]} "
|
200
|
+
end
|
201
|
+
|
202
|
+
@failures_var_values.inject(names + "\nvalues: ") do |s, e|
|
203
|
+
s << "#{e[0]} != #{e[1]} "
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def negative_failure_message
|
208
|
+
names = @failures_var_names.inject("names: ") do |s, e|
|
209
|
+
s << "#{e[0]} !!= #{e[1]}"
|
210
|
+
end
|
211
|
+
|
212
|
+
@failures_var_values.inject(names + "\nvalues: ") do |s, e|
|
213
|
+
s << "#{e[0]} !!= #{e[1]} "
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
module HaveStaticAssignments
|
219
|
+
def have_static_assignments(*args)
|
220
|
+
HaveStaticAssignmentsMatcher.new(*args)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
114
224
|
#module Spec::Example::ExampleMethods
|
115
225
|
class Object
|
116
226
|
include HavePosition
|
117
227
|
include HaveName
|
118
228
|
include HaveNameAndPosition
|
119
229
|
include HaveArgCounts
|
230
|
+
include HaveParameters
|
231
|
+
include HaveStaticAssignments
|
120
232
|
end
|
@@ -20,4 +20,17 @@ class Object
|
|
20
20
|
config = version == 1.8 ? CONFIG_18 : CONFIG_19
|
21
21
|
PARSER.parse "<code>", source(code), config
|
22
22
|
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# parse code but record first '^' and return the node which
|
26
|
+
# that offset represents. If you are testing source which contains
|
27
|
+
# a caret already you can substitute the value with a delimeter which
|
28
|
+
# will work.
|
29
|
+
def caret_parse(code, version=1.8, caret='^')
|
30
|
+
caret_index = code.index(caret)
|
31
|
+
raise ArgumentError.new("Caret '^' missing: #{code}") unless caret_index
|
32
|
+
|
33
|
+
root = parse(code.sub(caret, ''), version)
|
34
|
+
[root, root.node_at(caret_index)]
|
35
|
+
end
|
23
36
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
3
|
+
require 'java'
|
4
|
+
require 'jruby-parser'
|
5
|
+
require 'parser_helpers'
|
6
|
+
|
7
|
+
describe JRubyParser do
|
8
|
+
[JRubyParser::Compat::RUBY1_8, JRubyParser::Compat::RUBY1_9].each do |v|
|
9
|
+
it "children can ask for the method it is contained in [#{v}]" do
|
10
|
+
parse("def foo; true if false; end").find_node(:defn) do |defn|
|
11
|
+
defn.find_node(:true).method_for.should == defn
|
12
|
+
defn.find_node(:false).method_for.should == defn
|
13
|
+
defn.find_node(:if).method_for.should == defn
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "children can ask for the iter/block it is contained in [#{v}]" do
|
18
|
+
parse("proc { |a| proc { |b| true } }").find_node(:iter) do |iter1|
|
19
|
+
iter1.find_node(:true).innermost_iter.should_not == iter1
|
20
|
+
iter1.find_node(:true).outermost_iter.should == iter1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should not find an innermost block if method is inside block" do
|
25
|
+
parse("proc { def foo; true; end }").find_node(:true) do |tru|
|
26
|
+
tru.innermost_iter.should == nil
|
27
|
+
tru.outermost_iter.should == nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,25 +1,27 @@
|
|
1
1
|
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
2
3
|
require 'java'
|
3
4
|
require 'jruby-parser'
|
5
|
+
require 'parser_helpers'
|
4
6
|
|
5
7
|
describe JRubyParser do
|
6
|
-
[
|
7
|
-
it "finds fcall via simple symbol search" do
|
8
|
-
|
8
|
+
[1.8, 1.9].each do |v|
|
9
|
+
it "finds fcall via simple symbol search [#{v}]" do
|
10
|
+
parse("b = foo(1)").tap do |root|
|
9
11
|
fcall = root.find_type(:fcall)
|
10
12
|
fcall.should_not == nil
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
it "finds specific fcall by block and simple symbol" do
|
15
|
-
|
16
|
+
it "finds specific fcall by block and simple symbol [#{v}]" do
|
17
|
+
parse("foo(1); bar(2)").tap do |root|
|
16
18
|
fcall = root.find_type(:fcall) { |n| n.name == "bar" }
|
17
19
|
fcall.name.should == "bar"
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
it "finds type and method named based on Enumerable find" do
|
22
|
-
|
23
|
+
it "finds type and method named based on Enumerable find [#{v}]" do
|
24
|
+
parse("foo(1); bar(2)").tap do |root|
|
23
25
|
fcall = root.find { |n| n.short_name == "fcall" && n.name == "bar"}
|
24
26
|
fcall.name.should == "bar"
|
25
27
|
fcalls = root.find_all { |n| n.short_name == "fcall" }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
3
|
+
require 'java'
|
4
|
+
require 'jruby-parser'
|
5
|
+
require 'parser_helpers'
|
6
|
+
|
7
|
+
describe JRubyParser do
|
8
|
+
[1.8, 1.9].each do |v|
|
9
|
+
it "finds fcall via simple getNodeAt search [#{v}]" do
|
10
|
+
caret_parse("b = fo^o(1)", v).tap do |root, caret_node|
|
11
|
+
root.find_node(:fcall).should == caret_node
|
12
|
+
end
|
13
|
+
caret_parse("b = foo(^1)", v).tap do |root, caret_node|
|
14
|
+
root.find_node(:fixnum).should == caret_node
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
3
|
+
require 'java'
|
4
|
+
require 'jruby-parser'
|
5
|
+
require 'parser_helpers'
|
6
|
+
|
7
|
+
describe JRubyParser do
|
8
|
+
[1.8, 1.9].each do |v|
|
9
|
+
it "finds parameter via is_block_parameter [#{v}]" do
|
10
|
+
caret_parse("proc { |^a| }", v).tap do |root, caret_node|
|
11
|
+
caret_node.block_parameter?.should == true
|
12
|
+
end
|
13
|
+
caret_parse("proc { |^a,b| }", v).tap do |root, caret_node|
|
14
|
+
caret_node.block_parameter?.should == true
|
15
|
+
end
|
16
|
+
caret_parse("proc { |*^a| }", v).tap do |root, caret_node|
|
17
|
+
caret_node.block_parameter?.should == true
|
18
|
+
end
|
19
|
+
caret_parse("proc { |a, (b, ^c)| }", v).tap do |root, caret_node|
|
20
|
+
caret_node.block_parameter?.should == true
|
21
|
+
end
|
22
|
+
caret_parse("proc { |&^a| }", v).tap do |root, caret_node|
|
23
|
+
caret_node.block_parameter?.should == true
|
24
|
+
end
|
25
|
+
|
26
|
+
if v == 1.9
|
27
|
+
caret_parse("proc { |a, ^b=1| }", v).tap do |root, caret_node|
|
28
|
+
caret_node.block_parameter?.should == true
|
29
|
+
end
|
30
|
+
|
31
|
+
caret_parse("proc { |c| proc { |a, b=^c| } }", v).tap do |root, caret_node|
|
32
|
+
caret_node.block_parameter?.should == false
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
3
|
+
require 'java'
|
4
|
+
require 'jruby-parser'
|
5
|
+
require 'parser_helpers'
|
6
|
+
|
7
|
+
describe JRubyParser do
|
8
|
+
[1.8, 1.9].each do |v|
|
9
|
+
it "finds parameter via is_method_parameter [#{v}]" do
|
10
|
+
caret_parse("def foo(^a); end", v).tap do |root, caret_node|
|
11
|
+
caret_node.method_parameter?.should == true
|
12
|
+
end
|
13
|
+
caret_parse("def foo(^a,b); end", v).tap do |root, caret_node|
|
14
|
+
caret_node.method_parameter?.should == true
|
15
|
+
end
|
16
|
+
caret_parse("def foo(*^a); end", v).tap do |root, caret_node|
|
17
|
+
caret_node.method_parameter?.should == true
|
18
|
+
end
|
19
|
+
caret_parse("def foo(&^a); end", v).tap do |root, caret_node|
|
20
|
+
caret_node.method_parameter?.should == true
|
21
|
+
end
|
22
|
+
caret_parse("def foo(a, ^b=1); end", v).tap do |root, caret_node|
|
23
|
+
caret_node.method_parameter?.should == true
|
24
|
+
end
|
25
|
+
if v == 1.9
|
26
|
+
caret_parse("def foo(a, (b, ^c)); end", v).tap do |root, caret_node|
|
27
|
+
caret_node.method_parameter?.should == true
|
28
|
+
end
|
29
|
+
caret_parse("def foo(a, b=1, ^c); end", v).tap do |root, caret_node|
|
30
|
+
caret_node.method_parameter?.should == true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -2,51 +2,51 @@ $LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
|
2
2
|
require 'jruby-parser'
|
3
3
|
|
4
4
|
describe JRubyParser do
|
5
|
-
[
|
6
|
-
it "rewrites method name from foo to bar" do
|
7
|
-
|
5
|
+
[1.8, 1.9].each do |v|
|
6
|
+
it "rewrites method name from foo to bar [#{v}]" do
|
7
|
+
parse("b = foo(1)").tap do |root|
|
8
8
|
fcall = root.find_node(:fcall)
|
9
9
|
fcall.name = 'bar'
|
10
10
|
end.to_source.should == "b = bar(1)"
|
11
11
|
|
12
|
-
|
12
|
+
parse("b = foo 1").tap do |root|
|
13
13
|
fcall = root.find_node(:fcall)
|
14
14
|
fcall.name = 'bar'
|
15
15
|
end.to_source.should == "b = bar 1"
|
16
16
|
end
|
17
17
|
|
18
|
-
it "rewrites between different coercible ruby types" do
|
18
|
+
it "rewrites between different coercible ruby types [#{v}]" do
|
19
19
|
[1, 1.0, true, false, nil, "a"].each do |replace|
|
20
|
-
|
20
|
+
parse("foo 1").tap do |root|
|
21
21
|
fcall = root.find_node(:fcall)
|
22
22
|
fcall.args[0] = replace
|
23
23
|
end.to_source.should == "foo #{replace.inspect}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
it "rewrites receiver of a call" do
|
28
|
-
|
27
|
+
it "rewrites receiver of a call [#{v}]" do
|
28
|
+
parse("1.to_f(1)").tap do |root|
|
29
29
|
call = root.find_node(:call)
|
30
30
|
call.receiver = 2
|
31
31
|
end.to_source.should == "2.to_f(1)"
|
32
32
|
end
|
33
33
|
|
34
|
-
it "rewrites can add to simple args" do
|
35
|
-
|
34
|
+
it "rewrites can add to simple args [#{v}]" do
|
35
|
+
parse("foo(1)").tap do |root|
|
36
36
|
call = root.find_node(:fcall)
|
37
37
|
call.args << 2
|
38
38
|
end.to_source.should == "foo(1, 2)"
|
39
39
|
end
|
40
40
|
|
41
|
-
it "rewrites can add to simple args" do
|
42
|
-
|
41
|
+
it "rewrites can add to simple args [#{v}]" do
|
42
|
+
parse("foo(1)").tap do |root|
|
43
43
|
call = root.find_node(:fcall)
|
44
44
|
call.args = [3, 4]
|
45
45
|
end.to_source.should == "foo(3, 4)"
|
46
46
|
end
|
47
47
|
|
48
|
-
it "rewrites op element assignment" do
|
49
|
-
|
48
|
+
it "rewrites op element assignment [#{v}]" do
|
49
|
+
parse("a[3] += 5").tap do |root|
|
50
50
|
op = root.find_node(:opelementasgn)
|
51
51
|
op.receiver = 1
|
52
52
|
op.args[0] = 2
|
@@ -0,0 +1,171 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
3
|
+
require 'jruby-parser'
|
4
|
+
require 'parser_helpers'
|
5
|
+
require 'node_helpers'
|
6
|
+
|
7
|
+
describe Parser do
|
8
|
+
[1.9].each do |v|
|
9
|
+
it "parses a simple multiple assignment [#{v}]" do
|
10
|
+
parse("a,b,c = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
|
11
|
+
masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, 3]])
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "parses a simple lhs splat multiple assignment [#{v}]" do
|
16
|
+
parse("a,*b = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
|
17
|
+
masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]]])
|
18
|
+
end
|
19
|
+
parse("a,b,*c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
|
20
|
+
masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3,4]]])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "parses a simple lhs splat multiple assignment [#{v}]" do
|
25
|
+
parse("*a,b = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
|
26
|
+
masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3]])
|
27
|
+
end
|
28
|
+
parse("*a,b,c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
|
29
|
+
masgn.should have_static_assignments([[:a, [1, 2]], [:b, 3], [:c, 4]])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "parses a simple lhs splat multiple assignment [#{v}]" do
|
34
|
+
parse("a,*b, c = 1,2,3,4", v).find_node(:multipleasgn19).tap do |masgn|
|
35
|
+
masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4]])
|
36
|
+
end
|
37
|
+
parse("a, b, *c, d = 1,2,3,4,5", v).find_node(:multipleasgn19).tap do |masgn|
|
38
|
+
masgn.should have_static_assignments([[:a, 1], [:b, 2], [:c, [3, 4]], [:d, 5]])
|
39
|
+
end
|
40
|
+
parse("a, *b, c, d = 1,2,3,4,5", v).find_node(:multipleasgn19).tap do |masgn|
|
41
|
+
masgn.should have_static_assignments([[:a, 1], [:b, [2, 3]], [:c, 4], [:d, 5]])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "parses a simple lhs splat multiple assignment [#{v}]" do
|
46
|
+
parse("a,*b,c,d = 1,2,3", v).find_node(:multipleasgn19).tap do |masgn|
|
47
|
+
masgn.should have_static_assignments([[:a, 1], [:b, []], [:c, 2], [:d, 3]])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "parses a simple rhs splat multiple assignment [#{v}]" do
|
52
|
+
ast = parse("a,*b = 1,*foo", v)
|
53
|
+
foo = ast.find_node(:vcall)
|
54
|
+
ast.find_node(:multipleasgn19).tap do |masgn|
|
55
|
+
masgn.should have_static_assignments([[:a, 1], [:b, foo]])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it "parses a simple rhs splat multiple assignment [#{v}]" do
|
60
|
+
ast = parse("*a,b = *foo,1", v)
|
61
|
+
splatted_foo = ast.find_node(:splat)
|
62
|
+
ast.find_node(:multipleasgn19).tap do |masgn|
|
63
|
+
masgn.should have_static_assignments([[:a, splatted_foo], [:b, 1]])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "method: Can detect simple parameter is used" do
|
68
|
+
parse("def foo(a); a; end").find_node(:defn) do |defn|
|
69
|
+
defn.args.get_normative_parameter_name_list(true).each do |parameter|
|
70
|
+
defn.is_parameter_used(parameter).should == true
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
parse("def foo(a,b); a; b; end").find_node(:defn) do |defn|
|
75
|
+
defn.args.get_normative_parameter_name_list(true).each do |parameter|
|
76
|
+
defn.is_parameter_used(parameter).should == true
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
parse("def foo(a,b); a=1; b; end").find_node(:defn) do |defn|
|
81
|
+
defn.is_parameter_used("a").should == false
|
82
|
+
defn.is_parameter_used("b").should == true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "method: Can detect some simple parameters are used" do
|
87
|
+
parse("def foo(a,b); b; end").find_node(:defn) do |defn|
|
88
|
+
defn.is_parameter_used("a").should == false
|
89
|
+
defn.is_parameter_used("b").should == true
|
90
|
+
end
|
91
|
+
|
92
|
+
parse("def foo(a,b); b if true; end").find_node(:defn) do |defn|
|
93
|
+
defn.is_parameter_used("a").should == false
|
94
|
+
defn.is_parameter_used("b").should == true
|
95
|
+
end
|
96
|
+
|
97
|
+
parse("def foo(a,b); proc { b if true }; end").find_node(:defn) do |defn|
|
98
|
+
defn.is_parameter_used("a").should == false
|
99
|
+
defn.is_parameter_used("b").should == true
|
100
|
+
end
|
101
|
+
|
102
|
+
parse("def foo a, b, c\nputs a, b, c\nend").find_node(:defn) do |defn|
|
103
|
+
defn.is_parameter_used("a").should == true
|
104
|
+
defn.is_parameter_used("b").should == true
|
105
|
+
defn.is_parameter_used("c").should == true
|
106
|
+
end
|
107
|
+
|
108
|
+
parse("def foo(a, b); b.each_answer {|n| data if n == a }; end") do |defn|
|
109
|
+
defn.is_parameter_used("a").should == true
|
110
|
+
defn.is_parameter_used("b").should == true
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "method: Can detect some simple optarg params are used" do
|
115
|
+
parse("def foo(a,b = {}); b; end").find_node(:defn) do |defn|
|
116
|
+
defn.is_parameter_used("a").should == false
|
117
|
+
defn.is_parameter_used("b").should == true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
it "method: Can detect zsuper usage" do
|
122
|
+
parse("def foo(a,b = {}); super; end").find_node(:defn) do |defn|
|
123
|
+
defn.is_parameter_used("a").should == true
|
124
|
+
defn.is_parameter_used("b").should == true
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
it "block/iter: Can detect simple parameter is used" do
|
129
|
+
parse("proc { |a, b| a; b }").find_node(:iter) do |iter|
|
130
|
+
iter.is_parameter_used("a").should == true
|
131
|
+
iter.is_parameter_used("b").should == true
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "block/iter: Can detect simple parameter is used" do
|
136
|
+
parse("proc { |a, b| a=1; b }").find_node(:iter) do |iter|
|
137
|
+
iter.is_parameter_used("a").should == false
|
138
|
+
iter.is_parameter_used("b").should == true
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
it "block/iter: Can detect some simple parameters are used" do
|
143
|
+
parse("proc {|a,b| b }").find_node(:iter) do |iter|
|
144
|
+
iter.is_parameter_used("a").should == false
|
145
|
+
iter.is_parameter_used("b").should == true
|
146
|
+
end
|
147
|
+
|
148
|
+
parse("proc {|a,b| b if true }").find_node(:iter) do |iter|
|
149
|
+
iter.is_parameter_used("a").should == false
|
150
|
+
iter.is_parameter_used("b").should == true
|
151
|
+
end
|
152
|
+
|
153
|
+
parse("proc {|a,b| proc { b if true } }").find_node(:iter) do |iter|
|
154
|
+
iter.is_parameter_used("a").should == false
|
155
|
+
iter.is_parameter_used("b").should == true
|
156
|
+
end
|
157
|
+
|
158
|
+
parse("proc {|a, b, c| puts a, b, c }").find_node(:iter) do |iter|
|
159
|
+
iter.is_parameter_used("a").should == true
|
160
|
+
iter.is_parameter_used("b").should == true
|
161
|
+
iter.is_parameter_used("c").should == true
|
162
|
+
end
|
163
|
+
|
164
|
+
parse("proc {|a, b| b.each_answer {|n| data if n == a } }") do |iter|
|
165
|
+
iter.is_parameter_used("a").should == true
|
166
|
+
iter.is_parameter_used("b").should == true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
data/spec/positions/arg_spec.rb
CHANGED
@@ -10,6 +10,7 @@ describe Parser do
|
|
10
10
|
parse("def foo\nend\n", v).find_node(:defn).tap do |defn|
|
11
11
|
defn.should have_name_and_position("foo", 0, 1, 0, 11)
|
12
12
|
defn.args_node.should have_arg_counts(0, 0, false, false)
|
13
|
+
defn.args_node.should have_parameters()
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
@@ -17,6 +18,7 @@ describe Parser do
|
|
17
18
|
parse("def foo()\nend\n", v).find_node(:defn).tap do |defn|
|
18
19
|
defn.should have_name_and_position("foo", 0, 1, 0, 13)
|
19
20
|
defn.args_node.should have_arg_counts(0, 0, false, false)
|
21
|
+
defn.args_node.should have_parameters()
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -24,6 +26,7 @@ describe Parser do
|
|
24
26
|
parse("def foo a\nend\n", v).find_node(:defn).tap do |defn|
|
25
27
|
defn.should have_name_and_position("foo", 0, 1, 0, 13)
|
26
28
|
defn.args_node.should have_arg_counts(1, 0, false, false)
|
29
|
+
defn.args_node.should have_parameters('a')
|
27
30
|
defn.args_node.pre.tap do |pre|
|
28
31
|
pre.should have_position(0, 0, 8, 9)
|
29
32
|
pre[0].should have_name_and_position("a", 0, 0, 8, 9)
|
@@ -35,6 +38,7 @@ describe Parser do
|
|
35
38
|
parse("def foo(a)\nend\n", v).find_node(:defn).tap do |defn|
|
36
39
|
defn.should have_name_and_position("foo", 0, 1, 0, 14)
|
37
40
|
defn.args_node.should have_arg_counts(1, 0, false, false)
|
41
|
+
defn.args_node.should have_parameters('a')
|
38
42
|
defn.args_node.pre.tap do |pre|
|
39
43
|
pre.should have_position(0, 0, 8, 9)
|
40
44
|
pre[0].should have_name_and_position("a", 0, 0, 8, 9)
|
@@ -46,6 +50,7 @@ describe Parser do
|
|
46
50
|
parse("def foo a, b\nend\n", v).find_node(:defn).tap do |defn|
|
47
51
|
defn.should have_name_and_position("foo", 0, 1, 0, 16)
|
48
52
|
defn.args_node.should have_arg_counts(2, 0, false, false)
|
53
|
+
defn.args_node.should have_parameters('a', 'b')
|
49
54
|
defn.args_node.pre.tap do |pre|
|
50
55
|
pre.should have_position(0, 0, 8, 12)
|
51
56
|
pre[0].should have_name_and_position("a", 0, 0, 8, 9)
|
@@ -58,6 +63,7 @@ describe Parser do
|
|
58
63
|
parse("def foo(a, b)\nend\n", v).find_node(:defn) do |defn|
|
59
64
|
defn.should have_name_and_position("foo", 0, 1, 0, 17)
|
60
65
|
defn.args_node.should have_arg_counts(2, 0, false, false)
|
66
|
+
defn.args_node.should have_parameters('a', 'b')
|
61
67
|
defn.args_node.pre.tap do |pre|
|
62
68
|
pre.should have_position(0, 0, 8, 12)
|
63
69
|
pre[0].should have_name_and_position("a", 0, 0, 8, 9)
|
@@ -70,6 +76,7 @@ describe Parser do
|
|
70
76
|
parse("def foo a=1\nend\n", v).find_node(:defn).tap do |defn|
|
71
77
|
defn.should have_name_and_position("foo", 0, 1, 0, 15)
|
72
78
|
defn.args_node.should have_arg_counts(0, 1, false, false)
|
79
|
+
defn.args_node.should have_parameters('a')
|
73
80
|
lasgn = defn.args_node.optional.find_node(:localasgn)
|
74
81
|
lasgn.should have_name_and_position("a", 0, 0, 8, 11)
|
75
82
|
end
|
@@ -79,6 +86,7 @@ describe Parser do
|
|
79
86
|
parse("def foo(a=1)\nend\n", v).find_node(:defn).tap do |defn|
|
80
87
|
defn.should have_name_and_position("foo", 0, 1, 0, 16)
|
81
88
|
defn.args_node.should have_arg_counts(0, 1, false, false)
|
89
|
+
defn.args_node.should have_parameters('a')
|
82
90
|
lasgn = defn.args_node.optional.find_node(:localasgn)
|
83
91
|
lasgn.should have_name_and_position("a", 0, 0, 8, 11)
|
84
92
|
end
|
@@ -88,6 +96,7 @@ describe Parser do
|
|
88
96
|
parse("def foo *a\nend\n", v).find_node(:defn).tap do |defn|
|
89
97
|
defn.should have_name_and_position("foo", 0, 1, 0, 14)
|
90
98
|
defn.args_node.should have_arg_counts(0, 0, true, false)
|
99
|
+
defn.args_node.should have_parameters(['a', '*a'])
|
91
100
|
end
|
92
101
|
end
|
93
102
|
|
@@ -95,6 +104,8 @@ describe Parser do
|
|
95
104
|
parse("def foo(*a)\nend\n", v).find_node(:defn).tap do |defn|
|
96
105
|
defn.should have_name_and_position("foo", 0, 1, 0, 15)
|
97
106
|
defn.args_node.should have_arg_counts(0, 0, true, false)
|
107
|
+
defn.args_node.rest.should have_position(0, 0, 8, 10)
|
108
|
+
defn.args_node.should have_parameters(['a', '*a'])
|
98
109
|
end
|
99
110
|
end
|
100
111
|
|
@@ -102,6 +113,7 @@ describe Parser do
|
|
102
113
|
parse("def foo &a\nend\n", v).find_node(:defn).tap do |defn|
|
103
114
|
defn.should have_name_and_position("foo", 0, 1, 0, 14)
|
104
115
|
defn.args_node.should have_arg_counts(0, 0, false, true)
|
116
|
+
defn.args_node.should have_parameters(['a', '&a'])
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
@@ -109,13 +121,17 @@ describe Parser do
|
|
109
121
|
parse("def foo(&a)\nend\n", v).find_node(:defn).tap do |defn|
|
110
122
|
defn.should have_name_and_position("foo", 0, 1, 0, 15)
|
111
123
|
defn.args_node.should have_arg_counts(0, 0, false, true)
|
124
|
+
defn.args_node.block.should have_position(0, 0, 8, 10)
|
125
|
+
defn.args_node.should have_parameters(['a', '&a'])
|
112
126
|
end
|
113
127
|
end
|
114
128
|
|
115
129
|
it "parses a mixed-arg method sans parens [#{v}]" do
|
116
130
|
parse("def foo a, b, c = 1, *d\nend\n", v).find_node(:defn).tap do |defn|
|
117
131
|
defn.should have_name_and_position("foo", 0, 1, 0, 27)
|
118
|
-
defn.args_node
|
132
|
+
args = defn.args_node
|
133
|
+
args.should have_arg_counts(2, 1, true, false)
|
134
|
+
defn.args_node.should have_parameters('a', 'b', 'c', ['d', '*d'])
|
119
135
|
end
|
120
136
|
end
|
121
137
|
|
@@ -123,6 +139,7 @@ describe Parser do
|
|
123
139
|
parse("def foo(a, b, c = 1, *d)\nend\n", v).find_node(:defn).tap do |defn|
|
124
140
|
defn.should have_name_and_position("foo", 0, 1, 0, 28)
|
125
141
|
defn.args_node.should have_arg_counts(2, 1, true, false)
|
142
|
+
defn.args_node.should have_parameters('a', 'b', 'c', ['d', '*d'])
|
126
143
|
end
|
127
144
|
end
|
128
145
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../helpers"
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + "/../../lib"
|
3
|
+
require 'jruby-parser'
|
4
|
+
require 'parser_helpers'
|
5
|
+
require 'node_helpers'
|
6
|
+
|
7
|
+
describe Parser do
|
8
|
+
[1.8, 1.9].each do |v|
|
9
|
+
it "Should parse attr assign" do
|
10
|
+
parse("a[1] = 2", v).find_node(:attrassign).tap do |asgn|
|
11
|
+
asgn.should_not == nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/spec/positions/call_spec.rb
CHANGED
@@ -6,6 +6,12 @@ require 'node_helpers'
|
|
6
6
|
|
7
7
|
describe Parser do
|
8
8
|
[1.8, 1.9].each do |v|
|
9
|
+
it "parses a 0-arg method call sans parens +extra line [#{v}]" do
|
10
|
+
parse("\nblock_given?\n", v).find_node(:fcall).tap do |call|
|
11
|
+
call.should have_name_and_position("block_given?", 1, 1, 1, 13)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
9
15
|
it "parses a 0-arg method call sans parens +extra line [#{v}]" do
|
10
16
|
parse("\nputs\n", v).find_node(:vcall).tap do |call|
|
11
17
|
call.should have_name_and_position("puts", 1, 1, 1, 5)
|
metadata
CHANGED
@@ -1,33 +1,22 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: jruby-parser
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 3
|
8
|
-
version: "0.3"
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: '0.4'
|
9
6
|
platform: ruby
|
10
|
-
authors:
|
7
|
+
authors:
|
11
8
|
- Thomas E. Enebo
|
12
|
-
autorequire:
|
9
|
+
autorequire:
|
13
10
|
bindir: bin
|
14
11
|
cert_chain: []
|
15
|
-
|
16
|
-
date: 2012-04-18 00:00:00 -05:00
|
17
|
-
default_executable:
|
12
|
+
date: 2013-03-27 00:00:00.000000000 Z
|
18
13
|
dependencies: []
|
19
|
-
|
20
14
|
description: A Gem for syntactically correct parse trees of Ruby source
|
21
15
|
email: tom.enebo@gmail.com
|
22
|
-
executables:
|
23
|
-
- generate_parser
|
24
|
-
- optimize_parser.rb
|
25
|
-
- patch_parser.rb
|
16
|
+
executables: []
|
26
17
|
extensions: []
|
27
|
-
|
28
18
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
files:
|
19
|
+
files:
|
31
20
|
- lib/jruby-parser.rb
|
32
21
|
- lib/jruby-parser/core_ext/array.rb
|
33
22
|
- lib/jruby-parser/core_ext/attr_assign_node.rb
|
@@ -48,56 +37,64 @@ files:
|
|
48
37
|
- spec/ast/node_path.rb
|
49
38
|
- spec/helpers/node_helpers.rb
|
50
39
|
- spec/helpers/parser_helpers.rb
|
40
|
+
- spec/jruby-parser/find_scopes_spec.rb
|
51
41
|
- spec/jruby-parser/find_spec.rb
|
42
|
+
- spec/jruby-parser/get_node_at_spec.rb
|
43
|
+
- spec/jruby-parser/is_block_parameter_spec.rb
|
44
|
+
- spec/jruby-parser/is_method_parameter_spec.rb
|
52
45
|
- spec/jruby-parser/rewriting_spec.rb
|
46
|
+
- spec/jruby-parser/static_analysis_spec.rb
|
53
47
|
- spec/parser/alias_spec.rb
|
54
48
|
- spec/parser/broken_spec.rb
|
55
49
|
- spec/positions/arg_spec.rb
|
50
|
+
- spec/positions/attr_asgn_spec.rb
|
56
51
|
- spec/positions/call_spec.rb
|
57
52
|
- spec/positions/conditionals_spec.rb
|
58
53
|
- spec/positions/hash_spec.rb
|
59
54
|
- spec/positions/heredoc_spec.rb
|
60
55
|
- spec/positions/str_spec.rb
|
61
56
|
- lib/jruby-parser.jar
|
62
|
-
has_rdoc: true
|
63
57
|
homepage: http://github.com/jruby/jruby-parser
|
64
58
|
licenses: []
|
65
|
-
|
66
|
-
post_install_message:
|
59
|
+
post_install_message:
|
67
60
|
rdoc_options: []
|
68
|
-
|
69
|
-
require_paths:
|
61
|
+
require_paths:
|
70
62
|
- lib
|
71
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
73
65
|
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: !binary |-
|
68
|
+
MA==
|
69
|
+
none: false
|
70
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
80
72
|
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
|
83
|
-
|
84
|
-
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: !binary |-
|
75
|
+
MA==
|
76
|
+
none: false
|
85
77
|
requirements: []
|
86
|
-
|
87
78
|
rubyforge_project: jruby-parser
|
88
|
-
rubygems_version: 1.
|
89
|
-
signing_key:
|
79
|
+
rubygems_version: 1.8.24
|
80
|
+
signing_key:
|
90
81
|
specification_version: 3
|
91
82
|
summary: A Gem for syntactically correct parse trees of Ruby source
|
92
|
-
test_files:
|
83
|
+
test_files:
|
93
84
|
- spec/ast/node_path.rb
|
94
85
|
- spec/helpers/node_helpers.rb
|
95
86
|
- spec/helpers/parser_helpers.rb
|
87
|
+
- spec/jruby-parser/find_scopes_spec.rb
|
96
88
|
- spec/jruby-parser/find_spec.rb
|
89
|
+
- spec/jruby-parser/get_node_at_spec.rb
|
90
|
+
- spec/jruby-parser/is_block_parameter_spec.rb
|
91
|
+
- spec/jruby-parser/is_method_parameter_spec.rb
|
97
92
|
- spec/jruby-parser/rewriting_spec.rb
|
93
|
+
- spec/jruby-parser/static_analysis_spec.rb
|
98
94
|
- spec/parser/alias_spec.rb
|
99
95
|
- spec/parser/broken_spec.rb
|
100
96
|
- spec/positions/arg_spec.rb
|
97
|
+
- spec/positions/attr_asgn_spec.rb
|
101
98
|
- spec/positions/call_spec.rb
|
102
99
|
- spec/positions/conditionals_spec.rb
|
103
100
|
- spec/positions/hash_spec.rb
|
data/bin/generate_parser
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
#!/bin/sh
|
2
|
-
|
3
|
-
# Run from your JRuby home directory....More smarts needed here.
|
4
|
-
|
5
|
-
###### Change these to tastes ######
|
6
|
-
JAY=jay
|
7
|
-
RUBY=ruby
|
8
|
-
PARSER_BASE=DefaultRubyParser
|
9
|
-
YYTABLE_PREFIX=
|
10
|
-
DEBUG=true
|
11
|
-
###### Do not change below ######
|
12
|
-
|
13
|
-
if [ "$1" != "" ]; then
|
14
|
-
PARSER_BASE=$1
|
15
|
-
fi
|
16
|
-
shift
|
17
|
-
|
18
|
-
if [ "$1" != "" ]; then
|
19
|
-
YYTABLE_PREFIX=$1
|
20
|
-
fi
|
21
|
-
|
22
|
-
if [ "$DEBUG" != "" ]; then
|
23
|
-
DEBUG_FLAG=-t
|
24
|
-
# Nonesense...my script-fu is weak
|
25
|
-
DEBUG_STRIP="xdyhbk"
|
26
|
-
else
|
27
|
-
DEBUG_FLAG=
|
28
|
-
DEBUG_STRIP="^//t"
|
29
|
-
fi
|
30
|
-
|
31
|
-
echo "Generating Parser '$PARSER_BASE' w/ YYTable prefix of '$YYTABLE_PREFIX'"
|
32
|
-
|
33
|
-
PARSER_DIR=src/org/jrubyparser/parser
|
34
|
-
|
35
|
-
pushd $PARSER_DIR
|
36
|
-
|
37
|
-
# Generate grammar as intermediate file
|
38
|
-
$JAY $DEBUG_FLAG $PARSER_BASE.y < skeleton.parser | grep -v $DEBUG_STRIP >$PARSER_BASE.out
|
39
|
-
|
40
|
-
# Patch file to get around Java static initialization issues plus extract
|
41
|
-
# a bunch of stuff to seperate file (yytables).
|
42
|
-
$RUBY ../../../../bin/patch_parser.rb $PARSER_BASE.out $YYTABLE_PREFIX > $PARSER_BASE.out2
|
43
|
-
$RUBY ../../../../bin/optimize_parser.rb $PARSER_BASE.out2 $YYTABLE_PREFIX > $PARSER_BASE.java
|
44
|
-
rm -f $PARSER_BASE.out $PARSER_BASE.out2
|
45
|
-
|
46
|
-
popd
|
data/bin/optimize_parser.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
class PostProcessor
|
2
|
-
def initialize(source, out=STDOUT)
|
3
|
-
@out = out
|
4
|
-
@lines = File.readlines(source)
|
5
|
-
@index = -1
|
6
|
-
@case_bodies = {}
|
7
|
-
@max_case_number = -1
|
8
|
-
end
|
9
|
-
|
10
|
-
# Read/Unread with ability to push back one line for a single lookahead
|
11
|
-
def read
|
12
|
-
@index += 1
|
13
|
-
line = @last ? @last : @lines[@index]
|
14
|
-
@last = nil
|
15
|
-
line
|
16
|
-
end
|
17
|
-
|
18
|
-
def unread(line)
|
19
|
-
@index -= 1
|
20
|
-
@last = line
|
21
|
-
end
|
22
|
-
|
23
|
-
def end_of_actions?(line)
|
24
|
-
return line =~ %r{^//\s*ACTIONS_END}
|
25
|
-
end
|
26
|
-
|
27
|
-
def translate
|
28
|
-
while (line = read)
|
29
|
-
if line =~ %r{^//\s*ACTIONS_BEGIN}
|
30
|
-
translate_actions
|
31
|
-
elsif line =~ %r{^//\s*ACTION_BODIES}
|
32
|
-
generate_action_body_methods
|
33
|
-
else
|
34
|
-
@out.puts line
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def generate_action_body_methods
|
40
|
-
@out.puts "static ParserState[] states = new ParserState[#{@max_case_number+1}];"
|
41
|
-
@out.puts "static {";
|
42
|
-
@case_bodies.each do |state, code_body|
|
43
|
-
generate_action_body_method(state, code_body)
|
44
|
-
end
|
45
|
-
@out.puts "}";
|
46
|
-
end
|
47
|
-
|
48
|
-
def generate_action_body_method(state, code_body)
|
49
|
-
@out.puts "states[#{state}] = new ParserState() {"
|
50
|
-
@out.puts " public Object execute(ParserSupport support, Lexer lexer, Object yyVal, Object[] yyVals, int yyTop) {"
|
51
|
-
code_body.each { |line| @out.puts line }
|
52
|
-
@out.puts " return yyVal;"
|
53
|
-
@out.puts " }"
|
54
|
-
@out.puts "};"
|
55
|
-
end
|
56
|
-
|
57
|
-
def translate_actions
|
58
|
-
count = 1
|
59
|
-
while (translate_action)
|
60
|
-
count += 1
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Assumptions:
|
65
|
-
# 1. no break; in our code. A bit weak, but this is highly specialized code.
|
66
|
-
# 2. All productions will have a line containing only { (with optional comment)
|
67
|
-
# 3. All productions will end with a line containly only } followed by break in ass 1.
|
68
|
-
def translate_action
|
69
|
-
line = read
|
70
|
-
return false if end_of_actions?(line) || line !~ /case\s+(\d+):/
|
71
|
-
case_number = $1.to_i
|
72
|
-
|
73
|
-
line = read
|
74
|
-
return false if line !~ /line\s+(\d+)/
|
75
|
-
line_number = $1
|
76
|
-
|
77
|
-
# Extra boiler plate '{' that we do not need
|
78
|
-
line = read
|
79
|
-
return false if line !~ /^\s*\{\s*(\/\*.*\*\/)?$/
|
80
|
-
|
81
|
-
@max_case_number = case_number if case_number > @max_case_number
|
82
|
-
|
83
|
-
label = "case#{case_number}_line#{line_number}"
|
84
|
-
|
85
|
-
body = []
|
86
|
-
last_line = nil
|
87
|
-
while (line = read)
|
88
|
-
if line =~ /^\s*\}\s*$/ # Extra trailing boiler plate
|
89
|
-
next_line = read
|
90
|
-
if next_line =~ /break;/
|
91
|
-
break
|
92
|
-
else
|
93
|
-
body << line
|
94
|
-
unread next_line
|
95
|
-
end
|
96
|
-
else
|
97
|
-
body << line
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
@case_bodies[case_number] = body
|
102
|
-
true
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
PostProcessor.new(ARGV.shift).translate
|
data/bin/patch_parser.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
def get_numbers_until_end_block(table)
|
2
|
-
while gets
|
3
|
-
break if /\};/ =~ $_
|
4
|
-
next if /^\/\// =~ $_
|
5
|
-
split(/,/).each do |number|
|
6
|
-
n = number.strip
|
7
|
-
table.push(n.to_i) unless n == ""
|
8
|
-
end
|
9
|
-
end
|
10
|
-
table
|
11
|
-
end
|
12
|
-
|
13
|
-
while gets
|
14
|
-
break if /protected static final short\[\] yyTable = \{/ =~ $_
|
15
|
-
print $_
|
16
|
-
end
|
17
|
-
|
18
|
-
# A little hacky...gets before ARGV to shift off and open file
|
19
|
-
yytable_prefix = ARGV.shift || ''
|
20
|
-
|
21
|
-
table4 = get_numbers_until_end_block([])
|
22
|
-
|
23
|
-
puts " protected static final short[] yyTable = #{yytable_prefix}YyTables.yyTable();"
|
24
|
-
|
25
|
-
while gets
|
26
|
-
break if /protected static final short\[\] yyCheck = \{/ =~ $_
|
27
|
-
print $_
|
28
|
-
end
|
29
|
-
|
30
|
-
check4 = get_numbers_until_end_block([])
|
31
|
-
|
32
|
-
puts " protected static final short[] yyCheck = #{yytable_prefix}YyTables.yyCheck();"
|
33
|
-
|
34
|
-
while gets
|
35
|
-
print $_
|
36
|
-
end
|
37
|
-
|
38
|
-
table2 = table4.slice!(0, table4.size / 2)
|
39
|
-
table3 = table4.slice!(0, table4.size / 2)
|
40
|
-
table1 = table2.slice!(0, table2.size / 2)
|
41
|
-
check2 = check4.slice!(0, check4.size / 2)
|
42
|
-
check3 = check4.slice!(0, check4.size / 2)
|
43
|
-
check1 = check2.slice!(0, check2.size / 2)
|
44
|
-
|
45
|
-
def printShortArray(table, f)
|
46
|
-
table.each_with_index { |e, i|
|
47
|
-
f.print "\n " if (i % 10 == 0)
|
48
|
-
begin
|
49
|
-
f.printf "%4d, ", e
|
50
|
-
rescue ArgumentError => a
|
51
|
-
$stderr.puts "Trouble printing '#{e}' on index #{i}"
|
52
|
-
end
|
53
|
-
}
|
54
|
-
end
|
55
|
-
|
56
|
-
def printShortMethod(f, table, name)
|
57
|
-
f.puts " private static final short[] yy#{name}() {"
|
58
|
-
f.puts " return new short[] {"
|
59
|
-
printShortArray table, f
|
60
|
-
f.puts
|
61
|
-
f.puts " };"
|
62
|
-
f.puts " }"
|
63
|
-
f.puts
|
64
|
-
end
|
65
|
-
|
66
|
-
open("#{yytable_prefix}YyTables.java", "w") { |f|
|
67
|
-
f.print <<END
|
68
|
-
package org.jrubyparser.parser;
|
69
|
-
|
70
|
-
public class #{yytable_prefix}YyTables {
|
71
|
-
private static short[] combine(short[] t1, short[] t2,
|
72
|
-
short[] t3, short[] t4) {
|
73
|
-
short[] t = new short[t1.length + t2.length + t3.length + t4.length];
|
74
|
-
int index = 0;
|
75
|
-
System.arraycopy(t1, 0, t, index, t1.length);
|
76
|
-
index += t1.length;
|
77
|
-
System.arraycopy(t2, 0, t, index, t2.length);
|
78
|
-
index += t2.length;
|
79
|
-
System.arraycopy(t3, 0, t, index, t3.length);
|
80
|
-
index += t3.length;
|
81
|
-
System.arraycopy(t4, 0, t, index, t4.length);
|
82
|
-
return t;
|
83
|
-
}
|
84
|
-
|
85
|
-
public static final short[] yyTable() {
|
86
|
-
return combine(yyTable1(), yyTable2(), yyTable3(), yyTable4());
|
87
|
-
}
|
88
|
-
|
89
|
-
public static final short[] yyCheck() {
|
90
|
-
return combine(yyCheck1(), yyCheck2(), yyCheck3(), yyCheck4());
|
91
|
-
}
|
92
|
-
END
|
93
|
-
|
94
|
-
printShortMethod(f, table1, "Table1")
|
95
|
-
printShortMethod(f, table2, "Table2")
|
96
|
-
printShortMethod(f, table3, "Table3")
|
97
|
-
printShortMethod(f, table4, "Table4")
|
98
|
-
|
99
|
-
printShortMethod(f, check1, "Check1")
|
100
|
-
printShortMethod(f, check2, "Check2")
|
101
|
-
printShortMethod(f, check3, "Check3")
|
102
|
-
printShortMethod(f, check4, "Check4")
|
103
|
-
|
104
|
-
f.puts "}"
|
105
|
-
}
|