Project

General

Profile

Feature #14944 ยป 0001-Support-optional-inherit-argument-for-Module-method_.patch

jeremyevans0 (Jeremy Evans), 07/27/2018 04:57 PM

View differences:

test/ruby/test_module.rb
468 468
  end
469 469

  
470 470
  def test_method_defined?
471
    assert !User.method_defined?(:wombat)
472
    assert User.method_defined?(:mixin)
473
    assert User.method_defined?(:user)
474
    assert User.method_defined?(:user2)
475
    assert !User.method_defined?(:user3)
471
    [User, Class.new{include User}, Class.new{prepend User}].each do |klass|
472
      [[], [true]].each do |args|
473
        assert !klass.method_defined?(:wombat, *args)
474
        assert klass.method_defined?(:mixin, *args)
475
        assert klass.method_defined?(:user, *args)
476
        assert klass.method_defined?(:user2, *args)
477
        assert !klass.method_defined?(:user3, *args)
476 478

  
477
    assert !User.method_defined?("wombat")
478
    assert User.method_defined?("mixin")
479
    assert User.method_defined?("user")
480
    assert User.method_defined?("user2")
481
    assert !User.method_defined?("user3")
479
        assert !klass.method_defined?("wombat", *args)
480
        assert klass.method_defined?("mixin", *args)
481
        assert klass.method_defined?("user", *args)
482
        assert klass.method_defined?("user2", *args)
483
        assert !klass.method_defined?("user3", *args)
484
      end
485
    end
486
  end
487

  
488
  def test_method_defined_without_include_super
489
    assert User.method_defined?(:user, false)
490
    assert !User.method_defined?(:mixin, false)
491
    assert Mixin.method_defined?(:mixin, false)
492

  
493
    User.const_set(:FOO, c = Class.new)
494

  
495
    c.prepend(User)
496
    assert !c.method_defined?(:user, false)
497
    c.define_method(:user){}
498
    assert c.method_defined?(:user, false)
499

  
500
    assert !c.method_defined?(:mixin, false)
501
    c.define_method(:mixin){}
502
    assert c.method_defined?(:mixin, false)
503

  
504
    assert !c.method_defined?(:userx, false)
505
    c.define_method(:userx){}
506
    assert c.method_defined?(:userx, false)
482 507
  end
483 508

  
484 509
  def module_exec_aux
......
974 999
  end
975 1000

  
976 1001
  def test_method_defined
977
    c = Class.new
978
    c.class_eval do
1002
    cl = Class.new
1003
    def_methods = proc do
979 1004
      def foo; end
980 1005
      def bar; end
981 1006
      def baz; end
......
983 1008
      protected :bar
984 1009
      private :baz
985 1010
    end
1011
    cl.class_eval(&def_methods)
1012
    sc = Class.new(cl)
1013
    mod = Module.new(&def_methods)
1014
    only_prepend = Class.new{prepend(mod)}
1015
    empty_prepend = cl.clone
1016
    empty_prepend.prepend(Module.new)
1017
    overlap_prepend = cl.clone
1018
    overlap_prepend.prepend(mod)
986 1019

  
987
    assert_equal(true, c.public_method_defined?(:foo))
988
    assert_equal(false, c.public_method_defined?(:bar))
989
    assert_equal(false, c.public_method_defined?(:baz))
1020
    [[], [true], [false]].each do |args|
1021
      [cl, sc, only_prepend, empty_prepend, overlap_prepend].each do |c|
1022
        always_false = [sc, only_prepend].include?(c) && args == [false]
990 1023

  
991
    # Test if string arguments are converted to symbols
992
    assert_equal(true, c.public_method_defined?("foo"))
993
    assert_equal(false, c.public_method_defined?("bar"))
994
    assert_equal(false, c.public_method_defined?("baz"))
1024
        assert_equal(always_false ? false : true, c.public_method_defined?(:foo, *args))
1025
        assert_equal(always_false ? false : false, c.public_method_defined?(:bar, *args))
1026
        assert_equal(always_false ? false : false, c.public_method_defined?(:baz, *args))
995 1027

  
996
    assert_equal(false, c.protected_method_defined?(:foo))
997
    assert_equal(true, c.protected_method_defined?(:bar))
998
    assert_equal(false, c.protected_method_defined?(:baz))
1028
        # Test if string arguments are converted to symbols
1029
        assert_equal(always_false ? false : true, c.public_method_defined?("foo", *args))
1030
        assert_equal(always_false ? false : false, c.public_method_defined?("bar", *args))
1031
        assert_equal(always_false ? false : false, c.public_method_defined?("baz", *args))
999 1032

  
1000
    # Test if string arguments are converted to symbols
1001
    assert_equal(false, c.protected_method_defined?("foo"))
1002
    assert_equal(true, c.protected_method_defined?("bar"))
1003
    assert_equal(false, c.protected_method_defined?("baz"))
1033
        assert_equal(always_false ? false : false, c.protected_method_defined?(:foo, *args))
1034
        assert_equal(always_false ? false : true, c.protected_method_defined?(:bar, *args))
1035
        assert_equal(always_false ? false : false, c.protected_method_defined?(:baz, *args))
1004 1036

  
1005
    assert_equal(false, c.private_method_defined?(:foo))
1006
    assert_equal(false, c.private_method_defined?(:bar))
1007
    assert_equal(true, c.private_method_defined?(:baz))
1037
        # Test if string arguments are converted to symbols
1038
        assert_equal(always_false ? false : false, c.protected_method_defined?("foo", *args))
1039
        assert_equal(always_false ? false : true, c.protected_method_defined?("bar", *args))
1040
        assert_equal(always_false ? false : false, c.protected_method_defined?("baz", *args))
1008 1041

  
1009
    # Test if string arguments are converted to symbols
1010
    assert_equal(false, c.private_method_defined?("foo"))
1011
    assert_equal(false, c.private_method_defined?("bar"))
1012
    assert_equal(true, c.private_method_defined?("baz"))
1042
        assert_equal(always_false ? false : false, c.private_method_defined?(:foo, *args))
1043
        assert_equal(always_false ? false : false, c.private_method_defined?(:bar, *args))
1044
        assert_equal(always_false ? false : true, c.private_method_defined?(:baz, *args))
1045

  
1046
        # Test if string arguments are converted to symbols
1047
        assert_equal(always_false ? false : false, c.private_method_defined?("foo", *args))
1048
        assert_equal(always_false ? false : false, c.private_method_defined?("bar", *args))
1049
        assert_equal(always_false ? false : true, c.private_method_defined?("baz", *args))
1050
      end
1051
    end
1013 1052
  end
1014 1053

  
1015 1054
  def test_top_public_private
vm_method.c
1278 1278
    return mod;
1279 1279
}
1280 1280

  
1281
static rb_method_visibility_t
1282
check_definition_visibility(VALUE mod, int argc, VALUE *argv)
1283
{
1284
    const rb_method_entry_t *me;
1285
    VALUE mid, include_super, lookup_mod = mod;
1286
    int inc_super;
1287
    ID id;
1288

  
1289
    rb_scan_args(argc, argv, "11", &mid, &include_super);
1290
    id = rb_check_id(&mid);
1291
    if (!id) return METHOD_VISI_UNDEF;
1292

  
1293
    if (argc == 1) {
1294
	inc_super = 1;
1295
    } else {
1296
	inc_super = RTEST(include_super);
1297
	if (!inc_super) {
1298
	    lookup_mod = RCLASS_ORIGIN(mod);
1299
	}
1300
    }
1301

  
1302
    me = rb_method_entry_without_refinements(lookup_mod, id, NULL);
1303
    if (me) {
1304
	if (!inc_super && me->owner != mod) return METHOD_VISI_UNDEF; 
1305
	return METHOD_ENTRY_VISI(me);
1306
    }
1307
    return METHOD_VISI_UNDEF;
1308
}
1309

  
1281 1310
/*
1282 1311
 *  call-seq:
1283
 *     mod.method_defined?(symbol)    -> true or false
1284
 *     mod.method_defined?(string)    -> true or false
1312
 *     mod.method_defined?(symbol, inherit=true)    -> true or false
1313
 *     mod.method_defined?(string, inherit=true)    -> true or false
1285 1314
 *
1286 1315
 *  Returns +true+ if the named method is defined by
1287
 *  _mod_ (or its included modules and, if _mod_ is a class,
1288
 *  its ancestors). Public and protected methods are matched.
1316
 *  _mod_.  If _inherit_ is set, the lookup will also search _mod_'s
1317
 *  ancestors. Public and protected methods are matched.
1289 1318
 *  String arguments are converted to symbols.
1290 1319
 *
1291 1320
 *     module A
......
1306 1335
 *     A.method_defined? :method1              #=> true
1307 1336
 *     C.method_defined? "method1"             #=> true
1308 1337
 *     C.method_defined? "method2"             #=> true
1338
 *     C.method_defined? "method2", true       #=> true
1339
 *     C.method_defined? "method2", false      #=> false
1309 1340
 *     C.method_defined? "method3"             #=> true
1310 1341
 *     C.method_defined? "protected_method1"   #=> true
1311 1342
 *     C.method_defined? "method4"             #=> false
......
1313 1344
 */
1314 1345

  
1315 1346
static VALUE
1316
rb_mod_method_defined(VALUE mod, VALUE mid)
1347
rb_mod_method_defined(int argc, VALUE *argv, VALUE mod)
1317 1348
{
1318
    ID id = rb_check_id(&mid);
1319
    if (!id || !rb_method_boundp(mod, id, 1)) {
1320
	return Qfalse;
1321
    }
1322
    return Qtrue;
1323

  
1349
    rb_method_visibility_t visi = check_definition_visibility(mod, argc, argv);
1350
    return (visi == METHOD_VISI_PUBLIC || visi == METHOD_VISI_PROTECTED) ? Qtrue : Qfalse;
1324 1351
}
1325 1352

  
1326 1353
static VALUE
1327
check_definition(VALUE mod, VALUE mid, rb_method_visibility_t visi)
1354
check_definition(VALUE mod, int argc, VALUE *argv, rb_method_visibility_t visi)
1328 1355
{
1329
    const rb_method_entry_t *me;
1330
    ID id = rb_check_id(&mid);
1331
    if (!id) return Qfalse;
1332
    me = rb_method_entry_without_refinements(mod, id, NULL);
1333
    if (me) {
1334
	if (METHOD_ENTRY_VISI(me) == visi) return Qtrue;
1335
    }
1336
    return Qfalse;
1356
    return (check_definition_visibility(mod, argc, argv) == visi) ? Qtrue : Qfalse;
1337 1357
}
1338 1358

  
1339 1359
/*
1340 1360
 *  call-seq:
1341
 *     mod.public_method_defined?(symbol)   -> true or false
1342
 *     mod.public_method_defined?(string)   -> true or false
1361
 *     mod.public_method_defined?(symbol, inherit=true)   -> true or false
1362
 *     mod.public_method_defined?(string, inherit=true)   -> true or false
1343 1363
 *
1344 1364
 *  Returns +true+ if the named public method is defined by
1345
 *  _mod_ (or its included modules and, if _mod_ is a class,
1346
 *  its ancestors).
1365
 *  _mod_.  If _inherit_ is set, the lookup will also search _mod_'s
1366
 *  ancestors.
1347 1367
 *  String arguments are converted to symbols.
1348 1368
 *
1349 1369
 *     module A
......
1358 1378
 *       def method3()  end
1359 1379
 *     end
1360 1380
 *
1361
 *     A.method_defined? :method1           #=> true
1362
 *     C.public_method_defined? "method1"   #=> true
1363
 *     C.public_method_defined? "method2"   #=> false
1364
 *     C.method_defined? "method2"          #=> true
1381
 *     A.method_defined? :method1                 #=> true
1382
 *     C.public_method_defined? "method1"         #=> true
1383
 *     C.public_method_defined? "method1", true   #=> true
1384
 *     C.public_method_defined? "method1", false  #=> true
1385
 *     C.public_method_defined? "method2"         #=> false
1386
 *     C.method_defined? "method2"                #=> true
1365 1387
 */
1366 1388

  
1367 1389
static VALUE
1368
rb_mod_public_method_defined(VALUE mod, VALUE mid)
1390
rb_mod_public_method_defined(int argc, VALUE *argv, VALUE mod)
1369 1391
{
1370
    return check_definition(mod, mid, METHOD_VISI_PUBLIC);
1392
    return check_definition(mod, argc, argv, METHOD_VISI_PUBLIC);
1371 1393
}
1372 1394

  
1373 1395
/*
1374 1396
 *  call-seq:
1375
 *     mod.private_method_defined?(symbol)    -> true or false
1376
 *     mod.private_method_defined?(string)    -> true or false
1397
 *     mod.private_method_defined?(symbol, inherit=true)    -> true or false
1398
 *     mod.private_method_defined?(string, inherit=true)    -> true or false
1377 1399
 *
1378 1400
 *  Returns +true+ if the named private method is defined by
1379
 *  _ mod_ (or its included modules and, if _mod_ is a class,
1380
 *  its ancestors).
1401
 *  _mod_.  If _inherit_ is set, the lookup will also search _mod_'s
1402
 *  ancestors.
1381 1403
 *  String arguments are converted to symbols.
1382 1404
 *
1383 1405
 *     module A
......
1392 1414
 *       def method3()  end
1393 1415
 *     end
1394 1416
 *
1395
 *     A.method_defined? :method1            #=> true
1396
 *     C.private_method_defined? "method1"   #=> false
1397
 *     C.private_method_defined? "method2"   #=> true
1398
 *     C.method_defined? "method2"           #=> false
1417
 *     A.method_defined? :method1                   #=> true
1418
 *     C.private_method_defined? "method1"          #=> false
1419
 *     C.private_method_defined? "method2"          #=> true
1420
 *     C.private_method_defined? "method2", true    #=> true
1421
 *     C.private_method_defined? "method2", false   #=> false
1422
 *     C.method_defined? "method2"                  #=> false
1399 1423
 */
1400 1424

  
1401 1425
static VALUE
1402
rb_mod_private_method_defined(VALUE mod, VALUE mid)
1426
rb_mod_private_method_defined(int argc, VALUE *argv, VALUE mod)
1403 1427
{
1404
    return check_definition(mod, mid, METHOD_VISI_PRIVATE);
1428
    return check_definition(mod, argc, argv, METHOD_VISI_PRIVATE);
1405 1429
}
1406 1430

  
1407 1431
/*
1408 1432
 *  call-seq:
1409
 *     mod.protected_method_defined?(symbol)   -> true or false
1410
 *     mod.protected_method_defined?(string)   -> true or false
1433
 *     mod.protected_method_defined?(symbol, inherit=true)   -> true or false
1434
 *     mod.protected_method_defined?(string, inherit=true)   -> true or false
1411 1435
 *
1412 1436
 *  Returns +true+ if the named protected method is defined
1413
 *  by _mod_ (or its included modules and, if _mod_ is a
1414
 *  class, its ancestors).
1437
 *  _mod_.  If _inherit_ is set, the lookup will also search _mod_'s
1438
 *  ancestors.
1415 1439
 *  String arguments are converted to symbols.
1416 1440
 *
1417 1441
 *     module A
......
1426 1450
 *       def method3()  end
1427 1451
 *     end
1428 1452
 *
1429
 *     A.method_defined? :method1              #=> true
1430
 *     C.protected_method_defined? "method1"   #=> false
1431
 *     C.protected_method_defined? "method2"   #=> true
1432
 *     C.method_defined? "method2"             #=> true
1453
 *     A.method_defined? :method1                    #=> true
1454
 *     C.protected_method_defined? "method1"         #=> false
1455
 *     C.protected_method_defined? "method2"         #=> true
1456
 *     C.protected_method_defined? "method2", true   #=> true
1457
 *     C.protected_method_defined? "method2", false  #=> false
1458
 *     C.method_defined? "method2"                   #=> true
1433 1459
 */
1434 1460

  
1435 1461
static VALUE
1436
rb_mod_protected_method_defined(VALUE mod, VALUE mid)
1462
rb_mod_protected_method_defined(int argc, VALUE *argv, VALUE mod)
1437 1463
{
1438
    return check_definition(mod, mid, METHOD_VISI_PROTECTED);
1464
    return check_definition(mod, argc, argv, METHOD_VISI_PROTECTED);
1439 1465
}
1440 1466

  
1441 1467
int
......
2121 2147
    rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
2122 2148
    rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
2123 2149

  
2124
    rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
2125
    rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
2126
    rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
2127
    rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
2150
    rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, -1);
2151
    rb_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, -1);
2152
    rb_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, -1);
2153
    rb_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, -1);
2128 2154
    rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
2129 2155
    rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
2130 2156