Skip to content

Commit 9aed25b

Browse files
committed
[GR-45043] Integrate YARP parser [Part 8]
PullRequest: truffleruby/4097
2 parents 61d3ada + 9b405d7 commit 9aed25b

File tree

281 files changed

+10347
-4148
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

281 files changed

+10347
-4148
lines changed

3rd_party_licenses.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1308,7 +1308,7 @@ of
13081308
*/
13091309
================================================================================
13101310

1311-
ffi 1.14.2
1311+
ffi 1.15.5
13121312

13131313
Copyright (c) 2008-2016, Ruby FFI project contributors
13141314
All rights reserved.

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
New features:
44

55
* C/C++ extensions are now compiled using the system toolchain and executed natively instead of using GraalVM LLVM (Sulong). This leads to faster startup, no warmup, better compatibility, smaller distribution and faster installation for C/C++ extensions (#3118, @eregon).
6+
* Full suport for the Ruby 3.2 and Ruby 3.3 syntax by adopting the [Prism](https://github.com/ruby/prism) parser (#3117, #3038, #3039, @andrykonchin, @eregon).
7+
* Pattern matching is now fully supported, with the exception of Find pattern (`in [*, a, *]`) (#3332, #2683, @eregon, @razetime).
68

79
Bug fixes:
810

@@ -39,6 +41,8 @@ Compatibility:
3941
* Fix `Coverage.supported?` and raise `TypeError` if argument is not Symbol (#3039, @andrykonchin).
4042
* Accept options argument to `Regexp.{new,compile}` of String and warn for unknown types (#3039, @rwstauner).
4143
* Implement `Time#deconstruct_keys` from Ruby 3.2 (#3039, @rwstauner).
44+
* Do not autosplat a proc that accepts a single positional argument and keywords (#3039, @andrykonchin).
45+
* Support passing anonymous * and ** parameters as method call arguments (#3039, @andrykonchin).
4246

4347
Performance:
4448

doc/legal/legal.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,14 @@ files.
165165

166166
#### FFI
167167

168-
TruffleRuby includes parts of the FFI gem 1.14.2. The FFI gem is copyright
169-
2008-2016, Ruby FFI project contributors, and covered by the three-clause BSD
170-
licence (see `ffi.txt`).
168+
TruffleRuby includes parts of the FFI gem (version as described in [lib/truffle/ffi/version.rb](../../lib/truffle/ffi/version.rb)).
169+
The FFI gem is copyright 2008-2016, Ruby FFI project contributors, and covered by the three-clause BSD licence (see `ffi.txt`).
170+
171+
#### Prism
172+
173+
TruffleRuby uses the [Prism](https://github.com/ruby/prism) Ruby parser
174+
(version as described in [src/main/c/yarp/include/prism/version.h](../../src/main/c/yarp/include/prism/version.h)),
175+
copyright Shopify Inc. and is available under an MIT licence (see `src/main/c/yarp/LICENSE.md`).
171176

172177
# Java dependencies
173178

doc/user/options.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ Other binaries, such as `irb`, `gem`, and so on, support exactly the same switch
148148
149149
TruffleRuby needs to know where to locate files such as the standard library.
150150
These are stored in the TruffleRuby home directory.
151-
The Ruby home is always the one that the Truffle framework reports.
151+
The Ruby home is always either the one that the Truffle framework reports or the extracted internal resources.
152152
153-
If the Ruby home appears not to be correct, or is unset, a warning will be given but the program will continue and you will not be able to require standard libraries.
154-
You can tell TruffleRuby not to try to find a home at all using the `no-home-provided` option.
153+
If the Ruby home appears not to be correct, or is unset, a exception will be thrown.

lib/cext/ABI_check.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9
1+
10

lib/truffle/rbconfig.rb

-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
module RbConfig
3939

4040
ruby_home = Truffle::Boot.ruby_home
41-
raise 'The TruffleRuby home needs to be set to require RbConfig' unless ruby_home
4241
TOPDIR = ruby_home
4342

4443
sulong = Truffle::Boot.get_option('cexts-sulong')

lib/truffle/rubygems/defaults/truffleruby.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
module Gem
1515
# The path to the gems shipped with TruffleRuby
1616
def self.default_dir
17-
@default_dir ||= "#{Truffle::Boot.ruby_home or raise 'TruffleRuby home not found'}/lib/gems"
17+
@default_dir ||= "#{Truffle::Boot.ruby_home}/lib/gems"
1818
end
1919

2020
# Only report the RUBY platform as supported to make sure gems precompiled for MRI are not used.

mx.truffleruby/mx_truffleruby.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,21 @@ def clean(self, forBuild=False):
107107
def contents(self, result):
108108
classpath_deps = [dep for dep in self.subject.buildDependencies if isinstance(dep, mx.ClasspathDependency)]
109109
jvm_args = [pipes.quote(arg) for arg in mx.get_runtime_jvm_args(classpath_deps)]
110+
110111
debug_args = mx.java_debug_args()
111112
jvm_args.extend(debug_args)
112113
if debug_args:
113114
jvm_args.extend(['-ea', '-esa'])
115+
114116
jvm_args.append('-Dorg.graalvm.language.ruby.home=' + root)
117+
118+
libyarpbindings = list(mx.project('org.truffleruby.yarp.bindings').getArchivableResults())[0][0]
119+
jvm_args.append('-Dtruffleruby.libyarpbindings=' + libyarpbindings)
120+
115121
main_class = 'org.truffleruby.launcher.RubyLauncher'
116122
ruby_options = [
117123
'--experimental-options',
118-
'--building-core-cexts',
124+
'--building-core-cexts', # This lets the process know it's miniruby
119125
'--launcher=' + result,
120126
'--disable-gems',
121127
'--disable-rubyopt',

mx.truffleruby/suite.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -376,10 +376,11 @@
376376

377377
"org.truffleruby.bootstrap.launcher": {
378378
"class": "TruffleRubyBootstrapLauncherProject",
379-
"buildDependencies": [
379+
"buildDependencies": [ # These are used to build the module path
380380
"TRUFFLERUBY", # We need this jar to run extconf.rb
381381
"TRUFFLERUBY-LAUNCHER", # We need this jar to run extconf.rb
382382
"sulong:SULONG_NATIVE", # We need this jar to find the toolchain with Toolchain#getToolPath
383+
"org.truffleruby.yarp.bindings", # libyarpbindings.so
383384
],
384385
"license": ["EPL-2.0"],
385386
},
@@ -846,8 +847,9 @@
846847
"dependencies": ["org.truffleruby.tck"],
847848
"distDependencies": [
848849
"truffle:TRUFFLE_TCK",
849-
# runtime-only dependencies
850+
# runtime-only dependencies
850851
"TRUFFLERUBY",
852+
"TRUFFLERUBY-RESOURCES",
851853
],
852854
"description" : "Truffle TCK provider for Ruby language.",
853855
"license": ["EPL-2.0"],

spec/ruby/command_line/dash_r_spec.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1", exit_status: 1)
1717
$?.should_not.success?
1818
out.should include("REQUIRED")
19-
out.should include("syntax error")
19+
20+
# it's tempting not to rely on error message and rely only on exception class name,
21+
# but CRuby before 3.2 doesn't print class name for syntax error
22+
out.should include_any_of("syntax error", "SyntaxError")
2023
end
2124

2225
it "does not require the file if the main script file does not exist" do

spec/ruby/command_line/syntax_error_spec.rb

+8-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@
33
describe "The interpreter" do
44
it "prints an error when given a file with invalid syntax" do
55
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), args: "2>&1", exit_status: 1)
6-
out.should include "syntax error"
6+
7+
# it's tempting not to rely on error message and rely only on exception class name,
8+
# but CRuby before 3.2 doesn't print class name for syntax error
9+
out.should include_any_of("syntax error", "SyntaxError")
710
end
811

912
it "prints an error when given code via -e with invalid syntax" do
1013
out = ruby_exe(nil, args: "-e 'a{' 2>&1", exit_status: 1)
11-
out.should include "syntax error"
14+
15+
# it's tempting not to rely on error message and rely only on exception class name,
16+
# but CRuby before 3.2 doesn't print class name for syntax error
17+
out.should include_any_of("syntax error", "SyntaxError")
1218
end
1319
end

spec/ruby/core/kernel/eval_spec.rb

+9
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ class EvalSpecs
261261
end
262262
end
263263

264+
it "makes flip-flop operator work correctly" do
265+
ScratchPad.record []
266+
267+
eval "10.times { |i| ScratchPad << i if (i == 4)...(i == 4) }"
268+
ScratchPad.recorded.should == [4, 5, 6, 7, 8, 9]
269+
270+
ScratchPad.clear
271+
end
272+
264273
# See language/magic_comment_spec.rb for more magic comments specs
265274
describe "with a magic encoding comment" do
266275
it "uses the magic comment encoding for the encoding of literal strings" do

spec/ruby/language/block_spec.rb

+79-2
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,59 @@ def m(a) yield a end
4040
m([1, 2]) { |a=5, b, c, d| [a, b, c, d] }.should == [5, 1, 2, nil]
4141
end
4242

43+
it "assigns elements to pre arguments" do
44+
m([1, 2]) { |a, b, c, d=5| [a, b, c, d] }.should == [1, 2, nil, 5]
45+
end
46+
47+
it "assigns elements to pre and post arguments" do
48+
m([1 ]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 5, 6, nil, nil]
49+
m([1, 2 ]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 5, 6, 2, nil]
50+
m([1, 2, 3 ]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 5, 6, 2, 3]
51+
m([1, 2, 3, 4 ]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 2, 6, 3, 4]
52+
m([1, 2, 3, 4, 5 ]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 2, 3, 4, 5]
53+
m([1, 2, 3, 4, 5, 6]) { |a, b=5, c=6, d, e| [a, b, c, d, e] }.should == [1, 2, 3, 4, 5]
54+
end
55+
56+
it "assigns elements to pre and post arguments when *rest is present" do
57+
m([1 ]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 5, 6, [], nil, nil]
58+
m([1, 2 ]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 5, 6, [], 2, nil]
59+
m([1, 2, 3 ]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 5, 6, [], 2, 3]
60+
m([1, 2, 3, 4 ]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 2, 6, [], 3, 4]
61+
m([1, 2, 3, 4, 5 ]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 2, 3, [], 4, 5]
62+
m([1, 2, 3, 4, 5, 6]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 2, 3, [4], 5, 6]
63+
end
64+
4365
ruby_version_is "3.2" do
4466
it "does not autosplat single argument to required arguments when a keyword rest argument is present" do
4567
m([1, 2]) { |a, **k| [a, k] }.should == [[1, 2], {}]
4668
end
69+
70+
it "does not autosplat single argument to required arguments when keyword arguments are present" do
71+
m([1, 2]) { |a, b: :b, c: :c| [a, b, c] }.should == [[1, 2], :b, :c]
72+
end
73+
74+
it "raises error when required keyword arguments are present" do
75+
-> {
76+
m([1, 2]) { |a, b:, c:| [a, b, c] }
77+
}.should raise_error(ArgumentError, "missing keywords: :b, :c")
78+
end
4779
end
4880

4981
ruby_version_is ''..."3.2" do
5082
# https://bugs.ruby-lang.org/issues/18633
5183
it "autosplats single argument to required arguments when a keyword rest argument is present" do
5284
m([1, 2]) { |a, **k| [a, k] }.should == [1, {}]
5385
end
86+
87+
it "autosplats single argument to required arguments when optional keyword arguments are present" do
88+
m([1, 2]) { |a, b: :b, c: :c| [a, b, c] }.should == [1, :b, :c]
89+
end
90+
91+
it "raises error when required keyword arguments are present" do
92+
-> {
93+
m([1, 2]) { |a, b:, c:| [a, b, c] }
94+
}.should raise_error(ArgumentError, "missing keywords: :b, :c")
95+
end
5496
end
5597

5698
it "assigns elements to mixed argument types" do
@@ -368,7 +410,6 @@ def obj.to_ary; raise "Exception raised in #to_ary" end
368410

369411
-> { @y.s(obj) { |a, b| } }.should raise_error(ZeroDivisionError)
370412
end
371-
372413
end
373414

374415
describe "taking |a, *b| arguments" do
@@ -701,6 +742,42 @@ def obj.to_ary; raise "Exception raised in #to_ary" end
701742
eval("Proc.new { |_,_| }").should be_an_instance_of(Proc)
702743
end
703744
end
745+
746+
describe 'pre and post parameters' do
747+
it "assigns nil to unassigned required arguments" do
748+
proc { |a, *b, c, d| [a, b, c, d] }.call(1, 2).should == [1, [], 2, nil]
749+
end
750+
751+
it "assigns elements to optional arguments" do
752+
proc { |a=5, b=4, c=3| [a, b, c] }.call(1, 2).should == [1, 2, 3]
753+
end
754+
755+
it "assigns elements to post arguments" do
756+
proc { |a=5, b, c, d| [a, b, c, d] }.call(1, 2).should == [5, 1, 2, nil]
757+
end
758+
759+
it "assigns elements to pre arguments" do
760+
proc { |a, b, c, d=5| [a, b, c, d] }.call(1, 2).should == [1, 2, nil, 5]
761+
end
762+
763+
it "assigns elements to pre and post arguments" do
764+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1 ).should == [1, 5, 6, nil, nil]
765+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1, 2 ).should == [1, 5, 6, 2, nil]
766+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1, 2, 3 ).should == [1, 5, 6, 2, 3]
767+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1, 2, 3, 4 ).should == [1, 2, 6, 3, 4]
768+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1, 2, 3, 4, 5 ).should == [1, 2, 3, 4, 5]
769+
proc { |a, b=5, c=6, d, e| [a, b, c, d, e] }.call(1, 2, 3, 4, 5, 6).should == [1, 2, 3, 4, 5]
770+
end
771+
772+
it "assigns elements to pre and post arguments when *rest is present" do
773+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1 ).should == [1, 5, 6, [], nil, nil]
774+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1, 2 ).should == [1, 5, 6, [], 2, nil]
775+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1, 2, 3 ).should == [1, 5, 6, [], 2, 3]
776+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1, 2, 3, 4 ).should == [1, 2, 6, [], 3, 4]
777+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1, 2, 3, 4, 5 ).should == [1, 2, 3, [], 4, 5]
778+
proc { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.call(1, 2, 3, 4, 5, 6).should == [1, 2, 3, [4], 5, 6]
779+
end
780+
end
704781
end
705782

706783
describe "Block-local variables" do
@@ -921,7 +998,7 @@ def a; 1; end
921998

922999
describe "Anonymous block forwarding" do
9231000
ruby_version_is "3.1" do
924-
it "forwards blocks to other functions that formally declare anonymous blocks" do
1001+
it "forwards blocks to other method that formally declares anonymous block" do
9251002
eval <<-EOF
9261003
def b(&); c(&) end
9271004
def c(&); yield :non_null end

0 commit comments

Comments
 (0)