diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl index f18ae60df8..71aa464097 100644 --- a/src/Tests/TestComponentCSharp/TestComponentCSharp.idl +++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.idl @@ -624,6 +624,9 @@ namespace TestComponentCSharp overridable Int32 WarningOverridableProperty; // see https://github.com/microsoft/cppwinrt/issues/782 //overridable event Windows.Foundation.EventHandler WarningOverridableEvent; + Int32 CallOverridablePropertyGetter(); + void CallOverridablePropertySetter(Int32 value); + void CallOverridableMethod(); } } diff --git a/src/Tests/TestComponentCSharp/WarningClass.cpp b/src/Tests/TestComponentCSharp/WarningClass.cpp index 7bea7a352a..69c58eb2e2 100644 --- a/src/Tests/TestComponentCSharp/WarningClass.cpp +++ b/src/Tests/TestComponentCSharp/WarningClass.cpp @@ -41,6 +41,18 @@ namespace winrt::TestComponentCSharp::implementation void WarningClass::WarningOverridableProperty(int32_t value) { } + int32_t WarningClass::CallOverridablePropertyGetter() + { + return overridable().WarningOverridableProperty(); + } + void WarningClass::CallOverridablePropertySetter(int32_t value) + { + overridable().WarningOverridableProperty(value); + } + void WarningClass::CallOverridableMethod() + { + overridable().WarningOverridableMethod(); + } //winrt::event_token WarningClass::WarningOverridableEvent(Windows::Foundation::EventHandler const& handler) //{ // return {}; diff --git a/src/Tests/TestComponentCSharp/WarningClass.h b/src/Tests/TestComponentCSharp/WarningClass.h index bf8d580194..9e092be929 100644 --- a/src/Tests/TestComponentCSharp/WarningClass.h +++ b/src/Tests/TestComponentCSharp/WarningClass.h @@ -18,6 +18,9 @@ namespace winrt::TestComponentCSharp::implementation void WarningOverridableMethod(); int32_t WarningOverridableProperty(); void WarningOverridableProperty(int32_t value); + int32_t CallOverridablePropertyGetter(); + void CallOverridablePropertySetter(int32_t value); + void CallOverridableMethod(); //winrt::event_token WarningOverridableEvent(Windows::Foundation::EventHandler const& handler); //void WarningOverridableEvent(winrt::event_token const& token) noexcept; int32_t WarningInterfacePropertySetter(); diff --git a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs index 8912bb5411..94cbe4c07f 100644 --- a/src/Tests/UnitTest/TestComponentCSharp_Tests.cs +++ b/src/Tests/UnitTest/TestComponentCSharp_Tests.cs @@ -3553,6 +3553,41 @@ private void TestSupportedOSPlatformWarnings() } #endif +#if NET + [Fact] + public void TestOverridable() + { + var obj = new OverridableTestClass(); + + // Test overridable property round-trip through native overrides interface + Assert.Equal(42, obj.CallOverridablePropertyGetter()); + obj.CallOverridablePropertySetter(99); + Assert.Equal(99, obj.CallOverridablePropertyGetter()); + + // Test overridable method round-trip through native overrides interface + Assert.False(obj.MethodWasCalled); + obj.CallOverridableMethod(); + Assert.True(obj.MethodWasCalled); + } + + class OverridableTestClass : WarningClass + { + private int _value = 42; + public bool MethodWasCalled { get; private set; } + + protected override int WarningOverridableProperty + { + get => _value; + set => _value = value; + } + + protected override void WarningOverridableMethod() + { + MethodWasCalled = true; + } + } +#endif + [Fact] public void TestObjectFunctions() { diff --git a/src/cswinrt/code_writers.h b/src/cswinrt/code_writers.h index 9971ae62c8..d93ca4dcbc 100644 --- a/src/cswinrt/code_writers.h +++ b/src/cswinrt/code_writers.h @@ -3395,15 +3395,22 @@ private % AsInternal(InterfaceTag<%> _) => % ?? Make_%(); if (getter || base_getter) { w.write("%get => %; ", base_getter_platform_attribute, bind([&](writer& w) { - if (call_static_method) + if (is_private) { - auto iface = base_getter ? getter_property_iface : prop.Parent(); - w.write("%", bind(iface, prop, - w.write_temp("%", bind(iface)))); + if (call_static_method) + { + auto iface = base_getter ? getter_property_iface : prop.Parent(); + w.write("%", bind(iface, prop, + w.write_temp("%", bind(iface)))); + } + else + { + w.write("%.%", target, prop.Name()); + } } else { - w.write("%%", is_private ? target + "." : "", prop.Name()); + w.write("%", prop.Name()); } })); } @@ -3413,14 +3420,21 @@ private % AsInternal(InterfaceTag<%> _) => % ?? Make_%(); if (setter) { w.write("set => %;", bind([&](writer& w) { - if (call_static_method) + if (is_private) { - w.write("%", bind(prop.Parent(), prop, - w.write_temp("%", bind(prop.Parent())))); + if (call_static_method) + { + w.write("%", bind(prop.Parent(), prop, + w.write_temp("%", bind(prop.Parent())))); + } + else + { + w.write("%.% = value", target, prop.Name()); + } } else { - w.write("%% = value", is_private ? target + "." : "", prop.Name()); + w.write("% = value", prop.Name()); } })); }