From 387d49715ae00efb3cfa2c9d38bfc37258ba65c4 Mon Sep 17 00:00:00 2001 From: sk757a <112779947+sk757a@users.noreply.github.com> Date: Mon, 15 Jan 2024 12:03:34 +0000 Subject: [PATCH 01/16] Fix typos in cli options --- core/src/main/java/org/jruby/util/cli/Options.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/org/jruby/util/cli/Options.java b/core/src/main/java/org/jruby/util/cli/Options.java index 0d85ecd9935..f18e951bdc4 100644 --- a/core/src/main/java/org/jruby/util/cli/Options.java +++ b/core/src/main/java/org/jruby/util/cli/Options.java @@ -72,7 +72,7 @@ public class Options { public static final Option COMPILE_MODE = enumeration(COMPILER, "compile.mode", CompileMode.class, CompileMode.JIT, "Set compilation mode. JIT = at runtime; FORCE = before execution."); public static final Option COMPILE_DUMP = bool(COMPILER, "compile.dump", false, "Dump to console all bytecode generated at runtime."); public static final Option COMPILE_INVOKEDYNAMIC = bool(COMPILER, "compile.invokedynamic", INVOKEDYNAMIC_DEFAULT, "Use invokedynamic for optimizing Ruby code."); - public static final Option COMPILE_CACHE_CLASSES = bool(COMPILER, "compile.cache.classes", false, "Use cache of compiled sript classes"); + public static final Option COMPILE_CACHE_CLASSES = bool(COMPILER, "compile.cache.classes", false, "Use cache of compiled script classes"); public static final Option COMPILE_CACHE_CLASSES_LOGGING = bool(COMPILER, "compile.cache.classes.logging", false, "Log whether cached script classes are being saved or used"); public static final Option INVOKEDYNAMIC_MAXFAIL = integer(INVOKEDYNAMIC, "invokedynamic.maxfail", 1000, "Maximum call site failures after which to inline cache."); @@ -158,7 +158,7 @@ public class Options { public static final Option USE_FIXNUM_CACHE = bool(MISCELLANEOUS, "fixnum.cache", true, "Use a cache of low-valued Fixnum objects."); public static final Option FIXNUM_CACHE_RANGE = integer(MISCELLANEOUS, "fixnum.cache.size", 256, "Values to retrieve from Fixnum cache, in the range -X..(X-1)."); public static final Option PACKED_ARRAYS = bool(MISCELLANEOUS, "packed.arrays", true, "Toggle whether to use \"packed\" arrays for small tuples."); - public static final Option REGEXP_INTERRUPTIBLE = bool(MISCELLANEOUS, "regexp.interruptible", true, "Allow regexp operations to be interuptible from Ruby."); + public static final Option REGEXP_INTERRUPTIBLE = bool(MISCELLANEOUS, "regexp.interruptible", true, "Allow regexp operations to be interruptible from Ruby."); public static final Option JAR_CACHE_EXPIRATION = integer(MISCELLANEOUS, "jar.cache.expiration", 750, "The time (ms) between checks if a JAR file containing resources has been updated."); public static final Option DEBUG_LOADSERVICE = bool(DEBUG, "debug.loadService", false, "Log require/load file searches."); From bd968c6c328996a3c9c9860c82a78975bbb8f2b6 Mon Sep 17 00:00:00 2001 From: "Thomas E. Enebo" Date: Wed, 17 Jan 2024 16:08:25 -0500 Subject: [PATCH 02/16] Revert this opt for now. Something in AR tests is passing kwarg and thinking it is NO_ARGS signature --- core/src/main/java/org/jruby/ir/IRBuilder.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/core/src/main/java/org/jruby/ir/IRBuilder.java b/core/src/main/java/org/jruby/ir/IRBuilder.java index f5b6171d529..4cf739754d1 100644 --- a/core/src/main/java/org/jruby/ir/IRBuilder.java +++ b/core/src/main/java/org/jruby/ir/IRBuilder.java @@ -3151,12 +3151,6 @@ protected void receiveBlockArg(final ArgsNode argsNode) { public void receiveArgs(final ArgsNode argsNode) { Signature signature = scope.getStaticScope().getSignature(); - if (signature.equals(Signature.NO_ARGUMENTS)) { - addInstr(new CheckArityInstr(0, 0, false, -1, UndefinedValue.UNDEFINED)); - receiveBlockArg(argsNode); - return; - } - Variable keywords = addResultInstr(new ReceiveKeywordsInstr(temp(), signature.hasRest(), argsNode.hasKwargs())); KeywordRestArgNode keyRest = argsNode.getKeyRest(); From 46e69f261b1190a938ee61a6f6f2a4f6cbde11a7 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Thu, 18 Jan 2024 22:12:47 -0600 Subject: [PATCH 03/16] Update io-console to 0.7.2 for various fixes This includes several cleanups and fixes for all versions of the logic, plus it switches MacOS on AArch64 to use the "stty" version that shells out. This gets IRB working on MacOS again without disabling reline. --- lib/pom.rb | 2 +- lib/pom.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pom.rb b/lib/pom.rb index f64e6a106ca..872089a628f 100644 --- a/lib/pom.rb +++ b/lib/pom.rb @@ -50,7 +50,7 @@ def log(message=nil) ['forwardable', '1.3.2'], # ['gdbm', '2.1.0'], ['getoptlong', '0.1.1'], - ['io-console', '0.5.11'], + ['io-console', '0.7.2'], # https://github.com/ruby/io-nonblock/issues/4 # ['io-nonblock', '0.1.0'], ['io-wait', '0.3.0'], diff --git a/lib/pom.xml b/lib/pom.xml index 209b4b943bd..8934e1f1b6d 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -320,7 +320,7 @@ DO NOT MODIFY - GENERATED CODE rubygems io-console - 0.5.11 + 0.7.2 gem provided @@ -1088,7 +1088,7 @@ DO NOT MODIFY - GENERATED CODE specifications/find-0.1.1* specifications/forwardable-1.3.2* specifications/getoptlong-0.1.1* - specifications/io-console-0.5.11* + specifications/io-console-0.7.2* specifications/io-wait-0.3.0* specifications/ipaddr-1.2.4* specifications/irb-1.4.2* @@ -1166,7 +1166,7 @@ DO NOT MODIFY - GENERATED CODE gems/find-0.1.1*/**/* gems/forwardable-1.3.2*/**/* gems/getoptlong-0.1.1*/**/* - gems/io-console-0.5.11*/**/* + gems/io-console-0.7.2*/**/* gems/io-wait-0.3.0*/**/* gems/ipaddr-1.2.4*/**/* gems/irb-1.4.2*/**/* @@ -1244,7 +1244,7 @@ DO NOT MODIFY - GENERATED CODE cache/find-0.1.1* cache/forwardable-1.3.2* cache/getoptlong-0.1.1* - cache/io-console-0.5.11* + cache/io-console-0.7.2* cache/io-wait-0.3.0* cache/ipaddr-1.2.4* cache/irb-1.4.2* From d56f6209eb5e6164116b00864d05b0f8b5d0da8d Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 11:46:55 -0600 Subject: [PATCH 04/16] Split IO.pipe into specific arities --- core/src/main/java/org/jruby/RubyIO.java | 97 ++++++++++++------------ 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/core/src/main/java/org/jruby/RubyIO.java b/core/src/main/java/org/jruby/RubyIO.java index 866e2191f9e..28e94c572b4 100644 --- a/core/src/main/java/org/jruby/RubyIO.java +++ b/core/src/main/java/org/jruby/RubyIO.java @@ -4438,66 +4438,38 @@ public static IRubyObject popen(ThreadContext context, IRubyObject recv, IRubyOb } } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject recv) { - return pipe19(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + public static IRubyObject pipe(ThreadContext context, IRubyObject recv) { + return pipe(context, recv, Block.NULL_BLOCK); } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject recv, IRubyObject modes) { - return pipe19(context, recv, new IRubyObject[] {modes}, Block.NULL_BLOCK); + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, Block block) { + return pipe(context, klass, context.nil, context.nil, context.nil, block); } - @Deprecated - public static IRubyObject pipe19(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { - return pipe(context, klass, argv, block); + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject arg0, Block block) { + IRubyObject opt = TypeConverter.checkHashType(context.runtime, arg0); + + return pipe(context, klass, opt.isNil() ? arg0 : context.nil, context.nil, opt, block); } + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject arg0, IRubyObject arg1, Block block) { + IRubyObject opt = TypeConverter.checkHashType(context.runtime, arg1); - public static IRubyObject pipe(ThreadContext context, IRubyObject recv) { - return pipe(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + return pipe(context, klass, arg0, !opt.isNil() ? context.nil : arg1, opt, block); } - @JRubyMethod(name = "pipe", optional = 3, checkArity = false, meta = true) - public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { - int argc = Arity.checkArgumentCount(context, argv, 0, 3); - + @JRubyMethod(name = "pipe", meta = true) + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject v1, IRubyObject v2, IRubyObject opt, Block block) { Ruby runtime = context.runtime; - int state; + RubyIO r, w; -// IRubyObject args[] = new IRubyObject[3] - IRubyObject v1, v2; - IRubyObject opt; - v1 = v2 = opt = context.nil; OpenFile fptr, fptr2; int[] fmode_p = {0}; IRubyObject ret; - switch (argc) { - case 3: - opt = argv[2].convertToHash(); - argc--; - v2 = argv[1]; - v1 = argv[0]; - break; - case 2: - opt = TypeConverter.checkHashType(runtime, argv[1]); - if (!opt.isNil()) { - argc--; - } else { - v2 = argv[1]; - } - v1 = argv[0]; - break; - case 1: - opt = TypeConverter.checkHashType(runtime, argv[0]); - if (!opt.isNil()) { - argc--; - } else { - v1 = argv[0]; - } - } - PosixShim posix = new PosixShim(runtime); Channel[] fds = posix.pipe(); if (fds == null) @@ -4512,7 +4484,7 @@ public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyOb // close(pipes[1]); // rb_jump_tag(state); // } - r = new RubyIO(runtime, (RubyClass)klass); + r = new RubyIO(runtime, (RubyClass) klass); r.initializeCommon(context, new ChannelFD(fds[0], runtime.getPosix(), runtime.getFilenoUtil()), runtime.newFixnum(OpenFlags.O_RDONLY), context.nil); fptr = r.getOpenFileChecked(); @@ -4526,7 +4498,7 @@ public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyOb // if (!NIL_P(r)) rb_io_close(r); // rb_jump_tag(state); // } - w = new RubyIO(runtime, (RubyClass)klass); + w = new RubyIO(runtime, (RubyClass) klass); w.initializeCommon(context, new ChannelFD(fds[1], runtime.getPosix(), runtime.getFilenoUtil()), runtime.newFixnum(OpenFlags.O_WRONLY), context.nil); fptr2 = w.getOpenFileChecked(); fptr2.setSync(true); @@ -5646,6 +5618,37 @@ public IRubyObject sysread(ThreadContext context, IRubyObject[] args) { return sysreadCommon(context, runtime, _length, _str); } + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject recv) { + return pipe19(context, recv, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK); + } + + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject recv, IRubyObject modes) { + return pipe19(context, recv, new IRubyObject[] {modes}, Block.NULL_BLOCK); + } + + @Deprecated + public static IRubyObject pipe19(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { + return pipe(context, klass, argv, block); + } + + @Deprecated + public static IRubyObject pipe(ThreadContext context, IRubyObject klass, IRubyObject[] argv, Block block) { + switch (argv.length) { + case 0: + return pipe(context, klass, block); + case 1: + return pipe(context, klass, argv[0], block); + case 2: + return pipe(context, klass, argv[0], argv[1], block); + case 3: + return pipe(context, klass, argv[0], argv[1], argv[2], block); + default: + throw context.runtime.newArgumentError(argv.length, 0, 3); + } + } + protected OpenFile openFile; /** From 10083444d72fcc7513180f387e785a60322b63ef Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 14:32:11 -0600 Subject: [PATCH 05/16] Ensure singleton_method_added is called for attr on singleton We were only calling method_added, which does not match CRuby behavior. This was the root cause of Shopify/ruby-lsp#1263. --- core/src/main/java/org/jruby/RubyModule.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index 2d71ff8dea6..005af6f9e0b 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -2289,11 +2289,19 @@ private void addAccessor(ThreadContext context, RubySymbol identifier, Visibilit final String variableName = identifier.asInstanceVariable().idString(); if (readable) { addMethod(internedIdentifier, new AttrReaderMethod(methodLocation, visibility, variableName)); - callMethod(context, "method_added", identifier); + methodAdded(context, identifier); } if (writeable) { identifier = identifier.asWriter(); addMethod(identifier.idString(), new AttrWriterMethod(methodLocation, visibility, variableName)); + methodAdded(context, identifier); + } + } + + protected void methodAdded(ThreadContext context, RubySymbol identifier) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_added", identifier); + } else { callMethod(context, "method_added", identifier); } } @@ -3491,7 +3499,7 @@ public IRubyObject _module_function(ThreadContext context, IRubyObject[] args) { newMethod.setImplementationClass(getSingletonClass()); newMethod.setVisibility(PUBLIC); getSingletonClass().addMethod(name.idString(), newMethod); - callMethod(context, "singleton_method_added", name); + getSingletonClass().methodAdded(context, name); } } @@ -3619,11 +3627,7 @@ public IRubyObject aliasMethod(ThreadContext context, IRubyObject newId, IRubyOb defineAlias(newSym.idString(), oldSym.idString()); - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_added", newSym); - } else { - callMethod(context, "method_added", newSym); - } + methodAdded(context, newSym); return newSym; } From 130539702fdac0e396a726a3b4e2194eed7fbab2 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 14:34:15 -0600 Subject: [PATCH 06/16] Factor out a few more method hooks These are only called in one place, but may be needed in the future if they should be called for other logic that undefines or removes methods. --- core/src/main/java/org/jruby/RubyModule.java | 30 +++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index 005af6f9e0b..550224ff56c 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -1444,11 +1444,9 @@ public void undef(ThreadContext context, String name) { } methodLocation.addMethod(name, UndefinedMethod.getInstance()); - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_undefined", runtime.newSymbol(name)); - } else { - callMethod(context, "method_undefined", runtime.newSymbol(name)); - } + RubySymbol nameSymbol = runtime.newSymbol(name); + + methodUndefined(context, nameSymbol); } @JRubyMethod(name = "include?") @@ -1567,11 +1565,7 @@ public void removeMethod(ThreadContext context, String id) { invalidateCacheDescendants(); } - if (isSingleton()) { - ((MetaClass) this).getAttached().callMethod(context, "singleton_method_removed", name); - } else { - callMethod(context, "method_removed", name); - } + methodRemoved(context, name); } private static void warnMethodRemoval(final ThreadContext context, final String id) { @@ -2306,6 +2300,22 @@ protected void methodAdded(ThreadContext context, RubySymbol identifier) { } } + private void methodUndefined(ThreadContext context, RubySymbol nameSymbol) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_undefined", nameSymbol); + } else { + callMethod(context, "method_undefined", nameSymbol); + } + } + + private void methodRemoved(ThreadContext context, RubySymbol name) { + if (isSingleton()) { + ((MetaClass) this).getAttached().callMethod(context, "singleton_method_removed", name); + } else { + callMethod(context, "method_removed", name); + } + } + /** set_method_visibility * */ From c498a4653e36f5e6fcf768805fc5a9712c7bef31 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 15:09:50 -0600 Subject: [PATCH 07/16] Add spec for Module#attr* calling method_added hooks --- spec/ruby/core/module/attr_accessor_spec.rb | 3 ++ spec/ruby/core/module/attr_reader_spec.rb | 3 ++ spec/ruby/core/module/attr_spec.rb | 3 ++ spec/ruby/core/module/attr_writer_spec.rb | 3 ++ spec/ruby/core/module/shared/attr_added.rb | 34 +++++++++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 spec/ruby/core/module/shared/attr_added.rb diff --git a/spec/ruby/core/module/attr_accessor_spec.rb b/spec/ruby/core/module/attr_accessor_spec.rb index eea5b4b64b8..503dccc61ed 100644 --- a/spec/ruby/core/module/attr_accessor_spec.rb +++ b/spec/ruby/core/module/attr_accessor_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_accessor" do it "creates a getter and setter for each given attribute name" do @@ -106,4 +107,6 @@ class Integer 1.foobar.should be_nil end end + + it_behaves_like :module_attr_added, :attr_accessor end diff --git a/spec/ruby/core/module/attr_reader_spec.rb b/spec/ruby/core/module/attr_reader_spec.rb index 0b6d9967192..37fd537ff5c 100644 --- a/spec/ruby/core/module/attr_reader_spec.rb +++ b/spec/ruby/core/module/attr_reader_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_reader" do it "creates a getter for each given attribute name" do @@ -67,4 +68,6 @@ class TrueClass (attr_reader :foo, 'bar').should == [:foo, :bar] end end + + it_behaves_like :module_attr_added, :attr_reader end diff --git a/spec/ruby/core/module/attr_spec.rb b/spec/ruby/core/module/attr_spec.rb index 72a6646b1ee..2f9f4e26dc5 100644 --- a/spec/ruby/core/module/attr_spec.rb +++ b/spec/ruby/core/module/attr_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr" do before :each do @@ -153,4 +154,6 @@ def initialize (attr :qux, true).should == [:qux, :qux=] end end + + it_behaves_like :module_attr_added, :attr end diff --git a/spec/ruby/core/module/attr_writer_spec.rb b/spec/ruby/core/module/attr_writer_spec.rb index aaea0ce43f5..5b863ef88c1 100644 --- a/spec/ruby/core/module/attr_writer_spec.rb +++ b/spec/ruby/core/module/attr_writer_spec.rb @@ -1,5 +1,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' +require_relative 'shared/attr_added' describe "Module#attr_writer" do it "creates a setter for each given attribute name" do @@ -77,4 +78,6 @@ class TrueClass (attr_writer :foo, 'bar').should == [:foo=, :bar=] end end + + it_behaves_like :module_attr_added, :attr_writer end diff --git a/spec/ruby/core/module/shared/attr_added.rb b/spec/ruby/core/module/shared/attr_added.rb new file mode 100644 index 00000000000..e37622d284b --- /dev/null +++ b/spec/ruby/core/module/shared/attr_added.rb @@ -0,0 +1,34 @@ +describe :module_attr_added, shared: true do + it "calls method_added for normal classes" do + ScratchPad.record [] + + cls = Class.new do + class << self + def method_added(name) + ScratchPad.recorded << name + end + end + end + + cls.send(@method, :foo) + + ScratchPad.recorded.each {|name| name.to_s.should =~ /foo[=]?/} + end + + it "calls singleton_method_added for singleton classes" do + ScratchPad.record [] + cls = Class.new do + class << self + def singleton_method_added(name) + # called for this def so ignore it + return if name == :singleton_method_added + ScratchPad.recorded << name + end + end + end + + cls.singleton_class.send(@method, :foo) + + ScratchPad.recorded.each {|name| name.to_s.should =~ /foo[=]?/} + end +end \ No newline at end of file From aabeb50825a372cfac04ce69a7c024844faab187 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 15:49:02 -0600 Subject: [PATCH 08/16] Reserve singleton_method_added from Java binding If bound from a Java method, it almost certainly will have the wrong signature for Ruby calls to it, leading to arity and other errors when a singleton method or class method are defined on a Java proxy type. --- .../java/org/jruby/javasupport/binding/MethodGatherer.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java index f3a1d5f2586..7518ca151ac 100644 --- a/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java +++ b/core/src/main/java/org/jruby/javasupport/binding/MethodGatherer.java @@ -72,6 +72,8 @@ public class MethodGatherer { static { STATIC_RESERVED_NAMES = newReservedNamesMap(1); STATIC_RESERVED_NAMES.put("new", new AssignedName("new", Priority.RESERVED)); + // "singleton_method_added" gets called on the metaclass for metaclass method definitions + STATIC_RESERVED_NAMES.put("singleton_method_added", new AssignedName("singleton_method_added", Priority.RESERVED)); } static { @@ -82,6 +84,8 @@ public class MethodGatherer { INSTANCE_RESERVED_NAMES.put("initialize", new AssignedName("initialize", Priority.RESERVED)); // "equal?" should not be overridden (GH-5990) INSTANCE_RESERVED_NAMES.put("equal?", new AssignedName("equal?", Priority.RESERVED)); + // "singleton_method_added" gets called on the object for singleton method definitions + INSTANCE_RESERVED_NAMES.put("singleton_method_added", new AssignedName("singleton_method_added", Priority.RESERVED)); } // TODO: other reserved names? From 76ea3df24d77859e7714c9124a705602b69bbf36 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 15:51:29 -0600 Subject: [PATCH 09/16] Bump this up for recent gem updates --- test/check_versions.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/check_versions.sh b/test/check_versions.sh index 952cb6114e8..9c91f4f1a05 100755 --- a/test/check_versions.sh +++ b/test/check_versions.sh @@ -65,7 +65,7 @@ check lib/target/jruby-stdlib-$jar_version.jar 17 check maven/jruby-jars/pkg/jruby-jars-$gem_version.gem 30 check maven/jruby-jars/lib/jruby-core-$jar_version-complete.jar 16 check maven/jruby-jars/lib/jruby-stdlib-$jar_version.jar 17 -check maven/jruby-complete/target/jruby-complete-$jar_version.jar 32 +check maven/jruby-complete/target/jruby-complete-$jar_version.jar 33 check maven/jruby/target/jruby-$jar_version.jar 9 check maven/jruby-dist/target/jruby-dist-$jar_version-bin.tar.gz 45 jruby-$jar_version check maven/jruby-dist/target/jruby-dist-$jar_version-src.zip 20 jruby-$jar_version From a37fb3ff9b24e50bb75a558433b26d333cbb3188 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 15:36:07 -0600 Subject: [PATCH 10/16] Update some warnings to deprecated This also marks syscall as not implemented (warns of pending deletion in CRuby) and modifies all RubyWarnings.warning* forms to no-op on verbose, as they used to (unsure when this changed). --- core/src/main/java/org/jruby/RubyArray.java | 2 +- core/src/main/java/org/jruby/RubyGlobal.java | 4 ++-- core/src/main/java/org/jruby/RubyIO.java | 9 +++++--- core/src/main/java/org/jruby/RubyKernel.java | 4 ++-- core/src/main/java/org/jruby/RubyModule.java | 2 +- core/src/main/java/org/jruby/RubyRegexp.java | 2 +- .../java/org/jruby/common/RubyWarnings.java | 22 ++++++++++++++++++- 7 files changed, 34 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/jruby/RubyArray.java b/core/src/main/java/org/jruby/RubyArray.java index 106d60db6cc..a9e6adf2725 100644 --- a/core/src/main/java/org/jruby/RubyArray.java +++ b/core/src/main/java/org/jruby/RubyArray.java @@ -2210,7 +2210,7 @@ private IRubyObject getDefaultSeparator(Ruby runtime) { IRubyObject sep; sep = runtime.getGlobalVariables().get("$,"); if (!sep.isNil()) { - runtime.getWarnings().warn("$, is set to non-nil value"); + runtime.getWarnings().warningDeprecated("$, is set to non-nil value"); } return sep; } diff --git a/core/src/main/java/org/jruby/RubyGlobal.java b/core/src/main/java/org/jruby/RubyGlobal.java index c319f1caebc..bdfeebf5f56 100644 --- a/core/src/main/java/org/jruby/RubyGlobal.java +++ b/core/src/main/java/org/jruby/RubyGlobal.java @@ -829,13 +829,13 @@ public NonEffectiveGlobalVariable(Ruby runtime, String name, IRubyObject value) @Override public IRubyObject set(IRubyObject value) { - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored"); + runtime.getWarnings().warnDeprecated(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective; ignored"); return value; } @Override public IRubyObject get() { - runtime.getWarnings().warn(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective"); + runtime.getWarnings().warnDeprecated(ID.INEFFECTIVE_GLOBAL, "warning: variable " + name + " is no longer effective"); return value; } } diff --git a/core/src/main/java/org/jruby/RubyIO.java b/core/src/main/java/org/jruby/RubyIO.java index 28e94c572b4..60493cfe620 100644 --- a/core/src/main/java/org/jruby/RubyIO.java +++ b/core/src/main/java/org/jruby/RubyIO.java @@ -1819,6 +1819,7 @@ public static IRubyObject print(ThreadContext context, IRubyObject out, IRubyObj int i; IRubyObject line; int argc = args.length; + IRubyObject outputFS = runtime.getGlobalVariables().get("$,"); /* if no argument given, print `$_' */ if (argc == 0) { @@ -1826,8 +1827,10 @@ public static IRubyObject print(ThreadContext context, IRubyObject out, IRubyObj line = context.getLastLine(); args = new IRubyObject[]{line}; } + if (argc > 1 && !outputFS.isNil()) { + runtime.getWarnings().warnDeprecated("$, is set to non-nil value"); + } for (i=0; i0) { write(context, out, outputFS); } @@ -2403,7 +2406,7 @@ public IRubyObject close_on_exec_set(ThreadContext context, IRubyObject arg) { if (fptr == null || (fd = fptr.fd().realFileno) == -1 || !posix.isNative() || Platform.IS_WINDOWS ) { - runtime.getWarnings().warning("close_on_exec is not implemented on this platform for this stream type: " + fptr.fd().ch.getClass().getSimpleName()); + runtime.getWarnings().warningDeprecated("close_on_exec is not implemented on this platform for this stream type: " + fptr.fd().ch.getClass().getSimpleName()); return context.nil; } @@ -2858,7 +2861,7 @@ private static void warnWrite(final Ruby runtime, IRubyObject maybeIO) { } else { sep = '#'; } - runtime.getWarnings().warning(klass.toString() + sep + "write is outdated interface which accepts just one argument"); + runtime.getWarnings().warningDeprecated(klass.toString() + sep + "write is outdated interface which accepts just one argument"); } @JRubyMethod diff --git a/core/src/main/java/org/jruby/RubyKernel.java b/core/src/main/java/org/jruby/RubyKernel.java index c4aeaa95bc6..99d4b956dd9 100644 --- a/core/src/main/java/org/jruby/RubyKernel.java +++ b/core/src/main/java/org/jruby/RubyKernel.java @@ -1933,7 +1933,7 @@ public static RubyFixnum spawn(ThreadContext context, IRubyObject recv, IRubyObj return RubyProcess.spawn(context, recv, args); } - @JRubyMethod(required = 1, optional = 9, checkArity = false, module = true, visibility = PRIVATE) + @JRubyMethod(required = 1, optional = 9, checkArity = false, module = true, notImplemented = true, visibility = PRIVATE) public static IRubyObject syscall(ThreadContext context, IRubyObject recv, IRubyObject[] args) { throw context.runtime.newNotImplementedError("Kernel#syscall is not implemented in JRuby"); } @@ -2493,7 +2493,7 @@ public static IRubyObject nil_p(ThreadContext context, IRubyObject self) { // Writes backref due to decendant calls ending up in Regexp#=~ @JRubyMethod(name = "=~", writes = FrameField.BACKREF) public static IRubyObject op_match(ThreadContext context, IRubyObject self, IRubyObject arg) { - context.runtime.getWarnings().warn(ID.DEPRECATED_METHOD, + context.runtime.getWarnings().warnDeprecated(ID.DEPRECATED_METHOD, "deprecated Object#=~ is called on " + ((RubyBasicObject) self).type() + "; it always returns nil"); return ((RubyBasicObject) self).op_match(context, arg); diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index 2d71ff8dea6..d25f32b3c20 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -3000,7 +3000,7 @@ public IRubyObject attr(ThreadContext context, IRubyObject[] args) { Ruby runtime = context.runtime; if (args.length == 2 && (args[1] == runtime.getTrue() || args[1] == runtime.getFalse())) { - runtime.getWarnings().warning(ID.OBSOLETE_ARGUMENT, "optional boolean argument is obsoleted"); + runtime.getWarnings().warnDeprecated(ID.OBSOLETE_ARGUMENT, "optional boolean argument is obsoleted"); boolean writeable = args[1].isTrue(); RubySymbol sym = TypeConverter.checkID(args[0]); addAccessor(context, sym, getCurrentVisibilityForDefineMethod(context), args[0].isTrue(), writeable); diff --git a/core/src/main/java/org/jruby/RubyRegexp.java b/core/src/main/java/org/jruby/RubyRegexp.java index 417f2a9ab5f..0d38d2da104 100755 --- a/core/src/main/java/org/jruby/RubyRegexp.java +++ b/core/src/main/java/org/jruby/RubyRegexp.java @@ -934,7 +934,7 @@ public IRubyObject initialize_m(IRubyObject arg0, IRubyObject arg1, IRubyObject newOptions.setEncodingNone(true); return regexpInitialize(arg0.convertToString().getByteList(), ASCIIEncoding.INSTANCE, newOptions); } else { - metaClass.runtime.getWarnings().warn("encoding option is ignored - " + kcodeBytes); + metaClass.runtime.getWarnings().warnDeprecated("encoding option is ignored - " + kcodeBytes); } } return regexpInitializeString(arg0.convertToString(), newOptions); diff --git a/core/src/main/java/org/jruby/common/RubyWarnings.java b/core/src/main/java/org/jruby/common/RubyWarnings.java index 2f910627c23..cb8ce5ed1a8 100644 --- a/core/src/main/java/org/jruby/common/RubyWarnings.java +++ b/core/src/main/java/org/jruby/common/RubyWarnings.java @@ -191,6 +191,10 @@ public void warnDeprecated(ID id, String message) { if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(id, message); } + public void warnDeprecated(String message) { + if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(message); + } + public void warnDeprecatedAlternate(String name, String alternate) { if (runtime.getWarningCategories().contains(Category.DEPRECATED)) warn(ID.DEPRECATED_METHOD, name + " is deprecated; use " + alternate + " instead"); } @@ -208,26 +212,42 @@ public void warnOnce(ID id, String message) { } /** - * Verbose mode warning methods, their contract is that consumer must explicitly check for runtime.isVerbose() before calling them + * Verbose mode warning methods, only warn in verbose mode */ public void warning(String message) { warning(ID.MISCELLANEOUS, message); } + public void warningDeprecated(String message) { + warningDeprecated(ID.MISCELLANEOUS, message); + } + @Override public void warning(ID id, String message) { + if (!isVerbose()) return; + warn(id, message); } + public void warningDeprecated(ID id, String message) { + if (!isVerbose()) return; + + warnDeprecated(id, message); + } + /** * Prints a warning, only in verbose mode. */ @Override public void warning(ID id, String fileName, int lineNumber, String message) { + if (!isVerbose()) return; + warn(id, fileName, lineNumber, message); } public void warning(String fileName, int lineNumber, String message) { + if (!isVerbose()) return; + warn(fileName, lineNumber, message); } From 4d63582f7b0b11a3e272d8c2a0a12b209db53b65 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Fri, 19 Jan 2024 16:14:24 -0600 Subject: [PATCH 11/16] These should be warn, not warning warning at some point started to warn all the time, even when not verbose. Previous commit modified this logic to match CRuby, with warning only producing output in verbose mode, but several specs and tests failed that expected that output. These cases should be warn, as in CRuby. --- core/src/main/java/org/jruby/Ruby.java | 2 +- core/src/main/java/org/jruby/RubyArray.java | 18 +++++++++--------- .../main/java/org/jruby/RubyEnumerable.java | 14 +++++++------- core/src/main/java/org/jruby/RubyModule.java | 4 ++-- .../java/org/jruby/lexer/yacc/RubyLexer.java | 10 +++++++--- .../java/org/jruby/parser/RubyParserBase.java | 4 ++-- .../java/org/jruby/util/StringSupport.java | 2 +- 7 files changed, 29 insertions(+), 25 deletions(-) diff --git a/core/src/main/java/org/jruby/Ruby.java b/core/src/main/java/org/jruby/Ruby.java index 9f4931b7390..6ab6cfd51fa 100644 --- a/core/src/main/java/org/jruby/Ruby.java +++ b/core/src/main/java/org/jruby/Ruby.java @@ -5608,7 +5608,7 @@ public RubyClass getData() { private final WarnCallback regexpWarnings = new WarnCallback() { @Override public void warn(String message) { - getWarnings().warning(message); + getWarnings().warn(message); } }; diff --git a/core/src/main/java/org/jruby/RubyArray.java b/core/src/main/java/org/jruby/RubyArray.java index a9e6adf2725..10831978892 100644 --- a/core/src/main/java/org/jruby/RubyArray.java +++ b/core/src/main/java/org/jruby/RubyArray.java @@ -645,7 +645,7 @@ public IRubyObject initialize(ThreadContext context, Block block) { unpack(); realLength = 0; if (block.isGiven() && context.runtime.isVerbose()) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } return this; } @@ -2210,7 +2210,7 @@ private IRubyObject getDefaultSeparator(Ruby runtime) { IRubyObject sep; sep = runtime.getGlobalVariables().get("$,"); if (!sep.isNil()) { - runtime.getWarnings().warningDeprecated("$, is set to non-nil value"); + runtime.getWarnings().warnDeprecated("$, is set to non-nil value"); } return sep; } @@ -2549,7 +2549,7 @@ public IRubyObject index(ThreadContext context, IRubyObject obj) { @JRubyMethod(name = {"index", "find_index"}) public IRubyObject index(ThreadContext context, IRubyObject obj, Block unused) { - if (unused.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (unused.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); return index(context, obj); } @@ -2656,7 +2656,7 @@ public IRubyObject rindex(ThreadContext context, IRubyObject obj) { @JRubyMethod public IRubyObject rindex(ThreadContext context, IRubyObject obj, Block unused) { - if (unused.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (unused.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); return rindex(context, obj); } @@ -3521,7 +3521,7 @@ public IRubyObject count(ThreadContext context, Block block) { @JRubyMethod(name = "count") public IRubyObject count(ThreadContext context, IRubyObject obj, Block block) { - if (block.isGiven()) context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + if (block.isGiven()) context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); int n = 0; for (int i = 0; i < realLength; i++) { @@ -4929,7 +4929,7 @@ public IRubyObject all_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return all_pBlockless(context, arg); @@ -4972,7 +4972,7 @@ public IRubyObject any_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return any_pBlockless(context, arg); @@ -5014,7 +5014,7 @@ public IRubyObject none_pCommon(ThreadContext context, IRubyObject arg, Block bl boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return none_pBlockless(context, arg); @@ -5056,7 +5056,7 @@ public IRubyObject one_pCommon(ThreadContext context, IRubyObject arg, Block blo boolean patternGiven = arg != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } if (!block.isGiven() || patternGiven) return one_pBlockless(context, arg); diff --git a/core/src/main/java/org/jruby/RubyEnumerable.java b/core/src/main/java/org/jruby/RubyEnumerable.java index 1718be70cc6..334a3468520 100644 --- a/core/src/main/java/org/jruby/RubyEnumerable.java +++ b/core/src/main/java/org/jruby/RubyEnumerable.java @@ -163,7 +163,7 @@ public static IRubyObject count(ThreadContext context, IRubyObject self, final I final Ruby runtime = context.runtime; final SingleInt result = new SingleInt(); - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); each(context, eachSite(context), self, new JavaInternalBlockBody(runtime, context, "Enumerable#count", Signature.ONE_REQUIRED) { public IRubyObject yield(ThreadContext context1, IRubyObject[] args) { @@ -690,7 +690,7 @@ public static IRubyObject find_index(ThreadContext context, IRubyObject self, fi public static IRubyObject find_index(ThreadContext context, IRubyObject self, final IRubyObject cond, final Block block) { final Ruby runtime = context.runtime; - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); if (self instanceof RubyArray) return ((RubyArray) self).find_index(context, cond); return find_indexCommon(context, eachSite(context), self, cond); @@ -1086,7 +1086,7 @@ public static IRubyObject inject(ThreadContext context, IRubyObject self, IRubyO public static IRubyObject inject(ThreadContext context, IRubyObject self, IRubyObject init, IRubyObject method, final Block block) { final Ruby runtime = context.runtime; - if (block.isGiven()) runtime.getWarnings().warning(ID.BLOCK_UNUSED , "given block not used"); + if (block.isGiven()) runtime.getWarnings().warn(ID.BLOCK_UNUSED , "given block not used"); final String methodId = method.asJavaString(); final SingleObject result = new SingleObject<>(init); @@ -1591,7 +1591,7 @@ public static IRubyObject none_pCommon(ThreadContext context, CallSite each, IRu final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1646,7 +1646,7 @@ public static IRubyObject one_pCommon(ThreadContext context, CallSite each, IRub final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - context.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + context.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1729,7 +1729,7 @@ public static IRubyObject all_pCommon(ThreadContext localContext, CallSite each, final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - localContext.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + localContext.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { @@ -1819,7 +1819,7 @@ public static IRubyObject any_pCommon(ThreadContext localContext, CallSite site, final boolean patternGiven = pattern != null; if (block.isGiven() && patternGiven) { - localContext.runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + localContext.runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } try { diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index d25f32b3c20..0c24ff0f3bc 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -4912,9 +4912,9 @@ private IRubyObject setConstantCommon(String name, IRubyObject value, boolean hi if (notAutoload || !setAutoloadConstant(name, value, file, line)) { if (warn && notAutoload) { if (this.equals(getRuntime().getObject())) { - getRuntime().getWarnings().warning(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + name); + getRuntime().getWarnings().warn(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + name); } else { - getRuntime().getWarnings().warning(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + this + "::" + name); + getRuntime().getWarnings().warn(ID.CONSTANT_ALREADY_INITIALIZED, "already initialized constant " + this + "::" + name); } } diff --git a/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java b/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java index 8b786bca75b..38e4331b6fc 100644 --- a/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java +++ b/core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java @@ -162,6 +162,10 @@ private void warning(ID id, String file, int line, String message) { warnings.warning(id, file, line + 1, message); // rubysource-line is 0 based } + private void warn(ID id, String message) { + warnings.warn(id, getFile(), getRubySourceline(), message); + } + public enum Keyword { END ("end", new ByteList(new byte[] {'e', 'n', 'd'}, USASCII_ENCODING), keyword_end, keyword_end, EXPR_END), ELSE ("else", new ByteList(new byte[] {'e', 'l', 's', 'e'}, USASCII_ENCODING), keyword_else, keyword_else, EXPR_BEG), @@ -354,7 +358,7 @@ public int nextc() { c = '\n'; } else if (ruby_sourceline > last_cr_line) { last_cr_line = ruby_sourceline; - warning(ID.VOID_VALUE_EXPRESSION, "encountered \\r in middle of line, treated as a mere space"); + warn(ID.VOID_VALUE_EXPRESSION, "encountered \\r in middle of line, treated as a mere space"); } } @@ -1489,7 +1493,7 @@ private int dollar() { try { ref = Integer.parseInt(refAsString.substring(1)); } catch (NumberFormatException e) { - warning(ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil"); + warn(ID.AMBIGUOUS_ARGUMENT, "`" + refAsString + "' is too big for a number variable, always nil"); ref = 0; } @@ -1531,7 +1535,7 @@ private int dot() { } if (parenNest == 0 && isLookingAtEOL()) { - warning(ID.MISCELLANEOUS, "... at EOL, should be parenthesized?"); + warn(ID.MISCELLANEOUS, "... at EOL, should be parenthesized?"); } else if (getLeftParenBegin() >= 0 && getLeftParenBegin() + 1 == parenNest) { if (isLexState(last_state, EXPR_LABEL)) { return tDOT3; diff --git a/core/src/main/java/org/jruby/parser/RubyParserBase.java b/core/src/main/java/org/jruby/parser/RubyParserBase.java index a5e1a36f934..75c3f99fdb9 100644 --- a/core/src/main/java/org/jruby/parser/RubyParserBase.java +++ b/core/src/main/java/org/jruby/parser/RubyParserBase.java @@ -1597,11 +1597,11 @@ public void warn(int line, String message) { // FIXME: Replace this with file/line version and stop using ISourcePosition public void warning(int line, String message) { - if (warnings.isVerbose()) warning(ID.USELESS_EXPRESSION, lexer.getFile(), line, message); + warning(ID.USELESS_EXPRESSION, lexer.getFile(), line, message); } public void warning(ID id, String file, int line, String message) { - warnings.warning(id, file, line + 1, message); // node/lexer lines are 0 based + warnings.warn(id, file, line + 1, message); // node/lexer lines are 0 based } // ENEBO: Totally weird naming (in MRI is not allocated and is a local var name) [1.9] diff --git a/core/src/main/java/org/jruby/util/StringSupport.java b/core/src/main/java/org/jruby/util/StringSupport.java index 8b1e9f81838..77bad8bcce8 100644 --- a/core/src/main/java/org/jruby/util/StringSupport.java +++ b/core/src/main/java/org/jruby/util/StringSupport.java @@ -2071,7 +2071,7 @@ public static IRubyObject rbStrEnumerateLines(RubyString str, ThreadContext cont if (wantarray) { // this code should be live in 3.0 if (false) { // #if STRING_ENUMERATORS_WANTARRAY - runtime.getWarnings().warning(ID.BLOCK_UNUSED, "given block not used"); + runtime.getWarnings().warn(ID.BLOCK_UNUSED, "given block not used"); } else { runtime.getWarnings().warning(ID.BLOCK_DEPRECATED, "passing a block to String#lines is deprecated"); wantarray = false; From 7104469059b2f8b45c4b49c41bb9bef0db429191 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Sun, 21 Jan 2024 03:22:29 -0600 Subject: [PATCH 12/16] Update strscan to fix improper sharing The issue arises when the `StringScanner` string is being modified while being scanned. In such a case, that string's buffers will be improperly shared, forcing a new buffer to be created each time it is modified. Meanwhile the ever-growing buffers are held in memory by the improperly shared return values. This was fixed by https://github.com/ruby/strscan/issues/84 and strscan is updated in this PR. --- lib/pom.rb | 2 +- lib/pom.xml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/pom.rb b/lib/pom.rb index 872089a628f..76507d8ec68 100644 --- a/lib/pom.rb +++ b/lib/pom.rb @@ -98,7 +98,7 @@ def log(message=nil) ['shellwords', '0.1.0'], ['singleton', '0.1.1'], ['stringio', '3.0.8'], - ['strscan', '3.0.7'], + ['strscan', '3.0.9'], ['subspawn', '0.1.1'], # has 3 transitive deps: ['subspawn-posix', '0.1.1'], ['ffi-binary-libfixposix', '0.5.1.1'], diff --git a/lib/pom.xml b/lib/pom.xml index 8934e1f1b6d..83ef9e173b9 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -736,7 +736,7 @@ DO NOT MODIFY - GENERATED CODE rubygems strscan - 3.0.7 + 3.0.9 gem provided @@ -1120,7 +1120,7 @@ DO NOT MODIFY - GENERATED CODE specifications/shellwords-0.1.0* specifications/singleton-0.1.1* specifications/stringio-3.0.8* - specifications/strscan-3.0.7* + specifications/strscan-3.0.9* specifications/subspawn-0.1.1* specifications/subspawn-posix-0.1.1* specifications/ffi-binary-libfixposix-0.5.1.1* @@ -1198,7 +1198,7 @@ DO NOT MODIFY - GENERATED CODE gems/shellwords-0.1.0*/**/* gems/singleton-0.1.1*/**/* gems/stringio-3.0.8*/**/* - gems/strscan-3.0.7*/**/* + gems/strscan-3.0.9*/**/* gems/subspawn-0.1.1*/**/* gems/subspawn-posix-0.1.1*/**/* gems/ffi-binary-libfixposix-0.5.1.1*/**/* @@ -1276,7 +1276,7 @@ DO NOT MODIFY - GENERATED CODE cache/shellwords-0.1.0* cache/singleton-0.1.1* cache/stringio-3.0.8* - cache/strscan-3.0.7* + cache/strscan-3.0.9* cache/subspawn-0.1.1* cache/subspawn-posix-0.1.1* cache/ffi-binary-libfixposix-0.5.1.1* From eb9d87a83c356bb008c9d3862323f2f9b0a2f92b Mon Sep 17 00:00:00 2001 From: moste00 Date: Sat, 20 Jan 2024 22:53:22 +0200 Subject: [PATCH 13/16] Added Module#refinements, Refinement#target and Refinement#refined_class --- core/src/main/java/org/jruby/RubyModule.java | 31 ++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/core/src/main/java/org/jruby/RubyModule.java b/core/src/main/java/org/jruby/RubyModule.java index fda962e937c..f58e3a8720b 100644 --- a/core/src/main/java/org/jruby/RubyModule.java +++ b/core/src/main/java/org/jruby/RubyModule.java @@ -117,6 +117,7 @@ import org.jruby.runtime.opto.Invalidator; import org.jruby.runtime.opto.OptoFactory; import org.jruby.runtime.profile.MethodEnhancer; +import org.jruby.util.RubyStringBuilder; import org.jruby.util.ByteList; import org.jruby.util.ClassProvider; import org.jruby.util.CommonByteLists; @@ -4510,6 +4511,36 @@ public final void setConstantVisibility(Ruby runtime, String name, boolean hidde storeConstant(name, entry.value, hidden, entry.getFile(), entry.getLine()); } + @JRubyMethod(name = "refinements") + public IRubyObject refinements(ThreadContext context) { + RubyArray refinementModules = context.runtime.newArray(); + + refinements.forEach((key, value) -> { + refinementModules.append(value); + }); + return refinementModules; + } + + @JRubyMethod(name = "target") + public IRubyObject target(ThreadContext context) { + return getRefinedClassOrThrow(context, true); + } + + @JRubyMethod(name = "refined_class") + public IRubyObject refined_class(ThreadContext context) { + return getRefinedClassOrThrow(context, false); + } + + private IRubyObject getRefinedClassOrThrow(ThreadContext context, boolean nameIsTarget) { + if (!isRefinement()) { + String methodName = nameIsTarget ? "target" : "refined_class"; + String errMsg = RubyStringBuilder.str(context.runtime, + "undefined method `"+ methodName +"' for ", rubyBaseName(), + ":", getMetaClass()); + throw context.runtime.newNoMethodError(errMsg, this, "target", context.runtime.newEmptyArray()); + } + return refinedClass; + } // ////////////////// CLASS VARIABLE API METHODS //////////////// // From 3e122da77ab3e36a4536cda9eda07b07b388e670 Mon Sep 17 00:00:00 2001 From: "Thomas E. Enebo" Date: Mon, 22 Jan 2024 11:23:37 -0500 Subject: [PATCH 14/16] refine spec now passing --- spec/tags/ruby/core/module/refine_tags.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/tags/ruby/core/module/refine_tags.txt b/spec/tags/ruby/core/module/refine_tags.txt index f56a17a41d6..1a0ee3f3962 100644 --- a/spec/tags/ruby/core/module/refine_tags.txt +++ b/spec/tags/ruby/core/module/refine_tags.txt @@ -2,4 +2,3 @@ fails:Module#refine for methods accessed indirectly is not honored by & fails(not implemented, jruby/jruby#6161):Module#refine for methods accessed indirectly is honored by & fails:Module#refine when super is called in a refinement looks in the lexical scope refinements before other active refinements fails:Module#refine for methods accessed indirectly is honored by Kernel#public_method -fails:Module#refine raises TypeError if not passed a class From bf7481c4e1631132a049d5833dd04b25058a97cc Mon Sep 17 00:00:00 2001 From: "Thomas E. Enebo" Date: Mon, 22 Jan 2024 15:10:55 -0500 Subject: [PATCH 15/16] File{,Test}#exists? no longer exists? --- core/src/main/java/org/jruby/RubyFileTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/jruby/RubyFileTest.java b/core/src/main/java/org/jruby/RubyFileTest.java index 381e542bf01..15b7ef799d2 100644 --- a/core/src/main/java/org/jruby/RubyFileTest.java +++ b/core/src/main/java/org/jruby/RubyFileTest.java @@ -119,7 +119,7 @@ public static IRubyObject exist_p(IRubyObject recv, IRubyObject filename) { return exist_p(recv.getRuntime().getCurrentContext(), recv, filename); } - @JRubyMethod(name = {"exist?", "exists?"}, module = true) + @JRubyMethod(name = "exist?", module = true) public static IRubyObject exist_p(ThreadContext context, IRubyObject recv, IRubyObject filename) { // We get_path here to prevent doing it both existsOnClasspath and fileResource (Only call to_path once). return RubyBoolean.newBoolean(context, exist(context, get_path(context, filename))); From 4f149b2427500096c7bb58788a083ada2f8c70a0 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Mon, 22 Jan 2024 16:45:17 -0600 Subject: [PATCH 16/16] Add missing Integer operand to IR serialization read --- core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java b/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java index a7c682c3794..a2441ca04b6 100644 --- a/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java +++ b/core/src/main/java/org/jruby/ir/persistence/IRReaderStream.java @@ -529,6 +529,7 @@ public Operand decode(OperandType type) { case GLOBAL_VARIABLE: return GlobalVariable.decode(this); case HASH: return Hash.decode(this); case IR_EXCEPTION: return IRException.decode(this); + case INTEGER: return org.jruby.ir.operands.Integer.decode(this); case LABEL: return Label.decode(this); case LOCAL_VARIABLE: return LocalVariable.decode(this); case NIL: return manager.getNil();