|
77 | 77 | import org.truffleruby.language.arguments.ReadPreArgumentNode;
|
78 | 78 | import org.truffleruby.language.arguments.ReadSelfNode;
|
79 | 79 | import org.truffleruby.language.arguments.RubyArguments;
|
| 80 | +import org.truffleruby.language.backtrace.BacktraceFormatter; |
80 | 81 | import org.truffleruby.language.constants.GetConstantNode;
|
81 | 82 | import org.truffleruby.language.constants.LookupConstantInterface;
|
82 | 83 | import org.truffleruby.language.constants.LookupConstantNode;
|
@@ -1072,6 +1073,62 @@ protected Object constMissing(RubyModule module, String name) {
|
1072 | 1073 |
|
1073 | 1074 | }
|
1074 | 1075 |
|
| 1076 | + @CoreMethod(names = "const_source_location", required = 1, optional = 1) |
| 1077 | + @NodeChild(value = "module", type = RubyNode.class) |
| 1078 | + @NodeChild(value = "name", type = RubyNode.class) |
| 1079 | + @NodeChild(value = "inherit", type = RubyNode.class) |
| 1080 | + public abstract static class ConstSourceLocationNode extends CoreMethodNode { |
| 1081 | + |
| 1082 | + @Child private MakeStringNode makeStringNode = MakeStringNode.create(); |
| 1083 | + |
| 1084 | + @CreateCast("name") |
| 1085 | + protected RubyNode coerceToStringOrSymbol(RubyNode name) { |
| 1086 | + return ToStringOrSymbolNodeGen.create(name); |
| 1087 | + } |
| 1088 | + |
| 1089 | + @CreateCast("inherit") |
| 1090 | + protected RubyNode coerceToBoolean(RubyNode inherit) { |
| 1091 | + return BooleanCastWithDefaultNodeGen.create(true, inherit); |
| 1092 | + } |
| 1093 | + |
| 1094 | + @Specialization(guards = { "strings.isRubyString(name)" }) |
| 1095 | + @TruffleBoundary |
| 1096 | + protected Object constSourceLocation(RubyModule module, Object name, boolean inherit, |
| 1097 | + @CachedLibrary(limit = "2") RubyStringLibrary strings) { |
| 1098 | + final ConstantLookupResult lookupResult = ModuleOperations |
| 1099 | + .lookupScopedConstant(getContext(), module, strings.getJavaString(name), inherit, this, true); |
| 1100 | + |
| 1101 | + return getLocation(lookupResult); |
| 1102 | + } |
| 1103 | + |
| 1104 | + @Specialization |
| 1105 | + @TruffleBoundary |
| 1106 | + protected Object constSourceLocation(RubyModule module, RubySymbol name, boolean inherit) { |
| 1107 | + final ConstantLookupResult lookupResult = ModuleOperations |
| 1108 | + .lookupConstantWithInherit(getContext(), module, name.getString(), inherit, this, true); |
| 1109 | + |
| 1110 | + return getLocation(lookupResult); |
| 1111 | + } |
| 1112 | + |
| 1113 | + private Object getLocation(ConstantLookupResult lookupResult) { |
| 1114 | + if (!lookupResult.isFound()) { |
| 1115 | + return nil; |
| 1116 | + } |
| 1117 | + |
| 1118 | + final SourceSection sourceSection = lookupResult.getConstant().getSourceSection(); |
| 1119 | + if (!BacktraceFormatter.isAvailable(sourceSection)) { |
| 1120 | + return createEmptyArray(); |
| 1121 | + } else { |
| 1122 | + final RubyString file = makeStringNode.executeMake( |
| 1123 | + getContext().getSourcePath(sourceSection.getSource()), |
| 1124 | + UTF8Encoding.INSTANCE, |
| 1125 | + CodeRange.CR_UNKNOWN); |
| 1126 | + return createArray(new Object[]{ file, sourceSection.getStartLine() }); |
| 1127 | + } |
| 1128 | + } |
| 1129 | + |
| 1130 | + } |
| 1131 | + |
1075 | 1132 | @CoreMethod(names = "const_set", required = 2)
|
1076 | 1133 | @NodeChild(value = "module", type = RubyNode.class)
|
1077 | 1134 | @NodeChild(value = "name", type = RubyNode.class)
|
|
0 commit comments