Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compatibility] Add Module#refinements #3093

Merged
merged 3 commits into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/CHANGELOG.md merge=union

/spec/truffleruby.next-specs merge=union

# Rules for GitHub's Linguist language-classification system. We're abusing the
# 'vendored' attribute to exclude files as a lot of this isn't really vendored,
# and a whole lot of actually vendored code isn't listed! What we want to do is
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Compatibility:
* Add optional `timeout` argument to `Thread::Queue#pop` (#3039, @itarato).
* Add optional `timeout` argument to `Thread::SizedsQueue#pop` (#3039, @itarato).
* Handle `long long` and aliases in `Fiddle` (#3128, @eregon).
* Add `Module#refinements` (#3039, @itarato).

Performance:

Expand Down
1 change: 1 addition & 0 deletions spec/tags/truffle/methods_tags.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,4 @@ fails:Public methods on UnboundMethod should include private?
fails:Public methods on UnboundMethod should include protected?
fails:Public methods on UnboundMethod should include public?
fails:Public methods on String should not include bytesplice
fails:Public methods on Module should not include refinements
2 changes: 2 additions & 0 deletions spec/truffleruby.next-specs
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ spec/ruby/core/queue/shift_spec.rb
spec/ruby/core/sizedqueue/deq_spec.rb
spec/ruby/core/sizedqueue/pop_spec.rb
spec/ruby/core/sizedqueue/shift_spec.rb

spec/ruby/core/module/refinements_spec.rb
18 changes: 13 additions & 5 deletions src/main/java/org/truffleruby/core/module/ModuleNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2324,7 +2324,6 @@ protected RubyArray usedModules() {

}

@NonStandard
@CoreMethod(names = "used_refinements", onSingleton = true)
public abstract static class UsedRefinementsNode extends CoreMethodArrayArgumentsNode {

Expand All @@ -2335,15 +2334,24 @@ protected RubyArray usedRefinements() {
final DeclarationContext declarationContext = RubyArguments.getDeclarationContext(frame);
final Set<RubyModule> 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 {

@TruffleBoundary
@Specialization
protected RubyArray refinements(RubyModule self) {
return createArray(self.fields.getRefinements().values().toArray());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a TruffleBoundary (on the specialization to keep it simple) for the .values() and .toArray()

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

}

}

@GenerateUncached
@ImportStatic(ArrayGuards.class)
public abstract static class SetMethodVisibilityNode extends RubyBaseNode {
Expand Down
1 change: 1 addition & 0 deletions test/mri/excludes/TestRefinement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
exclude :test_unbound_refine_method, "needs investigation"
exclude :test_ancestors, "[ruby-core:86949] [Bug #14744]."
exclude :test_import_methods, "NoMethodError: undefined method `bar' for #<TestRefinement::TestImport::A:0x17bee78>"
exclude :test_refinements, "TruffleRuby does not guarantee refinement list ordering"
15 changes: 15 additions & 0 deletions test/mri/tests/ruby/test_refinement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1835,6 +1835,21 @@ def test_used_modules
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS
end

def test_refinements
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 = [
Expand Down