From a3026101067862f5ffa66b3e5c87588be20e5e32 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 21 Jan 2023 15:39:19 -0500 Subject: [PATCH] [Delegator] Improve error messages when return types are missing --- include/cantera/base/Delegator.h | 31 ++++++++++++++++++------- interfaces/cython/cantera/delegator.pxd | 2 ++ interfaces/cython/cantera/delegator.pyx | 2 ++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/include/cantera/base/Delegator.h b/include/cantera/base/Delegator.h index b8a0eed334..9aee98729e 100644 --- a/include/cantera/base/Delegator.h +++ b/include/cantera/base/Delegator.h @@ -102,6 +102,16 @@ namespace Cantera class Delegator { public: + //! Get the name of the user-defined class in the extension language + std::string delegatorName() const { + return m_delegatorName; + } + + //! Set the name of the user-defined class in the extension language + void setDelegatorName(const std::string& delegatorName) { + m_delegatorName = delegatorName; + } + //! Set delegates for member functions with the signature `void()`. void setDelegate(const std::string& name, const std::function& func, const std::string& when) @@ -215,7 +225,7 @@ class Delegator throw NotImplementedError("Delegator::setDelegate", "for function named '{}' with signature 'double(void*)'.", name); } - *m_funcs_d_vp[name] = makeDelegate(func, when, m_base_d_vp[name]); + *m_funcs_d_vp[name] = makeDelegate(name, func, when, m_base_d_vp[name]); } //! Set delegates for member functions with the signature `string(size_t)` @@ -228,7 +238,7 @@ class Delegator "for function named '{}' with signature " "'string(size_t)'.", name); } - *m_funcs_s_sz[name] = makeDelegate(func, when, m_base_s_sz[name]); + *m_funcs_s_sz[name] = makeDelegate(name, func, when, m_base_s_sz[name]); } //! Set delegates for member functions with the signature `size_t(string)` @@ -238,10 +248,10 @@ class Delegator { if (!m_funcs_sz_csr.count(name)) { throw NotImplementedError("Delegator::setDelegate", - "for function named '{}' with signature " + "for function '{}' with signature " "'size_t(const string&)'.", name); } - *m_funcs_sz_csr[name] = makeDelegate(func, when, m_base_sz_csr[name]); + *m_funcs_sz_csr[name] = makeDelegate(name, func, when, m_base_sz_csr[name]); } void holdExternalHandle(const shared_ptr& handle) { @@ -382,6 +392,7 @@ class Delegator //! Create a delegate for a function with a return value template std::function makeDelegate( + const std::string& name, const std::function& func, const std::string& when, const std::function& base) @@ -413,20 +424,21 @@ class Delegator } }; } else if (when == "replace") { - return [base, func](Args ... args) { + return [base, name, func, this](Args ... args) { ReturnType ret; int has_ret = func(ret, args ...); if (!has_ret) { throw CanteraError("Lambda generated by Delegator::makeDelegate", - "Delegate for function of type '{}'\ndid not return a value", - demangle(typeid(base))); + "Method '{}' of class '{}' did not return a value of type '{}'.", + name, delegatorName(), demangle(typeid(ret))); } return ret; }; } else { throw CanteraError("Delegator::makeDelegate", + "For function named '{}':\n" "'when' must be one of 'before', 'after', or 'replace';" - " not '{}", when); + " not '{}'", name, when); } } @@ -486,6 +498,9 @@ class Delegator //! Cleanup functions to be called from the destructor std::list> m_handles; + + //! Name of the class in the extension language + std::string m_delegatorName; }; } diff --git a/interfaces/cython/cantera/delegator.pxd b/interfaces/cython/cantera/delegator.pxd index a599b80a35..67f96a9660 100644 --- a/interfaces/cython/cantera/delegator.pxd +++ b/interfaces/cython/cantera/delegator.pxd @@ -26,6 +26,8 @@ cdef extern from "cantera/base/Delegator.h" namespace "Cantera": cdef cppclass CxxDelegator "Cantera::Delegator": Delegator() + void setDelegatorName(string&) + void setDelegate(string&, function[void()], string&) except +translate_exception void setDelegate(string&, function[void(cbool)], string&) except +translate_exception void setDelegate(string&, function[void(double)], string&) except +translate_exception diff --git a/interfaces/cython/cantera/delegator.pyx b/interfaces/cython/cantera/delegator.pyx index bcfab87525..d5c3505343 100644 --- a/interfaces/cython/cantera/delegator.pyx +++ b/interfaces/cython/cantera/delegator.pyx @@ -235,6 +235,8 @@ cdef int assign_delegates(obj, CxxDelegator* delegator) except -1: if present, indicates that the delegate is required, how it is executed with respect to the base class method (that is, ``before``, ``after``, or ``replace``). """ + delegator.setDelegatorName(stringify(obj.__class__.__name__)) + # Find all delegate methods, and make sure there aren't multiple # conflicting implementations cdef string cxx_name