opal 0.9.4 → 0.10.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.gitignore +2 -3
- data/.gitmodules +5 -2
- data/.jshintrc +1 -8
- data/.rspec +1 -1
- data/.travis.yml +15 -23
- data/CHANGELOG.md +511 -326
- data/CODE_OF_CONDUCT.md +13 -15
- data/CONTRIBUTING.md +26 -216
- data/Gemfile +20 -12
- data/Guardfile +2 -2
- data/HACKING.md +230 -0
- data/README.md +6 -7
- data/bin/opal-mspec +1 -1
- data/config.ru +2 -2
- data/docs/faq.md +1 -1
- data/docs/source_maps.md +1 -1
- data/lib/opal.rb +1 -0
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/cli.rb +30 -28
- data/lib/opal/cli_options.rb +3 -0
- data/lib/opal/cli_runners.rb +14 -1
- data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
- data/lib/opal/cli_runners/nashorn.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +2 -2
- data/lib/opal/cli_runners/phantom.js +24 -0
- data/lib/opal/cli_runners/phantomjs.rb +10 -10
- data/lib/opal/cli_runners/server.rb +3 -3
- data/lib/opal/compiler.rb +43 -4
- data/lib/opal/config.rb +3 -1
- data/lib/opal/errors.rb +13 -0
- data/lib/opal/fragment.rb +0 -13
- data/lib/opal/nodes.rb +10 -0
- data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
- data/lib/opal/nodes/args/kwarg.rb +29 -0
- data/lib/opal/nodes/args/kwoptarg.rb +29 -0
- data/lib/opal/nodes/args/kwrestarg.rb +39 -0
- data/lib/opal/nodes/args/mlhsarg.rb +79 -0
- data/lib/opal/nodes/args/normarg.rb +26 -0
- data/lib/opal/nodes/args/optarg.rb +27 -0
- data/lib/opal/nodes/args/post_args.rb +200 -0
- data/lib/opal/nodes/args/post_kwargs.rb +31 -0
- data/lib/opal/nodes/args/restarg.rb +33 -0
- data/lib/opal/nodes/base.rb +12 -0
- data/lib/opal/nodes/call.rb +92 -33
- data/lib/opal/nodes/def.rb +26 -169
- data/lib/opal/nodes/hash.rb +10 -4
- data/lib/opal/nodes/helpers.rb +6 -3
- data/lib/opal/nodes/inline_args.rb +61 -0
- data/lib/opal/nodes/iter.rb +73 -82
- data/lib/opal/nodes/logic.rb +12 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/node_with_args.rb +141 -0
- data/lib/opal/nodes/rescue.rb +121 -43
- data/lib/opal/nodes/scope.rb +24 -5
- data/lib/opal/nodes/super.rb +122 -54
- data/lib/opal/nodes/top.rb +0 -12
- data/lib/opal/nodes/yield.rb +2 -13
- data/lib/opal/parser.rb +67 -39
- data/lib/opal/parser/grammar.rb +3319 -2961
- data/lib/opal/parser/grammar.y +234 -46
- data/lib/opal/parser/lexer.rb +105 -17
- data/lib/opal/parser/sexp.rb +4 -0
- data/lib/opal/paths.rb +4 -0
- data/lib/opal/regexp_anchors.rb +19 -1
- data/lib/opal/sprockets.rb +21 -18
- data/lib/opal/sprockets/environment.rb +0 -8
- data/lib/opal/sprockets/processor.rb +13 -16
- data/lib/opal/sprockets/server.rb +6 -12
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/corelib/array.rb +209 -131
- data/opal/corelib/basic_object.rb +7 -3
- data/opal/corelib/class.rb +11 -17
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerable.rb +178 -355
- data/opal/corelib/enumerator.rb +3 -46
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +13 -1
- data/opal/corelib/hash.rb +26 -56
- data/opal/corelib/helpers.rb +10 -0
- data/opal/corelib/kernel.rb +6 -3
- data/opal/corelib/module.rb +62 -31
- data/opal/corelib/number.rb +7 -16
- data/opal/corelib/proc.rb +24 -9
- data/opal/corelib/range.rb +4 -13
- data/opal/corelib/runtime.js +515 -378
- data/opal/corelib/string.rb +21 -49
- data/opal/corelib/struct.rb +50 -35
- data/opal/corelib/unsupported.rb +18 -30
- data/opal/opal.rb +0 -1
- data/opal/opal/mini.rb +1 -0
- data/spec/README.md +6 -4
- data/spec/filters/bugs/array.rb +0 -42
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/bigdecimal.rb +160 -0
- data/spec/filters/bugs/class.rb +0 -5
- data/spec/filters/bugs/date.rb +1 -48
- data/spec/filters/bugs/enumerable.rb +4 -12
- data/spec/filters/bugs/enumerator.rb +0 -1
- data/spec/filters/bugs/exception.rb +4 -3
- data/spec/filters/bugs/float.rb +4 -2
- data/spec/filters/bugs/kernel.rb +25 -10
- data/spec/filters/bugs/language.rb +119 -68
- data/spec/filters/bugs/method.rb +135 -0
- data/spec/filters/bugs/module.rb +13 -28
- data/spec/filters/bugs/proc.rb +18 -8
- data/spec/filters/bugs/range.rb +0 -3
- data/spec/filters/bugs/rational.rb +4 -0
- data/spec/filters/bugs/regexp.rb +68 -36
- data/spec/filters/bugs/string.rb +1 -1
- data/spec/filters/bugs/struct.rb +0 -12
- data/spec/filters/bugs/time.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +2 -1
- data/spec/filters/unsupported/freeze.rb +3 -1
- data/spec/filters/unsupported/language.rb +0 -7
- data/spec/filters/unsupported/privacy.rb +7 -6
- data/spec/filters/unsupported/string.rb +10 -0
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +9 -0
- data/spec/filters/unsupported/taint.rb +0 -3
- data/spec/filters/unsupported/thread.rb +1 -0
- data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
- data/spec/lib/cli_spec.rb +42 -1
- data/spec/lib/compiler/call_spec.rb +700 -0
- data/spec/lib/compiler_spec.rb +46 -28
- data/spec/lib/config_spec.rb +13 -0
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/def_spec.rb +29 -0
- data/spec/lib/parser/iter_spec.rb +15 -15
- data/spec/lib/parser/lambda_spec.rb +153 -12
- data/spec/lib/parser/string_spec.rb +5 -0
- data/spec/lib/parser/undef_spec.rb +1 -1
- data/spec/lib/parser/variables_spec.rb +24 -0
- data/spec/lib/paths_spec.rb +12 -5
- data/spec/lib/spec_helper.rb +5 -0
- data/spec/lib/sprockets/processor_spec.rb +6 -5
- data/spec/lib/sprockets_spec.rb +8 -0
- data/spec/mspec-opal/formatters.rb +188 -0
- data/spec/mspec-opal/runner.rb +193 -0
- data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
- data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
- data/spec/opal/core/kernel/loop_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +1 -1
- data/spec/opal/core/language/heredoc_spec.rb +42 -0
- data/spec/opal/core/language/rescue_spec.rb +18 -0
- data/spec/opal/core/language_spec.rb +22 -0
- data/spec/opal/core/module/const_defined_spec.rb +1 -2
- data/spec/opal/core/module/name_spec.rb +6 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
- data/spec/opal/core/runtime/rescue_spec.rb +12 -2
- data/spec/opal/core/runtime/super_spec.rb +1 -0
- data/spec/opal/core/string_spec.rb +21 -0
- data/spec/opal/stdlib/js_spec.rb +1 -1
- data/spec/opal/stdlib/native/hash_spec.rb +7 -0
- data/spec/opal/stdlib/promise/always_spec.rb +24 -5
- data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
- data/spec/opal/stdlib/promise/then_spec.rb +13 -5
- data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
- data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
- data/spec/ruby_specs +122 -0
- data/spec/spec_helper.rb +3 -15
- data/stdlib/base64.rb +51 -121
- data/stdlib/bigdecimal.rb +231 -0
- data/stdlib/bigdecimal/bignumber.js.rb +11 -0
- data/stdlib/bigdecimal/kernel.rb +5 -0
- data/stdlib/date.rb +252 -10
- data/stdlib/native.rb +38 -38
- data/stdlib/nodejs/dir.rb +8 -6
- data/stdlib/nodejs/file.rb +28 -3
- data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
- data/stdlib/nodejs/require.rb +1 -1
- data/stdlib/nodejs/yaml.rb +3 -2
- data/stdlib/opal-parser.rb +7 -2
- data/stdlib/pathname.rb +23 -1
- data/stdlib/phantomjs.rb +10 -0
- data/stdlib/promise.rb +38 -23
- data/tasks/building.rake +3 -3
- data/tasks/testing.rake +27 -14
- data/tasks/testing/mspec_special_calls.rb +1 -1
- data/tasks/testing/sprockets-phantomjs.js +4 -0
- data/test/opal/test_keyword.rb +110 -110
- data/test/opal/unsupported_and_bugs.rb +30 -0
- data/vendored-minitest/minitest/assertions.rb +1 -1
- metadata +65 -15
- data/.spectator +0 -2
- data/.spectator-mspec +0 -3
- data/opal/corelib/array/inheritance.rb +0 -127
- data/spec/rubyspecs +0 -139
data/spec/lib/compiler_spec.rb
CHANGED
@@ -38,20 +38,20 @@ describe Opal::Compiler do
|
|
38
38
|
expect_compiled("self.inspect").to include("$inspect()")
|
39
39
|
expect_compiled("self.map { |a| a + 10 }").to include("$map")
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "adds method missing stubs" do
|
43
43
|
expect_compiled("self.puts 'hello'").to include("Opal.add_stubs(['$puts'])")
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
it 'adds method missing stubs with operators' do
|
47
47
|
expect_compiled("class Foo; end; Foo.new > 5").to include("Opal.add_stubs(['$>', '$new'])")
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "should compile constant lookups" do
|
51
51
|
expect_compiled("Object").to include("Object")
|
52
52
|
expect_compiled("Array").to include("Array")
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
it "should compile undef calls" do
|
56
56
|
expect_compiled("undef a").to include("Opal.udef(self, '$a')")
|
57
57
|
expect_compiled("undef a,b").to match(/Opal.udef\(self, '\$a'\);.*return Opal.udef\(self, '\$b'\);/m)
|
@@ -63,6 +63,24 @@ describe Opal::Compiler do
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
+
describe "method names" do
|
67
|
+
it "generates a named function for method" do
|
68
|
+
expect_compiled("def test_method; end").to include("function ːtest_method()")
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when function name is reserved" do
|
72
|
+
it "generates a valid named function for method" do
|
73
|
+
expect_compiled("def Array; end").to include("function ːArray()")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when function name is not valid" do
|
78
|
+
it "skips generating a name" do
|
79
|
+
expect_compiled("def test_method?; end").to include("function()")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
66
84
|
describe "debugger special method" do
|
67
85
|
it "generates debugger keyword in javascript" do
|
68
86
|
expect_compiled("debugger").to include("debugger")
|
@@ -133,7 +151,7 @@ describe Opal::Compiler do
|
|
133
151
|
end
|
134
152
|
end
|
135
153
|
end
|
136
|
-
|
154
|
+
|
137
155
|
describe 'truthy check' do
|
138
156
|
context 'no parentheses' do
|
139
157
|
context 'with operators' do
|
@@ -141,113 +159,113 @@ describe Opal::Compiler do
|
|
141
159
|
expect_compiled('foo = 42 if 2 > 3').to include('if ($rb_gt(2, 3))')
|
142
160
|
expect_compiled('foo = 42 if 2.5 > 3.5').to include('if ($rb_gt(2.5, 3.5))')
|
143
161
|
expect_compiled('foo = 42 if true > false').to include('if ($rb_gt(true, false))')
|
144
|
-
|
162
|
+
|
145
163
|
expect_compiled('foo = 42 if 2 == 3').to include("if ((2)['$=='](3))")
|
146
164
|
expect_compiled('foo = 42 if 2.5 == 3.5').to include("if ((2.5)['$=='](3.5))")
|
147
165
|
expect_compiled('foo = 42 if true == false').to include("if (true['$=='](false))")
|
148
166
|
end
|
149
|
-
|
167
|
+
|
150
168
|
it 'adds nil check for strings' do
|
151
169
|
expect_compiled('foo = 42 if "test" > "bar"').to include('if ((($a = $rb_gt("test", "bar")) !== nil && (!$a.$$is_boolean || $a == true)))')
|
152
170
|
end
|
153
|
-
|
171
|
+
|
154
172
|
it 'specifically == excludes nil check for strings' do
|
155
173
|
expect_compiled('foo = 42 if "test" == "bar"').to include("if (\"test\"['$=='](\"bar\"))")
|
156
174
|
end
|
157
|
-
|
175
|
+
|
158
176
|
it 'adds nil check for lvars' do
|
159
177
|
expect_compiled("bar = 4\nfoo = 42 if bar > 5").to include('if ((($a = $rb_gt(bar, 5)) !== nil && (!$a.$$is_boolean || $a == true)))')
|
160
178
|
end
|
161
|
-
|
179
|
+
|
162
180
|
it 'specifically == excludes nil check for lvars' do
|
163
181
|
expect_compiled("bar = 4\nfoo = 42 if bar == 5").to include("if (bar['$=='](5))")
|
164
182
|
end
|
165
|
-
|
183
|
+
|
166
184
|
it 'adds nil check for constants' do
|
167
185
|
expect_compiled("foo = 42 if Test > 4").to include("if ((($a = $rb_gt($scope.get('Test'), 4)) !== nil && (!$a.$$is_boolean || $a == true))) ")
|
168
186
|
end
|
169
|
-
|
187
|
+
|
170
188
|
it 'specifically == excludes nil check for constants' do
|
171
189
|
expect_compiled("foo = 42 if Test == 4").to include("if ($scope.get('Test')['$=='](4))")
|
172
190
|
end
|
173
191
|
end
|
174
|
-
|
192
|
+
|
175
193
|
context 'without operators' do
|
176
194
|
it 'adds nil check for primitives' do
|
177
195
|
expect_compiled('foo = 42 if 2').to include('if ((($a = 2) !== nil && (!$a.$$is_boolean || $a == true)))')
|
178
196
|
expect_compiled('foo = 42 if 2.5').to include('if ((($a = 2.5) !== nil && (!$a.$$is_boolean || $a == true)))')
|
179
197
|
expect_compiled('foo = 42 if true').to include('if ((($a = true) !== nil && (!$a.$$is_boolean || $a == true)))')
|
180
198
|
end
|
181
|
-
|
199
|
+
|
182
200
|
it 'adds nil check for boolean method calls' do
|
183
201
|
expect_compiled('foo = 42 if true.something').to include('if ((($a = true.$something()) !== nil && (!$a.$$is_boolean || $a == true)))')
|
184
202
|
end
|
185
|
-
|
203
|
+
|
186
204
|
it 'adds nil check for strings' do
|
187
205
|
expect_compiled('foo = 42 if "test"').to include('if ((($a = "test") !== nil && (!$a.$$is_boolean || $a == true)))')
|
188
206
|
end
|
189
|
-
|
207
|
+
|
190
208
|
it 'adds nil check for lvars' do
|
191
209
|
expect_compiled("bar = 4\nfoo = 42 if bar").to include('if (bar !== false && bar !== nil)')
|
192
210
|
end
|
193
|
-
|
211
|
+
|
194
212
|
it 'adds nil check for constants' do
|
195
213
|
expect_compiled("foo = 42 if Test").to include("if ((($a = $scope.get('Test')) !== nil && (!$a.$$is_boolean || $a == true)))")
|
196
214
|
end
|
197
215
|
end
|
198
216
|
end
|
199
|
-
|
217
|
+
|
200
218
|
context 'parentheses' do
|
201
219
|
context 'with operators' do
|
202
220
|
it 'adds nil check for primitives' do
|
203
221
|
expect_compiled('foo = 42 if (2 > 3)').to include('if ((($a = ($rb_gt(2, 3))) !== nil && (!$a.$$is_boolean || $a == true)))')
|
204
222
|
expect_compiled('foo = 42 if (2.5 > 3.5)').to include('if ((($a = ($rb_gt(2.5, 3.5))) !== nil && (!$a.$$is_boolean || $a == true)))')
|
205
223
|
expect_compiled('foo = 42 if (true > false)').to include('if ((($a = ($rb_gt(true, false))) !== nil && (!$a.$$is_boolean || $a == true)))')
|
206
|
-
|
224
|
+
|
207
225
|
expect_compiled('foo = 42 if (2 == 3)').to include("if ((($a = ((2)['$=='](3))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
208
226
|
expect_compiled('foo = 42 if (2.5 == 3.5)').to include("if ((($a = ((2.5)['$=='](3.5))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
209
227
|
expect_compiled('foo = 42 if (true == false)').to include("if ((($a = (true['$=='](false))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
210
228
|
end
|
211
|
-
|
229
|
+
|
212
230
|
it 'adds nil check for strings' do
|
213
231
|
expect_compiled('foo = 42 if ("test" > "bar")').to include('if ((($a = ($rb_gt("test", "bar"))) !== nil && (!$a.$$is_boolean || $a == true)))')
|
214
232
|
expect_compiled('foo = 42 if ("test" == "bar")').to include("if ((($a = (\"test\"['$=='](\"bar\"))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
215
233
|
end
|
216
|
-
|
234
|
+
|
217
235
|
it 'adds nil check for lvars' do
|
218
236
|
expect_compiled("bar = 4\nfoo = 42 if (bar > 5)").to include('if ((($a = ($rb_gt(bar, 5))) !== nil && (!$a.$$is_boolean || $a == true)))')
|
219
237
|
expect_compiled("bar = 4\nfoo = 42 if (bar == 5)").to include("if ((($a = (bar['$=='](5))) !== nil && (!$a.$$is_boolean || $a == true))) ")
|
220
238
|
end
|
221
|
-
|
239
|
+
|
222
240
|
it 'adds nil check for constants' do
|
223
241
|
expect_compiled("foo = 42 if (Test > 4)").to include("if ((($a = ($rb_gt($scope.get('Test'), 4))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
224
242
|
expect_compiled("foo = 42 if (Test == 4)").to include("if ((($a = ($scope.get('Test')['$=='](4))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
225
243
|
end
|
226
244
|
end
|
227
|
-
|
245
|
+
|
228
246
|
context 'without operators' do
|
229
247
|
it 'adds nil check for primitives' do
|
230
248
|
expect_compiled('foo = 42 if (2)').to include('if ((($a = (2)) !== nil && (!$a.$$is_boolean || $a == true)))')
|
231
249
|
expect_compiled('foo = 42 if (2.5)').to include('if ((($a = (2.5)) !== nil && (!$a.$$is_boolean || $a == true)))')
|
232
250
|
expect_compiled('foo = 42 if (true)').to include('if ((($a = (true)) !== nil && (!$a.$$is_boolean || $a == true)))')
|
233
251
|
end
|
234
|
-
|
252
|
+
|
235
253
|
it 'adds nil check for boolean method calls' do
|
236
254
|
expect_compiled('foo = 42 if (true.something)').to include('if ((($a = (true.$something())) !== nil && (!$a.$$is_boolean || $a == true)))')
|
237
255
|
end
|
238
|
-
|
256
|
+
|
239
257
|
it 'adds nil check for strings' do
|
240
258
|
expect_compiled('foo = 42 if ("test")').to include('if ((($a = ("test")) !== nil && (!$a.$$is_boolean || $a == true)))')
|
241
259
|
end
|
242
|
-
|
260
|
+
|
243
261
|
it 'adds nil check for lvars' do
|
244
262
|
expect_compiled("bar = 4\nfoo = 42 if (bar)").to include('if ((($a = (bar)) !== nil && (!$a.$$is_boolean || $a == true)))')
|
245
263
|
end
|
246
|
-
|
264
|
+
|
247
265
|
it 'adds nil check for constants' do
|
248
266
|
expect_compiled("foo = 42 if (Test)").to include("if ((($a = ($scope.get('Test'))) !== nil && (!$a.$$is_boolean || $a == true)))")
|
249
267
|
end
|
250
|
-
end
|
268
|
+
end
|
251
269
|
end
|
252
270
|
end
|
253
271
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'lib/spec_helper'
|
2
|
+
require 'opal/config'
|
3
|
+
|
4
|
+
describe Opal::Config do
|
5
|
+
describe '.default_config' do
|
6
|
+
it 'is new each time' do
|
7
|
+
default_config1 = described_class.default_config
|
8
|
+
default_config2 = described_class.default_config
|
9
|
+
expect(default_config1).to eq(default_config2)
|
10
|
+
expect(default_config1).not_to equal(default_config2)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -23,6 +23,10 @@ describe "Method calls" do
|
|
23
23
|
parsed("foo\n.bar").should == [:call, [:call, nil, :foo, [:arglist]], :bar, [:arglist]]
|
24
24
|
lambda { parsed("foo\n..bar") }.should raise_error(Exception)
|
25
25
|
end
|
26
|
+
|
27
|
+
it "parses method starting on the next line after \\" do
|
28
|
+
parsed("\\\nfoo").should == [:call, nil, :foo, [:arglist]]
|
29
|
+
end
|
26
30
|
end
|
27
31
|
|
28
32
|
describe "Operator calls" do
|
@@ -181,3 +185,17 @@ describe 'Calls with trailing comma' do
|
|
181
185
|
[:hash, [:sym, :a], [:int, 100]]]]
|
182
186
|
end
|
183
187
|
end
|
188
|
+
|
189
|
+
describe 'Calls with kwsplat' do
|
190
|
+
it 'parses empty kwsplat' do
|
191
|
+
parsed('foo(**{})').should == [:call, nil, :foo, [:arglist, [:hash, [:kwsplat, [:hash]]]]]
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'parses non-empty kwsplat' do
|
195
|
+
parsed('foo(**{ a: 1 })').should == [:call, nil, :foo, [:arglist, [:hash, [:kwsplat, [:hash, [:sym, :a], [:int, 1]]]]]]
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'supports kwargs and kwsplat' do
|
199
|
+
parsed('foo(a: 1, **{ b: 2 })').should == [:call, nil, :foo, [:arglist, [:hash, [:sym, :a], [:int, 1], [:kwsplat, [:hash, [:sym, :b], [:int, 2]]]]]]
|
200
|
+
end
|
201
|
+
end
|
data/spec/lib/parser/def_spec.rb
CHANGED
@@ -33,6 +33,10 @@ describe "The def keyword" do
|
|
33
33
|
parsed("def foo(a = 1); end")[3].should == [:args, [:optarg, :a, [:int, 1]]]
|
34
34
|
parsed("def foo(a = 1, b = 2); end")[3].should == [:args, [:optarg, :a, [:int, 1]], [:optarg, :b, [:int, 2]]]
|
35
35
|
end
|
36
|
+
|
37
|
+
it "parses norm arg after optarg" do
|
38
|
+
parsed("def foo(a = 1, b); end")[3].should == [:args, [:optarg, :a, [:int, 1]], [:arg, :b]]
|
39
|
+
end
|
36
40
|
end
|
37
41
|
|
38
42
|
describe "with rest args" do
|
@@ -77,4 +81,29 @@ describe "The def keyword" do
|
|
77
81
|
parsed("def foo a: 1, b: 2; end")[3].should == [:args, [:kwoptarg, :a, [:int, 1]], [:kwoptarg, :b, [:int, 2]]]
|
78
82
|
end
|
79
83
|
end
|
84
|
+
|
85
|
+
it "parses (a,b=1,*c,d,&blk) arguments" do
|
86
|
+
expected = [:args, [:arg, :a], [:optarg, :b, [:int, 1]], [:restarg, :c], [:arg, :d], [:blockarg, :blk]]
|
87
|
+
parsed("def m(a,b=1,*c,d,&blk); end")[3].should == expected
|
88
|
+
end
|
89
|
+
|
90
|
+
it "parses (a,b=1,c,&blk) arguments" do
|
91
|
+
expected = [:args, [:arg, :a], [:optarg, :b, [:int, 1]], [:arg, :c], [:blockarg, :blk]]
|
92
|
+
parsed("def m(a,b=1,c,&blk); end")[3].should == expected
|
93
|
+
end
|
94
|
+
|
95
|
+
it "parses (a,*b,c,&blk) arguments" do
|
96
|
+
expected = [:args, [:arg, :a], [:restarg, :b], [:arg, :c], [:blockarg, :blk]]
|
97
|
+
parsed("def m(a,*b,c,&blk); end")[3].should == expected
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses (a=1,*b,c,&blk) arguments" do
|
101
|
+
expected = [:args, [:optarg, :a, [:int, 1]], [:restarg, :b], [:arg, :c], [:blockarg, :blk]]
|
102
|
+
parsed("def m(a=1,*b,c,&blk); end")[3].should == expected
|
103
|
+
end
|
104
|
+
|
105
|
+
it "parses (*b,c,&blk) arguments" do
|
106
|
+
expected = [:args, [:restarg, :b], [:arg, :c], [:blockarg, :blk]]
|
107
|
+
parsed("def m(*b,c,&blk); end")[3].should == expected
|
108
|
+
end
|
80
109
|
end
|
@@ -21,39 +21,39 @@ describe "Iters" do
|
|
21
21
|
end
|
22
22
|
|
23
23
|
describe "with normal args" do
|
24
|
-
it "adds a single s(:
|
25
|
-
parsed("proc do |a|; end")[4][1].should == [:
|
24
|
+
it "adds a single s(:masgn) for 1 norm arg" do
|
25
|
+
parsed("proc do |a|; end")[4][1].should == [:masgn, [:args, [:arg, :a]]]
|
26
26
|
end
|
27
27
|
|
28
28
|
it "lists multiple norm args inside a s(:masgn)" do
|
29
|
-
parsed("proc do |a, b|; end")[4][1].should == [:masgn, [:
|
30
|
-
parsed("proc do |a, b, c|; end")[4][1].should == [:masgn, [:
|
29
|
+
parsed("proc do |a, b|; end")[4][1].should == [:masgn, [:args, [:arg, :a], [:arg, :b]]]
|
30
|
+
parsed("proc do |a, b, c|; end")[4][1].should == [:masgn, [:args, [:arg, :a], [:arg, :b], [:arg, :c]]]
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
describe "with splat arg" do
|
35
|
-
it "adds a s(:masgn) for the s(:
|
36
|
-
parsed("proc do |*a|; end")[4][1].should == [:masgn, [:
|
37
|
-
parsed("proc do |a, *b|; end")[4][1].should == [:masgn, [:
|
35
|
+
it "adds a s(:masgn) for the s(:restarg) even if its the only arg" do
|
36
|
+
parsed("proc do |*a|; end")[4][1].should == [:masgn, [:args, [:restarg, :a]]]
|
37
|
+
parsed("proc do |a, *b|; end")[4][1].should == [:masgn, [:args, [:arg, :a], [:restarg, :b]]]
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
describe "with opt args" do
|
42
|
-
it "adds a s(:
|
43
|
-
parsed("proc do |a = 1|; end")[4][1].should == [:masgn, [:
|
44
|
-
parsed("proc do |a = 1, b = 2|; end")[4][1].should == [:masgn, [:
|
42
|
+
it "adds a s(:optarg) arg each optional argument" do
|
43
|
+
parsed("proc do |a = 1|; end")[4][1].should == [:masgn, [:args, [:optarg, :a, [:int, 1]]]]
|
44
|
+
parsed("proc do |a = 1, b = 2|; end")[4][1].should == [:masgn, [:args, [:optarg, :a, [:int, 1]], [:optarg, :b, [:int, 2]]]]
|
45
45
|
end
|
46
46
|
|
47
|
-
it "should add
|
48
|
-
parsed("proc do |a, b = 1|; end")[4][1].should == [:masgn, [:
|
49
|
-
parsed("proc do |b = 1, *c|; end")[4][1].should == [:masgn, [:
|
50
|
-
parsed("proc do |b = 1, &c|; end")[4][1].should == [:masgn, [:
|
47
|
+
it "should add args in the direct order" do
|
48
|
+
parsed("proc do |a, b = 1|; end")[4][1].should == [:masgn, [:args, [:arg, :a], [:optarg, :b, [:int, 1]]]]
|
49
|
+
parsed("proc do |b = 1, *c|; end")[4][1].should == [:masgn, [:args, [:optarg, :b, [:int, 1]], [:restarg, :c]]]
|
50
|
+
parsed("proc do |b = 1, &c|; end")[4][1].should == [:masgn, [:args, [:optarg, :b, [:int, 1]], [:block_pass, [:lasgn, :c]]]]
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
describe "with block arg" do
|
55
55
|
it "should add block arg with s(:block_pass) wrapping s(:lasgn) prefix" do
|
56
|
-
parsed("proc do |&a|; end")[4][1].should == [:masgn, [:
|
56
|
+
parsed("proc do |&a|; end")[4][1].should == [:masgn, [:args, [:block_pass, [:lasgn, :a]]]]
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -10,6 +10,10 @@ describe "Lambda literals" do
|
|
10
10
|
parsed("-> {}").should == [:call, nil, :lambda, [:arglist], [:iter, nil]]
|
11
11
|
end
|
12
12
|
|
13
|
+
def parsed_args(source)
|
14
|
+
parsed(source)[4][1][1]
|
15
|
+
end
|
16
|
+
|
13
17
|
describe "with no args" do
|
14
18
|
it "should accept no args" do
|
15
19
|
parsed("-> {}")[4][1].should == nil
|
@@ -17,34 +21,34 @@ describe "Lambda literals" do
|
|
17
21
|
end
|
18
22
|
|
19
23
|
describe "with normal args" do
|
20
|
-
it "adds a single s(:
|
21
|
-
parsed("->(a) {}")[4][1].should == [:
|
24
|
+
it "adds a single s(:masgn) for 1 norm arg" do
|
25
|
+
parsed("->(a) {}")[4][1].should == [:masgn, [:args, [:arg, :a]]]
|
22
26
|
end
|
23
27
|
|
24
28
|
it "lists multiple norm args inside a s(:masgn)" do
|
25
|
-
parsed("-> (a, b) {}")[4][1].should == [:masgn, [:
|
26
|
-
parsed("-> (a, b, c) {}")[4][1].should == [:masgn, [:
|
29
|
+
parsed("-> (a, b) {}")[4][1].should == [:masgn, [:args, [:arg, :a], [:arg, :b]]]
|
30
|
+
parsed("-> (a, b, c) {}")[4][1].should == [:masgn, [:args, [:arg, :a], [:arg, :b], [:arg, :c]]]
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
describe "with optional braces" do
|
31
35
|
it "parses normal args" do
|
32
|
-
parsed("-> a {}")[4][1].should == [:
|
33
|
-
parsed("-> a, b {}")[4][1].should == [:masgn, [:
|
36
|
+
parsed("-> a {}")[4][1].should == [:masgn, [:args, [:arg, :a]]]
|
37
|
+
parsed("-> a, b {}")[4][1].should == [:masgn, [:args, [:arg, :a], [:arg, :b]]]
|
34
38
|
end
|
35
39
|
|
36
40
|
it "parses splat args" do
|
37
|
-
parsed("-> *a {}")[4][1].should == [:masgn, [:
|
38
|
-
parsed("-> a, *b {}")[4][1].should == [:masgn, [:
|
41
|
+
parsed("-> *a {}")[4][1].should == [:masgn, [:args, [:restarg, :a]]]
|
42
|
+
parsed("-> a, *b {}")[4][1].should == [:masgn, [:args, [:arg, :a], [:restarg, :b]]]
|
39
43
|
end
|
40
44
|
|
41
45
|
it "parses opt args" do
|
42
|
-
parsed("-> a = 1 {}")[4][1].should == [:masgn, [:
|
43
|
-
parsed("-> a = 1, b = 2 {}")[4][1].should == [:masgn, [:
|
46
|
+
parsed("-> a = 1 {}")[4][1].should == [:masgn, [:args, [:optarg, :a, [:int, 1]]]]
|
47
|
+
parsed("-> a = 1, b = 2 {}")[4][1].should == [:masgn, [:args, [:optarg, :a, [:int, 1]], [:optarg, :b, [:int, 2]]]]
|
44
48
|
end
|
45
49
|
|
46
50
|
it "parses block args" do
|
47
|
-
parsed("-> &a {}")[4][1].should == [:masgn, [:
|
51
|
+
parsed("-> &a {}")[4][1].should == [:masgn, [:args, [:block_pass, [:lasgn, :a]]]]
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
@@ -64,7 +68,7 @@ describe "Lambda literals" do
|
|
64
68
|
|
65
69
|
it "can parse do..end blocks inside lambda body" do
|
66
70
|
# regression test; see GH issue 544
|
67
|
-
call_b = [:call, nil, :b, [:arglist], [:iter, [:
|
71
|
+
call_b = [:call, nil, :b, [:arglist], [:iter, [:masgn, [:args, [:arg, :c]]]]]
|
68
72
|
lambda = [:call, nil, :lambda, [:arglist], [:iter, nil, call_b]]
|
69
73
|
expected = [:call, nil, :a, [:arglist, lambda]]
|
70
74
|
parsed("a -> { b do |c| end }").should == expected
|
@@ -75,4 +79,141 @@ describe "Lambda literals" do
|
|
75
79
|
expected = [:call, nil, :a, [:arglist, [:call, nil, :lambda, [:arglist], [:iter, nil, [:call, nil, :b, [:arglist]]]]], [:iter, nil]]
|
76
80
|
parsed("a ->{b} do; end").should == expected
|
77
81
|
end
|
82
|
+
|
83
|
+
context "kwargs as arguments" do
|
84
|
+
def s_kwarg
|
85
|
+
[:kwarg, :kw]
|
86
|
+
end
|
87
|
+
|
88
|
+
def s_kwoptarg
|
89
|
+
[:kwoptarg, :kwopt, [:sym, :default]]
|
90
|
+
end
|
91
|
+
|
92
|
+
def s_kwrestarg
|
93
|
+
[:kwrestarg, :kwrest]
|
94
|
+
end
|
95
|
+
|
96
|
+
def s_block
|
97
|
+
[:block_pass, [:lasgn, :blk]]
|
98
|
+
end
|
99
|
+
|
100
|
+
it "parses kwarg" do
|
101
|
+
parsed_args("->(kw:){}").should == [:args, s_kwarg]
|
102
|
+
end
|
103
|
+
|
104
|
+
it "parses kwoptarg" do
|
105
|
+
parsed_args("->(kwopt: :default){}").should == [:args, s_kwoptarg]
|
106
|
+
end
|
107
|
+
|
108
|
+
it "parses kwrestarg" do
|
109
|
+
parsed_args("->(**kwrest){}").should == [:args, s_kwrestarg]
|
110
|
+
end
|
111
|
+
|
112
|
+
it "parses kwarg + kwoptarg" do
|
113
|
+
parsed_args("->(kw:,kwopt: :default){}").should == [:args, s_kwarg, s_kwoptarg]
|
114
|
+
end
|
115
|
+
|
116
|
+
it "parses kwarg + kwrestarg" do
|
117
|
+
parsed_args("->(kw:,**kwrest){}").should == [:args, s_kwarg, s_kwrestarg]
|
118
|
+
end
|
119
|
+
|
120
|
+
it "parses kwarg + kwoptarg + kwrestarg" do
|
121
|
+
parsed_args("->(kw:,kwopt: :default,**kwrest){}").should == [:args, s_kwarg, s_kwoptarg, s_kwrestarg]
|
122
|
+
end
|
123
|
+
|
124
|
+
it "parses block + kwarg" do
|
125
|
+
parsed_args("->(kw:,&blk){}").should == [:args, s_kwarg, s_block]
|
126
|
+
end
|
127
|
+
|
128
|
+
it "parses block + kwoptarg" do
|
129
|
+
parsed_args("->(kwopt: :default,&blk){}").should == [:args, s_kwoptarg, s_block]
|
130
|
+
end
|
131
|
+
|
132
|
+
it "parses block + kwrestarg" do
|
133
|
+
parsed_args("->(**kwrest,&blk){}").should == [:args, s_kwrestarg, s_block]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context 'rest args' do
|
138
|
+
it "parses ->(*a,b)" do
|
139
|
+
parsed_args("->(*a, b){}").should == [:args, [:restarg, :a], [:arg, :b]]
|
140
|
+
end
|
141
|
+
|
142
|
+
it "parses ->(a,b=1,*c,d,&blk)" do
|
143
|
+
expected = [:args, [:arg, :a], [:optarg, :b, [:int, 1]], [:restarg, :c], [:arg, :d], [:block_pass, [:lasgn, :blk]]]
|
144
|
+
parsed_args("->(a,b=1,*c,d,&blk){}").should == expected
|
145
|
+
end
|
146
|
+
|
147
|
+
it "parses ->(a,b=1,c,&blk)" do
|
148
|
+
expected = [:args, [:arg, :a], [:optarg, :b, [:int, 1]], [:arg, :c], [:block_pass, [:lasgn, :blk]]]
|
149
|
+
parsed_args("->(a,b=1,c,&blk){}").should == expected
|
150
|
+
end
|
151
|
+
|
152
|
+
it "parses ->(a,*b,c,&blk){}" do
|
153
|
+
expected = [:args, [:arg, :a], [:restarg, :b], [:arg, :c], [:block_pass, [:lasgn, :blk]]]
|
154
|
+
parsed_args("->(a,*b,c,&blk){}").should == expected
|
155
|
+
end
|
156
|
+
|
157
|
+
it "parses ->(a=1,*b,c,&blk){}" do
|
158
|
+
expected = [:args, [:optarg, :a, [:int, 1]], [:restarg, :b], [:arg, :c], [:block_pass, [:lasgn, :blk]]]
|
159
|
+
parsed_args("->(a=1,*b,c,&blk){}").should == expected
|
160
|
+
end
|
161
|
+
|
162
|
+
it "parses ->(a=1,b,&blk)" do
|
163
|
+
expected = [:args, [:optarg, :a, [:int, 1]], [:arg, :b], [:block_pass, [:lasgn, :blk]]]
|
164
|
+
parsed_args("->(a=1,b,&blk){}").should == expected
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context 'shadow args' do
|
169
|
+
it "parses lambda{|a;b|}" do
|
170
|
+
parsed_args("lambda{|a;b|}").should == [:args, [:arg, :a], [:shadowarg, :b]]
|
171
|
+
end
|
172
|
+
|
173
|
+
it "parses lambda{|;a|}" do
|
174
|
+
parsed_args("lambda{|;a|}").should == [:args, [:shadowarg, :a]]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'mlhs args' do
|
179
|
+
it "parses ->((a)){}" do
|
180
|
+
parsed_args("->((a)){}").should == [:args, [:mlhs, [:arg, :a]]]
|
181
|
+
end
|
182
|
+
|
183
|
+
it "parses ->((a,*b)){}" do
|
184
|
+
parsed_args("->((a,*b)){}").should == [:args, [:mlhs, [:arg, :a], [:restarg, :b]]]
|
185
|
+
end
|
186
|
+
|
187
|
+
it "parses ->((a,*b,c)){}" do
|
188
|
+
parsed_args("->((a,*b,c)){}").should == [:args, [:mlhs, [:arg, :a], [:restarg, :b], [:arg, :c]]]
|
189
|
+
end
|
190
|
+
|
191
|
+
it "parses ->((a,*)){}" do
|
192
|
+
parsed_args("->((a,*)){}").should == [:args, [:mlhs, [:arg, :a], [:restarg]]]
|
193
|
+
end
|
194
|
+
|
195
|
+
it "parses ->((a,*,b)){}" do
|
196
|
+
parsed_args("->((a,*,b)){}").should == [:args, [:mlhs, [:arg, :a], [:restarg], [:arg, :b]]]
|
197
|
+
end
|
198
|
+
|
199
|
+
it "parses ->((*a)){}" do
|
200
|
+
parsed_args("->((*a)){}").should == [:args, [:mlhs, [:restarg, :a]]]
|
201
|
+
end
|
202
|
+
|
203
|
+
it "parses ->((*a,b)){}" do
|
204
|
+
parsed_args("->((*a,b)){}").should == [:args, [:mlhs, [:restarg, :a], [:arg, :b]]]
|
205
|
+
end
|
206
|
+
|
207
|
+
it "parses ->((*)){}" do
|
208
|
+
parsed_args("->((*)){}").should == [:args, [:mlhs, [:restarg]]]
|
209
|
+
end
|
210
|
+
|
211
|
+
it "parses ->((*,a)){}" do
|
212
|
+
parsed_args("->((*,a)){}").should == [:args, [:mlhs, [:restarg], [:arg, :a]]]
|
213
|
+
end
|
214
|
+
|
215
|
+
it "parses ->(a,(b,(c,d))){}" do
|
216
|
+
parsed_args("->(a,(b,(c,d))){}").should == [:args, [:arg, :a], [:mlhs, [:arg, :b], [:mlhs, [:arg, :c], [:arg, :d]]]]
|
217
|
+
end
|
218
|
+
end
|
78
219
|
end
|