Project

General

Profile

Feature #17749 » 0001-Add-constant-location-information-to-classes.patch

tenderlovemaking (Aaron Patterson), 03/25/2021 11:29 PM

View differences:

constant.h
VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
void rb_free_const_table(struct rb_id_table *tbl);
VALUE rb_const_source_location(VALUE, ID);
VALUE rb_const_source_location_of(VALUE);
MJIT_SYMBOL_EXPORT_BEGIN
int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
internal/class.h
#include "internal/serial.h" /* for rb_serial_t */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/intern.h" /* for rb_alloc_func_t */
#include "constant.h" /* for rb_const_entry_t */
#include "ruby/ruby.h" /* for struct RBasic */
#ifdef RCLASS_SUPER
......
struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
struct rb_subclass_entry *subclasses;
struct rb_subclass_entry **parent_subclasses;
rb_const_entry_t *location;
/**
* In the case that this is an `ICLASS`, `module_subclasses` points to the link
* in the module's `subclasses` list that indicates that the klass has been
object.c
const char *pbeg, *p, *path, *pend;
ID id;
rb_check_arity(argc, 1, 2);
rb_check_arity(argc, 0, 2);
if (argc == 0) {
rb_const_entry_t *ce = RCLASS_EXT(mod)->location;
if (ce) {
return rb_assoc_new(ce->file, INT2NUM(ce->line));
}
else {
return Qnil;
}
}
name = argv[0];
recur = (argc == 1) ? Qtrue : argv[1];
test/ruby/test_module.rb
end
ConstLocation = [__FILE__, __LINE__]
class ConstLocationClass; end
module ConstLocationModule; end
def test_const_source_location
assert_equal(ConstLocation, self.class.const_source_location(:ConstLocation))
......
assert_raise_with_message(TypeError, %r'does not refer to class/module') {
self.class.const_source_location("ConstLocation::FILE")
}
assert_equal(self.class.const_source_location(:ConstLocationClass), ConstLocationClass.const_source_location)
assert_equal(self.class.const_source_location(:ConstLocationModule), ConstLocationModule.const_source_location)
end
module CloneTestM_simple
variable.c
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
QUOTE_ID(id));
......
{
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
if (!tbl) {
RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
rb_clear_constant_cache();
ce = ZALLOC(rb_const_entry_t);
rb_id_table_insert(tbl, id, (VALUE)ce);
setup_const_entry(ce, klass, val, CONST_PUBLIC);
}
else {
struct autoload_const ac = {
.mod = klass, .id = id,
.value = val, .flag = CONST_PUBLIC,
/* fill the rest with 0 */
};
const_tbl_update(&ac);
RCLASS_CONST_TBL(klass) = rb_id_table_create(0);
}
struct autoload_const ac = {
.mod = klass, .id = id,
.value = val, .flag = CONST_PUBLIC,
/* fill the rest with 0 */
};
const_tbl_update(&ac);
}
RB_VM_LOCK_LEAVE();
......
ce = ZALLOC(rb_const_entry_t);
rb_id_table_insert(tbl, id, (VALUE)ce);
if (RB_TYPE_P(val, T_MODULE) || RB_TYPE_P(val, T_CLASS)) {
RCLASS_EXT(val)->location = ce;
}
setup_const_entry(ce, klass, val, visibility);
}
}
(1-1/2)