diff --git a/cppwinrt/code_writers.h b/cppwinrt/code_writers.h index 9d75d3476..b5ceed07e 100644 --- a/cppwinrt/code_writers.h +++ b/cppwinrt/code_writers.h @@ -2150,6 +2150,10 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable w.write("\n friend impl::consume_t;", name); w.write("\n friend impl::require_one;", name); } + else if (info.overridable) + { + w.write("\n friend impl::produce;", name); + } } } @@ -2275,13 +2279,13 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable static void write_class_override_usings(writer& w, get_interfaces_t const& required_interfaces) { - std::map> method_usage; + std::map> method_usage; - for (auto&& [interface_name, info] : required_interfaces) + for (auto&& interface_desc : required_interfaces) { - for (auto&& method : info.type.MethodList()) + for (auto&& method : interface_desc.second.type.MethodList()) { - method_usage[get_name(method)].insert(interface_name); + method_usage[get_name(method)].insert(interface_desc); } } @@ -2292,9 +2296,9 @@ struct WINRT_IMPL_EMPTY_BASES produce_dispatch_to_overridable continue; } - for (auto&& interface_name : interfaces) + for (auto&& [interface_name, info] : interfaces) { - w.write(" using impl::consume_t::%;\n", + w.write(info.overridable ? " using %T::%;\n" : " using impl::consume_t::%;\n", interface_name, method_name); } diff --git a/test/test_component/OverloadClass.cpp b/test/test_component/OverloadClass.cpp new file mode 100644 index 000000000..d89f19ea5 --- /dev/null +++ b/test/test_component/OverloadClass.cpp @@ -0,0 +1,23 @@ +#include "pch.h" +#include "OverloadClass.h" +#include "OverloadClass.g.cpp" + +namespace winrt::test_component::implementation +{ + void OverloadClass::Overload() + { + throw hresult_not_implemented(); + } + void OverloadClass::Overload(int a) + { + throw hresult_not_implemented(); + } + void OverloadClass::Overload(int a, int b) + { + throw hresult_not_implemented(); + } + void OverloadClass::Overload(int a, int b, int c) + { + throw hresult_not_implemented(); + } +} diff --git a/test/test_component/OverloadClass.h b/test/test_component/OverloadClass.h new file mode 100644 index 000000000..1b155e801 --- /dev/null +++ b/test/test_component/OverloadClass.h @@ -0,0 +1,21 @@ +#pragma once +#include "OverloadClass.g.h" + +namespace winrt::test_component::implementation +{ + struct OverloadClass : OverloadClassT + { + OverloadClass() = default; + + void Overload(); + void Overload(int a); + void Overload(int a, int b); + void Overload(int a, int b, int c); + }; +} +namespace winrt::test_component::factory_implementation +{ + struct OverloadClass : OverloadClassT + { + }; +} diff --git a/test/test_component/test_component.idl b/test/test_component/test_component.idl index a027c394c..536a703f5 100644 --- a/test/test_component/test_component.idl +++ b/test/test_component/test_component.idl @@ -334,4 +334,51 @@ namespace test_component delegate void Delegate(); } + + [exclusiveto(test_component.OverloadClass)] + [version(1), uuid(EF902013-00F3-4549-9032-49E86D536C07)] + interface IOverloadClass : IInspectable + { + HRESULT Overload(); + } + + [exclusiveto(test_component.OverloadClass)] + [version(1), uuid(DFDFFB61-EA72-4977-B1A7-3F0D2C32BB58)] + interface IOverloadClassFactory : IInspectable + { + HRESULT CreateInstance([in] IInspectable* baseInterface, [out] IInspectable** innerInterface, [out][retval] test_component.OverloadClass** value); + } + + [exclusiveto(test_component.OverloadClass)] + [version(1), uuid(32510F72-9229-4C69-95BD-DE7B8189C85C)] + interface IOverloadClassOverrides : IInspectable + { + [overload("Overload")] HRESULT OverloadWithOne(int a); + } + + [exclusiveto(test_component.OverloadClass)] + [version(1), uuid(50205BCE-FAD3-4C66-801F-17AAD007B26C)] + interface IOverloadClassOverrides2 : IInspectable + { + [overload("Overload")] HRESULT OverloadWithTwo(int a, int b); + } + + [exclusiveto(test_component.OverloadClass)] + [version(1), uuid(6EDD1A3F-2616-45B7-9731-F84DA9CCECA1)] + interface IOverloadClassProtected : IInspectable + { + [overload("Overload")] HRESULT OverloadWithThree(int a, int b, int c); + } + + [composable(test_component.IOverloadClassFactory, public, 1)] + [marshaling_behavior(agile)] + [threading(both)] + [version(1)] + runtimeclass OverloadClass + { + [default] interface test_component.IOverloadClass; + [protected] interface test_component.IOverloadClassProtected; + [overridable] interface test_component.IOverloadClassOverrides; + [overridable] interface test_component.IOverloadClassOverrides2; + } } diff --git a/test/test_component/test_component.vcxproj b/test/test_component/test_component.vcxproj index b6b3aa5d4..001587bed 100644 --- a/test/test_component/test_component.vcxproj +++ b/test/test_component/test_component.vcxproj @@ -384,6 +384,8 @@ + + Create @@ -397,6 +399,7 @@ + diff --git a/test/test_component/test_overload.cpp b/test/test_component/test_overload.cpp new file mode 100644 index 000000000..fb95ca20e --- /dev/null +++ b/test/test_component/test_overload.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "winrt/test_component.h" + +// Simple compile-only test to validate overloads coming from overridable interfaces compile. + +using namespace winrt; +using namespace test_component; + +struct DerivedClass : OverloadClassT +{ + void Foo() + { + // make sure we can actually call the overloads (no ambiguous call errors) + Overload(); + Overload(1); + Overload(1, 2); + Overload(1, 2, 3); + } +}; \ No newline at end of file