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
42 42
VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj);
43 43
void rb_free_const_table(struct rb_id_table *tbl);
44 44
VALUE rb_const_source_location(VALUE, ID);
45
VALUE rb_const_source_location_of(VALUE);
45 46

  
46 47
MJIT_SYMBOL_EXPORT_BEGIN
47 48
int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag);
internal/class.h
14 14
#include "internal/serial.h"    /* for rb_serial_t */
15 15
#include "ruby/internal/stdbool.h"     /* for bool */
16 16
#include "ruby/intern.h"        /* for rb_alloc_func_t */
17
#include "constant.h"      /* for rb_const_entry_t */
17 18
#include "ruby/ruby.h"          /* for struct RBasic */
18 19

  
19 20
#ifdef RCLASS_SUPER
......
42 43
    struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
43 44
    struct rb_subclass_entry *subclasses;
44 45
    struct rb_subclass_entry **parent_subclasses;
46

  
47
    rb_const_entry_t *location;
48

  
45 49
    /**
46 50
     * In the case that this is an `ICLASS`, `module_subclasses` points to the link
47 51
     * in the module's `subclasses` list that indicates that the klass has been
object.c
2788 2788
    const char *pbeg, *p, *path, *pend;
2789 2789
    ID id;
2790 2790

  
2791
    rb_check_arity(argc, 1, 2);
2791
    rb_check_arity(argc, 0, 2);
2792

  
2793
    if (argc == 0) {
2794
        rb_const_entry_t *ce = RCLASS_EXT(mod)->location;
2795
        if (ce) {
2796
            return rb_assoc_new(ce->file, INT2NUM(ce->line));
2797
        }
2798
        else {
2799
            return Qnil;
2800
        }
2801
    }
2802

  
2792 2803
    name = argv[0];
2793 2804
    recur = (argc == 1) ? Qtrue : argv[1];
2794 2805

  
test/ruby/test_module.rb
2869 2869
  end
2870 2870

  
2871 2871
  ConstLocation = [__FILE__, __LINE__]
2872
  class ConstLocationClass; end
2873
  module ConstLocationModule; end
2872 2874

  
2873 2875
  def test_const_source_location
2874 2876
    assert_equal(ConstLocation, self.class.const_source_location(:ConstLocation))
......
2883 2885
    assert_raise_with_message(TypeError, %r'does not refer to class/module') {
2884 2886
      self.class.const_source_location("ConstLocation::FILE")
2885 2887
    }
2888
    assert_equal(self.class.const_source_location(:ConstLocationClass), ConstLocationClass.const_source_location)
2889
    assert_equal(self.class.const_source_location(:ConstLocationModule), ConstLocationModule.const_source_location)
2886 2890
  end
2887 2891

  
2888 2892
  module CloneTestM_simple
variable.c
2998 2998
void
2999 2999
rb_const_set(VALUE klass, ID id, VALUE val)
3000 3000
{
3001
    rb_const_entry_t *ce;
3002

  
3003 3001
    if (NIL_P(klass)) {
3004 3002
	rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
3005 3003
		 QUOTE_ID(id));
......
3015 3013
    {
3016 3014
        struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
3017 3015
        if (!tbl) {
3018
            RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
3019
            rb_clear_constant_cache();
3020
            ce = ZALLOC(rb_const_entry_t);
3021
            rb_id_table_insert(tbl, id, (VALUE)ce);
3022
            setup_const_entry(ce, klass, val, CONST_PUBLIC);
3023
        }
3024
        else {
3025
            struct autoload_const ac = {
3026
                .mod = klass, .id = id,
3027
                .value = val, .flag = CONST_PUBLIC,
3028
                /* fill the rest with 0 */
3029
            };
3030
            const_tbl_update(&ac);
3016
            RCLASS_CONST_TBL(klass) = rb_id_table_create(0);
3031 3017
        }
3018
        struct autoload_const ac = {
3019
            .mod = klass, .id = id,
3020
            .value = val, .flag = CONST_PUBLIC,
3021
            /* fill the rest with 0 */
3022
        };
3023
        const_tbl_update(&ac);
3032 3024
    }
3033 3025
    RB_VM_LOCK_LEAVE();
3034 3026

  
......
3129 3121

  
3130 3122
	ce = ZALLOC(rb_const_entry_t);
3131 3123
	rb_id_table_insert(tbl, id, (VALUE)ce);
3124
	if (RB_TYPE_P(val, T_MODULE) || RB_TYPE_P(val, T_CLASS)) {
3125
            RCLASS_EXT(val)->location = ce;
3126
        }
3132 3127
	setup_const_entry(ce, klass, val, visibility);
3133 3128
    }
3134 3129
}