Project

General

Profile

Feature #21543 ยป poc.patch

mame (Yusuke Endoh), 08/22/2025 03:18 AM

View differences:

compile.c
rb_id2str(mid),
ISEQ_TYPE_METHOD, line);
#ifdef USE_ISEQ_NODE_ID
// Store the DefNode's node_id in the method iseq location
ISEQ_BODY(method_iseq)->location.node_id = nd_node_id(node);
#endif
debugp_param("defn/iseq", rb_iseqw_new(method_iseq));
ADD_INSN2(ret, node, definemethod, ID2SYM(mid), method_iseq);
RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)method_iseq);
......
rb_id2str(mid),
ISEQ_TYPE_METHOD, line);
#ifdef USE_ISEQ_NODE_ID
// Store the DefNode's node_id in the singleton method iseq location
ISEQ_BODY(singleton_method_iseq)->location.node_id = nd_node_id(node);
#endif
debugp_param("defs/iseq", rb_iseqw_new(singleton_method_iseq));
CHECK(COMPILE(ret, "defs: recv", RNODE_DEFS(node)->nd_recv));
ADD_INSN2(ret, node, definesmethod, ID2SYM(mid), singleton_method_iseq);
lib/error_highlight/base.rb
when :OP_CDECL
spot_op_cdecl
when :DEFN
raise NotImplementedError if @point_type != :name
spot_defn
when :DEFS
raise NotImplementedError if @point_type != :name
spot_defs
when :call_node
case @point_type
when :name
......
when :constant_path_operator_write_node
prism_spot_constant_path_operator_write
when :def_node
case @point_type
when :name
prism_spot_def_for_name
when :args
raise NotImplementedError
end
end
if @snippet && @beg_column && @end_column && @beg_column < @end_column
......
end
end
# Example:
# def bar; end
# ^^^
def spot_defn
mid, = @node.children
fetch_line(@node.first_lineno)
if @snippet.match(/\Gdef\s+(#{ Regexp.quote(mid) }\b)/, @node.first_column)
@beg_column = $~.begin(1)
@end_column = $~.end(1)
end
end
# Example:
# def Foo.bar; end
# ^^^^
def spot_defs
nd_recv, mid, = @node.children
fetch_line(nd_recv.last_lineno)
if @snippet.match(/\G\s*(\.\s*#{ Regexp.quote(mid) }\b)/, nd_recv.last_column)
@beg_column = $~.begin(1)
@end_column = $~.end(1)
end
end
def fetch_line(lineno)
@beg_lineno = @end_lineno = lineno
@snippet = @fetch[lineno]
......
prism_location(@node.binary_operator_loc.chop)
end
end
def prism_spot_def_for_name
location = @node.name_loc
location = location.join(@node.operator_loc) if @node.operator_loc
prism_location(location)
end
end
private_constant :Spotter
lib/error_highlight/core_ext.rb
module ErrorHighlight
module CoreExt
private def generate_snippet
spot = ErrorHighlight.spot(self)
return "" unless spot
return ErrorHighlight.formatter.message_for(spot)
if ArgumentError === self && message =~ /\Awrong number of arguments/
locs = self.backtrace_locations
return "" if locs.size < 2
callee_loc, caller_loc = locs
callee_spot = ErrorHighlight.spot(self, backtrace_location: callee_loc, point_type: :name)
return "" unless callee_spot
caller_spot = ErrorHighlight.spot(self, backtrace_location: caller_loc, point_type: :name)
return "" unless caller_spot
"\n\n" + [["caller", caller_loc, caller_spot], ["callee", callee_loc, callee_spot]].map do |msg, loc, spot|
_, _, snippet, highlight = ErrorHighlight.formatter.message_for(spot).lines
" #{ loc.path }:#{ loc.lineno }: #{ msg }\n | #{ snippet } #{ highlight }"
end.join("\n")
else
spot = ErrorHighlight.spot(self)
return "" unless spot
return ErrorHighlight.formatter.message_for(spot)
end
end
if Exception.method_defined?(:detailed_message)
prism_compile.c
rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, location.line);
pm_scope_node_destroy(&next_scope_node);
#ifdef USE_ISEQ_NODE_ID
// Store the DefNode's node_id in the method iseq location for Prism
ISEQ_BODY(method_iseq)->location.node_id = (int)location.node_id;
#endif
if (cast->receiver) {
PM_COMPILE_NOT_POPPED(cast->receiver);
PUSH_INSN2(ret, location, definesmethod, ID2SYM(method_name), method_iseq);
vm_backtrace.c
}
if (lineno) *lineno = ISEQ_BODY(iseq)->location.first_lineno;
#ifdef USE_ISEQ_NODE_ID
if (node_id) *node_id = -1;
if (node_id) {
// Use the node_id stored in the iseq location
*node_id = ISEQ_BODY(iseq)->location.node_id;
}
#endif
return 1;
}
......
static int
location_node_id(rb_backtrace_location_t *loc)
{
if (loc->iseq && loc->pc) {
if (loc->iseq) {
return calc_node_id(loc->iseq, loc->pc);
}
return -1;
    (1-1/1)