diff --git a/CHANGELOG.md b/CHANGELOG.md index 6973d8b998f5..ddf49bd848c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ Compatibility: * Add `String#bytesplice` (#3039, @itarato). * Add `String#byteindex` and `String#byterindex` (#3039, @itarato). * Add implementations of `rb_proc_call_with_block`, `rb_proc_call_kw`, `rb_proc_call_with_block_kw` and `rb_funcall_with_block_kw` (#3068, @andrykonchin). +* Add `Module#refinements` (#3039, @itarato). Performance: diff --git a/spec/truffleruby.next-specs b/spec/truffleruby.next-specs index 0f5e3e312239..1bd92763fdc2 100644 --- a/spec/truffleruby.next-specs +++ b/spec/truffleruby.next-specs @@ -21,3 +21,5 @@ spec/ruby/core/string/bytesplice_spec.rb spec/ruby/core/string/byteindex_spec.rb spec/ruby/core/string/byterindex_spec.rb + +spec/ruby/core/module/refinements_spec.rb diff --git a/src/main/java/org/truffleruby/core/module/ModuleNodes.java b/src/main/java/org/truffleruby/core/module/ModuleNodes.java index 24d8210ebdd1..35e0d323e2fb 100644 --- a/src/main/java/org/truffleruby/core/module/ModuleNodes.java +++ b/src/main/java/org/truffleruby/core/module/ModuleNodes.java @@ -10,6 +10,7 @@ package org.truffleruby.core.module; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -37,7 +38,6 @@ import org.truffleruby.builtins.CoreMethodArrayArgumentsNode; import org.truffleruby.builtins.CoreMethodNode; import org.truffleruby.annotations.CoreModule; -import org.truffleruby.builtins.NonStandard; import org.truffleruby.annotations.Primitive; import org.truffleruby.builtins.PrimitiveArrayArgumentsNode; import org.truffleruby.builtins.PrimitiveNode; @@ -2324,7 +2324,6 @@ protected RubyArray usedModules() { } - @NonStandard @CoreMethod(names = "used_refinements", onSingleton = true) public abstract static class UsedRefinementsNode extends CoreMethodArrayArgumentsNode { @@ -2335,15 +2334,23 @@ protected RubyArray usedRefinements() { final DeclarationContext declarationContext = RubyArguments.getDeclarationContext(frame); final Set refinements = new HashSet<>(); for (RubyModule[] refinementModules : declarationContext.getRefinements().values()) { - for (RubyModule refinementModule : refinementModules) { - refinements.add(refinementModule); - } + Collections.addAll(refinements, refinementModules); } return createArray(refinements.toArray()); } } + @CoreMethod(names = "refinements") + public abstract static class RefinementsNode extends CoreMethodArrayArgumentsNode { + + @Specialization + protected RubyArray refinements(RubyModule self) { + return createArray(self.fields.getRefinements().values().toArray()); + } + + } + @GenerateUncached @ImportStatic(ArrayGuards.class) public abstract static class SetMethodVisibilityNode extends RubyBaseNode { diff --git a/test/mri/tests/ruby/test_refinement.rb b/test/mri/tests/ruby/test_refinement.rb index 9a153a0c25b4..a5cc872a459e 100644 --- a/test/mri/tests/ruby/test_refinement.rb +++ b/test/mri/tests/ruby/test_refinement.rb @@ -1835,6 +1835,21 @@ def test_used_modules assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS end + def test_refinements + int_refinement = nil + str_refinement = nil + m = Module.new { + refine Integer do + int_refinement = self + end + + refine String do + str_refinement = self + end + } + assert_equal([int_refinement, str_refinement], m.refinements) + end + def test_warn_setconst_in_refinmenet bug10103 = '[ruby-core:64143] [Bug #10103]' warnings = [