Feature #17749 » 0001-Add-constant-location-information-to-classes.patch
| 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);
|
||
|
name = argv[0];
|
||
|
recur = (argc == 1) ? Qtrue : argv[1];
|
||
| ... | ... | |
|
UNREACHABLE_RETURN(Qundef);
|
||
|
}
|
||
|
static VALUE
|
||
|
rb_mod_source_location(VALUE mod)
|
||
|
{
|
||
|
rb_const_entry_t *ce = RCLASS_EXT(mod)->location;
|
||
|
if (ce) {
|
||
|
return rb_assoc_new(ce->file, INT2NUM(ce->line));
|
||
|
}
|
||
|
else {
|
||
|
return Qnil;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* call-seq:
|
||
|
* obj.instance_variable_get(symbol) -> obj
|
||
| ... | ... | |
|
rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
|
||
|
rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
|
||
|
rb_define_method(rb_cModule, "const_source_location", rb_mod_const_source_location, -1);
|
||
|
rb_define_method(rb_cModule, "source_location", rb_mod_source_location, 0);
|
||
|
rb_define_private_method(rb_cModule, "remove_const",
|
||
|
rb_mod_remove_const, 1); /* in variable.c */
|
||
|
rb_define_method(rb_cModule, "const_missing",
|
||
| 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))
|
||
| ... | ... | |
|
}
|
||
|
end
|
||
|
def test_source_location
|
||
|
assert_equal(self.class.const_source_location(:ConstLocationClass), ConstLocationClass.source_location)
|
||
|
assert_equal(self.class.const_source_location(:ConstLocationModule), ConstLocationModule.source_location)
|
||
|
end
|
||
|
module CloneTestM_simple
|
||
|
C = 1
|
||
|
def self.m; C; end
|
||
| 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);
|
||
|
}
|
||
|
}
|
||
- « Previous
- 1
- 2
- Next »