More compatibility with Ruby <2.7

This commit is contained in:
Matthias Koefferlein 2023-12-29 23:00:06 +01:00
parent b37002cf7f
commit f335ab69af
6 changed files with 45 additions and 32 deletions

View File

@ -91,7 +91,7 @@ module DRC
macro = RBA::Macro::macro_by_path(script)
macro || raise("Can't find DRC script #{script} - unable to re-run")
DRCExecutable::new(macro, @interpreter, self.generator({ "script" => script }, 0), params["rdb_index"])
DRCExecutable::new(macro, @interpreter, self.generator("script" => script), params["rdb_index"])
end
@ -128,7 +128,7 @@ module DRC
# Implements the execute method
def executable(macro)
DRCExecutable::new(macro, self, @recipe.generator({"script" => macro.path}, 0))
DRCExecutable::new(macro, self, @recipe.generator("script" => macro.path))
end
end
@ -155,7 +155,7 @@ module DRC
# Implements the execute method
def executable(macro)
DRCExecutable::new(macro, self, @recipe.generator({ "script" => macro.path }, 0))
DRCExecutable::new(macro, self, @recipe.generator("script" => macro.path))
end
end

View File

@ -693,12 +693,12 @@ static Recipe_Impl *make_recipe (const std::string &name, const std::string &des
return new Recipe_Impl (name, description);
}
static tl::Variant make_impl (const std::string &generator, const std::map<std::string, tl::Variant> &add_params, int /*dummy*/)
static tl::Variant make_impl (const std::string &generator, const std::map<std::string, tl::Variant> &add_params)
{
return Recipe_Impl::make (generator, add_params);
}
std::string generator_impl (Recipe_Impl *recipe, const std::map<std::string, tl::Variant> &params, int /*dummy*/)
std::string generator_impl (Recipe_Impl *recipe, const std::map<std::string, tl::Variant> &params)
{
return recipe->generator (params);
}
@ -713,23 +713,15 @@ Class<Recipe_Impl> decl_Recipe_Impl ("tl", "Recipe",
gsi::method ("description", &Recipe_Impl::description,
"@brief Gets the description of the recipe."
) +
gsi::method ("make", &make_impl, gsi::arg ("generator"), gsi::arg ("add_params", std::map<std::string, tl::Variant> (), "{}"), gsi::arg ("dummy", 0),
gsi::method ("make", &make_impl, gsi::arg ("generator"), gsi::arg ("add_params", std::map<std::string, tl::Variant> (), "{}"),
"@brief Executes the recipe given by the generator string.\n"
"The generator string is the one delivered with \\generator.\n"
"Additional parameters can be passed in \"add_params\". They have lower priority than the parameters "
"kept inside the generator string."
"\n"
"The dummy argument has been added in version 0.29 and disambiguates between keyword parameters "
"and a single hash argument in Ruby. This is required for Ruby versions before 'real keywords'. Simply "
"add this parameter with any value.\n"
) +
gsi::method_ext ("generator", &generator_impl, gsi::arg ("params"), gsi::arg ("dummy", 0),
gsi::method_ext ("generator", &generator_impl, gsi::arg ("params"),
"@brief Delivers the generator string from the given parameters.\n"
"The generator string can be used with \\make to re-run the recipe."
"\n"
"The dummy argument has been added in version 0.29 and disambiguates between keyword parameters "
"and a single hash argument in Ruby. This is required for Ruby versions before 'real keywords'. Simply "
"add this parameter with any value.\n"
) +
gsi::callback ("executable", &Recipe_Impl::executable, &Recipe_Impl::executable_cb, gsi::arg ("params"),
"@brief Reimplement this method to provide an executable object for the actual implementation.\n"

View File

@ -91,7 +91,7 @@ module LVS
macro = RBA::Macro::macro_by_path(script)
macro || raise("Can't find LVS script #{script} - unable to re-run")
LVSExecutable::new(macro, @interpreter, self.generator({ "script" => script }, 0), params["l2ndb_index"])
LVSExecutable::new(macro, @interpreter, self.generator("script" => script), params["l2ndb_index"])
end
@ -128,7 +128,7 @@ module LVS
# Implements the execute method
def executable(macro)
LVSExecutable::new(macro, self, @recipe.generator({ "script" => macro.path }, 0))
LVSExecutable::new(macro, self, @recipe.generator("script" => macro.path))
end
end
@ -155,7 +155,7 @@ module LVS
# Implements the execute method
def executable(macro)
LVSExecutable::new(macro, self, @recipe.generator({ "script" => macro.path }, 0))
LVSExecutable::new(macro, self, @recipe.generator("script" => macro.path))
end
end

View File

@ -92,7 +92,7 @@ module D25
macro = RBA::Macro::macro_by_path(script)
macro || raise("Can't find D25 script #{script} - unable to re-run")
D25Executable::new(macro, @interpreter, self.generator({ "script" => script }, 0))
D25Executable::new(macro, @interpreter, self.generator("script" => script))
end
@ -129,7 +129,7 @@ module D25
# Implements the execute method
def executable(macro)
D25Executable::new(macro, self, @recipe.generator({ "script" => macro.path }, 0))
D25Executable::new(macro, self, @recipe.generator("script" => macro.path))
end
end
@ -156,7 +156,7 @@ module D25
# Implements the execute method
def executable(macro)
D25Executable::new(macro, self, @recipe.generator({ "script" => macro.path }, 0))
D25Executable::new(macro, self, @recipe.generator("script" => macro.path))
end
end

View File

@ -1147,15 +1147,6 @@ method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor)
RBA_TRY
VALUE kwargs = Qnil;
bool check_last = true;
#if HAVE_RUBY_VERSION_CODE>=20700
check_last = rb_keyword_given_p ();
#endif
if (check_last && argc > 0 && RB_TYPE_P (argv[argc - 1], T_HASH)) {
kwargs = argv[--argc];
}
tl::Heap heap;
const gsi::ClassBase *cls_decl;
@ -1187,6 +1178,36 @@ method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor)
}
// Check for keyword arguments ..
VALUE kwargs = Qnil;
bool check_last = true;
#if HAVE_RUBY_VERSION_CODE>=20700
check_last = rb_keyword_given_p ();
#endif
// This is a heuristics to distinguish methods that are potential candidates for
// accepting a keyword argument. Problem is that Ruby confuses function calls with
// keyword arguments with arguments that take a single hash argument.
// We accept only methods here as candidates that do not have a last argument which
// is a map.
// For compatibility we do this check also for Ruby >=2.7 which supports rb_keyword_given_p.
if (check_last) {
const MethodTableEntry &e = mt->entry (mid);
for (auto m = e.begin (); m != e.end () && check_last; ++m) {
auto a = (*m)->end_arguments ();
if (a != (*m)->begin_arguments () && (--a)->type () == gsi::T_map) {
check_last = false;
}
}
}
if (check_last && argc > 0 && RB_TYPE_P (argv[argc - 1], T_HASH)) {
kwargs = argv[--argc];
}
// Identify the matching variant
const gsi::MethodBase *meth = mt->entry (mid).get_variant (argc, argv, kwargs, rb_block_given_p (), ctor, p == 0, p != 0 && p->const_ref ());
if (! meth) {

View File

@ -301,10 +301,10 @@ class Tl_TestClass < TestBase
assert_equal(my_recipe.name, "rba_test_recipe")
assert_equal(my_recipe.description, "description")
g = my_recipe.generator({ "A" => 6, "B" => 7.0 }, 0)
g = my_recipe.generator("A" => 6, "B" => 7.0)
assert_equal(g, "rba_test_recipe: A=#6,B=##7")
assert_equal("%g" % RBA::Recipe::make(g), "42")
assert_equal("%g" % RBA::Recipe::make(g, { "C" => 1.5 }, 0).to_s, "63")
assert_equal("%g" % RBA::Recipe::make(g, "C" => 1.5).to_s, "63")
my_recipe._destroy
my_recipe = nil