Skip to content

Commit f1971ab

Browse files
committed
[GR-19220] Implement UnboundMethod#original_name (#2874)
PullRequest: truffleruby/3658
2 parents 96f2b2a + 352238e commit f1971ab

File tree

10 files changed

+41
-25
lines changed

10 files changed

+41
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Compatibility:
7777
* Fix `Enumerable` methods `each_cons` and `each_slice` to return receiver (#2733, @horakivo)
7878
* `Module` methods `#private`, `#public`, `#protected`, `#module_function` now returns their arguments like in CRuby 3.1 (#2733, @horakivo)
7979
* `Kernel#exit!`, killing Fibers and internal errors do not run code in `ensure` clauses anymore, the same as CRuby (@eregon).
80+
* Implement `UnboundMethod#original_name` (@paracycle, @nirvdrum).
8081

8182
Performance:
8283

spec/tags/core/unboundmethod/original_name_tags.txt

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/main/java/org/truffleruby/core/MainNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected Object mainUsing(Frame callerFrame, Object self, Object[] rubyArgs, Ro
7373

7474
@TruffleBoundary
7575
private boolean isCalledFromTopLevel(InternalMethod callerMethod) {
76-
final String name = callerMethod.getSharedMethodInfo().getBacktraceName();
76+
final String name = callerMethod.getOriginalName();
7777
return name.equals("<main>") || name.startsWith("<top ");
7878
}
7979
}

src/main/java/org/truffleruby/core/method/UnboundMethodNodes.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.truffleruby.builtins.PrimitiveArrayArgumentsNode;
2020
import org.truffleruby.core.Hashing;
2121
import org.truffleruby.core.array.RubyArray;
22+
import org.truffleruby.core.cast.ToSymbolNode;
2223
import org.truffleruby.core.encoding.Encodings;
2324
import org.truffleruby.core.klass.RubyClass;
2425
import org.truffleruby.core.module.MethodLookupResult;
@@ -136,9 +137,8 @@ protected RubySymbol name(RubyUnboundMethod unboundMethod) {
136137

137138
}
138139

139-
// TODO: We should have an additional method for this but we need to access it for #inspect.
140-
@CoreMethod(names = "origin", visibility = Visibility.PRIVATE)
141-
public abstract static class OriginNode extends CoreMethodArrayArgumentsNode {
140+
@Primitive(name = "unbound_method_origin")
141+
public abstract static class OriginNode extends PrimitiveArrayArgumentsNode {
142142

143143
@Specialization
144144
protected RubyModule origin(RubyUnboundMethod unboundMethod) {
@@ -147,6 +147,17 @@ protected RubyModule origin(RubyUnboundMethod unboundMethod) {
147147

148148
}
149149

150+
@CoreMethod(names = "original_name")
151+
public abstract static class OriginalNameNode extends CoreMethodArrayArgumentsNode {
152+
153+
@Specialization
154+
protected RubySymbol originalName(RubyUnboundMethod unboundMethod,
155+
@Cached ToSymbolNode toSymbolNode) {
156+
String originalName = unboundMethod.method.getOriginalName();
157+
return toSymbolNode.execute(originalName);
158+
}
159+
}
160+
150161
@CoreMethod(names = "owner")
151162
public abstract static class OwnerNode extends CoreMethodArrayArgumentsNode {
152163

src/main/java/org/truffleruby/core/proc/ProcNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ public abstract static class ProcSymbolToProcSymbolNode extends PrimitiveArrayAr
286286
@Specialization
287287
protected Object symbolToProcSymbol(RubyProc proc) {
288288
if (proc.arity == SymbolNodes.ToProcNode.ARITY) {
289-
return getSymbol(proc.getSharedMethodInfo().getBacktraceName());
289+
return getSymbol(proc.getSharedMethodInfo().getOriginalName());
290290
} else {
291291
return nil;
292292
}

src/main/java/org/truffleruby/language/backtrace/Backtrace.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public static String labelFor(TruffleStackTraceElement e) {
151151
RootNode root = e.getTarget().getRootNode();
152152
String label = root instanceof RubyRootNode
153153
// Ruby backtraces do not include the class name for MRI compatibility.
154-
? ((RubyRootNode) root).getSharedMethodInfo().getBacktraceName()
154+
? ((RubyRootNode) root).getSharedMethodInfo().getOriginalName()
155155
: root.getName();
156156
return label == null ? "<unknown>" : label;
157157
}

src/main/java/org/truffleruby/language/methods/InternalMethod.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ public String getName() {
195195
return name;
196196
}
197197

198+
public String getOriginalName() {
199+
return sharedMethodInfo.getOriginalName();
200+
}
201+
198202
public Visibility getVisibility() {
199203
return visibility;
200204
}

src/main/java/org/truffleruby/language/methods/SharedMethodInfo.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
import org.truffleruby.parser.OpenModule;
2525
import org.truffleruby.parser.ParserContext;
2626

27-
/** {@link InternalMethod} objects are copied as properties such as visibility are changed. {@link SharedMethodInfo}
28-
* stores the state that does not change, such as where the method was defined. */
27+
/** SharedMethodInfo represents static information from the parser for either a method definition or a block like its
28+
* name, SourceSection, etc. Such information is always "original" since it comes from the source as opposed to
29+
* "aliased" (e.g. the aliased name of a method). In contrast, {@link InternalMethod} are runtime objects containing
30+
* properties that change for a method. */
2931
public final class SharedMethodInfo {
3032

3133
private final SourceSection sourceSection;
@@ -34,7 +36,7 @@ public final class SharedMethodInfo {
3436
private final Arity arity;
3537
/** The original name of the method. Does not change when aliased. Looks like "block in foo" or "block (2 levels) in
3638
* foo" for blocks. This is the name shown in backtraces: "from FILE:LINE:in `NAME'". */
37-
private final String backtraceName;
39+
private final String originalName;
3840
/** The "static" name of this method at parse time, such as "M::C#foo", "M::C.foo", "<module:Inner>", "block (2
3941
* levels) in M::C.foo" or "block (2 levels) in <module:Inner>". This name is used for tools. */
4042
private final String parseName;
@@ -48,16 +50,16 @@ public SharedMethodInfo(
4850
SourceSection sourceSection,
4951
LexicalScope staticLexicalScope,
5052
Arity arity,
51-
String backtraceName,
53+
String originalName,
5254
int blockDepth,
5355
String parseName,
5456
String notes,
5557
ArgumentDescriptor[] argumentDescriptors) {
56-
assert blockDepth == 0 || backtraceName.startsWith("block ") : backtraceName;
58+
assert blockDepth == 0 || originalName.startsWith("block ") : originalName;
5759
this.sourceSection = sourceSection;
5860
this.staticLexicalScope = staticLexicalScope;
5961
this.arity = arity;
60-
this.backtraceName = backtraceName;
62+
this.originalName = originalName;
6163
this.blockDepth = blockDepth;
6264
this.parseName = parseName;
6365
this.notes = notes;
@@ -93,7 +95,7 @@ public SharedMethodInfo withArity(Arity newArity) {
9395
sourceSection,
9496
staticLexicalScope,
9597
newArity,
96-
backtraceName,
98+
originalName,
9799
blockDepth,
98100
parseName,
99101
notes,
@@ -131,7 +133,7 @@ public boolean isBlock() {
131133

132134
@TruffleBoundary
133135
public boolean isModuleBody() {
134-
boolean isModuleBody = isModuleBody(getBacktraceName());
136+
boolean isModuleBody = isModuleBody(getOriginalName());
135137
assert !(isModuleBody && isBlock()) : this;
136138
return isModuleBody;
137139
}
@@ -150,19 +152,20 @@ public static boolean isModuleBody(String name) {
150152
}
151153
}
152154

153-
public String getBacktraceName() {
154-
return backtraceName;
155+
/** See {@link #originalName} */
156+
public String getOriginalName() {
157+
return originalName;
155158
}
156159

157160
/** Returns the method name on its own. Can start with "<" like "<module:Inner>" for module bodies. */
158161
public String getMethodName() {
159-
return blockDepth == 0 ? backtraceName : notes;
162+
return blockDepth == 0 ? originalName : notes;
160163
}
161164

162165
/** More efficient than {@link #getMethodName()} when we know blockDepth == 0 */
163166
public String getMethodNameForNotBlock() {
164167
assert blockDepth == 0;
165-
return backtraceName;
168+
return originalName;
166169
}
167170

168171
public String getParseName() {

src/main/java/org/truffleruby/parser/BodyTranslator.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ private ModuleBodyDefinition compileClassNode(SourceIndexLength sourceSection, P
10791079
environment.getReturnID());
10801080

10811081
return new ModuleBodyDefinition(
1082-
environment.getSharedMethodInfo().getBacktraceName(),
1082+
environment.getSharedMethodInfo().getOriginalName(),
10831083
environment.getSharedMethodInfo(),
10841084
rootNode.getCallTarget(),
10851085
environment.getStaticLexicalScopeOrNull());
@@ -2006,14 +2006,14 @@ private RubyNode translateBlockLikeNode(IterParseNode node, boolean isStabbyLamb
20062006
final int blockDepth = environment.getBlockDepth() + 1;
20072007

20082008
// "block in foo"
2009-
String backtraceName = SharedMethodInfo.getBlockName(blockDepth, methodName);
2009+
String originalName = SharedMethodInfo.getBlockName(blockDepth, methodName);
20102010
// "block (2 levels) in M::C.foo"
20112011
String parseName = SharedMethodInfo.getBlockName(blockDepth, methodParent.getSharedMethodInfo().getParseName());
20122012
final SharedMethodInfo sharedMethodInfo = new SharedMethodInfo(
20132013
sourceSection.toSourceSection(source),
20142014
environment.getStaticLexicalScopeOrNull(),
20152015
argsNode.getArity(),
2016-
backtraceName,
2016+
originalName,
20172017
blockDepth,
20182018
parseName,
20192019
methodName,

src/main/ruby/truffleruby/core/unbound_method.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
class UnboundMethod
1212
def inspect
13-
Truffle::MethodOperations.inspect_method(self, origin, owner)
13+
Truffle::MethodOperations.inspect_method(self, Primitive.unbound_method_origin(self), owner)
1414
end
1515
alias_method :to_s, :inspect
1616

0 commit comments

Comments
 (0)