From 0fa5feab889b6b0d826c125c50c55614f0c8d54d Mon Sep 17 00:00:00 2001 From: Peter Arato Date: Tue, 6 Jun 2023 15:26:52 -0400 Subject: [PATCH] Move Refinement things to its own RefinementNodes node --- .../truffleruby/core/module/ModuleNodes.java | 77 ------------- .../core/refinement/RefinementNodes.java | 108 ++++++++++++++++++ src/main/ruby/truffleruby/core/refinement.rb | 2 +- 3 files changed, 109 insertions(+), 78 deletions(-) create mode 100644 src/main/java/org/truffleruby/core/refinement/RefinementNodes.java diff --git a/src/main/java/org/truffleruby/core/module/ModuleNodes.java b/src/main/java/org/truffleruby/core/module/ModuleNodes.java index b1b86e69c2b..4ed17fbc88c 100644 --- a/src/main/java/org/truffleruby/core/module/ModuleNodes.java +++ b/src/main/java/org/truffleruby/core/module/ModuleNodes.java @@ -32,7 +32,6 @@ import com.oracle.truffle.api.strings.TruffleString; import com.oracle.truffle.api.strings.TruffleString.ByteIndexOfStringNode; import org.truffleruby.RubyContext; -import org.truffleruby.RubyLanguage; import org.truffleruby.annotations.CoreMethod; import org.truffleruby.builtins.CoreMethodArrayArgumentsNode; import org.truffleruby.builtins.CoreMethodNode; @@ -2467,73 +2466,6 @@ private RubyModule newRefinementModule(RubyModule namespace, RubyModule moduleTo } - @Primitive(name = "refinement_import_methods") - public abstract static class ImportMethodsNode extends PrimitiveArrayArgumentsNode { - - @TruffleBoundary - @Specialization - protected RubyModule importMethods(RubyModule refinement, RubyModule moduleToImportFrom) { - var firstNonRubyMethod = getFirstNonRubyMethodOrNull(moduleToImportFrom, getLanguage()); - if (firstNonRubyMethod != null) { - throw new RaiseException(getContext(), - coreExceptions().argumentError(createErrorMessage(firstNonRubyMethod, moduleToImportFrom), - this)); - } - - importMethodsFromModuleToRefinement(moduleToImportFrom, refinement); - - return refinement; - } - - private String createErrorMessage(InternalMethod method, RubyModule module) { - return StringUtils.format("Can't import method which is not defined with Ruby code: %s#%s", - module.getName(), method.getName()); - } - - private void importMethodsFromModuleToRefinement(RubyModule module, RubyModule refinement) { - var declarationContext = createDeclarationContextWithRefinement(refinement); - for (InternalMethod methodToCopy : module.fields.getMethods()) { - var clonedMethod = cloneMethod(methodToCopy, declarationContext, refinement); - refinement.fields.addMethod(getContext(), this, clonedMethod); - } - } - - private InternalMethod getFirstNonRubyMethodOrNull(RubyModule module, RubyLanguage language) { - for (InternalMethod method : module.fields.getMethods()) { - if (!method.isDefinedInRuby(language)) { - return method; - } - } - - return null; - } - - // Creates a declaration context which contains the refined methods from the given refinement - private DeclarationContext createDeclarationContextWithRefinement(RubyModule refinement) { - final Map refinements = new HashMap<>(); - refinements.put(refinement.fields.getRefinedModule(), new RubyModule[]{ refinement }); - return new DeclarationContext( - Visibility.PUBLIC, - new FixedDefaultDefinee(refinement), - refinements); - } - - private InternalMethod cloneMethod(InternalMethod method, DeclarationContext declarationContext, - RubyModule refinement) { - var clonedCallTarget = cloneCallTarget(method); - return method.withCallTargetAndDeclarationContextAndDeclarationModule(clonedCallTarget, declarationContext, - refinement); - } - - private RootCallTarget cloneCallTarget(InternalMethod method) { - var rubyRootNode = (RubyRootNode) method.getCallTarget().getRootNode(); - var clonedRootNode = rubyRootNode.cloneUninitialized(); - - return clonedRootNode.getCallTarget(); - } - } - - @GenerateUncached @CoreMethod(names = "using", required = 1, visibility = Visibility.PRIVATE, alwaysInlined = true) public abstract static class ModuleUsingNode extends UsingNode { @@ -2584,13 +2516,4 @@ protected Object doClass(RubyClass rubyClass) { return rubyClass.isSingleton; } } - - @Primitive(name = "refined_class") - public abstract static class RefinedClassNode extends PrimitiveArrayArgumentsNode { - - @Specialization - protected RubyModule refinedClass(RubyModule refinement) { - return refinement.fields.getRefinedModule(); - } - } } diff --git a/src/main/java/org/truffleruby/core/refinement/RefinementNodes.java b/src/main/java/org/truffleruby/core/refinement/RefinementNodes.java new file mode 100644 index 00000000000..4704e52d3f0 --- /dev/null +++ b/src/main/java/org/truffleruby/core/refinement/RefinementNodes.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. This + * code is released under a tri EPL/GPL/LGPL license. You can use it, + * redistribute it and/or modify it under the terms of the: + * + * Eclipse Public License version 2.0, or + * GNU General Public License version 2, or + * GNU Lesser General Public License version 2.1. + */ +package org.truffleruby.core.refinement; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.dsl.Specialization; +import org.truffleruby.RubyLanguage; +import org.truffleruby.annotations.CoreModule; +import org.truffleruby.annotations.Primitive; +import org.truffleruby.annotations.Visibility; +import org.truffleruby.builtins.PrimitiveArrayArgumentsNode; +import org.truffleruby.core.module.RubyModule; +import org.truffleruby.core.string.StringUtils; +import org.truffleruby.language.RubyRootNode; +import org.truffleruby.language.control.RaiseException; +import org.truffleruby.language.methods.DeclarationContext; +import org.truffleruby.language.methods.DeclarationContext.FixedDefaultDefinee; +import org.truffleruby.language.methods.InternalMethod; + +import java.util.HashMap; +import java.util.Map; + +@CoreModule(value = "Refinement", isClass = true) +public abstract class RefinementNodes { + + @Primitive(name = "import_methods") + public abstract static class ImportMethodsNode extends PrimitiveArrayArgumentsNode { + + @TruffleBoundary + @Specialization + protected RubyModule importMethods(RubyModule refinement, RubyModule moduleToImportFrom) { + var firstNonRubyMethod = getFirstNonRubyMethodOrNull(moduleToImportFrom, getLanguage()); + if (firstNonRubyMethod != null) { + throw new RaiseException(getContext(), + coreExceptions().argumentError(createErrorMessage(firstNonRubyMethod, moduleToImportFrom), + this)); + } + + importMethodsFromModuleToRefinement(moduleToImportFrom, refinement); + + return refinement; + } + + private String createErrorMessage(InternalMethod method, RubyModule module) { + return StringUtils.format("Can't import method which is not defined with Ruby code: %s#%s", + module.getName(), method.getName()); + } + + private void importMethodsFromModuleToRefinement(RubyModule module, RubyModule refinement) { + var declarationContext = createDeclarationContextWithRefinement(refinement); + for (InternalMethod methodToCopy : module.fields.getMethods()) { + var clonedMethod = cloneMethod(methodToCopy, declarationContext, refinement); + refinement.fields.addMethod(getContext(), this, clonedMethod); + } + } + + private InternalMethod getFirstNonRubyMethodOrNull(RubyModule module, RubyLanguage language) { + for (InternalMethod method : module.fields.getMethods()) { + if (!method.isDefinedInRuby(language)) { + return method; + } + } + + return null; + } + + // Creates a declaration context which contains the refined methods from the given refinement + private DeclarationContext createDeclarationContextWithRefinement(RubyModule refinement) { + final Map refinements = new HashMap<>(); + refinements.put(refinement.fields.getRefinedModule(), new RubyModule[]{ refinement }); + return new DeclarationContext( + Visibility.PUBLIC, + new FixedDefaultDefinee(refinement), + refinements); + } + + private InternalMethod cloneMethod(InternalMethod method, DeclarationContext declarationContext, + RubyModule refinement) { + var clonedCallTarget = cloneCallTarget(method); + return method.withCallTargetAndDeclarationContextAndDeclarationModule(clonedCallTarget, declarationContext, + refinement); + } + + private RootCallTarget cloneCallTarget(InternalMethod method) { + var rubyRootNode = (RubyRootNode) method.getCallTarget().getRootNode(); + var clonedRootNode = rubyRootNode.cloneUninitialized(); + + return clonedRootNode.getCallTarget(); + } + } + + @Primitive(name = "refined_class") + public abstract static class RefinedClassNode extends PrimitiveArrayArgumentsNode { + + @Specialization + protected RubyModule refinedClass(RubyModule refinement) { + return refinement.fields.getRefinedModule(); + } + } +} diff --git a/src/main/ruby/truffleruby/core/refinement.rb b/src/main/ruby/truffleruby/core/refinement.rb index d59dfe4d68a..9a1556c4acd 100644 --- a/src/main/ruby/truffleruby/core/refinement.rb +++ b/src/main/ruby/truffleruby/core/refinement.rb @@ -21,7 +21,7 @@ def import_methods(*modules) if mod.ancestors.length > 1 warn("#{mod} has ancestors, but Refinement#import_methods doesn't import their methods", uplevel: 1) end - Primitive.refinement_import_methods(self, mod) + Primitive.import_methods(self, mod) end self end