Implement support for noexcept overridable methods (#910)

This commit is contained in:
Charles Milette 2021-04-01 08:57:58 -04:00 коммит произвёл GitHub
Родитель 07f5b9aa7e
Коммит 464e59198c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 45 добавлений и 2 удалений

Просмотреть файл

@ -1905,7 +1905,7 @@ namespace cppwinrt
static void write_dispatch_overridable_method(writer& w, MethodDef const& method)
{
auto format = R"( auto %(%)
auto format = R"( auto %(%)%
{
if (auto overridable = this->shim_overridable())
{
@ -1921,6 +1921,7 @@ namespace cppwinrt
w.write(format,
get_name(method),
bind<write_implementation_params>(signature),
is_noexcept(method) ? " noexcept" : "",
get_name(method),
bind<write_consume_args>(signature),
get_name(method),
@ -1950,7 +1951,7 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
static void write_interface_override_method(writer& w, MethodDef const& method, std::string_view const& interface_name)
{
auto format = R"( template <typename D> WINRT_IMPL_AUTO(%) %T<D>::%(%) const
auto format = R"( template <typename D> WINRT_IMPL_AUTO(%) %T<D>::%(%) const%
{
return shim().template try_as<%>().%(%);
}
@ -1964,6 +1965,7 @@ struct __declspec(empty_bases) produce_dispatch_to_overridable<T, D, %>
interface_name,
method_name,
bind<write_consume_params>(signature),
is_noexcept(method) ? " noexcept" : "",
interface_name,
method_name,
bind<write_consume_args>(signature));

Просмотреть файл

@ -21,6 +21,11 @@ namespace winrt::Composable::implementation
return overridable().OverridableVirtualMethod();
}
int32_t Base::CallOverridableNoexceptMethod() noexcept
{
return overridable().OverridableNoexceptMethod();
}
hstring Base::OverridableMethod()
{
return L"Base::OverridableMethod";
@ -31,6 +36,11 @@ namespace winrt::Composable::implementation
return L"Base::OverridableVirtualMethod";
}
int32_t Base::OverridableNoexceptMethod() noexcept
{
return 42;
}
hstring Base::Name() const
{
return m_name;

Просмотреть файл

@ -14,8 +14,10 @@ namespace winrt::Composable::implementation
virtual hstring VirtualMethod();
hstring CallOverridableMethod();
hstring CallOverridableVirtualMethod();
int32_t CallOverridableNoexceptMethod() noexcept;
hstring OverridableMethod() ;
virtual hstring OverridableVirtualMethod();
int32_t OverridableNoexceptMethod() noexcept;
hstring Name() const;

Просмотреть файл

@ -1,5 +1,14 @@
import "Windows.Foundation.idl";
namespace Windows.Foundation.Metadata
{
[attributeusage(target_method, target_property)]
[attributename("noexcept2")]
attribute NoExceptionAttribute
{
}
}
namespace Composable
{
runtimeclass Base;
@ -11,6 +20,7 @@ namespace Composable
HRESULT VirtualMethod([out, retval] HSTRING* value);
HRESULT CallOverridableMethod([out, retval] HSTRING* value);
HRESULT CallOverridableVirtualMethod([out, retval] HSTRING* value);
[noexcept2] HRESULT CallOverridableNoexceptMethod([out, retval] int* value);
[propget] HRESULT Name([out, retval] HSTRING* value);
};
@ -27,6 +37,7 @@ namespace Composable
{
HRESULT OverridableMethod([out, retval] HSTRING* value);
HRESULT OverridableVirtualMethod([out, retval] HSTRING* value);
[noexcept2] HRESULT OverridableNoexceptMethod([out, retval] int* value);
};
[version(1.0), uuid(5f3996e1-3cf7-4716-9a3d-11eb5d32caff), exclusiveto(Derived)]

Просмотреть файл

@ -13,12 +13,14 @@ namespace
constexpr auto Base_VirtualMethod{ L"Base::VirtualMethod"sv };
constexpr auto Base_OverridableMethod{ L"Base::OverridableMethod"sv };
constexpr auto Base_OverridableVirtualMethod{ L"Base::OverridableVirtualMethod"sv };
constexpr auto Base_OverridableNoexceptMethod{ 42 };
constexpr auto Derived_VirtualMethod{ L"Derived::VirtualMethod"sv };
constexpr auto Derived_OverridableVirtualMethod{ L"Derived::OverridableVirtualMethod"sv };
constexpr auto OverriddenBase_OverridableMethod{ L"OverriddenBase::OverridableMethod"sv };
constexpr auto OverriddenBase_OverridableVirtualMethod{ L"OverriddenBase::OverridableVirtualMethod"sv };
constexpr auto OverriddenBase_OverridableNoexceptMethod{ 1337 };
}
TEST_CASE("Composable.Base")
@ -27,6 +29,7 @@ TEST_CASE("Composable.Base")
REQUIRE(base.VirtualMethod() == Base_VirtualMethod);
REQUIRE(base.CallOverridableMethod() == Base_OverridableMethod);
REQUIRE(base.CallOverridableVirtualMethod() == Base_OverridableVirtualMethod);
REQUIRE(base.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
}
TEST_CASE("Composable.OverriddenBase")
@ -39,6 +42,7 @@ TEST_CASE("Composable.OverriddenBase")
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
REQUIRE(object.CallOverridableMethod() == Base_OverridableMethod);
REQUIRE(object.CallOverridableVirtualMethod() == Base_OverridableVirtualMethod);
REQUIRE(object.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
}
{
struct OverriddenBase : BaseT<OverriddenBase>
@ -52,15 +56,22 @@ TEST_CASE("Composable.OverriddenBase")
{
return hstring(OverriddenBase_OverridableVirtualMethod);
}
int32_t OverridableNoexceptMethod() const noexcept
{
return OverriddenBase_OverridableNoexceptMethod;
}
};
auto object = make<OverriddenBase>();
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
REQUIRE(object.CallOverridableMethod() == OverriddenBase_OverridableMethod);
REQUIRE(object.CallOverridableVirtualMethod() == OverriddenBase_OverridableVirtualMethod);
REQUIRE(object.CallOverridableNoexceptMethod() == OverriddenBase_OverridableNoexceptMethod);
}
{
const std::wstring OverridableMethodResult = std::wstring(OverriddenBase_OverridableMethod) + L"=>" + Base_OverridableMethod.data();
const std::wstring OverridableVirtualMethodResult = std::wstring(OverriddenBase_OverridableVirtualMethod) + L"=>" + Base_OverridableVirtualMethod.data();
const int32_t OverridableNoexceptMethodResult = OverriddenBase_OverridableNoexceptMethod + Base_OverridableNoexceptMethod;
struct OverriddenBase : BaseT<OverriddenBase>
{
@ -73,11 +84,17 @@ TEST_CASE("Composable.OverriddenBase")
{
return OverriddenBase_OverridableVirtualMethod + L"=>" + BaseT<OverriddenBase>::OverridableVirtualMethod();
}
int32_t OverridableNoexceptMethod() const noexcept
{
return OverriddenBase_OverridableNoexceptMethod + BaseT<OverriddenBase>::OverridableNoexceptMethod();
}
};
auto object = make<OverriddenBase>();
REQUIRE(object.VirtualMethod() == Base_VirtualMethod);
REQUIRE(object.CallOverridableMethod() == OverridableMethodResult);
REQUIRE(object.CallOverridableVirtualMethod() == OverridableVirtualMethodResult);
REQUIRE(object.CallOverridableNoexceptMethod() == OverridableNoexceptMethodResult);
}
}
@ -88,6 +105,7 @@ TEST_CASE("Composable.Derived")
REQUIRE(obj.VirtualMethod() == Derived_VirtualMethod);
REQUIRE(obj.CallOverridableMethod() == Base_OverridableMethod);
REQUIRE(obj.CallOverridableVirtualMethod() == Derived_OverridableVirtualMethod);
REQUIRE(obj.CallOverridableNoexceptMethod() == Base_OverridableNoexceptMethod);
}
namespace