Feature #21543 ยป poc.patch
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;
|