GitHub

@@ -12,6 +12,7 @@

1212

#define MT_PUBLIC MRB_METHOD_PUBLIC_FL

1313

#define MT_PRIVATE MRB_METHOD_PRIVATE_FL

1414

#define MT_PROTECTED MRB_METHOD_PROTECTED_FL

15+

#define MT_NOPRIV (MT_PRIVATE|MT_PROTECTED)

15161617

static mrb_value

1718

mrb_f_nil(mrb_state *mrb, mrb_value cv)

@@ -128,43 +129,38 @@ mrb_local_variables(mrb_state *mrb, mrb_value self)

128129

return mrb_proc_local_variables(mrb, mrb->c->ci[-1].proc);

129130

}

130131131-

KHASH_DECLARE(st, mrb_sym, char, FALSE)

132-

KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal)

132+

KHASH_DECLARE(st, mrb_sym, char, TRUE)

133+

KHASH_DEFINE(st, mrb_sym, char, TRUE, kh_int_hash_func, kh_int_hash_equal)

133134134135

struct mt_set {

136+

unsigned int visibility;

135137

khash_t(st) *set;

136-

khash_t(st) *undef;

137138

};

138139140+

#define vicheck(flags, visi) (((visi)==MT_NOPRIV) ? (((flags)&0x3)!=MT_PRIVATE) : (((flags)&0x3)==(visi)))

141+139142

static int

140143

method_entry_i(mrb_state *mrb, mrb_sym mid, mrb_method_t m, void *p)

141144

{

142145

struct mt_set *s = (struct mt_set*)p;

143146144-

if (MRB_METHOD_UNDEF_P(m)) {

145-

if (s->undef) {

146-

kh_put(st, mrb, s->undef, mid);

147-

}

148-

}

149-

else if (s->undef == NULL ||

150-

kh_get(st, mrb, s->undef, mid) == kh_end(s->undef)) {

151-

kh_put(st, mrb, s->set, mid);

147+

if (vicheck(m.flags, s->visibility) && kh_get(st, mrb, s->set, mid) == kh_end(s->set)) {

148+

khint_t k = kh_put(st, mrb, s->set, mid);

149+

kh_val(s->set, k) = !MRB_METHOD_UNDEF_P(m);

152150

}

153151

return 0;

154152

}

155153156154

static void

157-

method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_t(st) *undef)

155+

method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, unsigned int visibility)

158156

{

159-

struct mt_set s;

157+

struct mt_set s = {visibility, set};

160158161-

s.set = set;

162-

s.undef = undef;

163159

mrb_mt_foreach(mrb, klass, method_entry_i, (void*)&s);

164160

}

165161166162

static mrb_value

167-

mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass)

163+

mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass, unsigned int flags)

168164

{

169165

mrb_value ary;

170166

khash_t(st) *set = kh_init(st, mrb);

@@ -173,24 +169,24 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *kl

173169

if (klass->flags & MRB_FL_CLASS_IS_PREPENDED) {

174170

MRB_CLASS_ORIGIN(klass);

175171

}

176-

method_entry_loop(mrb, klass, set, NULL);

172+

method_entry_loop(mrb, klass, set, flags);

177173

}

178174

else {

179-

khash_t(st) *undef = kh_init(st, mrb);

180175

struct RClass *oldklass = NULL;

181176182177

while (klass && (klass != oldklass)) {

183-

method_entry_loop(mrb, klass, set, undef);

178+

method_entry_loop(mrb, klass, set, flags);

184179

oldklass = klass;

185180

klass = klass->super;

186181

}

187-

kh_destroy(st, mrb, undef);

188182

}

189183190184

ary = mrb_ary_new_capa(mrb, kh_size(set));

191185

for (khint_t i=0; i<kh_end(set); i++) {

192186

if (kh_exist(set, i)) {

193-

mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));

187+

if (kh_val(set, i)) {

188+

mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));

189+

}

194190

}

195191

}

196192

kh_destroy(st, mrb, set);

@@ -199,18 +195,26 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *kl

199195

}

200196201197

static mrb_value

202-

mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, int flag)

198+

mrb_obj_methods(mrb_state *mrb, mrb_value obj, unsigned int flags)

203199

{

204-

return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj));

200+

mrb_bool regular = TRUE;

201+

mrb_get_args(mrb, "|b", &regular);

202+203+

struct RClass *c = (regular) ? mrb_class(mrb, obj) : mrb_obj_ptr(obj)->c;

204+

return mrb_class_instance_method_list(mrb, regular, c, flags);

205205

}

206+206207

/* 15.3.1.3.31 */

207208

/*

208209

* call-seq:

209-

* obj.methods -> array

210+

* obj.methods(regular=true) -> array

210211

*

211-

* Returns a list of the names of methods publicly accessible in

212-

* <i>obj</i>. This will include all the methods accessible in

213-

* <i>obj</i>'s ancestors.

212+

* Returns a list of the names of public and protected methods of

213+

* `obj`. This will include all the methods accessible in

214+

* `obj`'s ancestors.

215+

* If the optional parameter is `false`, it

216+

* returns an array of `obj`'s public and protected singleton methods,

217+

* the array will not include methods in modules included in `obj`.

214218

*

215219

* class Klass

216220

* def kMethod()

@@ -225,9 +229,7 @@ mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, int flag)

225229

static mrb_value

226230

mrb_obj_methods_m(mrb_state *mrb, mrb_value self)

227231

{

228-

mrb_bool recur = TRUE;

229-

mrb_get_args(mrb, "|b", &recur);

230-

return mrb_obj_methods(mrb, recur, self, MT_PUBLIC); /* everything but private */

232+

return mrb_obj_methods(mrb, self, MT_NOPRIV);

231233

}

232234233235

/* 15.3.1.3.36 */

@@ -242,9 +244,7 @@ mrb_obj_methods_m(mrb_state *mrb, mrb_value self)

242244

static mrb_value

243245

mrb_obj_private_methods(mrb_state *mrb, mrb_value self)

244246

{

245-

mrb_bool recur = TRUE;

246-

mrb_get_args(mrb, "|b", &recur);

247-

return mrb_obj_methods(mrb, recur, self, MT_PRIVATE); /* private attribute not define */

247+

return mrb_obj_methods(mrb, self, MT_PRIVATE);

248248

}

249249250250

/* 15.3.1.3.37 */

@@ -259,9 +259,7 @@ mrb_obj_private_methods(mrb_state *mrb, mrb_value self)

259259

static mrb_value

260260

mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)

261261

{

262-

mrb_bool recur = TRUE;

263-

mrb_get_args(mrb, "|b", &recur);

264-

return mrb_obj_methods(mrb, recur, self, MT_PROTECTED); /* protected attribute not define */

262+

return mrb_obj_methods(mrb, self, MT_PROTECTED);

265263

}

266264267265

/* 15.3.1.3.38 */

@@ -276,9 +274,7 @@ mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)

276274

static mrb_value

277275

mrb_obj_public_methods(mrb_state *mrb, mrb_value self)

278276

{

279-

mrb_bool recur = TRUE;

280-

mrb_get_args(mrb, "|b", &recur);

281-

return mrb_obj_methods(mrb, recur, self, MT_PUBLIC); /* public attribute not define */

277+

return mrb_obj_methods(mrb, self, MT_PUBLIC);

282278

}

283279284280

static mrb_value

@@ -287,17 +283,16 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)

287283

mrb_value ary;

288284

struct RClass *klass;

289285

khash_t(st) *set = kh_init(st, mrb);

290-

khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL);

291286292287

klass = mrb_class(mrb, obj);

293288294289

if (klass && (klass->tt == MRB_TT_SCLASS)) {

295-

method_entry_loop(mrb, klass, set, undef);

290+

method_entry_loop(mrb, klass, set, MT_PUBLIC);

296291

klass = klass->super;

297292

}

298293

if (recur) {

299294

while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {

300-

method_entry_loop(mrb, klass, set, undef);

295+

method_entry_loop(mrb, klass, set, MT_PUBLIC);

301296

klass = klass->super;

302297

}

303298

}

@@ -309,7 +304,6 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)

309304

}

310305

}

311306

kh_destroy(st, mrb, set);

312-

if (undef) kh_destroy(st, mrb, undef);

313307314308

return ary;

315309

}

@@ -526,6 +520,15 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self)

526520

return result;

527521

}

528522523+

static mrb_value

524+

mod_instance_methods(mrb_state *mrb, mrb_value mod, unsigned int visibility)

525+

{

526+

struct RClass *c = mrb_class_ptr(mod);

527+

mrb_bool recur = TRUE;

528+

mrb_get_args(mrb, "|b", &recur);

529+

return mrb_class_instance_method_list(mrb, recur, c, visibility);

530+

}

531+529532

/* 15.2.2.4.33 */

530533

/*

531534

* call-seq:

@@ -557,10 +560,7 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self)

557560

static mrb_value

558561

mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod)

559562

{

560-

struct RClass *c = mrb_class_ptr(mod);

561-

mrb_bool recur = TRUE;

562-

mrb_get_args(mrb, "|b", &recur);

563-

return mrb_class_instance_method_list(mrb, recur, c);

563+

return mod_instance_methods(mrb, mod, MT_NOPRIV);

564564

}

565565566566

static int

Read the original on github.com ↗