looksee 3.0.0-universal-java-1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +66 -0
- data/LICENSE +22 -0
- data/README.markdown +175 -0
- data/Rakefile +13 -0
- data/ext/extconf.rb +19 -0
- data/ext/mri/1.9.2/debug.h +36 -0
- data/ext/mri/1.9.2/id.h +170 -0
- data/ext/mri/1.9.2/method.h +103 -0
- data/ext/mri/1.9.2/node.h +483 -0
- data/ext/mri/1.9.2/thread_pthread.h +27 -0
- data/ext/mri/1.9.2/vm_core.h +707 -0
- data/ext/mri/1.9.2/vm_opts.h +51 -0
- data/ext/mri/1.9.3/atomic.h +56 -0
- data/ext/mri/1.9.3/debug.h +41 -0
- data/ext/mri/1.9.3/id.h +175 -0
- data/ext/mri/1.9.3/internal.h +227 -0
- data/ext/mri/1.9.3/internal_falcon.h +248 -0
- data/ext/mri/1.9.3/method.h +105 -0
- data/ext/mri/1.9.3/node.h +503 -0
- data/ext/mri/1.9.3/thread_pthread.h +51 -0
- data/ext/mri/1.9.3/vm_core.h +755 -0
- data/ext/mri/1.9.3/vm_opts.h +51 -0
- data/ext/mri/2.0.0/internal.h +378 -0
- data/ext/mri/2.0.0/method.h +138 -0
- data/ext/mri/2.1.0/internal.h +889 -0
- data/ext/mri/2.1.0/method.h +142 -0
- data/ext/mri/2.2.0/internal.h +1182 -0
- data/ext/mri/2.2.0/method.h +141 -0
- data/ext/mri/env-1.8.h +27 -0
- data/ext/mri/eval_c-1.8.h +27 -0
- data/ext/mri/mri.c +309 -0
- data/ext/mri/node-1.9.h +35 -0
- data/ext/rbx/rbx.c +13 -0
- data/lib/looksee.rb +2 -0
- data/lib/looksee/JRuby.jar +0 -0
- data/lib/looksee/adapter.rb +8 -0
- data/lib/looksee/adapter/base.rb +105 -0
- data/lib/looksee/adapter/rubinius.rb +84 -0
- data/lib/looksee/clean.rb +169 -0
- data/lib/looksee/columnizer.rb +73 -0
- data/lib/looksee/core_ext.rb +48 -0
- data/lib/looksee/editor.rb +64 -0
- data/lib/looksee/help.rb +54 -0
- data/lib/looksee/inspector.rb +70 -0
- data/lib/looksee/lookup_path.rb +95 -0
- data/lib/looksee/rbx.bundle +0 -0
- data/lib/looksee/version.rb +11 -0
- data/spec/looksee/adapter_spec.rb +588 -0
- data/spec/looksee/clean_spec.rb +41 -0
- data/spec/looksee/columnizer_spec.rb +52 -0
- data/spec/looksee/core_ext_spec.rb +17 -0
- data/spec/looksee/editor_spec.rb +107 -0
- data/spec/looksee/inspector_spec.rb +179 -0
- data/spec/looksee/lookup_path_spec.rb +87 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/core_ext.rb +25 -0
- data/spec/support/temporary_classes.rb +78 -0
- data/spec/support/test_adapter.rb +83 -0
- metadata +116 -0
@@ -0,0 +1,141 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
|
3
|
+
method.h -
|
4
|
+
|
5
|
+
$Author: normal $
|
6
|
+
created at: Wed Jul 15 20:02:33 2009
|
7
|
+
|
8
|
+
Copyright (C) 2009 Koichi Sasada
|
9
|
+
|
10
|
+
**********************************************************************/
|
11
|
+
#ifndef METHOD_H
|
12
|
+
#define METHOD_H
|
13
|
+
|
14
|
+
#include "internal.h"
|
15
|
+
|
16
|
+
#ifndef END_OF_ENUMERATION
|
17
|
+
# if defined(__GNUC__) &&! defined(__STRICT_ANSI__)
|
18
|
+
# define END_OF_ENUMERATION(key)
|
19
|
+
# else
|
20
|
+
# define END_OF_ENUMERATION(key) END_OF_##key##_PLACEHOLDER = 0
|
21
|
+
# endif
|
22
|
+
#endif
|
23
|
+
|
24
|
+
typedef enum {
|
25
|
+
NOEX_PUBLIC = 0x00,
|
26
|
+
NOEX_NOSUPER = 0x01,
|
27
|
+
NOEX_PRIVATE = 0x02,
|
28
|
+
NOEX_PROTECTED = 0x04,
|
29
|
+
NOEX_MASK = 0x06,
|
30
|
+
NOEX_BASIC = 0x08,
|
31
|
+
NOEX_UNDEF = NOEX_NOSUPER,
|
32
|
+
NOEX_MODFUNC = 0x12,
|
33
|
+
NOEX_SUPER = 0x20,
|
34
|
+
NOEX_VCALL = 0x40,
|
35
|
+
NOEX_RESPONDS = 0x80,
|
36
|
+
|
37
|
+
NOEX_BIT_WIDTH = 8,
|
38
|
+
NOEX_SAFE_SHIFT_OFFSET = ((NOEX_BIT_WIDTH+3)/4)*4 /* round up to nibble */
|
39
|
+
} rb_method_flag_t;
|
40
|
+
|
41
|
+
#define NOEX_SAFE(n) ((int)((n) >> NOEX_SAFE_SHIFT_OFFSET) & 0x0F)
|
42
|
+
#define NOEX_WITH(n, s) (((s) << NOEX_SAFE_SHIFT_OFFSET) | (n) | (ruby_running ? 0 : NOEX_BASIC))
|
43
|
+
#define NOEX_WITH_SAFE(n) NOEX_WITH((n), rb_safe_level())
|
44
|
+
|
45
|
+
/* method data type */
|
46
|
+
|
47
|
+
typedef enum {
|
48
|
+
VM_METHOD_TYPE_ISEQ,
|
49
|
+
VM_METHOD_TYPE_CFUNC,
|
50
|
+
VM_METHOD_TYPE_ATTRSET,
|
51
|
+
VM_METHOD_TYPE_IVAR,
|
52
|
+
VM_METHOD_TYPE_BMETHOD,
|
53
|
+
VM_METHOD_TYPE_ZSUPER,
|
54
|
+
VM_METHOD_TYPE_UNDEF,
|
55
|
+
VM_METHOD_TYPE_NOTIMPLEMENTED,
|
56
|
+
VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
|
57
|
+
VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */
|
58
|
+
VM_METHOD_TYPE_REFINED,
|
59
|
+
|
60
|
+
END_OF_ENUMERATION(VM_METHOD_TYPE)
|
61
|
+
} rb_method_type_t;
|
62
|
+
|
63
|
+
struct rb_call_info_struct;
|
64
|
+
|
65
|
+
typedef struct rb_method_cfunc_struct {
|
66
|
+
VALUE (*func)(ANYARGS);
|
67
|
+
VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv);
|
68
|
+
int argc;
|
69
|
+
} rb_method_cfunc_t;
|
70
|
+
|
71
|
+
typedef struct rb_method_attr_struct {
|
72
|
+
ID id;
|
73
|
+
const VALUE location;
|
74
|
+
} rb_method_attr_t;
|
75
|
+
|
76
|
+
typedef struct rb_iseq_struct rb_iseq_t;
|
77
|
+
|
78
|
+
typedef struct rb_method_definition_struct {
|
79
|
+
rb_method_type_t type; /* method type */
|
80
|
+
int alias_count;
|
81
|
+
ID original_id;
|
82
|
+
union {
|
83
|
+
rb_iseq_t * const iseq; /* should be mark */
|
84
|
+
rb_method_cfunc_t cfunc;
|
85
|
+
rb_method_attr_t attr;
|
86
|
+
const VALUE proc; /* should be mark */
|
87
|
+
enum method_optimized_type {
|
88
|
+
OPTIMIZED_METHOD_TYPE_SEND,
|
89
|
+
OPTIMIZED_METHOD_TYPE_CALL,
|
90
|
+
|
91
|
+
OPTIMIZED_METHOD_TYPE__MAX
|
92
|
+
} optimize_type;
|
93
|
+
struct rb_method_entry_struct *orig_me;
|
94
|
+
} body;
|
95
|
+
} rb_method_definition_t;
|
96
|
+
|
97
|
+
typedef struct rb_method_entry_struct {
|
98
|
+
rb_method_flag_t flag;
|
99
|
+
char mark;
|
100
|
+
rb_method_definition_t *def;
|
101
|
+
ID called_id;
|
102
|
+
VALUE klass; /* should be mark */
|
103
|
+
} rb_method_entry_t;
|
104
|
+
|
105
|
+
struct unlinked_method_entry_list_entry {
|
106
|
+
struct unlinked_method_entry_list_entry *next;
|
107
|
+
rb_method_entry_t *me;
|
108
|
+
};
|
109
|
+
|
110
|
+
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
|
111
|
+
|
112
|
+
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex);
|
113
|
+
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
|
114
|
+
rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
|
115
|
+
rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
|
116
|
+
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
|
117
|
+
rb_method_entry_t *rb_resolve_refined_method(VALUE refinements,
|
118
|
+
const rb_method_entry_t *me,
|
119
|
+
VALUE *defined_class_ptr);
|
120
|
+
rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id,
|
121
|
+
VALUE *defined_class_ptr);
|
122
|
+
rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id,
|
123
|
+
VALUE *defined_class_ptr);
|
124
|
+
|
125
|
+
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr);
|
126
|
+
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex);
|
127
|
+
|
128
|
+
int rb_method_entry_arity(const rb_method_entry_t *me);
|
129
|
+
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
|
130
|
+
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
|
131
|
+
|
132
|
+
VALUE rb_method_entry_location(rb_method_entry_t *me);
|
133
|
+
VALUE rb_mod_method_location(VALUE mod, ID id);
|
134
|
+
VALUE rb_obj_method_location(VALUE obj, ID id);
|
135
|
+
|
136
|
+
void rb_mark_method_entry(const rb_method_entry_t *me);
|
137
|
+
void rb_free_method_entry(rb_method_entry_t *me);
|
138
|
+
void rb_sweep_method_entry(void *vm);
|
139
|
+
void rb_free_m_tbl_wrapper(struct method_table_wrapper *wrapper);
|
140
|
+
|
141
|
+
#endif /* METHOD_H */
|
data/ext/mri/env-1.8.h
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
struct FRAME {
|
2
|
+
VALUE self;
|
3
|
+
int argc;
|
4
|
+
ID last_func;
|
5
|
+
ID orig_func;
|
6
|
+
VALUE last_class;
|
7
|
+
struct FRAME *prev;
|
8
|
+
struct FRAME *tmp;
|
9
|
+
struct RNode *node;
|
10
|
+
int iter;
|
11
|
+
int flags;
|
12
|
+
unsigned long uniq;
|
13
|
+
};
|
14
|
+
|
15
|
+
struct SCOPE {
|
16
|
+
struct RBasic super;
|
17
|
+
ID *local_tbl;
|
18
|
+
VALUE *local_vars;
|
19
|
+
int flags;
|
20
|
+
};
|
21
|
+
|
22
|
+
struct RVarmap {
|
23
|
+
struct RBasic super;
|
24
|
+
ID id;
|
25
|
+
VALUE val;
|
26
|
+
struct RVarmap *next;
|
27
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
struct BLOCK {
|
2
|
+
NODE *var;
|
3
|
+
NODE *body;
|
4
|
+
VALUE self;
|
5
|
+
struct FRAME frame;
|
6
|
+
struct SCOPE *scope;
|
7
|
+
VALUE klass;
|
8
|
+
NODE *cref;
|
9
|
+
int iter;
|
10
|
+
int vmode;
|
11
|
+
int flags;
|
12
|
+
int uniq;
|
13
|
+
struct RVarmap *dyna_vars;
|
14
|
+
VALUE orig_thread;
|
15
|
+
VALUE wrapper;
|
16
|
+
VALUE block_obj;
|
17
|
+
struct BLOCK *outer;
|
18
|
+
struct BLOCK *prev;
|
19
|
+
};
|
20
|
+
|
21
|
+
struct METHOD {
|
22
|
+
VALUE klass, rklass;
|
23
|
+
VALUE recv;
|
24
|
+
ID id, oid;
|
25
|
+
int safe_level;
|
26
|
+
NODE *body;
|
27
|
+
};
|
data/ext/mri/mri.c
ADDED
@@ -0,0 +1,309 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#if RUBY_VERSION >= 200
|
4
|
+
# include "method.h"
|
5
|
+
# include "internal.h"
|
6
|
+
#elif RUBY_VERSION >= 193
|
7
|
+
# include "ruby/st.h"
|
8
|
+
# ifdef SA_EMPTY
|
9
|
+
# include "internal_falcon.h"
|
10
|
+
# define Looksee_method_table_foreach sa_foreach
|
11
|
+
# define Looksee_method_table_lookup sa_lookup
|
12
|
+
# else
|
13
|
+
# include "internal.h"
|
14
|
+
# endif
|
15
|
+
# include "vm_core.h"
|
16
|
+
# include "method.h"
|
17
|
+
#elif RUBY_VERSION >= 192
|
18
|
+
# include "vm_core.h"
|
19
|
+
# include "method.h"
|
20
|
+
# include "ruby/st.h"
|
21
|
+
#elif RUBY_VERSION >= 190
|
22
|
+
# include "node-1.9.h"
|
23
|
+
# include "ruby/st.h"
|
24
|
+
#else
|
25
|
+
# include "node.h"
|
26
|
+
# include "st.h"
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#ifndef Looksee_method_table_foreach
|
30
|
+
# define Looksee_method_table_foreach st_foreach
|
31
|
+
# define Looksee_method_table_lookup st_lookup
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#if RUBY_VERSION < 187
|
35
|
+
# define RCLASS_IV_TBL(c) (RCLASS(c)->iv_tbl)
|
36
|
+
# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
|
37
|
+
# define RCLASS_SUPER(c) (RCLASS(c)->super)
|
38
|
+
#endif
|
39
|
+
|
40
|
+
/*
|
41
|
+
* Return the internal superclass of this class.
|
42
|
+
*
|
43
|
+
* This is either a Class or "IClass." IClasses represent Modules
|
44
|
+
* included in the ancestry, and should be treated as opaque objects
|
45
|
+
* in ruby space. Convert the IClass to a Module using #iclass_to_module
|
46
|
+
* before using it in ruby.
|
47
|
+
*/
|
48
|
+
VALUE Looksee_internal_superclass(VALUE self, VALUE internal_class) {
|
49
|
+
VALUE super = RCLASS_SUPER(internal_class);
|
50
|
+
if (!super)
|
51
|
+
return Qnil;
|
52
|
+
return super;
|
53
|
+
}
|
54
|
+
|
55
|
+
/*
|
56
|
+
* Return the internal class of the given object.
|
57
|
+
*
|
58
|
+
* This is either the object's singleton class, if it exists, or the
|
59
|
+
* object's birth class.
|
60
|
+
*/
|
61
|
+
VALUE Looksee_internal_class(VALUE self, VALUE object) {
|
62
|
+
return CLASS_OF(object);
|
63
|
+
}
|
64
|
+
|
65
|
+
#if RUBY_VERSION >= 192
|
66
|
+
|
67
|
+
# define VISIBILITY_TYPE rb_method_flag_t
|
68
|
+
|
69
|
+
typedef struct add_method_if_matching_arg {
|
70
|
+
VALUE names;
|
71
|
+
VISIBILITY_TYPE visibility;
|
72
|
+
} add_method_if_matching_arg_t;
|
73
|
+
|
74
|
+
static int add_method_if_matching(ID method_name, rb_method_entry_t *me, add_method_if_matching_arg_t *arg) {
|
75
|
+
# ifdef ID_ALLOCATOR
|
76
|
+
if (method_name == ID_ALLOCATOR)
|
77
|
+
return ST_CONTINUE;
|
78
|
+
# endif
|
79
|
+
|
80
|
+
if (UNDEFINED_METHOD_ENTRY_P(me))
|
81
|
+
return ST_CONTINUE;
|
82
|
+
|
83
|
+
if ((me->flag & NOEX_MASK) == arg->visibility)
|
84
|
+
rb_ary_push(arg->names, ID2SYM(method_name));
|
85
|
+
|
86
|
+
return ST_CONTINUE;
|
87
|
+
}
|
88
|
+
|
89
|
+
static int add_method_if_undefined(ID method_name, rb_method_entry_t *me, VALUE *names) {
|
90
|
+
# ifdef ID_ALLOCATOR
|
91
|
+
/* The allocator can be undefined with rb_undef_alloc_func, e.g. Struct. */
|
92
|
+
if (method_name == ID_ALLOCATOR)
|
93
|
+
return ST_CONTINUE;
|
94
|
+
# endif
|
95
|
+
|
96
|
+
if (UNDEFINED_METHOD_ENTRY_P(me))
|
97
|
+
rb_ary_push(*names, ID2SYM(method_name));
|
98
|
+
return ST_CONTINUE;
|
99
|
+
}
|
100
|
+
|
101
|
+
#else
|
102
|
+
|
103
|
+
# if RUBY_VERSION >= 190
|
104
|
+
# define VISIBILITY(node) ((node)->nd_body->nd_noex & NOEX_MASK)
|
105
|
+
# else
|
106
|
+
# define VISIBILITY(node) ((node)->nd_noex & NOEX_MASK)
|
107
|
+
# endif
|
108
|
+
|
109
|
+
# define VISIBILITY_TYPE unsigned long
|
110
|
+
|
111
|
+
typedef struct add_method_if_matching_arg {
|
112
|
+
VALUE names;
|
113
|
+
VISIBILITY_TYPE visibility;
|
114
|
+
} add_method_if_matching_arg_t;
|
115
|
+
|
116
|
+
static int add_method_if_matching(ID method_name, NODE *body, add_method_if_matching_arg_t *arg) {
|
117
|
+
# ifdef ID_ALLOCATOR
|
118
|
+
/* This entry is for the internal allocator function. */
|
119
|
+
if (method_name == ID_ALLOCATOR)
|
120
|
+
return ST_CONTINUE;
|
121
|
+
# endif
|
122
|
+
|
123
|
+
/* Module#undef_method:
|
124
|
+
* * sets body->nd_body to NULL in ruby <= 1.8
|
125
|
+
* * sets body to NULL in ruby >= 1.9
|
126
|
+
*/
|
127
|
+
if (!body || !body->nd_body)
|
128
|
+
return ST_CONTINUE;
|
129
|
+
|
130
|
+
if (VISIBILITY(body) == arg->visibility)
|
131
|
+
rb_ary_push(arg->names, ID2SYM(method_name));
|
132
|
+
return ST_CONTINUE;
|
133
|
+
}
|
134
|
+
|
135
|
+
static int add_method_if_undefined(ID method_name, NODE *body, VALUE *names) {
|
136
|
+
# ifdef ID_ALLOCATOR
|
137
|
+
/* The allocator can be undefined with rb_undef_alloc_func, e.g. Struct. */
|
138
|
+
if (method_name == ID_ALLOCATOR)
|
139
|
+
return ST_CONTINUE;
|
140
|
+
# endif
|
141
|
+
|
142
|
+
if (!body || !body->nd_body)
|
143
|
+
rb_ary_push(*names, ID2SYM(method_name));
|
144
|
+
return ST_CONTINUE;
|
145
|
+
}
|
146
|
+
|
147
|
+
#endif
|
148
|
+
|
149
|
+
static VALUE internal_instance_methods(VALUE klass, VISIBILITY_TYPE visibility) {
|
150
|
+
add_method_if_matching_arg_t arg;
|
151
|
+
arg.names = rb_ary_new();
|
152
|
+
arg.visibility = visibility;
|
153
|
+
|
154
|
+
Looksee_method_table_foreach(RCLASS_M_TBL(klass), add_method_if_matching, (st_data_t)&arg);
|
155
|
+
return arg.names;
|
156
|
+
}
|
157
|
+
|
158
|
+
/*
|
159
|
+
* Return the list of public instance methods (as Symbols) of the
|
160
|
+
* given internal class.
|
161
|
+
*/
|
162
|
+
VALUE Looksee_internal_public_instance_methods(VALUE self, VALUE klass) {
|
163
|
+
return internal_instance_methods(klass, NOEX_PUBLIC);
|
164
|
+
}
|
165
|
+
|
166
|
+
/*
|
167
|
+
* Return the list of protected instance methods (as Symbols) of the
|
168
|
+
* given internal class.
|
169
|
+
*/
|
170
|
+
VALUE Looksee_internal_protected_instance_methods(VALUE self, VALUE klass) {
|
171
|
+
return internal_instance_methods(klass, NOEX_PROTECTED);
|
172
|
+
}
|
173
|
+
|
174
|
+
/*
|
175
|
+
* Return the list of private instance methods (as Symbols) of the
|
176
|
+
* given internal class.
|
177
|
+
*/
|
178
|
+
VALUE Looksee_internal_private_instance_methods(VALUE self, VALUE klass) {
|
179
|
+
return internal_instance_methods(klass, NOEX_PRIVATE);
|
180
|
+
}
|
181
|
+
|
182
|
+
/*
|
183
|
+
* Return the list of undefined instance methods (as Symbols) of the
|
184
|
+
* given internal class.
|
185
|
+
*/
|
186
|
+
VALUE Looksee_internal_undefined_instance_methods(VALUE self, VALUE klass) {
|
187
|
+
VALUE names = rb_ary_new();
|
188
|
+
Looksee_method_table_foreach(RCLASS_M_TBL(klass), add_method_if_undefined, (st_data_t)&names);
|
189
|
+
return names;
|
190
|
+
}
|
191
|
+
|
192
|
+
/*
|
193
|
+
* Return true if the given object is an included class or origin class, false
|
194
|
+
* otherwise.
|
195
|
+
*/
|
196
|
+
VALUE Looksee_included_class_p(VALUE self, VALUE object) {
|
197
|
+
return !SPECIAL_CONST_P(object) && BUILTIN_TYPE(object) == T_ICLASS ?
|
198
|
+
Qtrue : Qfalse;
|
199
|
+
}
|
200
|
+
|
201
|
+
VALUE Looksee_singleton_class_p(VALUE self, VALUE object) {
|
202
|
+
return BUILTIN_TYPE(object) == T_CLASS && FL_TEST(object, FL_SINGLETON) ? Qtrue : Qfalse;
|
203
|
+
}
|
204
|
+
|
205
|
+
VALUE Looksee_singleton_instance(VALUE self, VALUE singleton_class) {
|
206
|
+
if (BUILTIN_TYPE(singleton_class) == T_CLASS && FL_TEST(singleton_class, FL_SINGLETON)) {
|
207
|
+
VALUE object;
|
208
|
+
if (!Looksee_method_table_lookup(RCLASS_IV_TBL(singleton_class), rb_intern("__attached__"), (st_data_t *)&object))
|
209
|
+
rb_raise(rb_eRuntimeError, "[looksee bug] can't find singleton object");
|
210
|
+
return object;
|
211
|
+
} else {
|
212
|
+
rb_raise(rb_eTypeError, "expected singleton class, got %s", rb_obj_classname(singleton_class));
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
VALUE Looksee_real_module(VALUE self, VALUE module_or_included_class) {
|
217
|
+
if (BUILTIN_TYPE(module_or_included_class) == T_ICLASS)
|
218
|
+
return RBASIC(module_or_included_class)->klass;
|
219
|
+
else
|
220
|
+
return module_or_included_class;
|
221
|
+
}
|
222
|
+
|
223
|
+
VALUE Looksee_module_name(VALUE self, VALUE module) {
|
224
|
+
if (BUILTIN_TYPE(module) == T_CLASS || BUILTIN_TYPE(module) == T_MODULE) {
|
225
|
+
VALUE name = rb_mod_name(module);
|
226
|
+
return name == Qnil ? rb_str_new2("") : name;
|
227
|
+
} else if (BUILTIN_TYPE(module) == T_ICLASS) {
|
228
|
+
VALUE wrapped = RBASIC(module)->klass;
|
229
|
+
VALUE name = Looksee_module_name(self, wrapped);
|
230
|
+
if (BUILTIN_TYPE(wrapped) == T_CLASS)
|
231
|
+
name = rb_str_cat2(name, " (origin)");
|
232
|
+
return name;
|
233
|
+
} else {
|
234
|
+
rb_raise(rb_eTypeError, "expected module, got %s", rb_obj_classname(module));
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
#if RUBY_VERSION < 190
|
239
|
+
|
240
|
+
#include "env-1.8.h"
|
241
|
+
#include "eval_c-1.8.h"
|
242
|
+
|
243
|
+
/*
|
244
|
+
* Return the source file and line number of the given object and method.
|
245
|
+
*/
|
246
|
+
VALUE Looksee_source_location(VALUE self, VALUE unbound_method) {
|
247
|
+
if (!rb_obj_is_kind_of(unbound_method, rb_cUnboundMethod))
|
248
|
+
rb_raise(rb_eTypeError, "expected UnboundMethod, got %s", rb_obj_classname(unbound_method));
|
249
|
+
|
250
|
+
struct METHOD *method;
|
251
|
+
Data_Get_Struct(unbound_method, struct METHOD, method);
|
252
|
+
|
253
|
+
NODE *node;
|
254
|
+
switch (nd_type(method->body)) {
|
255
|
+
// Can't be a FBODY or ZSUPER.
|
256
|
+
case NODE_SCOPE:
|
257
|
+
node = method->body->nd_defn;
|
258
|
+
break;
|
259
|
+
case NODE_BMETHOD:
|
260
|
+
{
|
261
|
+
struct BLOCK *block;
|
262
|
+
Data_Get_Struct(method->body->nd_orig, struct BLOCK, block);
|
263
|
+
(node = block->frame.node) || (node = block->body);
|
264
|
+
// Proc#to_s suggests this may be NULL sometimes.
|
265
|
+
if (!node)
|
266
|
+
return Qnil;
|
267
|
+
}
|
268
|
+
break;
|
269
|
+
case NODE_DMETHOD:
|
270
|
+
{
|
271
|
+
struct METHOD *original_method;
|
272
|
+
NODE *body = method->body;
|
273
|
+
Data_Get_Struct(body->nd_orig, struct METHOD, original_method);
|
274
|
+
node = original_method->body->nd_defn;
|
275
|
+
}
|
276
|
+
break;
|
277
|
+
default:
|
278
|
+
return Qnil;
|
279
|
+
}
|
280
|
+
VALUE file = rb_str_new2(node->nd_file);
|
281
|
+
VALUE line = INT2NUM(nd_line(node));
|
282
|
+
VALUE location = rb_ary_new2(2);
|
283
|
+
rb_ary_store(location, 0, file);
|
284
|
+
rb_ary_store(location, 1, line);
|
285
|
+
return location;
|
286
|
+
}
|
287
|
+
|
288
|
+
#endif
|
289
|
+
|
290
|
+
void Init_mri(void) {
|
291
|
+
VALUE mLooksee = rb_const_get(rb_cObject, rb_intern("Looksee"));
|
292
|
+
VALUE mAdapter = rb_const_get(mLooksee, rb_intern("Adapter"));
|
293
|
+
VALUE mBase = rb_const_get(mAdapter, rb_intern("Base"));
|
294
|
+
VALUE mMRI = rb_define_class_under(mAdapter, "MRI", mBase);
|
295
|
+
rb_define_method(mMRI, "internal_superclass", Looksee_internal_superclass, 1);
|
296
|
+
rb_define_method(mMRI, "internal_class", Looksee_internal_class, 1);
|
297
|
+
rb_define_method(mMRI, "internal_public_instance_methods", Looksee_internal_public_instance_methods, 1);
|
298
|
+
rb_define_method(mMRI, "internal_protected_instance_methods", Looksee_internal_protected_instance_methods, 1);
|
299
|
+
rb_define_method(mMRI, "internal_private_instance_methods", Looksee_internal_private_instance_methods, 1);
|
300
|
+
rb_define_method(mMRI, "internal_undefined_instance_methods", Looksee_internal_undefined_instance_methods, 1);
|
301
|
+
rb_define_method(mMRI, "included_class?", Looksee_included_class_p, 1);
|
302
|
+
rb_define_method(mMRI, "singleton_class?", Looksee_singleton_class_p, 1);
|
303
|
+
rb_define_method(mMRI, "singleton_instance", Looksee_singleton_instance, 1);
|
304
|
+
rb_define_method(mMRI, "real_module", Looksee_real_module, 1);
|
305
|
+
rb_define_method(mMRI, "module_name", Looksee_module_name, 1);
|
306
|
+
#if RUBY_VERSION < 190
|
307
|
+
rb_define_method(mMRI, "source_location", Looksee_source_location, 1);
|
308
|
+
#endif
|
309
|
+
}
|