From 4e7b0bbd6b905a3279cd6912fa75340f6d28a7f2 Mon Sep 17 00:00:00 2001 From: dukesta3 Date: Sun, 21 Apr 2019 07:59:30 -0500 Subject: [PATCH 01/61] =?UTF-8?q?housekeeping:=20updated=20docs=20to=20Ana?= =?UTF-8?q?=C3=AFs=20Betters=20(#2003)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit did a search for betts and updated README.md, and multiple *.build.props folders. --- README.md | 4 ++-- directory.build.props | 2 +- integrationtests/Directory.Build.props | 2 +- src/Directory.build.props | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e4abfa895e..67f335b236 100644 --- a/README.md +++ b/README.md @@ -349,9 +349,9 @@ The following have been core team members in the past.

London, United Kingdom

- +
- Paul Betts + Anaïs Betts

San Francisco, USA

diff --git a/directory.build.props b/directory.build.props index 6caac2ea90..1d4ece3727 100644 --- a/directory.build.props +++ b/directory.build.props @@ -5,7 +5,7 @@ MIT https://reactiveui.net https://github.com/reactiveui/styleguide/blob/master/logo/main.png?raw=true - xpaulbettsx;ghuntley + xanaisbettsx;ghuntley ReactiveUI ($(TargetFramework)) mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen https://github.com/reactiveui/ReactiveUI/releases diff --git a/integrationtests/Directory.Build.props b/integrationtests/Directory.Build.props index 87a8c6860e..771ccf8e11 100644 --- a/integrationtests/Directory.Build.props +++ b/integrationtests/Directory.Build.props @@ -4,7 +4,7 @@ https://reactiveui.net https://i.imgur.com/7WDbqSy.png .NET Foundation and Contributors - xpaulbettsx;ghuntley + xanaisbettsx;ghuntley ReactiveUI Integration Tests ($(TargetFramework)) mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen https://reactiveui.net/blog/ diff --git a/src/Directory.build.props b/src/Directory.build.props index 91fde9e2d4..e6dff6f4db 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -1,6 +1,6 @@ - xpaulbettsx;ghuntley + xanaisbettsx;ghuntley mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen https://reactiveui.net/blog/ true From 25f99e6ed8e89cff0035deb65f6d7062bc33a58d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 26 Apr 2019 10:30:46 +1000 Subject: [PATCH 02/61] build(deps): bump FodyPackaging from 4.2.1 to 5.0.1 (#2009) Bumps [FodyPackaging](https://github.com/Fody/Fody) from 4.2.1 to 5.0.1. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index e04eb05f6a..b269573000 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -15,7 +15,7 @@ - + From 93b144620149e1c440c769d9e709f37da41dae56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 26 Apr 2019 10:44:55 +1000 Subject: [PATCH 03/61] build(deps): bump Fody from 4.2.1 to 5.0.1 (#2011) Bumps [Fody](https://github.com/Fody/Fody) from 4.2.1 to 5.0.1. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index b269573000..635467e930 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -14,7 +14,7 @@ - + From a3b4eba0cf2737c3e1447329e80550461a4880e1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Fri, 26 Apr 2019 10:45:16 +1000 Subject: [PATCH 04/61] build(deps): bump FodyHelpers from 4.2.1 to 5.0.1 (#2010) Bumps [FodyHelpers](https://github.com/Fody/Fody) from 4.2.1 to 5.0.1. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody/ReactiveUI.Fody.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj index 1b19d2be2f..cc8a633788 100644 --- a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj +++ b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj @@ -7,6 +7,6 @@ - + \ No newline at end of file From 09cdaefae18d8f83ba2851ffe723bd4a2d3c0697 Mon Sep 17 00:00:00 2001 From: Glenn Watson <5834289+glennawatson@users.noreply.github.com> Date: Fri, 26 Apr 2019 19:37:59 +1000 Subject: [PATCH 05/61] housekeeping: further convert some more projects --- .../MasterDetail/MasterDetail/MasterDetail.csproj | 4 ++-- .../xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj | 2 +- src/EventBuilder/Platforms/XamForms.cs | 2 +- .../ReactiveUI.Events.XamForms.csproj | 2 +- version.json | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj b/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj index 8bf04bab70..53ad9b729b 100644 --- a/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj +++ b/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj @@ -6,7 +6,7 @@ - - + + \ No newline at end of file diff --git a/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj b/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj index 58b713d01f..ef81ce12d8 100644 --- a/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj +++ b/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj @@ -149,7 +149,7 @@ - + diff --git a/src/EventBuilder/Platforms/XamForms.cs b/src/EventBuilder/Platforms/XamForms.cs index f5ea59a080..35f7378d8b 100644 --- a/src/EventBuilder/Platforms/XamForms.cs +++ b/src/EventBuilder/Platforms/XamForms.cs @@ -21,7 +21,7 @@ public class XamForms : BasePlatform { private readonly PackageIdentity[] _packageNames = new[] { - new PackageIdentity("Xamarin.Forms", new NuGetVersion("3.5.0.129452")), + new PackageIdentity("Xamarin.Forms", new NuGetVersion("4.0.0.346134-pre9")), }; /// diff --git a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj index 1e51832966..7b3eb7cb11 100644 --- a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj +++ b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/version.json b/version.json index 983607298e..7eb1ba704e 100644 --- a/version.json +++ b/version.json @@ -1,8 +1,8 @@ { - "version": "9.13", + "version": "10.0.1-xamarin-forms4-preview.{height}", "publicReleaseRefSpec": [ "^refs/heads/master$", // we release out of master - "^refs/heads/develop$", // we release out of develop + "^refs/heads/preview/.*", // we release previews "^refs/heads/rel/\\d+\\.\\d+\\.\\d+" // we also release branches starting with rel/N.N.N ], "nugetPackageVersion":{ From b91bb7c406b48afb4a3a9e99ea40fdd2fa7a23f6 Mon Sep 17 00:00:00 2001 From: Glenn Watson <5834289+glennawatson@users.noreply.github.com> Date: Fri, 26 Apr 2019 19:55:00 +1000 Subject: [PATCH 06/61] Revert "housekeeping: further convert some more projects" This reverts commit 09cdaefae18d8f83ba2851ffe723bd4a2d3c0697. --- .../MasterDetail/MasterDetail/MasterDetail.csproj | 4 ++-- .../xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj | 2 +- src/EventBuilder/Platforms/XamForms.cs | 2 +- .../ReactiveUI.Events.XamForms.csproj | 2 +- version.json | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj b/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj index 53ad9b729b..8bf04bab70 100644 --- a/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj +++ b/samples/xamarin-forms/MasterDetail/MasterDetail/MasterDetail.csproj @@ -6,7 +6,7 @@ - - + + \ No newline at end of file diff --git a/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj b/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj index ef81ce12d8..58b713d01f 100644 --- a/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj +++ b/samples/xamarin-forms/MasterDetail/iOS/MasterDetail.iOS.csproj @@ -149,7 +149,7 @@ - + diff --git a/src/EventBuilder/Platforms/XamForms.cs b/src/EventBuilder/Platforms/XamForms.cs index 35f7378d8b..f5ea59a080 100644 --- a/src/EventBuilder/Platforms/XamForms.cs +++ b/src/EventBuilder/Platforms/XamForms.cs @@ -21,7 +21,7 @@ public class XamForms : BasePlatform { private readonly PackageIdentity[] _packageNames = new[] { - new PackageIdentity("Xamarin.Forms", new NuGetVersion("4.0.0.346134-pre9")), + new PackageIdentity("Xamarin.Forms", new NuGetVersion("3.5.0.129452")), }; /// diff --git a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj index 7b3eb7cb11..1e51832966 100644 --- a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj +++ b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj @@ -16,7 +16,7 @@ - + \ No newline at end of file diff --git a/version.json b/version.json index 7eb1ba704e..983607298e 100644 --- a/version.json +++ b/version.json @@ -1,8 +1,8 @@ { - "version": "10.0.1-xamarin-forms4-preview.{height}", + "version": "9.13", "publicReleaseRefSpec": [ "^refs/heads/master$", // we release out of master - "^refs/heads/preview/.*", // we release previews + "^refs/heads/develop$", // we release out of develop "^refs/heads/rel/\\d+\\.\\d+\\.\\d+" // we also release branches starting with rel/N.N.N ], "nugetPackageVersion":{ From 612f46888b88b3f56bb3891949c3889a7b8d6f03 Mon Sep 17 00:00:00 2001 From: Glenn Watson <5834289+glennawatson@users.noreply.github.com> Date: Fri, 26 Apr 2019 20:11:27 +1000 Subject: [PATCH 07/61] remove uap from tests for the moment --- src/ReactiveUI.Tests/ReactiveUI.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj b/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj index abe76aaa88..486a6cddc3 100644 --- a/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj +++ b/src/ReactiveUI.Tests/ReactiveUI.Tests.csproj @@ -2,7 +2,7 @@ netcoreapp2.0 - $(TargetFrameworks);net461;uap10.0.17763 + $(TargetFrameworks);net461 From a1cb284e2119a705dfc80315bf340df505d66503 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sat, 27 Apr 2019 16:44:24 +1000 Subject: [PATCH 08/61] housekeeping: Update to MSBuild.Sdk.Extras v2.0.24 and output API differences on DevOps builds. (#2012) --- .../ReactiveUI.Events.WPF.csproj | 2 +- .../ReactiveUI.Events.Winforms.csproj | 2 +- .../ReactiveUI.Events.csproj | 6 ---- .../ApiApprovalTests.Wpf.net461.approved.txt | 12 -------- .../Utilities/ApiApprovalBase.cs | 30 ++++++++++++++++++- .../ReactiveUI.Winforms.csproj | 2 +- src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj | 2 +- src/global.json | 2 +- 8 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj index 7d9a98a948..db7b5c8bf9 100644 --- a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj +++ b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj @@ -4,7 +4,7 @@ ReactiveUI.Events Provides Observable-based events API for WPF UI controls/eventhandlers. The contents of this package is automatically generated, please target pull-requests to the code generator. ReactiveUI.Events.WPF - true + true $(NoWarn);CS1570;CA1812 diff --git a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj index 181920cb2d..86291fd3bf 100644 --- a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj +++ b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj @@ -5,7 +5,7 @@ ReactiveUI.Events Provides Observable-based events API for Winforms UI controls/eventhandlers. The contents of this package is automatically generated, please target pull-requests to the code generator. ReactiveUI.Events.Winforms - true + true $(NoWarn);CS1570;CA1812 diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index c82e5f0318..3b7cac72a4 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -18,12 +18,6 @@ - - Windows Desktop Extensions for the UWP - - - Windows Mobile Extensions for the UWP - diff --git a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt index 61423593e4..1fd8a824c2 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt +++ b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt @@ -121,16 +121,4 @@ namespace ReactiveUI.Wpf public Registrations() { } public void Register(System.Action, System.Type> registerFunction) { } } -} -namespace XamlGeneratedNamespace -{ - public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper - { - public GeneratedInternalTypeHelper() { } - protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) { } - protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) { } - protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) { } - protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) { } - protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) { } - } } \ No newline at end of file diff --git a/src/ReactiveUI.Tests/Utilities/ApiApprovalBase.cs b/src/ReactiveUI.Tests/Utilities/ApiApprovalBase.cs index b70b89db78..34ff7703e7 100644 --- a/src/ReactiveUI.Tests/Utilities/ApiApprovalBase.cs +++ b/src/ReactiveUI.Tests/Utilities/ApiApprovalBase.cs @@ -5,11 +5,13 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; @@ -46,7 +48,33 @@ protected static void CheckApproval(Assembly assembly, [CallerMemberName]string if (!string.Equals(receivedPublicApi, approvedPublicApi, StringComparison.InvariantCulture)) { File.WriteAllText(receivedFileName, receivedPublicApi); - ShouldlyConfiguration.DiffTools.GetDiffTool().Open(receivedFileName, approvedFileName, true); + try + { + ShouldlyConfiguration.DiffTools.GetDiffTool().Open(receivedFileName, approvedFileName, true); + } + catch (ShouldAssertException) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + Arguments = $"\"{approvedFileName}\" \"{receivedFileName}\"", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + } + }; +#if NET_461 + process.StartInfo.FileName = "FC"; +#else + process.StartInfo.FileName = "diff"; +#endif + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + throw new Exception("Invalid API configuration: " + Environment.NewLine + output); + } } Assert.Equal(approvedPublicApi, receivedPublicApi); diff --git a/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj b/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj index 06d525a43d..20a2476cf2 100644 --- a/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj +++ b/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj @@ -6,7 +6,7 @@ ReactiveUI.Winforms Windows Forms specific extensions to ReactiveUI ReactiveUI.WinForms - true + true diff --git a/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj b/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj index eb92fc1017..eeeb035b67 100644 --- a/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj +++ b/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj @@ -3,7 +3,7 @@ net461 WPF specific extensions to ReactiveUI ReactiveUI.WPF - true + true diff --git a/src/global.json b/src/global.json index 1e4edb34a6..ddab91af6c 100644 --- a/src/global.json +++ b/src/global.json @@ -1,5 +1,5 @@ { "msbuild-sdks": { - "MSBuild.Sdk.Extras": "1.6.68" + "MSBuild.Sdk.Extras": "2.0.24" } } From 8fb7684354b12829818608d39865065360f7d32e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 30 Apr 2019 11:13:00 +1000 Subject: [PATCH 09/61] build(deps): bump Microsoft.Xaml.Behaviors.Uwp.Managed (#2015) Bumps Microsoft.Xaml.Behaviors.Uwp.Managed from 2.0.0 to 2.0.1. Signed-off-by: dependabot[bot] --- src/ReactiveUI.Blend/ReactiveUI.Blend.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj b/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj index cbb2791a28..f523132ca2 100644 --- a/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj +++ b/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj @@ -25,7 +25,7 @@ - + From cbcc5acfad186da9b01799ebdf03e3fb0b38e619 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 30 Apr 2019 12:29:14 +1000 Subject: [PATCH 10/61] build(deps): bump CommandLineParser from 2.4.3 to 2.5.0 (#2014) Bumps [CommandLineParser](https://github.com/commandlineparser/commandline) from 2.4.3 to 2.5.0. - [Release notes](https://github.com/commandlineparser/commandline/releases) - [Changelog](https://github.com/commandlineparser/commandline/blob/master/docs/ChangeLog) - [Commits](https://github.com/commandlineparser/commandline/compare/v2.4.3...v2.5.0) Signed-off-by: dependabot[bot] --- src/EventBuilder/EventBuilder.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventBuilder/EventBuilder.csproj b/src/EventBuilder/EventBuilder.csproj index 2eca6b610e..547e7f22dc 100644 --- a/src/EventBuilder/EventBuilder.csproj +++ b/src/EventBuilder/EventBuilder.csproj @@ -18,7 +18,7 @@ - + From 1838154065e9b318457ff0e899a22543b65ad342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 6 May 2019 10:29:39 +1000 Subject: [PATCH 11/61] build(deps): bump Fody from 5.0.1 to 5.0.5 (#2017) Bumps [Fody](https://github.com/Fody/Fody) from 5.0.1 to 5.0.5. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index 635467e930..fb68bd59ad 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -14,7 +14,7 @@ - + From a41b3f46467f206d94743c2155d5627775ff5701 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 6 May 2019 10:30:47 +1000 Subject: [PATCH 12/61] build(deps): bump FodyHelpers from 5.0.1 to 5.0.6 (#2018) Bumps [FodyHelpers](https://github.com/Fody/Fody) from 5.0.1 to 5.0.6. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody/ReactiveUI.Fody.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj index cc8a633788..b98b86f887 100644 --- a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj +++ b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj @@ -7,6 +7,6 @@ - + \ No newline at end of file From 8fdca6979f5acd1ce55d270c4f6ae7903e38f897 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 6 May 2019 10:31:22 +1000 Subject: [PATCH 13/61] build(deps): bump FodyPackaging from 5.0.1 to 5.0.6 (#2016) Bumps [FodyPackaging](https://github.com/Fody/Fody) from 5.0.1 to 5.0.6. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index fb68bd59ad..5dcb8d151d 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -15,7 +15,7 @@ - + From 7da21d1d135fc745bef85059c9b1c35e9c46878a Mon Sep 17 00:00:00 2001 From: Rodney Littles II <6969701+RLittlesII@users.noreply.github.com> Date: Mon, 6 May 2019 22:47:01 -0500 Subject: [PATCH 14/61] housekeeping: Added IBuilder and Extensions (#2019) --- src/ReactiveUI.Mac.sln | 60 ++++++- .../ReactiveUI.Testing.Tests.csproj | 17 ++ src/ReactiveUI.Testing.Tests/TestFixture.cs | 35 ++++ .../TestFixtureBuilder.cs | 85 +++++++++ .../TestFixtureBuilderExtensionTests.cs | 167 ++++++++++++++++++ src/ReactiveUI.Testing/IBuilderExtensions.cs | 144 +++++++++++++++ .../MessageBusExtensions.cs | 69 ++++++++ .../{TestUtils.cs => SchedulerExtensions.cs} | 53 +----- ...iApprovalTests.Testing.net461.approved.txt | 26 ++- ...alTests.Testing.netcoreapp2.0.approved.txt | 26 ++- src/ReactiveUI.Tests/API/ApiApprovalTests.cs | 2 +- src/ReactiveUI.sln | 60 ++++++- 12 files changed, 681 insertions(+), 63 deletions(-) create mode 100644 src/ReactiveUI.Testing.Tests/ReactiveUI.Testing.Tests.csproj create mode 100644 src/ReactiveUI.Testing.Tests/TestFixture.cs create mode 100644 src/ReactiveUI.Testing.Tests/TestFixtureBuilder.cs create mode 100644 src/ReactiveUI.Testing.Tests/TestFixtureBuilderExtensionTests.cs create mode 100644 src/ReactiveUI.Testing/IBuilderExtensions.cs create mode 100644 src/ReactiveUI.Testing/MessageBusExtensions.cs rename src/ReactiveUI.Testing/{TestUtils.cs => SchedulerExtensions.cs} (81%) diff --git a/src/ReactiveUI.Mac.sln b/src/ReactiveUI.Mac.sln index 22ef441963..1a69974a9e 100644 --- a/src/ReactiveUI.Mac.sln +++ b/src/ReactiveUI.Mac.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26730.15 MinimumVisualStudioVersion = 10.0.40219.1 @@ -28,6 +28,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Fody.Helpers", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Fody.Tests", "ReactiveUI.Fody.Tests\ReactiveUI.Fody.Tests.csproj", "{404B0F3F-7343-4E54-A863-F27B99FE788B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{6591097A-342A-4EA0-AFF6-D2B3207F3E09}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -468,6 +470,62 @@ Global {404B0F3F-7343-4E54-A863-F27B99FE788B}.Release|x64.Build.0 = Release|Any CPU {404B0F3F-7343-4E54-A863-F27B99FE788B}.Release|x86.ActiveCfg = Release|Any CPU {404B0F3F-7343-4E54-A863-F27B99FE788B}.Release|x86.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|Mixed Platforms.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|ARM.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|iPhone.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|Mixed Platforms.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|x64.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|x64.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|x86.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.AppStore|x86.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|ARM.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|ARM.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|iPhone.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|x64.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|x64.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|x86.ActiveCfg = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Debug|x86.Build.0 = Debug|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|Any CPU.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|ARM.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|ARM.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|iPhone.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|iPhone.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|x64.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|x64.Build.0 = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|x86.ActiveCfg = Release|Any CPU + {6591097A-342A-4EA0-AFF6-D2B3207F3E09}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/ReactiveUI.Testing.Tests/ReactiveUI.Testing.Tests.csproj b/src/ReactiveUI.Testing.Tests/ReactiveUI.Testing.Tests.csproj new file mode 100644 index 0000000000..79162b61fd --- /dev/null +++ b/src/ReactiveUI.Testing.Tests/ReactiveUI.Testing.Tests.csproj @@ -0,0 +1,17 @@ + + + netcoreapp2.0 + $(TargetFrameworks);net461 + netstandard2.0 + $(TargetFramework) + + + + + + + + + + + diff --git a/src/ReactiveUI.Testing.Tests/TestFixture.cs b/src/ReactiveUI.Testing.Tests/TestFixture.cs new file mode 100644 index 0000000000..ab66321b2d --- /dev/null +++ b/src/ReactiveUI.Testing.Tests/TestFixture.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace ReactiveUI.Testing.Tests +{ + /// + /// Test fixture. + /// + public class TestFixture + { + /// + /// Gets or sets the count. + /// + public int Count { get; set; } + + /// + /// Gets or sets the name. + /// + public string Name { get; set; } + + /// + /// Gets or sets the tests. + /// + public IEnumerable Tests { get; set; } + + /// + /// Gets or sets the variables. + /// + public Dictionary Variables { get; set; } + } +} diff --git a/src/ReactiveUI.Testing.Tests/TestFixtureBuilder.cs b/src/ReactiveUI.Testing.Tests/TestFixtureBuilder.cs new file mode 100644 index 0000000000..65e67133e4 --- /dev/null +++ b/src/ReactiveUI.Testing.Tests/TestFixtureBuilder.cs @@ -0,0 +1,85 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace ReactiveUI.Testing.Tests +{ + /// + /// An that constructs a . + /// + public class TestFixtureBuilder : IBuilder + { + private int _count; + private string _name; + private List _tests = new List(); + private Dictionary _variables = new Dictionary(); + + /// + /// Performs an implicit conversion from to . + /// + /// The builder. + /// The test fixture. + public static implicit operator TestFixture(TestFixtureBuilder builder) => builder.Build(); + + /// + /// Adds the count to the builder. + /// + /// The count. + /// The builder. + public TestFixtureBuilder WithCount(int count) => this.With(ref _count, count); + + /// + /// Adds the dictionary to the builder. + /// + /// The dictionary. + /// The builder. + public TestFixtureBuilder WithDictionary(Dictionary variables) => this.With(ref _variables, variables); + + /// + /// Adds the key value pair to the builder. + /// + /// The key value pair. + /// The builder. + public TestFixtureBuilder WithKeyValue(KeyValuePair keyValuePair) => this.With(ref _variables, keyValuePair); + + /// + /// Adds a key value pair to the builder. + /// + /// The key. + /// The value. + /// The builder. + public TestFixtureBuilder WithKeyValue(string key, string value) => this.With(ref _variables, key, value); + + /// + /// Adds a name to the builder. + /// + /// The name. + /// The builder. + public TestFixtureBuilder WithName(string name) => this.With(ref _name, name); + + /// + /// Adds a test to the builder. + /// + /// The test. + /// The builder. + public TestFixtureBuilder WithTest(string test) => this.With(ref _tests, test); + + /// + /// Adds tests to the builder. + /// + /// The tests. + /// The builder. + public TestFixtureBuilder WithTests(IEnumerable tests) => this.With(ref _tests, tests); + + private TestFixture Build() => new TestFixture + { + Name = _name, + Count = _count, + Tests = _tests, + Variables = _variables + }; + } +} diff --git a/src/ReactiveUI.Testing.Tests/TestFixtureBuilderExtensionTests.cs b/src/ReactiveUI.Testing.Tests/TestFixtureBuilderExtensionTests.cs new file mode 100644 index 0000000000..68b061126e --- /dev/null +++ b/src/ReactiveUI.Testing.Tests/TestFixtureBuilderExtensionTests.cs @@ -0,0 +1,167 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using Shouldly; +using Xunit; + +namespace ReactiveUI.Testing.Tests +{ + /// + /// Test for . + /// + public sealed class TestFixtureBuilderExtensionTests + { + /// + /// Gets data for the test execution. + /// + public static IEnumerable Data => + new List + { + new object[] { "testing", string.Empty, string.Empty }, + new object[] { "testing", "testing", string.Empty }, + new object[] { "testing", "testing", "one" }, + new object[] { "testing", "one", "two" } + }; + + /// + /// Gets key value for the test execution. + /// + public static IEnumerable KeyValues => + new List + { + new object[] { "testing", string.Empty }, + new object[] { "testing", "one" }, + new object[] { "testing", "two" }, + new object[] { "testing", "one two" } + }; + + /// + /// Gets key value pairs for the test execution. + /// + public static IEnumerable KeyValuePairs => new List + { + new object[] { new KeyValuePair("latch", "key") }, + new object[] { new KeyValuePair("skeleton", "key") }, + new object[] { new KeyValuePair("electronic", "key") }, + new object[] { new KeyValuePair("rsa", "key") } + }; + + /// + /// A test to verify the a dictionary is added to the . + /// + [Fact] + public void Should_Add_Dictionary() + { + // Given, When + var dictionary = new Dictionary + { + { "check", "one" }, + { "testing", "two" } + }; + TestFixture builder = + new TestFixtureBuilder() + .WithDictionary(dictionary); + + // Then + builder.Variables.ShouldBe(dictionary); + Assert.Equal(dictionary, builder.Variables); + } + + /// + /// A test to verify the key value pairs are added to the . + /// + /// The key. + /// The value. + [Theory] + [MemberData(nameof(KeyValues))] + public void Should_Add_Key_Value(string key, string value) + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithKeyValue(key, value); + + // Then + builder.Variables[key].ShouldBe(value); + } + + /// + /// A test to verify the key value pairs are added to the . + /// + /// The key value pair. + [Theory] + [MemberData(nameof(KeyValuePairs))] + public void Should_Add_Key_Value_Pair(KeyValuePair keyValuePair) + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithKeyValue(keyValuePair); + + // Then + builder.Variables[keyValuePair.Key].ShouldBe(keyValuePair.Value); + } + + /// + /// A test to verify a range of values are added to the . + /// + /// The first test. + /// The second test. + /// The third test. + [Theory] + [MemberData(nameof(Data))] + public void Should_Add_Range_To_List(string test1, string test2, string test3) + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithTests(new[] { test1, test2, test3 }); + + // Then + builder.Tests.ShouldBe(new[] { test1, test2, test3 }); + } + + /// + /// A test to verify a value added to a list of tests on the . + /// + [Fact] + public void Should_Add_Value_To_List() + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithTest("testing"); + + // Then + builder.Tests.ShouldBe(new[] { "testing" }); + } + + /// + /// A test to verify the count. + /// + /// The count. + [Theory] + [InlineData(1)] + [InlineData(100)] + [InlineData(1000)] + [InlineData(10000)] + [InlineData(100000)] + public void Should_Return_Count(int count) + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithCount(count); + + // Then + builder.Count.ShouldBe(count); + } + + [Theory] + [InlineData("ReactiveUI")] + [InlineData("Splat")] + [InlineData("Sextant")] + [InlineData("Akavache")] + public void Should_Return_Name(string name) + { + // Given, When + TestFixture builder = new TestFixtureBuilder().WithName(name); + + // Then + builder.Name.ShouldBe(name); + } + } +} diff --git a/src/ReactiveUI.Testing/IBuilderExtensions.cs b/src/ReactiveUI.Testing/IBuilderExtensions.cs new file mode 100644 index 0000000000..a6beb9ff05 --- /dev/null +++ b/src/ReactiveUI.Testing/IBuilderExtensions.cs @@ -0,0 +1,144 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace ReactiveUI.Testing +{ +#pragma warning disable SA1402, SA1649, CA1040 + /// + /// An interface for building. + /// + public interface IBuilder + { + } + + /// + /// Default methods for the abstraction. + /// + public static class IBuilderExtensions + { + /// + /// Adds the specified field to the builder. + /// + /// The type of the builder. + /// The type of the field. + /// This builder. + /// The field. + /// The value. + /// The builder. + public static TBuilder With(this TBuilder builder, ref TField field, TField value) + where TBuilder : IBuilder + { + field = value; + return builder; + } + + /// + /// Adds the specified list of fields to the builder. + /// + /// The type of the builder. + /// The type of the field. + /// This builder. + /// The field. + /// The values. + /// The builder. + public static TBuilder With( + this TBuilder builder, + ref List field, + IEnumerable values) + where TBuilder : IBuilder + { + if (values == null) + { + field = null; + } + else + { + field.AddRange(values); + } + + return builder; + } + + /// + /// Adds the specified field to the builder. + /// + /// The type of the builder. + /// The type of the field. + /// This builder. + /// The field. + /// The value. + /// The builder. + public static TBuilder With(this TBuilder builder, ref List field, TField value) + where TBuilder : IBuilder + { + field.Add(value); + return builder; + } + + /// + /// Adds the specified key value pair to the provided dictionary. + /// + /// The type of the builder. + /// The type of the key. + /// The type of the field. + /// This builder. + /// The dictionary. + /// The key value pair. + /// The builder. + public static TBuilder With( + this TBuilder builder, + ref Dictionary dictionary, + KeyValuePair keyValuePair) + where TBuilder : IBuilder + { + dictionary.Add(keyValuePair.Key, keyValuePair.Value); + return builder; + } + + /// + /// Adds the specified key and value to the provided dictionary. + /// + /// The type of the builder. + /// The type of the key. + /// The type of the field. + /// This builder. + /// The dictionary. + /// The key. + /// The value. + /// The builder. + public static TBuilder With( + this TBuilder builder, + ref Dictionary dictionary, + TKey key, + TField value) + where TBuilder : IBuilder + { + dictionary.Add(key, value); + return builder; + } + + /// + /// Adds the specified dictionary to the provided dictionary. + /// + /// The type of the builder. + /// The type of the key. + /// The type of the field. + /// This builder. + /// The dictionary. + /// The key value pair. + /// The builder. + public static TBuilder With( + this TBuilder builder, + ref Dictionary dictionary, + IDictionary keyValuePair) + { + dictionary = (Dictionary)keyValuePair; + return builder; + } + } +#pragma warning restore SA1402, SA1649, CA1040 +} diff --git a/src/ReactiveUI.Testing/MessageBusExtensions.cs b/src/ReactiveUI.Testing/MessageBusExtensions.cs new file mode 100644 index 0000000000..5f9614d548 --- /dev/null +++ b/src/ReactiveUI.Testing/MessageBusExtensions.cs @@ -0,0 +1,69 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.Reactive.Disposables; +using System.Threading; + +namespace ReactiveUI.Testing +{ + /// + /// Message bus testing extensions. + /// + public static class MessageBusExtensions + { + private static readonly object mbGate = 42; + + /// + /// Override the default Message Bus during the specified block. + /// + /// The return type. + /// The message bus to use for the block. + /// The function to execute. + /// The return value of the function. + public static TRet With(this IMessageBus messageBus, Func block) + { + using (messageBus.WithMessageBus()) + { + return block(); + } + } + + /// + /// WithMessageBus allows you to override the default Message Bus + /// implementation until the object returned is disposed. If a + /// message bus is not specified, a default empty one is created. + /// + /// The message bus to use, or null to create + /// a new one using the default implementation. + /// An object that when disposed, restores the original + /// message bus. + public static IDisposable WithMessageBus(this IMessageBus messageBus) + { + var origMessageBus = MessageBus.Current; + + Monitor.Enter(mbGate); + MessageBus.Current = messageBus ?? new MessageBus(); + return Disposable.Create(() => + { + MessageBus.Current = origMessageBus; + Monitor.Exit(mbGate); + }); + } + + /// + /// Override the default Message Bus during the specified block. + /// + /// The message bus to use for the block. + /// The action to execute. + public static void With(this IMessageBus messageBus, Action block) + { + using (messageBus.WithMessageBus()) + { + block(); + } + } + } +} diff --git a/src/ReactiveUI.Testing/TestUtils.cs b/src/ReactiveUI.Testing/SchedulerExtensions.cs similarity index 81% rename from src/ReactiveUI.Testing/TestUtils.cs rename to src/ReactiveUI.Testing/SchedulerExtensions.cs index 023fa6c0d2..404423076f 100644 --- a/src/ReactiveUI.Testing/TestUtils.cs +++ b/src/ReactiveUI.Testing/SchedulerExtensions.cs @@ -15,11 +15,10 @@ namespace ReactiveUI.Testing { #pragma warning disable SA1600 // Elements should be documented - public static class TestUtils + public static class SchedulerExtensions #pragma warning restore SA1600 // Elements should be documented { private static readonly AutoResetEvent schedGate = new AutoResetEvent(true); - private static readonly object mbGate = 42; /// /// WithScheduler overrides the default Deferred and Taskpool schedulers @@ -47,28 +46,6 @@ public static IDisposable WithScheduler(IScheduler sched) }); } - /// - /// WithMessageBus allows you to override the default Message Bus - /// implementation until the object returned is disposed. If a - /// message bus is not specified, a default empty one is created. - /// - /// The message bus to use, or null to create - /// a new one using the default implementation. - /// An object that when disposed, restores the original - /// message bus. - public static IDisposable WithMessageBus(this IMessageBus messageBus) - { - var origMessageBus = MessageBus.Current; - - Monitor.Enter(mbGate); - MessageBus.Current = messageBus ?? new MessageBus(); - return Disposable.Create(() => - { - MessageBus.Current = origMessageBus; - Monitor.Exit(mbGate); - }); - } - /// /// With is an extension method that uses the given scheduler as the /// default Deferred and Taskpool schedulers for the given Func. Use @@ -150,34 +127,6 @@ public static Task WithAsync(this T sched, Func block) }); } - /// - /// Override the default Message Bus during the specified block. - /// - /// The return type. - /// The message bus to use for the block. - /// The function to execute. - /// The return value of the function. - public static TRet With(this IMessageBus messageBus, Func block) - { - using (messageBus.WithMessageBus()) - { - return block(); - } - } - - /// - /// Override the default Message Bus during the specified block. - /// - /// The message bus to use for the block. - /// The action to execute. - public static void With(this IMessageBus messageBus, Action block) - { - using (messageBus.WithMessageBus()) - { - block(); - } - } - /// /// AdvanceToMs moves the TestScheduler to the specified time in /// milliseconds. diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.net461.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.net461.approved.txt index 92b48a4a3d..517ff80fca 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.net461.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.net461.approved.txt @@ -1,7 +1,28 @@ [assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName=".NET Framework 4.6.1")] namespace ReactiveUI.Testing { - public class static TestUtils + public interface IBuilder { } + public class static IBuilderExtensions + { + public static TBuilder With(this TBuilder builder, ref TField field, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.List<> field, System.Collections.Generic.IEnumerable values) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.List<> field, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, System.Collections.Generic.KeyValuePair keyValuePair) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, TKey key, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, System.Collections.Generic.IDictionary keyValuePair) { } + } + public class static MessageBusExtensions + { + public static TRet With(this ReactiveUI.IMessageBus messageBus, System.Func block) { } + public static void With(this ReactiveUI.IMessageBus messageBus, System.Action block) { } + public static System.IDisposable WithMessageBus(this ReactiveUI.IMessageBus messageBus) { } + } + public class static SchedulerExtensions { public static void AdvanceByMs(this Microsoft.Reactive.Testing.TestScheduler sched, double milliseconds) { } public static void AdvanceToMs(this Microsoft.Reactive.Testing.TestScheduler sched, double milliseconds) { } @@ -13,13 +34,10 @@ namespace ReactiveUI.Testing where T : System.Reactive.Concurrency.IScheduler { } public static void With(this T sched, System.Action block) where T : System.Reactive.Concurrency.IScheduler { } - public static TRet With(this ReactiveUI.IMessageBus messageBus, System.Func block) { } - public static void With(this ReactiveUI.IMessageBus messageBus, System.Action block) { } public static System.Threading.Tasks.Task WithAsync(this T sched, System.Func> block) where T : System.Reactive.Concurrency.IScheduler { } public static System.Threading.Tasks.Task WithAsync(this T sched, System.Func block) where T : System.Reactive.Concurrency.IScheduler { } - public static System.IDisposable WithMessageBus(this ReactiveUI.IMessageBus messageBus) { } public static System.IDisposable WithScheduler(System.Reactive.Concurrency.IScheduler sched) { } } } \ No newline at end of file diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.netcoreapp2.0.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.netcoreapp2.0.approved.txt index 4a2e257408..af2f4a4878 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.netcoreapp2.0.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.Testing.netcoreapp2.0.approved.txt @@ -1,7 +1,28 @@ [assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v2.0", FrameworkDisplayName="")] namespace ReactiveUI.Testing { - public class static TestUtils + public interface IBuilder { } + public class static IBuilderExtensions + { + public static TBuilder With(this TBuilder builder, ref TField field, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.List<> field, System.Collections.Generic.IEnumerable values) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.List<> field, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, System.Collections.Generic.KeyValuePair keyValuePair) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, TKey key, TField value) + where TBuilder : ReactiveUI.Testing.IBuilder { } + public static TBuilder With(this TBuilder builder, ref System.Collections.Generic.Dictionary<, > dictionary, System.Collections.Generic.IDictionary keyValuePair) { } + } + public class static MessageBusExtensions + { + public static TRet With(this ReactiveUI.IMessageBus messageBus, System.Func block) { } + public static void With(this ReactiveUI.IMessageBus messageBus, System.Action block) { } + public static System.IDisposable WithMessageBus(this ReactiveUI.IMessageBus messageBus) { } + } + public class static SchedulerExtensions { public static void AdvanceByMs(this Microsoft.Reactive.Testing.TestScheduler sched, double milliseconds) { } public static void AdvanceToMs(this Microsoft.Reactive.Testing.TestScheduler sched, double milliseconds) { } @@ -13,13 +34,10 @@ namespace ReactiveUI.Testing where T : System.Reactive.Concurrency.IScheduler { } public static void With(this T sched, System.Action block) where T : System.Reactive.Concurrency.IScheduler { } - public static TRet With(this ReactiveUI.IMessageBus messageBus, System.Func block) { } - public static void With(this ReactiveUI.IMessageBus messageBus, System.Action block) { } public static System.Threading.Tasks.Task WithAsync(this T sched, System.Func> block) where T : System.Reactive.Concurrency.IScheduler { } public static System.Threading.Tasks.Task WithAsync(this T sched, System.Func block) where T : System.Reactive.Concurrency.IScheduler { } - public static System.IDisposable WithMessageBus(this ReactiveUI.IMessageBus messageBus) { } public static System.IDisposable WithScheduler(System.Reactive.Concurrency.IScheduler sched) { } } } \ No newline at end of file diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.cs b/src/ReactiveUI.Tests/API/ApiApprovalTests.cs index ccef8ee02e..ddccdbbcab 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.cs +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.cs @@ -18,7 +18,7 @@ public class ApiApprovalTests : ApiApprovalBase [Fact] public void Testing() { - CheckApproval(typeof(Testing.TestUtils).Assembly); + CheckApproval(typeof(Testing.SchedulerExtensions).Assembly); } [Fact] diff --git a/src/ReactiveUI.sln b/src/ReactiveUI.sln index 9193af3007..f9c29ccc32 100644 --- a/src/ReactiveUI.sln +++ b/src/ReactiveUI.sln @@ -1,4 +1,4 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 +Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26730.15 MinimumVisualStudioVersion = 10.0.40219.1 @@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Fody.Tests", "Re EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Splat.Tests", "ReactiveUI.Splat.Tests\ReactiveUI.Splat.Tests.csproj", "{7ED6D69F-138F-40BD-9F37-3E4050E4D19B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Ad-Hoc|Any CPU = Ad-Hoc|Any CPU @@ -758,6 +760,62 @@ Global {7ED6D69F-138F-40BD-9F37-3E4050E4D19B}.Release|x64.Build.0 = Release|Any CPU {7ED6D69F-138F-40BD-9F37-3E4050E4D19B}.Release|x86.ActiveCfg = Release|Any CPU {7ED6D69F-138F-40BD-9F37-3E4050E4D19B}.Release|x86.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|Mixed Platforms.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|ARM.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|iPhone.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|Mixed Platforms.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|x64.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|x64.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|x86.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.AppStore|x86.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|ARM.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|ARM.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|iPhone.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|x64.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|x64.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|x86.ActiveCfg = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Debug|x86.Build.0 = Debug|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|Any CPU.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|ARM.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|ARM.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|iPhone.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|iPhone.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x64.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x64.Build.0 = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.ActiveCfg = Release|Any CPU + {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From a941bda455ee36a1bf56c8d8dc7106be31dc4e8d Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Tue, 7 May 2019 14:18:39 +1000 Subject: [PATCH 15/61] Update version.json --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 983607298e..e03f7d0f40 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "9.13", + "version": "9.14", "publicReleaseRefSpec": [ "^refs/heads/master$", // we release out of master "^refs/heads/develop$", // we release out of develop From f0b78c4648881422d27d9900f501c2a9f84e6a26 Mon Sep 17 00:00:00 2001 From: Artyom Date: Wed, 8 May 2019 14:55:26 +0300 Subject: [PATCH 16/61] fix: POCOObservableForProperty having a race condition (#2020) --- .../ObservableForProperty/POCOObservableForProperty.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ReactiveUI/ObservableForProperty/POCOObservableForProperty.cs b/src/ReactiveUI/ObservableForProperty/POCOObservableForProperty.cs index fb54ab0ffa..55fd028027 100644 --- a/src/ReactiveUI/ObservableForProperty/POCOObservableForProperty.cs +++ b/src/ReactiveUI/ObservableForProperty/POCOObservableForProperty.cs @@ -4,6 +4,7 @@ // See the LICENSE file in the project root for full license information. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq.Expressions; using System.Reactive.Linq; @@ -18,7 +19,7 @@ namespace ReactiveUI /// public class POCOObservableForProperty : ICreatesObservableForProperty { - private static readonly Dictionary<(Type, string), bool> hasWarned = new Dictionary<(Type, string), bool>(); + private static readonly IDictionary<(Type, string), bool> hasWarned = new ConcurrentDictionary<(Type, string), bool>(); /// public int GetAffinityForObject(Type type, string propertyName, bool beforeChanged = false) From afdf520a8c5ee7f6bee053af61d7593fad93c2ce Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 12 May 2019 16:41:17 +1000 Subject: [PATCH 17/61] fix: WhenActivated not fired when in ViewModelViewHost (#2023) --- 4eac0733-0a64-4c41-a024-157e17e6276c.cake | 2 ++ src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj | 1 + .../ReactiveUI.Events.Winforms.csproj | 1 + src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj | 1 + src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj | 1 + 5 files changed, 6 insertions(+) create mode 100644 4eac0733-0a64-4c41-a024-157e17e6276c.cake diff --git a/4eac0733-0a64-4c41-a024-157e17e6276c.cake b/4eac0733-0a64-4c41-a024-157e17e6276c.cake new file mode 100644 index 0000000000..944cbe2555 --- /dev/null +++ b/4eac0733-0a64-4c41-a024-157e17e6276c.cake @@ -0,0 +1,2 @@ +#module nuget:?package=Cake.DotNetTool.Module&version=0.2.0 +#tool dotnet:?package=nbgv&version=2.3.125 diff --git a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj index db7b5c8bf9..82be16bf7a 100644 --- a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj +++ b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj @@ -5,6 +5,7 @@ Provides Observable-based events API for WPF UI controls/eventhandlers. The contents of this package is automatically generated, please target pull-requests to the code generator. ReactiveUI.Events.WPF true + true $(NoWarn);CS1570;CA1812 diff --git a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj index 86291fd3bf..0f708db9a0 100644 --- a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj +++ b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj @@ -6,6 +6,7 @@ Provides Observable-based events API for Winforms UI controls/eventhandlers. The contents of this package is automatically generated, please target pull-requests to the code generator. ReactiveUI.Events.Winforms true + true $(NoWarn);CS1570;CA1812 diff --git a/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj b/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj index 20a2476cf2..8e783dc7d4 100644 --- a/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj +++ b/src/ReactiveUI.Winforms/ReactiveUI.Winforms.csproj @@ -7,6 +7,7 @@ Windows Forms specific extensions to ReactiveUI ReactiveUI.WinForms true + true diff --git a/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj b/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj index eeeb035b67..8a485de71e 100644 --- a/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj +++ b/src/ReactiveUI.Wpf/ReactiveUI.Wpf.csproj @@ -4,6 +4,7 @@ WPF specific extensions to ReactiveUI ReactiveUI.WPF true + true From dfe84987fd9df8861316c600b2f6a2580996faba Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Mon, 13 May 2019 19:16:07 +1000 Subject: [PATCH 18/61] housekeeping: Update from ReactiveExtensions 4.0.0 to 4.1.5 (#2025) --- ...iveUI.Samples.Testing.SimpleViewModelsUnitTests.csproj | 2 +- src/Directory.build.props | 8 ++++---- src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj | 2 +- .../ReactiveUI.Events.Winforms.csproj | 2 +- .../ReactiveUI.Events.XamEssentials.csproj | 2 +- .../ReactiveUI.Events.XamForms.csproj | 2 +- src/ReactiveUI.Events/ReactiveUI.Events.csproj | 2 +- .../ReactiveUI.Fody.Helpers.csproj | 2 +- src/ReactiveUI.Testing/ReactiveUI.Testing.csproj | 2 +- src/ReactiveUI/ReactiveUI.csproj | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/samples/testing/ReactiveUI.Samples.Testing.SimpleViewModels/src/ReactiveUI.Samples.Testing.SimpleViewModels.Tests/ReactiveUI.Samples.Testing.SimpleViewModelsUnitTests.csproj b/samples/testing/ReactiveUI.Samples.Testing.SimpleViewModels/src/ReactiveUI.Samples.Testing.SimpleViewModels.Tests/ReactiveUI.Samples.Testing.SimpleViewModelsUnitTests.csproj index 6644f8d464..c5ffddf033 100644 --- a/samples/testing/ReactiveUI.Samples.Testing.SimpleViewModels/src/ReactiveUI.Samples.Testing.SimpleViewModels.Tests/ReactiveUI.Samples.Testing.SimpleViewModelsUnitTests.csproj +++ b/samples/testing/ReactiveUI.Samples.Testing.SimpleViewModels/src/ReactiveUI.Samples.Testing.SimpleViewModels.Tests/ReactiveUI.Samples.Testing.SimpleViewModelsUnitTests.csproj @@ -3,7 +3,7 @@ netcoreapp2.2;net461 - + diff --git a/src/Directory.build.props b/src/Directory.build.props index e6dff6f4db..b0e4deb9eb 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -27,13 +27,13 @@ - + - + - + @@ -58,7 +58,7 @@ - + diff --git a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj index 82be16bf7a..b39539f464 100644 --- a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj +++ b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj index 0f708db9a0..cc2914e4da 100644 --- a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj +++ b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj index 01a67d0663..90574acfef 100644 --- a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj +++ b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj index 1e51832966..955b8ae905 100644 --- a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj +++ b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index 3b7cac72a4..836ec679c0 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index 5dcb8d151d..1803341f0a 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj b/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj index 26ba93cf0e..c5d3abf429 100644 --- a/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj +++ b/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/ReactiveUI/ReactiveUI.csproj b/src/ReactiveUI/ReactiveUI.csproj index ca8b047c24..6dc37dd017 100644 --- a/src/ReactiveUI/ReactiveUI.csproj +++ b/src/ReactiveUI/ReactiveUI.csproj @@ -11,7 +11,7 @@ - + From 3cf59aba88d4e14aa94c5f19264d8d47d8db77bd Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Mon, 13 May 2019 20:13:30 +1000 Subject: [PATCH 19/61] fix: WhenActivated on WPF by reverting to MsBuild.Sdk.Extras 1.6.18 (#2027) --- src/ReactiveUI.Events/ReactiveUI.Events.csproj | 6 ++++++ .../wpf/API/ApiApprovalTests.Wpf.net461.approved.txt | 12 ++++++++++++ src/global.json | 2 +- version.json | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index 836ec679c0..31596662f7 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -17,6 +17,12 @@ + + Windows Desktop Extensions for the UWP + + + Windows Mobile Extensions for the UWP + diff --git a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt index 1fd8a824c2..61423593e4 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt +++ b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt @@ -121,4 +121,16 @@ namespace ReactiveUI.Wpf public Registrations() { } public void Register(System.Action, System.Type> registerFunction) { } } +} +namespace XamlGeneratedNamespace +{ + public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper + { + public GeneratedInternalTypeHelper() { } + protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) { } + protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) { } + protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) { } + protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) { } + protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) { } + } } \ No newline at end of file diff --git a/src/global.json b/src/global.json index ddab91af6c..1e4edb34a6 100644 --- a/src/global.json +++ b/src/global.json @@ -1,5 +1,5 @@ { "msbuild-sdks": { - "MSBuild.Sdk.Extras": "2.0.24" + "MSBuild.Sdk.Extras": "1.6.68" } } diff --git a/version.json b/version.json index e03f7d0f40..75a1e504c3 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "9.14", + "version": "9.15", "publicReleaseRefSpec": [ "^refs/heads/master$", // we release out of master "^refs/heads/develop$", // we release out of develop From 97d1aa3780f79f933933befda79666b27a83a76b Mon Sep 17 00:00:00 2001 From: Artyom Date: Mon, 13 May 2019 14:30:14 +0300 Subject: [PATCH 20/61] Add Universal Windows routing example (#2030) --- samples/uwp/ReactiveUI.UwpRouting.sln | 51 +++++ samples/uwp/ReactiveUI.UwpRouting/App.xaml | 5 + samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs | 33 ++++ .../Assets/LockScreenLogo.scale-200.png | 3 + .../Assets/SplashScreen.scale-200.png | 3 + .../Assets/Square150x150Logo.scale-200.png | 3 + .../Assets/Square44x44Logo.scale-200.png | 3 + ...x44Logo.targetsize-24_altform-unplated.png | 3 + .../Assets/StoreLogo.png | 3 + .../Assets/Wide310x150Logo.scale-200.png | 3 + .../Package.appxmanifest | 49 +++++ .../Properties/AssemblyInfo.cs | 29 +++ .../Properties/Default.rd.xml | 31 +++ .../ReactiveUI.UwpRouting.csproj | 181 ++++++++++++++++++ .../ViewModels/FirstViewModel.cs | 15 ++ .../ViewModels/MainViewModel.cs | 39 ++++ .../Views/FirstView.xaml | 16 ++ .../Views/FirstView.xaml.cs | 30 +++ .../ReactiveUI.UwpRouting/Views/MainView.xaml | 19 ++ .../Views/MainView.xaml.cs | 31 +++ 20 files changed, 550 insertions(+) create mode 100644 samples/uwp/ReactiveUI.UwpRouting.sln create mode 100644 samples/uwp/ReactiveUI.UwpRouting/App.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml.cs diff --git a/samples/uwp/ReactiveUI.UwpRouting.sln b/samples/uwp/ReactiveUI.UwpRouting.sln new file mode 100644 index 0000000000..f5624f7e8d --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.489 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.UwpRouting", "ReactiveUI.UwpRouting\ReactiveUI.UwpRouting.csproj", "{702CB6D2-A9E0-40A4-A64D-BAACC63893A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.ActiveCfg = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.Build.0 = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.Deploy.0 = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.Build.0 = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.ActiveCfg = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.Build.0 = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.Deploy.0 = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.ActiveCfg = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.Build.0 = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.Deploy.0 = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.ActiveCfg = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.Build.0 = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.Deploy.0 = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.ActiveCfg = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.Build.0 = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.Deploy.0 = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.ActiveCfg = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.Build.0 = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.Deploy.0 = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.ActiveCfg = Release|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.Build.0 = Release|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7F4403AB-47C8-4125-8E65-DC8E07DBDA1E} + EndGlobalSection +EndGlobal diff --git a/samples/uwp/ReactiveUI.UwpRouting/App.xaml b/samples/uwp/ReactiveUI.UwpRouting/App.xaml new file mode 100644 index 0000000000..5d3b064472 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/App.xaml @@ -0,0 +1,5 @@ + + diff --git a/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs b/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs new file mode 100644 index 0000000000..3b952c8bf5 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs @@ -0,0 +1,33 @@ +using System; +using Windows.ApplicationModel.Activation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; +using ReactiveUI.UwpRouting.Views; + +namespace ReactiveUI.UwpRouting +{ + public sealed partial class App : Application + { + public App() => InitializeComponent(); + + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + if (!(Window.Current.Content is Frame rootFrame)) + { + rootFrame = new Frame(); + rootFrame.NavigationFailed += OnNavigationFailed; + Window.Current.Content = rootFrame; + } + + if (e.PrelaunchActivated != false) return; + if (rootFrame.Content == null) rootFrame.Navigate(typeof(MainView), e.Arguments); + Window.Current.Activate(); + } + + private static void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000..8cf1cc0297 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a41a053b3fc3b0c109720ccd437a19725ae9163ea75990222a12b596b9c7ca76 +size 1430 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000..1ade290fb9 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3382b0b1b834e95b888f06d483dc2d78fa1b3855e0683d5cfbd5167be9731a6 +size 7700 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000..f269619be8 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f3cb5738e8f05544445f79996a313f8b47dee22dbc9c7be859d2707710f0c73 +size 2937 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000..818d96d80a --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:594492a25070951d7462c091d9f899a66f55ba992bb9b05d98d50f67cdfb2abe +size 1647 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000..8c010282f4 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48cf9c22156a0b3d77982641f972785e7861a7257f7bcf155be7d5a12e1aa3d8 +size 1255 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png new file mode 100644 index 0000000000..679f7d7461 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae95e99a96251abaf8de15c9cdaddb8cefb1b8b320b10a4f1f4e1dc3c25c1b1a +size 1451 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000..7578982624 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5b7754832c08e58faacfe64ea4b9f8b59b52a658e4eea4aab3790cfb89faa03 +size 3204 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest b/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest new file mode 100644 index 0000000000..eb37fd2af9 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + ReactiveUI.UwpRouting + prizr + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs b/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..73eef03c56 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ReactiveUI.UwpRouting")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ReactiveUI.UwpRouting")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml b/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml new file mode 100644 index 0000000000..af00722cdf --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj b/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj new file mode 100644 index 0000000000..eb2cc216d5 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj @@ -0,0 +1,181 @@ + + + + + Debug + x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8} + AppContainerExe + Properties + ReactiveUI.UwpRouting + ReactiveUI.UwpRouting + en-US + UAP + 10.0.17763.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + ReactiveUI.UwpRouting_TemporaryKey.pfx + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + + + + FirstView.xaml + + + MainView.xaml + + + + + Designer + + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + 6.2.8 + + + 9.15.1 + + + + 14.0 + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs new file mode 100644 index 0000000000..f0cb835f3f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs @@ -0,0 +1,15 @@ +using System; + +namespace ReactiveUI.UwpRouting.ViewModels +{ + public class FirstViewModel : ReactiveObject, IRoutableViewModel + { + // Reference to IScreen that owns the routable view model. + public IScreen HostScreen { get; } + + // Unique identifier for the routable view model. + public string UrlPathSegment { get; } = Guid.NewGuid().ToString().Substring(0, 5); + + public FirstViewModel(IScreen screen) => HostScreen = screen; + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs new file mode 100644 index 0000000000..62e3ffabcd --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs @@ -0,0 +1,39 @@ +using System.Reactive; +using ReactiveUI.UwpRouting.Views; +using Splat; + +namespace ReactiveUI.UwpRouting.ViewModels +{ + public class MainViewModel : ReactiveObject, IScreen + { + // The Router associated with this Screen. + // Required by the IScreen interface. + public RoutingState Router { get; } = new RoutingState(); + + // The command that navigates a user to first view model. + public ReactiveCommand GoNext { get; } + + // The command that navigates a user back. + public ReactiveCommand GoBack => Router.NavigateBack; + + public MainViewModel() + { + // Router uses Splat.Locator to resolve views for + // view models, so we need to register our views + // using Locator.CurrentMutable.Register* methods. + // + Locator.CurrentMutable.Register(() => new FirstView(), typeof(IViewFor)); + + // Manage the routing state. Use the Router.Navigate.Execute + // command to navigate to different view models. + // + // Note, that the Navigate.Execute method accepts an instance + // of a view model, this allows you to pass parameters to + // your view models, or to reuse existing view models. + // + GoNext = ReactiveCommand.CreateFromObservable( + () => Router.Navigate.Execute(new FirstViewModel(this)) + ); + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml new file mode 100644 index 0000000000..53fecbb525 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs new file mode 100644 index 0000000000..dc1470a19f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs @@ -0,0 +1,30 @@ +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using ReactiveUI.UwpRouting.ViewModels; + +namespace ReactiveUI.UwpRouting.Views +{ + public sealed partial class FirstView : UserControl, IViewFor + { + public static readonly DependencyProperty ViewModelProperty = DependencyProperty + .Register(nameof(ViewModel), typeof(FirstViewModel), typeof(FirstView), null); + + public FirstView() + { + InitializeComponent(); + this.WhenActivated(disposables => { }); + } + + public FirstViewModel ViewModel + { + get => (FirstViewModel)GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (FirstViewModel)value; + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml b/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml new file mode 100644 index 0000000000..7fa82a804f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml @@ -0,0 +1,19 @@ + + + + + + + + + - public static partial class ControlFetcherMixin + public static partial class ControlFetcherMixin { - private static readonly Dictionary controlIds; - private static readonly ConditionalWeakTable> viewCache = new ConditionalWeakTable>(); private static readonly MethodInfo getControlActivity; private static readonly MethodInfo getControlView; - [SuppressMessage("Design", "CA1065: Not not throw exceptions in static constructor", Justification = "TODO: Future fix")] static ControlFetcherMixin() { - // NB: This is some hacky shit, but on Xamarin.Android at the moment, - // this is always the entry assembly. - var assm = AppDomain.CurrentDomain.GetAssemblies()[1]; - var resources = assm.GetModules().SelectMany(x => x.GetTypes()).First(x => x.Name == "Resource"); - - try - { - controlIds = resources.GetNestedType("Id").GetFields() - .Where(x => x.FieldType == typeof(int)) - .ToDictionary(k => k.Name.ToLowerInvariant(), v => (int)v.GetRawConstantValue()); - } - catch (ArgumentException argumentException) - { - var duplicates = resources.GetNestedType("Id").GetFields() - .Where(x => x.FieldType == typeof(int)) - .GroupBy(k => k.Name.ToLowerInvariant()) - .Where(g => g.Count() > 1) - .Select(g => "{ " + string.Join(" = ", g.Select(v => v.Name)) + " }") - .ToList(); - - if (duplicates.Any()) - { - throw new InvalidOperationException("You're using multiple resource ID's with the same name but with different casings which isn't allowed for WireUpControls: " + string.Join(", ", duplicates), argumentException); - } - - throw; - } - var type = typeof(ControlFetcherMixin); getControlActivity = type.GetMethod("GetControl", new[] { typeof(Activity), typeof(string) }); getControlView = type.GetMethod("GetControl", new[] { typeof(View), typeof(string) }); @@ -70,163 +38,181 @@ static ControlFetcherMixin() /// Gets the control from an activity. /// /// The control type. - /// The activity. + /// The activity. /// The property name. /// The return view. - public static T GetControl(this Activity @this, [CallerMemberName]string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, @this, () => @this.FindViewById(controlIds[propertyName.ToLowerInvariant()]).JavaCast()); + public static T GetControl(this Activity activity, [CallerMemberName] string propertyName = null) + where T : View => (T)GetCachedControl(propertyName, activity, () => activity + .FindViewById(GetResourceId(activity, propertyName)) + .JavaCast()); /// /// Gets the control from an activity. /// /// The control type. - /// The view. + /// The view. /// The property. /// The return view. - public static T GetControl(this View @this, [CallerMemberName]string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, @this, () => @this.FindViewById(controlIds[propertyName.ToLowerInvariant()]).JavaCast()); + public static T GetControl(this View view, [CallerMemberName] string propertyName = null) + where T : View => (T)GetCachedControl(propertyName, view, () => view + .FindViewById(GetResourceId(view, propertyName)) + .JavaCast()); /// /// Gets the control from an activity. /// /// The control type. - /// The fragment. + /// The fragment. /// The property name. /// The return view. - public static T GetControl(this Fragment @this, [CallerMemberName]string propertyName = null) - where T : View => GetControl(@this.View, propertyName); + public static T GetControl(this Fragment fragment, [CallerMemberName] string propertyName = null) + where T : View => GetControl(fragment.View, propertyName); /// /// Wires a control to a property. /// - /// The layout view host. + /// The layout view host. /// The resolve members. - public static void WireUpControls(this ILayoutViewHost @this, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) + public static void WireUpControls(this ILayoutViewHost layoutHost, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) { - var members = @this.GetWireUpMembers(resolveMembers); - - members.ToList().ForEach(m => + var members = layoutHost.GetWireUpMembers(resolveMembers).ToList(); + foreach (var member in members) { try { - // Find the android control with the same name - var view = @this.View.GetControlInternal(m.PropertyType, m.GetResourceName()); - - // Set the activity field's value to the view with that identifier - m.SetValue(@this, view); + var view = layoutHost.View.GetControlInternal(member.PropertyType, member.GetResourceName()); + member.SetValue(layoutHost, view); } catch (Exception ex) { - throw new MissingFieldException("Failed to wire up the Property " + m.Name + " to a View in your layout with a corresponding identifier", ex); + throw new + MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); } - }); + } } /// /// Wires a control to a property. /// - /// The view. + /// The view. /// The resolve members. - public static void WireUpControls(this View @this, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) + public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) { - var members = @this.GetWireUpMembers(resolveMembers); + var members = view.GetWireUpMembers(resolveMembers); - members.ToList().ForEach(m => + foreach (var member in members) { try { // Find the android control with the same name - var view = @this.GetControlInternal(m.PropertyType, m.GetResourceName()); + var currentView = view.GetControlInternal(member.PropertyType, member.GetResourceName()); // Set the activity field's value to the view with that identifier - m.SetValue(@this, view); + member.SetValue(view, currentView); } catch (Exception ex) { - throw new MissingFieldException("Failed to wire up the Property " + m.Name + " to a View in your layout with a corresponding identifier", ex); + throw new + MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); } - }); + } } /// /// Wires a control to a property. - /// This should be called in the Fragement's OnCreateView, with the newly inflated layout. + /// This should be called in the Fragment's OnCreateView, with the newly inflated layout. /// - /// The fragment. + /// The fragment. /// The inflated view. /// The resolve members. - public static void WireUpControls(this Fragment @this, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) + public static void WireUpControls(this Fragment fragment, View inflatedView, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = + ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) { - var members = @this.GetWireUpMembers(resolveMembers); + var members = fragment.GetWireUpMembers(resolveMembers); - members.ToList().ForEach(m => + foreach (var member in members) { try { // Find the android control with the same name from the view - var view = inflatedView.GetControlInternal(m.PropertyType, m.GetResourceName()); + var view = inflatedView.GetControlInternal(member.PropertyType, member.GetResourceName()); // Set the activity field's value to the view with that identifier - m.SetValue(@this, view); + member.SetValue(fragment, view); } catch (Exception ex) { - throw new MissingFieldException("Failed to wire up the Property " + m.Name + " to a View in your layout with a corresponding identifier", ex); + throw new + MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); } - }); + } } /// /// Wires a control to a property. /// - /// The Activity. + /// The Activity. /// The resolve members. - public static void WireUpControls(this Activity @this, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) + public static void WireUpControls(this Activity activity, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) { - var members = @this.GetWireUpMembers(resolveMembers); + var members = activity.GetWireUpMembers(resolveMembers); - members.ToList().ForEach(m => + foreach (var member in members) { try { // Find the android control with the same name - var view = @this.GetControlInternal(m.PropertyType, m.GetResourceName()); + var view = activity.GetControlInternal(member.PropertyType, member.GetResourceName()); // Set the activity field's value to the view with that identifier - m.SetValue(@this, view); + member.SetValue(activity, view); } catch (Exception ex) { - throw new MissingFieldException("Failed to wire up the Property " + m.Name + " to a View in your layout with a corresponding identifier", ex); + throw new + MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); } - }); + } } private static View GetControlInternal(this View parent, Type viewType, string name) { - var mi = getControlView.MakeGenericMethod(new[] { viewType }); - return (View)mi.Invoke(null, new object[] { parent, name }); + var memberInfo = getControlView.MakeGenericMethod(new[] { viewType }); + return (View)memberInfo.Invoke(null, new object[] { parent, name }); } private static View GetControlInternal(this Activity parent, Type viewType, string name) { - var mi = getControlActivity.MakeGenericMethod(new[] { viewType }); - return (View)mi.Invoke(null, new object[] { parent, name }); + var memberInfo = getControlActivity.MakeGenericMethod(new[] { viewType }); + return (View)memberInfo.Invoke(null, new object[] { parent, name }); + } + + private static int GetResourceId(Activity activity, string resourceName) + { + var res = activity.Resources; + return res.GetIdentifier(resourceName, "id", activity.PackageName); + } + + private static int GetResourceId(View view, string resourceName) + { + var res = view.Context.Resources; + return res.GetIdentifier(resourceName, "id", view.Context.PackageName); } private static View GetCachedControl(string propertyName, object rootView, Func fetchControlFromView) { + View ret; var ourViewCache = viewCache.GetOrCreateValue(rootView); - if (ourViewCache.TryGetValue(propertyName, out View view)) + if (ourViewCache.TryGetValue(propertyName, out ret)) { - return view; + return ret; } - view = fetchControlFromView(); + ret = fetchControlFromView(); - ourViewCache.Add(propertyName, view); - return view; + ourViewCache.Add(propertyName, ret); + return ret; } private static string GetResourceName(this PropertyInfo member) @@ -235,22 +221,23 @@ private static string GetResourceName(this PropertyInfo member) return resourceNameOverride ?? member.Name; } - private static IEnumerable GetWireUpMembers(this object @this, ResolveStrategy resolveStrategy) + private static IEnumerable GetWireUpMembers(this object @this, ReactiveUI.ControlFetcherMixin.ResolveStrategy + resolveStrategy) { var members = @this.GetType().GetRuntimeProperties(); switch (resolveStrategy) { default: // Implicit matches the Default. - return members.Where(m => m.PropertyType.IsSubclassOf(typeof(View)) - || m.GetCustomAttribute(true) != null); + return members.Where(member => member.PropertyType.IsSubclassOf(typeof(View)) + || member.GetCustomAttribute(true) != null); - case ResolveStrategy.ExplicitOptIn: - return members.Where(m => m.GetCustomAttribute(true) != null); + case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptIn: + return members.Where(member => member.GetCustomAttribute(true) != null); - case ResolveStrategy.ExplicitOptOut: - return members.Where(m => typeof(View).IsAssignableFrom(m.PropertyType) - && m.GetCustomAttribute(true) == null); + case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptOut: + return members.Where(member => typeof(View).IsAssignableFrom(member.PropertyType) + && member.GetCustomAttribute(true) == null); } } } From 090e6d46a2fc19f56916fe6c0d36d1301f8371dd Mon Sep 17 00:00:00 2001 From: Clinton Rocksmith Date: Mon, 27 May 2019 09:05:54 +1000 Subject: [PATCH 32/61] Feature: ReactiveRecyclerViewAdapter.GetItemViewType now passed view model type (#2051) * Added new method to provide the ViewModel and position Id Also guarded against possible null exceptions with the lists by trying to get the ViewModel at a position --- .../ReactiveRecyclerViewAdapter.cs | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs index 591e6f6dc7..743deef296 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs @@ -52,10 +52,28 @@ protected ReactiveRecyclerViewAdapter(IObservable> backin /// public override int ItemCount => _list.Count; + /// + public override int GetItemViewType(int position) + { + return GetItemViewType(position, GetViewModelByPosition(position)); + } + + /// + /// Determine the View that will be used/re-used in lists where + /// the list contains different cell designs. + /// + /// The position of the current view in the list. + /// The ViewModel associated with the current View. + /// An ID to be used in OnCreateViewHolder. + public int GetItemViewType(int position, TViewModel viewModel) + { + return base.GetItemViewType(position); + } + /// public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position) { - ((IViewFor)holder).ViewModel = _list.Items.ElementAt(position); + ((IViewFor)holder).ViewModel = GetViewModelByPosition(position); } /// @@ -70,6 +88,11 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } + private TViewModel GetViewModelByPosition(int position) + { + return position > _list.Count ? null : _list.Items.ElementAt(position); + } + private void UpdateBindings(Change change) { switch (change.Reason) From da0840e0458f310211844bf4dd1f69fab2ce3aa4 Mon Sep 17 00:00:00 2001 From: Clinton Rocksmith Date: Thu, 30 May 2019 09:58:52 +1000 Subject: [PATCH 33/61] Fix: ControlFetcherMixin using wrong type (#2054) --- src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs b/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs index 1d6286079f..9ae2b19aa2 100644 --- a/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs +++ b/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs @@ -8,11 +8,10 @@ using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; - using Android.App; using Android.Views; - using Java.Interop; +using Fragment = Android.Support.V4.App.Fragment; namespace ReactiveUI.AndroidSupport { From cb3e02871703bc5b8ccd8d4f0bd71c488f42f24b Mon Sep 17 00:00:00 2001 From: Clinton Rocksmith Date: Thu, 30 May 2019 12:56:05 +1000 Subject: [PATCH 34/61] fix: ReactiveRecyclerViewAdapter having a incorrect out of bounds check (#2055) --- src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs index 743deef296..7ba639d8cf 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs @@ -90,7 +90,7 @@ protected override void Dispose(bool disposing) private TViewModel GetViewModelByPosition(int position) { - return position > _list.Count ? null : _list.Items.ElementAt(position); + return position >= _list.Count ? null : _list.Items.ElementAt(position); } private void UpdateBindings(Change change) From 790dc809027f6b8782295a6e510256a87a3a7ef4 Mon Sep 17 00:00:00 2001 From: Artyom Date: Fri, 31 May 2019 15:22:55 +0300 Subject: [PATCH 35/61] fix: Correct links to Installation docs (#2060) --- src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs | 2 +- .../Platforms/netstandard2.0/PlatformRegistrations.cs | 2 +- src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs | 2 +- src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs b/src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs index a5423dd4bf..6b7dc518e7 100644 --- a/src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs +++ b/src/ReactiveUI/Mixins/ReactiveNotifyPropertyChangedMixin.cs @@ -205,7 +205,7 @@ private static IObservable> NotifyForProperty(ob if (result == null) { - throw new Exception($"Could not find a ICreatesObservableForProperty for {sender.GetType()} property {propertyName}. This should never happen, your service locator is probably broken. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation/nuget-packages for guidance."); + throw new Exception($"Could not find a ICreatesObservableForProperty for {sender.GetType()} property {propertyName}. This should never happen, your service locator is probably broken. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } return result.GetNotificationForProperty(sender, expression, propertyName, beforeChange, suppressWarnings); diff --git a/src/ReactiveUI/Platforms/netstandard2.0/PlatformRegistrations.cs b/src/ReactiveUI/Platforms/netstandard2.0/PlatformRegistrations.cs index d3ab33b32f..df364f2a25 100644 --- a/src/ReactiveUI/Platforms/netstandard2.0/PlatformRegistrations.cs +++ b/src/ReactiveUI/Platforms/netstandard2.0/PlatformRegistrations.cs @@ -16,7 +16,7 @@ public class PlatformRegistrations : IWantsToRegisterStuff /// public void Register(Action, Type> registerFunction) { - throw new Exception("You are referencing the Portable version of ReactiveUI in an App. Please change your reference to the specific version for your platform found here: https://reactiveui.net/docs/getting-started/installation/nuget-packages"); + throw new Exception("You are referencing the Portable version of ReactiveUI in an App. Please change your reference to the specific version for your platform found here: https://reactiveui.net/docs/getting-started/installation"); } } } diff --git a/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs b/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs index d4751c0ff5..e48eb30616 100644 --- a/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs +++ b/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs @@ -69,7 +69,7 @@ public RoutedViewHost() { // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. - this.Log().Error("Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation/nuget-packages for guidance."); + this.Log().Error("Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { diff --git a/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs b/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs index c63ad25063..3f7ccf1154 100644 --- a/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs +++ b/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs @@ -73,7 +73,7 @@ public ViewModelViewHost() { // NB: This used to be an error but WPF design mode can't read // good or do other stuff good. - this.Log().Error("Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation/nuget-packages for guidance."); + this.Log().Error("Couldn't find an IPlatformOperations implementation. Please make sure you have installed the latest version of the ReactiveUI packages for your platform. See https://reactiveui.net/docs/getting-started/installation for guidance."); } else { From 1c45ce3079849c863e99bae3ee315a79ac672add Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Tue, 4 Jun 2019 11:28:21 +1000 Subject: [PATCH 36/61] build(deps): bump Stubble.Core from 1.2.7 to 1.3.4 (#2062) Bumps [Stubble.Core](https://github.com/stubbleorg/stubble) from 1.2.7 to 1.3.4. - [Release notes](https://github.com/stubbleorg/stubble/releases) - [Changelog](https://github.com/StubbleOrg/Stubble/blob/master/docs/breaking-changes.md) - [Commits](https://github.com/stubbleorg/stubble/commits) --- src/EventBuilder/EventBuilder.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EventBuilder/EventBuilder.csproj b/src/EventBuilder/EventBuilder.csproj index 547e7f22dc..879f267df5 100644 --- a/src/EventBuilder/EventBuilder.csproj +++ b/src/EventBuilder/EventBuilder.csproj @@ -25,7 +25,7 @@ - + From 5aa4264061f3542e6b27e4ece4994bbea1540b3d Mon Sep 17 00:00:00 2001 From: Clinton Rocksmith Date: Sat, 8 Jun 2019 20:55:59 +1000 Subject: [PATCH 37/61] housekeeping: Added Virtual Keyword to method to allow overriding (#2064) --- src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs index 7ba639d8cf..f3f237d272 100644 --- a/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs +++ b/src/ReactiveUI.AndroidSupport/ReactiveRecyclerViewAdapter.cs @@ -65,7 +65,7 @@ public override int GetItemViewType(int position) /// The position of the current view in the list. /// The ViewModel associated with the current View. /// An ID to be used in OnCreateViewHolder. - public int GetItemViewType(int position, TViewModel viewModel) + public virtual int GetItemViewType(int position, TViewModel viewModel) { return base.GetItemViewType(position); } From ee5d742751d5d1226fcce68714880955f3be6c78 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Tue, 11 Jun 2019 00:08:32 +1000 Subject: [PATCH 38/61] feature: Swap the xam essentials to latest version. (#2066) Change processing over to using Pharmacist msbuild plugin --- build.cake | 3 --- .../ReactiveUI.Events.XamEssentials.csproj | 11 ++--------- .../ReactiveUI.Events.XamForms.csproj | 9 +-------- src/ReactiveUI.Events/ReactiveUI.Events.csproj | 3 ++- 4 files changed, 5 insertions(+), 21 deletions(-) diff --git a/build.cake b/build.cake index 33ca302089..ad3977a60d 100644 --- a/build.cake +++ b/build.cake @@ -57,10 +57,7 @@ var eventGenerators = new List<(string targetName, DirectoryPath destination)> ("android", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), ("ios", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), ("mac", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("tizen4", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("essentials", MakeAbsolute(Directory("src/ReactiveUI.Events.XamEssentials/"))), ("tvos", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("xamforms", MakeAbsolute(Directory("src/ReactiveUI.Events.XamForms/"))), }; if (IsRunningOnWindows()) diff --git a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj index 90574acfef..028af7c1fa 100644 --- a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj +++ b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj @@ -9,14 +9,7 @@ - - - - - - - - - + + \ No newline at end of file diff --git a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj index 3f0a00d333..68aaa6a20b 100644 --- a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj +++ b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj @@ -8,15 +8,8 @@ $(NoWarn);CS1570;CA1812 - - - - - - - - + \ No newline at end of file diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index 31596662f7..edfefdc0c4 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -39,7 +39,8 @@ - + + From a8d1439f70fb73db0a8e33c69edc5959b591e9a2 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Thu, 13 Jun 2019 21:40:23 +1000 Subject: [PATCH 39/61] housekeeeping: Change blend SDK to use official microsoft version. (#2070) --- src/ReactiveUI.Blend/FollowObservableStateBehavior.cs | 2 +- src/ReactiveUI.Blend/Platforms/net461/ObservableTrigger.cs | 2 +- src/ReactiveUI.Blend/ReactiveUI.Blend.csproj | 2 +- .../Api/ApiApprovalTests.Blend.net461.approved.txt | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ReactiveUI.Blend/FollowObservableStateBehavior.cs b/src/ReactiveUI.Blend/FollowObservableStateBehavior.cs index 3cfd5cdf45..940ef27625 100644 --- a/src/ReactiveUI.Blend/FollowObservableStateBehavior.cs +++ b/src/ReactiveUI.Blend/FollowObservableStateBehavior.cs @@ -12,7 +12,7 @@ #else using System.Windows; using System.Windows.Controls; -using System.Windows.Interactivity; +using Microsoft.Xaml.Behaviors; #endif #pragma warning disable SA1201 // A field should not follow a property - macro if statements make this hard diff --git a/src/ReactiveUI.Blend/Platforms/net461/ObservableTrigger.cs b/src/ReactiveUI.Blend/Platforms/net461/ObservableTrigger.cs index add0d80e0a..13fdcc6dec 100644 --- a/src/ReactiveUI.Blend/Platforms/net461/ObservableTrigger.cs +++ b/src/ReactiveUI.Blend/Platforms/net461/ObservableTrigger.cs @@ -9,7 +9,7 @@ using System.Reactive.Linq; using System.Text; using System.Windows; -using System.Windows.Interactivity; +using Microsoft.Xaml.Behaviors; namespace ReactiveUI.Blend { diff --git a/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj b/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj index f523132ca2..57b3e7f55f 100644 --- a/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj +++ b/src/ReactiveUI.Blend/ReactiveUI.Blend.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/ReactiveUI.Tests/Platforms/windows-xaml/Api/ApiApprovalTests.Blend.net461.approved.txt b/src/ReactiveUI.Tests/Platforms/windows-xaml/Api/ApiApprovalTests.Blend.net461.approved.txt index b41cce3e66..902d975511 100644 --- a/src/ReactiveUI.Tests/Platforms/windows-xaml/Api/ApiApprovalTests.Blend.net461.approved.txt +++ b/src/ReactiveUI.Tests/Platforms/windows-xaml/Api/ApiApprovalTests.Blend.net461.approved.txt @@ -1,7 +1,7 @@ [assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName=".NET Framework 4.6.1")] namespace ReactiveUI.Blend { - public class FollowObservableStateBehavior : System.Windows.Interactivity.Behavior + public class FollowObservableStateBehavior : Microsoft.Xaml.Behaviors.Behavior { public static readonly System.Windows.DependencyProperty StateObservableProperty; public static readonly System.Windows.DependencyProperty TargetObjectProperty; @@ -12,7 +12,7 @@ namespace ReactiveUI.Blend protected override void OnDetaching() { } protected static void OnStateObservableChanged(System.Windows.DependencyObject sender, System.Windows.DependencyPropertyChangedEventArgs e) { } } - public class ObservableTrigger : System.Windows.Interactivity.TriggerBase + public class ObservableTrigger : Microsoft.Xaml.Behaviors.TriggerBase { public static readonly System.Windows.DependencyProperty ObservableProperty; public ObservableTrigger() { } From e044cd1387b4ce73c57a5f3b35fe477fdddaa20f Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sat, 15 Jun 2019 01:34:37 +1000 Subject: [PATCH 40/61] housekeeping: Use Pharmacist for platform code generation. (#2072) --- build.cake | 71 ++--- src/EventBuilder.sln | 25 -- src/EventBuilder/App.config | 19 -- src/EventBuilder/AutoPlatform.cs | 70 ----- .../Cecil/DelegateTemplateInformation.cs | 111 -------- .../Cecil/EventTemplateInformation.cs | 259 ------------------ .../Cecil/PathSearchAssemblyResolver.cs | 125 --------- src/EventBuilder/Cecil/README.md | 39 --- src/EventBuilder/Cecil/SafeTypes.cs | 23 -- .../Cecil/StaticEventTemplateInformation.cs | 163 ----------- src/EventBuilder/CommandLineOptions.cs | 49 ---- src/EventBuilder/DefaultTemplate.mustache | 144 ---------- .../Entities/MultiParameterMethod.cs | 33 --- src/EventBuilder/Entities/NamespaceInfo.cs | 25 -- .../Entities/ObsoleteEventInfo.cs | 23 -- src/EventBuilder/Entities/ParentInfo.cs | 18 -- src/EventBuilder/Entities/PublicEventInfo.cs | 33 --- src/EventBuilder/Entities/PublicTypeInfo.cs | 56 ---- .../Entities/SingleParameterMethod.cs | 28 -- src/EventBuilder/EventBuilder.csproj | 33 --- src/EventBuilder/EventBuilder.sln | 31 --- src/EventBuilder/ExitCode.cs | 23 -- src/EventBuilder/NuGet/NuGetLogger.cs | 101 ------- src/EventBuilder/NuGet/NuGetPackageHelper.cs | 94 ------- src/EventBuilder/NuGet/NuGetProjectContext.cs | 80 ------ .../NuGet/SourceRepositoryProvider.cs | 99 ------- src/EventBuilder/PlatformHelper.cs | 29 -- src/EventBuilder/Platforms/Android.cs | 68 ----- src/EventBuilder/Platforms/BasePlatform.cs | 38 --- src/EventBuilder/Platforms/Bespoke.cs | 26 -- src/EventBuilder/Platforms/Essentials.cs | 54 ---- src/EventBuilder/Platforms/IPlatform.cs | 38 --- src/EventBuilder/Platforms/Mac.cs | 61 ----- src/EventBuilder/Platforms/Tizen.cs | 47 ---- src/EventBuilder/Platforms/UWP.cs | 33 --- src/EventBuilder/Platforms/WPF.cs | 38 --- src/EventBuilder/Platforms/Winforms.cs | 130 --------- src/EventBuilder/Platforms/XamForms.cs | 58 ---- src/EventBuilder/Platforms/iOS.cs | 66 ----- src/EventBuilder/Platforms/tvOS.cs | 61 ----- src/EventBuilder/Program.cs | 197 ------------- .../XamarinEssentialsTemplate.mustache | 47 ---- .../ReactiveUI.Events.WPF.csproj | 3 +- .../ReactiveUI.Events.Winforms.csproj | 5 +- .../ReactiveUI.Events.csproj | 15 +- src/ReactiveUI.Events/SingleAwaitSubject.cs | 47 ---- tools/nuget/nuget.exe | 3 - 47 files changed, 30 insertions(+), 2809 deletions(-) delete mode 100644 src/EventBuilder.sln delete mode 100644 src/EventBuilder/App.config delete mode 100644 src/EventBuilder/AutoPlatform.cs delete mode 100644 src/EventBuilder/Cecil/DelegateTemplateInformation.cs delete mode 100644 src/EventBuilder/Cecil/EventTemplateInformation.cs delete mode 100644 src/EventBuilder/Cecil/PathSearchAssemblyResolver.cs delete mode 100644 src/EventBuilder/Cecil/README.md delete mode 100644 src/EventBuilder/Cecil/SafeTypes.cs delete mode 100644 src/EventBuilder/Cecil/StaticEventTemplateInformation.cs delete mode 100644 src/EventBuilder/CommandLineOptions.cs delete mode 100644 src/EventBuilder/DefaultTemplate.mustache delete mode 100644 src/EventBuilder/Entities/MultiParameterMethod.cs delete mode 100644 src/EventBuilder/Entities/NamespaceInfo.cs delete mode 100644 src/EventBuilder/Entities/ObsoleteEventInfo.cs delete mode 100644 src/EventBuilder/Entities/ParentInfo.cs delete mode 100644 src/EventBuilder/Entities/PublicEventInfo.cs delete mode 100644 src/EventBuilder/Entities/PublicTypeInfo.cs delete mode 100644 src/EventBuilder/Entities/SingleParameterMethod.cs delete mode 100644 src/EventBuilder/EventBuilder.csproj delete mode 100644 src/EventBuilder/EventBuilder.sln delete mode 100644 src/EventBuilder/ExitCode.cs delete mode 100644 src/EventBuilder/NuGet/NuGetLogger.cs delete mode 100644 src/EventBuilder/NuGet/NuGetPackageHelper.cs delete mode 100644 src/EventBuilder/NuGet/NuGetProjectContext.cs delete mode 100644 src/EventBuilder/NuGet/SourceRepositoryProvider.cs delete mode 100644 src/EventBuilder/PlatformHelper.cs delete mode 100644 src/EventBuilder/Platforms/Android.cs delete mode 100644 src/EventBuilder/Platforms/BasePlatform.cs delete mode 100644 src/EventBuilder/Platforms/Bespoke.cs delete mode 100644 src/EventBuilder/Platforms/Essentials.cs delete mode 100644 src/EventBuilder/Platforms/IPlatform.cs delete mode 100644 src/EventBuilder/Platforms/Mac.cs delete mode 100644 src/EventBuilder/Platforms/Tizen.cs delete mode 100644 src/EventBuilder/Platforms/UWP.cs delete mode 100644 src/EventBuilder/Platforms/WPF.cs delete mode 100644 src/EventBuilder/Platforms/Winforms.cs delete mode 100644 src/EventBuilder/Platforms/XamForms.cs delete mode 100644 src/EventBuilder/Platforms/iOS.cs delete mode 100644 src/EventBuilder/Platforms/tvOS.cs delete mode 100644 src/EventBuilder/Program.cs delete mode 100644 src/EventBuilder/XamarinEssentialsTemplate.mustache delete mode 100644 src/ReactiveUI.Events/SingleAwaitSubject.cs delete mode 100644 tools/nuget/nuget.exe diff --git a/build.cake b/build.cake index ad3977a60d..0c0e13e2fb 100644 --- a/build.cake +++ b/build.cake @@ -6,6 +6,8 @@ const string project = "ReactiveUI"; +private const string PharmacistTool = "#tool dotnet:?package=Pharmacist&prerelease"; + ////////////////////////////////////////////////////////////////////// // PROJECTS ////////////////////////////////////////////////////////////////////// @@ -52,21 +54,18 @@ if (IsRunningOnWindows()) }); } -var eventGenerators = new List<(string targetName, DirectoryPath destination)> +var eventGenerators = new List<(string[] targetNames, DirectoryPath destination)> { - ("android", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("ios", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("mac", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("tvos", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), + (new[] { "android", "ios", "mac", "tvos" }, MakeAbsolute(Directory("src/ReactiveUI.Events/"))), + (new[] { "wpf" }, MakeAbsolute(Directory("src/ReactiveUI.Events.WPF/"))), + (new[] { "winforms" }, MakeAbsolute(Directory("src/ReactiveUI.Events.Winforms/"))), }; if (IsRunningOnWindows()) { eventGenerators.AddRange(new [] { - ("wpf", MakeAbsolute(Directory("src/ReactiveUI.Events.WPF/"))), - ("uwp", MakeAbsolute(Directory("src/ReactiveUI.Events/"))), - ("winforms", MakeAbsolute(Directory("src/ReactiveUI.Events.Winforms/"))), + (new[] { "uwp" }, MakeAbsolute(Directory("src/ReactiveUI.Events/"))), }); } @@ -90,58 +89,30 @@ ToolSettings.SetToolSettings(context: Context); // TASKS ////////////////////////////////////////////////////////////////////// -Task("BuildEventBuilder") - .Does(() => -{ - BuildProject("./src/EventBuilder.sln", false); -}); - Task("GenerateEvents") - .IsDependentOn("BuildEventBuilder") - .Does (() => + .Does(() => RequireGlobalTool(PharmacistTool, () => { var eventsArtifactDirectory = BuildParameters.ArtifactsDirectory.Combine("Events"); EnsureDirectoryExists(eventsArtifactDirectory); - var workingDirectory = MakeAbsolute(Directory("./src/EventBuilder/bin/Release/netcoreapp2.1")); - var eventBuilder = workingDirectory.CombineWithFilePath("EventBuilder.dll"); - - DirectoryPath referenceAssembliesPath = null; - if (IsRunningOnWindows()) - { - referenceAssembliesPath = ToolSettings.VsLocation.Combine("./Common7/IDE/ReferenceAssemblies/Microsoft/Framework"); - } - else - { - referenceAssembliesPath = Directory("⁨/Library⁩/Frameworks⁩/Libraries/⁨mono⁩"); - } - foreach (var eventGenerator in eventGenerators) { - var (platform, directory) = eventGenerator; - - var settings = new DotNetCoreExecuteSettings - { - WorkingDirectory = workingDirectory, - }; - - var filename = String.Format("Events_{0}.cs", platform); - var output = directory.CombineWithFilePath(filename); - - Information("Generating events for '{0}'", platform); - DotNetCoreExecute( - eventBuilder, - new ProcessArgumentBuilder() - .AppendSwitch("--platform","=", platform) - .AppendSwitchQuoted("--reference","=", referenceAssembliesPath.ToString()) - .AppendSwitchQuoted("--output-path", "=", output.ToString()), - settings); - - Information("The events have been written to '{0}'", output); + var (platforms, directory) = eventGenerator; + + Information("Generating events for '{0}'", string.Join(", ", platforms)); + StartProcess(Context.Tools.Resolve("Pharmacist*").ToString(), new ProcessSettings { + Arguments = new ProcessArgumentBuilder() + .Append("generate-platform") + .AppendSwitch("-p", string.Join(",", platforms)) + .AppendSwitch("-o", directory.ToString()) + .AppendSwitch("--output-prefix", "Events_") + }); + + Information("The events have been written to '{0}'", directory); } CopyFiles(GetFiles("./src/ReactiveUI.**/Events_*.cs"), eventsArtifactDirectory); -}); +})); BuildParameters.Tasks.BuildTask.IsDependentOn("GenerateEvents"); diff --git a/src/EventBuilder.sln b/src/EventBuilder.sln deleted file mode 100644 index 985dcc3fe6..0000000000 --- a/src/EventBuilder.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.12 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBuilder", "EventBuilder\EventBuilder.csproj", "{A6B86E12-057F-4591-98A3-FD50E9CEAE69}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {238383E8-35F5-48A0-9043-8347D6C27876} - EndGlobalSection -EndGlobal diff --git a/src/EventBuilder/App.config b/src/EventBuilder/App.config deleted file mode 100644 index 96e5fcd879..0000000000 --- a/src/EventBuilder/App.config +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/EventBuilder/AutoPlatform.cs b/src/EventBuilder/AutoPlatform.cs deleted file mode 100644 index 7a6bd9a064..0000000000 --- a/src/EventBuilder/AutoPlatform.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder -{ - /// - /// The event builder platform. - /// - public enum AutoPlatform - { - /// - /// No platform. - /// - None, - - /// - /// Android platform. - /// - Android, - -#pragma warning disable SA1300 // Element should begin with upper-case letter - /// - /// iOS platform. - /// - iOS, -#pragma warning restore SA1300 // Element should begin with upper-case letter - - /// - /// Mac platform. - /// - Mac, - - /// - /// Tizen platform. - /// - Tizen4, - - /// - /// WPF platform. - /// - WPF, - - /// - /// Xamarin Forms platform. - /// - XamForms, - - /// - /// UWP platform. - /// - UWP, - - /// - /// Win Forms platform. - /// - Winforms, - - /// - /// TV OS platform. - /// - TVOS, - - /// - /// Xamarin Essentials platform. - /// - Essentials - } -} diff --git a/src/EventBuilder/Cecil/DelegateTemplateInformation.cs b/src/EventBuilder/Cecil/DelegateTemplateInformation.cs deleted file mode 100644 index 523541fee5..0000000000 --- a/src/EventBuilder/Cecil/DelegateTemplateInformation.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Globalization; -using System.Linq; -using EventBuilder.Entities; -using Mono.Cecil; - -namespace EventBuilder.Cecil -{ - /// - /// Represents delegate handler mapping from assemblies. - /// - public static class DelegateTemplateInformation - { - /// - /// Creates namespace information from the specified target assemblies. - /// - /// The target assemblies. - /// The namespaces in the target assemblies. - public static NamespaceInfo[] Create(AssemblyDefinition[] targetAssemblies) - { - var garbageTypeList = new[] - { - "AVPlayerItemLegibleOutputPushDelegate" - - // NB: Aparrently this used to break "build on device because of reasons". We don't know what these reasons are and this may not be needed anymore. - }; - - var publicDelegateTypes = targetAssemblies - .SelectMany(SafeTypes.GetSafeTypes) - .Where(x => x.IsPublic && !x.IsInterface && !x.HasGenericParameters && IsCocoaDelegateName(x.Name)) - .Where(x => x.BaseType == null || !x.BaseType.FullName.Contains("MulticastDelegate", StringComparison.InvariantCulture)) - .Where(x => !garbageTypeList.Any(y => x.FullName.Contains(y, StringComparison.InvariantCulture))) - .Select(x => new { Type = x, Delegates = GetPublicDelegateMethods(x) }) - .Where(x => x.Delegates.Length > 0) - .ToArray(); - - return publicDelegateTypes - .GroupBy(x => x.Type.Namespace) - .Select(x => new NamespaceInfo - { - Name = x.Key, - Types = x.Select(y => new PublicTypeInfo - { - Name = y.Type.Name, - Type = y.Type, - Abstract = y.Type.IsAbstract ? "abstract" : string.Empty, - ZeroParameterMethods = - y.Delegates.Where(z => z.Parameters.Count == 0).Select(z => new ParentInfo - { - Name = z.Name - }).ToArray(), - SingleParameterMethods = - y.Delegates.Where(z => z.Parameters.Count == 1).Select(z => new SingleParameterMethod - { - Name = z.Name, - ParameterType = z.Parameters[0].ParameterType.FullName, - ParameterName = z.Parameters[0].Name - }).ToArray(), - MultiParameterMethods = - y.Delegates.Where(z => z.Parameters.Count > 1).Select(z => new MultiParameterMethod - { - Name = z.Name, - ParameterList = - string.Join( - ", ", - z.Parameters.Select( - a => string.Format( - CultureInfo.InvariantCulture, - "{0} {1}", - a.ParameterType.FullName, - a.Name))), - ParameterTypeList = - string.Join(", ", z.Parameters.Select(a => a.ParameterType.FullName)), - ParameterNameList = string.Join(", ", z.Parameters.Select(a => a.Name)) - }).ToArray() - }).ToArray() - }).ToArray(); - } - - private static bool IsCocoaDelegateName(string name) - { - if (name.EndsWith("Delegate", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - if (name.EndsWith("UITableViewSource", StringComparison.OrdinalIgnoreCase)) - { - return true; - } - - return false; - } - - private static MethodDefinition[] GetPublicDelegateMethods(TypeDefinition t) - { - var bannedMethods = new[] { "Dispose", "Finalize" }; - return t.Methods - .Where(x => x.IsVirtual && !x.IsConstructor && !x.IsSetter && x.ReturnType.FullName == "System.Void") - .Where(x => x.Parameters.All(y => !y.ParameterType.FullName.Contains("&", StringComparison.InvariantCulture))) - .Where(x => !bannedMethods.Contains(x.Name)) - .GroupBy(x => x.Name).Select(x => x.OrderByDescending(y => y.Parameters.Count).First()) - .ToArray(); - } - } -} diff --git a/src/EventBuilder/Cecil/EventTemplateInformation.cs b/src/EventBuilder/Cecil/EventTemplateInformation.cs deleted file mode 100644 index 3a709622c8..0000000000 --- a/src/EventBuilder/Cecil/EventTemplateInformation.cs +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using EventBuilder.Entities; -using Mono.Cecil; -using Serilog; - -namespace EventBuilder.Cecil -{ - /// - /// Event template information about events and handlers. - /// - public static class EventTemplateInformation - { - private static readonly Dictionary SubstitutionList = new Dictionary - { - { "Windows.UI.Xaml.Data.PropertyChangedEventArgs", "global::System.ComponentModel.PropertyChangedEventArgs" }, - { "Windows.UI.Xaml.Data.PropertyChangedEventHandler", "global::System.ComponentModel.PropertyChangedEventHandler" }, - { "Windows.Foundation.EventHandler", "EventHandler" }, - { "Windows.Foundation.EventHandler`1", "EventHandler" }, - { "Windows.Foundation.EventHandler`2", "EventHandler" }, - { "System.Boolean", "Boolean" }, - { "System.Boolean`1", "Boolean" }, - { "System.EventHandler", "EventHandler" }, - { "System.EventHandler`1", "EventHandler" }, - { "System.EventHandler`2", "EventHandler" }, - { "System.EventArgs", "EventArgs" }, - { "System.EventArgs`1", "EventArgs" }, - { "System.EventArgs`2", "EventArgs" }, - { "Tizen.NUI.EventHandlerWithReturnType", "Tizen.NUI.EventHandlerWithReturnType" }, - { "Tizen.NUI.EventHandlerWithReturnType`1", "Tizen.NUI.EventHandlerWithReturnType" }, - { "Tizen.NUI.EventHandlerWithReturnType`2", "Tizen.NUI.EventHandlerWithReturnType" }, - { "Tizen.NUI.EventHandlerWithReturnType`3", "Tizen.NUI.EventHandlerWithReturnType" }, - }; - - /// - /// Creates namespace information from the specified target assemblies. - /// - /// The target assemblies. - /// The namespaces in the target assemblies. - public static NamespaceInfo[] Create(AssemblyDefinition[] targetAssemblies) - { - var publicTypesWithEvents = targetAssemblies - .SelectMany(SafeTypes.GetSafeTypes) - .Where(x => x.IsPublic && !x.HasGenericParameters) - .Select(x => new { Type = x, Events = GetPublicEvents(x) }) - .Where(x => x.Events.Length > 0) - .ToArray(); - - var garbageNamespaceList = new[] - { - "Windows.UI.Xaml.Data", - "Windows.UI.Xaml.Interop", - "Windows.UI.Xaml.Input", - "MonoTouch.AudioToolbox", - "MonoMac.AudioToolbox", - "ReactiveUI.Events", - - // Winforms - "System.Collections.Specialized", - "System.Configuration", - "System.ComponentModel.Design", - "System.ComponentModel.Design.Serialization", - "System.CodeDom", - "System.Data.SqlClient", - "System.Data.OleDb", - "System.Data.Odbc", - "System.Data.Common", - "System.Drawing.Design", - "System.Media", - "System.Net", - "System.Net.Mail", - "System.Net.NetworkInformation", - "System.Net.Sockets", - "System.ServiceProcess.Design", - "System.Windows.Input", - "System.Windows.Forms.ComponentModel.Com2Interop", - "System.Windows.Forms.Design", - "System.Timers" - }; - - var namespaceData = publicTypesWithEvents - .GroupBy(x => x.Type.Namespace) - .Where(x => !garbageNamespaceList.Contains(x.Key)) - .Select(x => new NamespaceInfo - { - Name = x.Key, - Types = x.Select(y => new PublicTypeInfo - { - Name = y.Type.Name, - Type = y.Type, - Events = y.Events.Select(z => new PublicEventInfo - { - Name = z.Name, - EventHandlerType = GetRealTypeName(z.EventType), - EventArgsType = GetEventArgsTypeForEvent(z), - ObsoleteEventInfo = GetObsoleteInfo(z) - }).ToArray() - }).ToArray() - }).ToArray(); - - foreach (var type in namespaceData.SelectMany(x => x.Types)) - { - var parentWithEvents = GetParents(type.Type).FirstOrDefault(x => GetPublicEvents(x).Any()); - if (parentWithEvents == null) - { - continue; - } - - type.Parent = new ParentInfo { Name = parentWithEvents.FullName }; - } - - return namespaceData; - } - - private static string RenameBogusTypes(string typeName) - { - if (SubstitutionList.ContainsKey(typeName)) - { - return SubstitutionList[typeName]; - } - - return typeName; - } - - [SuppressMessage("Globalization", "CA1307: Specify StringComparison", Justification = "Replace overload is for .NET Standard only")] - private static string GetEventArgsTypeForEvent(EventDefinition ei) - { - // Find the EventArgs type parameter of the event via digging around via reflection - var type = ei.EventType.Resolve(); - - if (type == null) - { - Log.Debug($"Type for {ei.EventType} is not valid"); - return null; - } - - var invoke = type.Methods.First(x => x.Name == "Invoke"); - if (invoke.Parameters.Count < 2) - { - return null; - } - - var param = invoke.Parameters[1]; - var ret = RenameBogusTypes(param.ParameterType.FullName); - - var generic = ei.EventType as GenericInstanceType; - if (generic != null) - { - foreach ( - var kvp in - type.GenericParameters.Zip(generic.GenericArguments, (name, actual) => new { name, actual })) - { - var realType = GetRealTypeName(kvp.actual); - - var temp = ret.Replace(kvp.name.FullName, realType); - if (temp != ret) - { - ret = temp; - break; - } - } - } - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static string GetRealTypeName(TypeDefinition t) - { - if (t.GenericParameters.Count == 0) - { - return RenameBogusTypes(t.FullName); - } - - var ret = string.Format( - CultureInfo.InvariantCulture, - "{0}<{1}>", - RenameBogusTypes(t.Namespace + "." + t.Name), - string.Join(",", t.GenericParameters.Select(x => GetRealTypeName(x.Resolve())))); - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static string GetRealTypeName(TypeReference t) - { - var generic = t as GenericInstanceType; - if (generic == null) - { - return RenameBogusTypes(t.FullName); - } - - var ret = string.Format( - CultureInfo.InvariantCulture, - "{0}<{1}>", - RenameBogusTypes(generic.Namespace + "." + generic.Name), - string.Join(",", generic.GenericArguments.Select(GetRealTypeName))); - - // NB: Handy place to hook to troubleshoot if something needs to be added to SubstitutionList - // if (generic.FullName.Contains("MarkReachedEventArgs")) { - // // Tizen.NUI.EventHandlerWithReturnType`3 - // // - // } - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static ObsoleteEventInfo GetObsoleteInfo(EventDefinition ei) - { - var obsoleteAttribute = ei.CustomAttributes - .FirstOrDefault(attr => attr.AttributeType.FullName.Equals("System.ObsoleteAttribute", StringComparison.InvariantCulture)); - - if (obsoleteAttribute == null) - { - return null; - } - - return new ObsoleteEventInfo - { - Message = obsoleteAttribute.ConstructorArguments?.ElementAtOrDefault(0).Value?.ToString() ?? string.Empty, - IsError = bool.Parse(obsoleteAttribute.ConstructorArguments?.ElementAtOrDefault(1).Value?.ToString() ?? bool.FalseString) - }; - } - - private static EventDefinition[] GetPublicEvents(TypeDefinition t) - { - return - t.Events.Where(x => x.AddMethod.IsPublic && !x.AddMethod.IsStatic && GetEventArgsTypeForEvent(x) != null) - .ToArray(); - } - - private static IEnumerable GetParents(TypeDefinition type) - { - var current = type.BaseType != null - ? type.BaseType.Resolve() - : null; - - while (current != null) - { - yield return current.Resolve(); - - current = current.BaseType != null - ? current.BaseType.Resolve() - : null; - } - } - } -} diff --git a/src/EventBuilder/Cecil/PathSearchAssemblyResolver.cs b/src/EventBuilder/Cecil/PathSearchAssemblyResolver.cs deleted file mode 100644 index e285960682..0000000000 --- a/src/EventBuilder/Cecil/PathSearchAssemblyResolver.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Linq; -using Mono.Cecil; -using Serilog; - -namespace EventBuilder.Cecil -{ - /// - /// Assembly resolver. - /// - /// - public sealed class PathSearchAssemblyResolver : IAssemblyResolver - { - private readonly string[] _targetAssemblyDirs; - - /// - /// Initializes a new instance of the class. - /// - /// The target assembly dirs. - public PathSearchAssemblyResolver(string[] targetAssemblyDirs) - { - _targetAssemblyDirs = targetAssemblyDirs; - } - - /// - public void Dispose() - { - } - - /// - /// Resolves the specified full assembly name. - /// - /// The full name. - /// The parameters. - /// The assembly definition. - public AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) - { - var dllName = fullName.Split(',')[0] + ".dll"; - - var fullPath = _targetAssemblyDirs.Select(x => Path.Combine(x, dllName)).FirstOrDefault(File.Exists); - if (fullPath == null) - { - dllName = fullName.Split(',')[0] + ".winmd"; - fullPath = _targetAssemblyDirs.Select(x => Path.Combine(x, dllName)).FirstOrDefault(File.Exists); - } - - // NB: This hacks WinRT's weird mscorlib to just use the regular one - // We forget why this was needed, maybe it's not needed anymore? - if (fullName.Contains("mscorlib", StringComparison.InvariantCulture) && fullName.Contains("255", StringComparison.InvariantCulture)) - { - fullPath = - Environment.ExpandEnvironmentVariables( - @"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"); - } - - if (fullPath == null) - { - var errorMessage = $"Failed to resolve!!! {fullName}"; - Log.Error(errorMessage); - throw new Exception(errorMessage); - } - - return AssemblyDefinition.ReadAssembly(fullPath, parameters); - } - - /// - /// Resolves the specified full assembly name. - /// - /// The full name. - /// The assembly definition. - public AssemblyDefinition Resolve(string fullName) - { - var dllName = fullName.Split(',')[0] + ".dll"; - - var fullPath = _targetAssemblyDirs.Select(x => Path.Combine(x, dllName)).FirstOrDefault(File.Exists); - if (fullPath == null) - { - dllName = fullName.Split(',')[0] + ".winmd"; - fullPath = _targetAssemblyDirs.Select(x => Path.Combine(x, dllName)).FirstOrDefault(File.Exists); - } - - // NB: This hacks WinRT's weird mscorlib to just use the regular one - if (fullName.Contains("mscorlib", StringComparison.InvariantCulture) && fullName.Contains("255", StringComparison.InvariantCulture)) - { - fullPath = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"); - } - - if (fullPath == null) - { - var errorMessage = $"Failed to resolve!!! {fullName}"; - Log.Error(errorMessage); - throw new Exception(errorMessage); - } - - return AssemblyDefinition.ReadAssembly(fullPath); - } - - /// - /// Resolves the specified full assembly name. - /// - /// The assembly name reference. - /// The reader parameters. - /// The assembly definition. - public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) - { - return Resolve(name.FullName, parameters); - } - - /// - /// Resolves the specified full assembly name. - /// - /// The assembly name reference. - /// The assembly definition. - public AssemblyDefinition Resolve(AssemblyNameReference name) - { - return Resolve(name.FullName); - } - } -} diff --git a/src/EventBuilder/Cecil/README.md b/src/EventBuilder/Cecil/README.md deleted file mode 100644 index d39ac823ad..0000000000 --- a/src/EventBuilder/Cecil/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Here be dragons (tm) -This section of EventBuilder is a hairball of complexity, it has served us well but it was written in a fit of rage and there now exist better ways which that at the time did not exist. If you have the skills and time, we would _really_ appreciate a pull request that contains a refactor of this away from `Mono.Cecil` towards the `System.Reflection.Metadata` nuget package. - -Deliverables: - -* Unit tests. -* Proper OO modeling instead of static everywhere. -* Refactored to use System.Reflection.Metadata. -* Inline comments explaining what it is doing, how it works and why it's doing what it does. - -Here's an example of how to use `System.Reflection.Metadata` we hope it sets you on the right path forward. - -```csharp -//string path = @"C:\windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll"; -string path = @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Xamarin.iOS\v1.0\Xamarin.iOS.dll"; -//string path = @"C:\PROGRA~2\Windows Phone Kits\8.1\References\CommonConfiguration\Neutral\Windows.winmd"; -using ( - var peReader = new PEReader(new FileStream(path, FileMode.Open, FileAccess.Read), - PEStreamOptions.PrefetchMetadata)) -{ - var contractReader = peReader.GetMetadataReader(); - - MetadataReader metadataReader = peReader.GetMetadataReader(); - foreach (var type in metadataReader.TypeDefinitions) - { - TypeDefinition typeDefinition = metadataReader.GetTypeDefinition(type); - - foreach (var eventDefinitionHandle in typeDefinition.GetEvents()) - { - var event = metadataReader.GetEvent(eventDefinitionHandle); - var eventName = metadataReader.GetString(test.Name); - - Console.WriteLine(eventName); - } - - } -} -``` - diff --git a/src/EventBuilder/Cecil/SafeTypes.cs b/src/EventBuilder/Cecil/SafeTypes.cs deleted file mode 100644 index 4b44997a61..0000000000 --- a/src/EventBuilder/Cecil/SafeTypes.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Linq; -using Mono.Cecil; - -namespace EventBuilder.Cecil -{ - /// - /// Safe type helper methods. - /// - public static class SafeTypes - { - /// - /// Gets the safe types from an assembly definition. - /// - /// The assembly definition. - /// Type definitions from the assembly. - public static TypeDefinition[] GetSafeTypes(AssemblyDefinition a) => a.Modules.SelectMany(x => x.GetTypes()).ToArray(); - } -} diff --git a/src/EventBuilder/Cecil/StaticEventTemplateInformation.cs b/src/EventBuilder/Cecil/StaticEventTemplateInformation.cs deleted file mode 100644 index 5d9bc5ba55..0000000000 --- a/src/EventBuilder/Cecil/StaticEventTemplateInformation.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Linq; -using EventBuilder.Entities; -using Mono.Cecil; - -namespace EventBuilder.Cecil -{ - /// - /// Static event template methods. - /// - public static class StaticEventTemplateInformation - { - /// - /// Creates the specified target assemblies. - /// - /// The target assemblies. - /// The namespace information for the assemblies. - public static NamespaceInfo[] Create(AssemblyDefinition[] targetAssemblies) - { - var publicTypesWithEvents = targetAssemblies - .SelectMany(SafeTypes.GetSafeTypes) - .Where(x => x.IsPublic && !x.HasGenericParameters) - .Select(x => new { Type = x, Events = GetPublicEvents(x) }) - .Where(x => x.Events.Length > 0) - .ToArray(); - - var garbageNamespaceList = new[] - { - "ReactiveUI.Events" - }; - - var namespaceData = publicTypesWithEvents - .GroupBy(x => x.Type.Namespace) - .Where(x => !garbageNamespaceList.Contains(x.Key)) - .Select(x => new NamespaceInfo - { - Name = x.Key, - Types = x.Select(y => new PublicTypeInfo - { - Name = y.Type.Name, - Type = y.Type, - Events = y.Events.Select(z => new PublicEventInfo - { - Name = z.Name, - EventHandlerType = GetRealTypeName(z.EventType), - EventArgsType = GetEventArgsTypeForEvent(z) - }).ToArray() - }).ToArray() - }).ToArray(); - - foreach (var type in namespaceData.SelectMany(x => x.Types)) - { - var parentWithEvents = GetParents(type.Type).FirstOrDefault(x => GetPublicEvents(x).Any()); - if (parentWithEvents == null) - { - continue; - } - - type.Parent = new ParentInfo { Name = parentWithEvents.FullName }; - } - - return namespaceData; - } - - private static IEnumerable GetParents(TypeDefinition type) - { - var current = type.BaseType != null && type.BaseType.ToString() != "System.Object" - ? type.BaseType.Resolve() - : null; - - while (current != null) - { - yield return current.Resolve(); - - current = current.BaseType != null - ? current.BaseType.Resolve() - : null; - } - } - - [SuppressMessage("Globalization", "CA1307: Specify StringComparison", Justification = "Replace overload is for .NET Standard only")] - private static string GetEventArgsTypeForEvent(EventDefinition ei) - { - // Find the EventArgs type parameter of the event via digging around via reflection - var type = ei.EventType.Resolve(); - var invoke = type.Methods.First(x => x.Name == "Invoke"); - if (invoke.Parameters.Count < 1) - { - return null; - } - - var param = invoke.Parameters.Count == 1 ? invoke.Parameters[0] : invoke.Parameters[1]; - var ret = param.ParameterType.FullName; - - var generic = ei.EventType as GenericInstanceType; - if (generic != null) - { - foreach ( - var kvp in - type.GenericParameters.Zip(generic.GenericArguments, (name, actual) => new { name, actual })) - { - var realType = GetRealTypeName(kvp.actual); - - ret = ret.Replace(kvp.name.FullName, realType); - } - } - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static string GetRealTypeName(TypeDefinition t) - { - if (t.GenericParameters.Count == 0) - { - return t.FullName; - } - - var ret = string.Format( - CultureInfo.InvariantCulture, - "{0}<{1}>", - t.Namespace + "." + t.Name, - string.Join(",", t.GenericParameters.Select(x => GetRealTypeName(x.Resolve())))); - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static string GetRealTypeName(TypeReference t) - { - var generic = t as GenericInstanceType; - if (generic == null) - { - return t.FullName; - } - - var ret = string.Format( - CultureInfo.InvariantCulture, - "{0}<{1}>", - generic.Namespace + "." + generic.Name, - string.Join(",", generic.GenericArguments.Select(GetRealTypeName))); - - // NB: Inner types in Mono.Cecil get reported as 'Foo/Bar' - return ret.Replace('/', '.'); - } - - private static EventDefinition[] GetPublicEvents(TypeDefinition t) - { - return - t.Events - - .Where(x => x.AddMethod.IsPublic && GetEventArgsTypeForEvent(x) != null) - .ToArray(); - } - } -} diff --git a/src/EventBuilder/CommandLineOptions.cs b/src/EventBuilder/CommandLineOptions.cs deleted file mode 100644 index 2415ef2d98..0000000000 --- a/src/EventBuilder/CommandLineOptions.cs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using CommandLine; - -namespace EventBuilder -{ - /// - /// Command line options for the event builder. - /// - public class CommandLineOptions - { - /// - /// Gets or sets the platform. - /// - [Option('p', "platform", Required = true, HelpText = "Platform to automatically generate. Possible options include: NONE, ANDROID, IOS, WPF, MAC, TIZEN, UWP, XAMFORMS, WINFORMS, TVOS")] - public AutoPlatform Platform { get; set; } - - /// - /// Gets or sets the path where to output the contents. - /// - [Option('o', "output-path", Required = true, HelpText = "The file path where to output the contents.")] - public string OutputPath { get; set; } - - /// - /// Gets or sets the template. - /// - [Option('t', "template", Required = false, HelpText = "Specify another mustache template other than the default.")] - public string Template { get; set; } - - /// - /// Gets or sets the reference assemblies. - /// - [Option('r', "reference", Required = false, HelpText = "Specify a Reference Assemblies location to override the default")] - public string ReferenceAssemblies { get; set; } - - /// - /// Gets or sets the assemblies. - /// Manual generation using the specified assemblies. Use with --platform=NONE. - /// - [Option('a', "assemblies", Required = false, HelpText = "List of assemblies to process. Used for the NONE option")] -#pragma warning disable CA2227 // Collection properties should be read only - public IEnumerable Assemblies { get; set; } -#pragma warning restore CA2227 // Collection properties should be read only - } -} diff --git a/src/EventBuilder/DefaultTemplate.mustache b/src/EventBuilder/DefaultTemplate.mustache deleted file mode 100644 index b7a752e505..0000000000 --- a/src/EventBuilder/DefaultTemplate.mustache +++ /dev/null @@ -1,144 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -#pragma warning disable 1591,0618,0105,0672,0108,SA1402,SA1200,SA1514,SA1615,SA1210,SA1001,SA1403,SA1201,SA1306,SA1601,SA1513,SA1004,SA1516,SA1508,SA1629,SA1507,SA1121,SA1208 - -using System; -using System.Reactive; -using System.Reactive.Linq; -using System.Reactive.Subjects; -using ReactiveUI.Events; - -{{#Namespaces}} -using {{Name}}; -{{/Namespaces}} -{{#DelegateNamespaces}} -using {{Name}}; -{{/DelegateNamespaces}} - -{{#Namespaces}} -namespace {{Name}} -{ - /// - /// Methods that expose events for the platform. - /// - public static class EventsMixin - { -{{#Types}} - /// - /// This class emits {{Name}} events as observables. - /// - /// This instance of {{Name}}. - public static {{Name}}Events Events(this {{Name}} @this) => new {{Name}}Events(@this); -{{/Types}} - } - -{{#Types}} - - /// - /// This class emits {{Name}} events as observables. - /// - public class {{Name}}Events -{{#Parent}} - : {{Name}}Events -{{/Parent}} - { - private {{Name}} _this; - - /// - /// Initializes a new instance of the class. - /// - /// This instance of {{Name}}. - public {{Name}}Events({{Name}} @this) -{{#Parent}} - : base(@this) -{{/Parent}} - { - _this = @this; - } -{{#Events}} - - /// - /// Returns an observable sequence of {{EventArgsType}}. - /// -{{#ObsoleteEventInfo}} - [Obsolete{{#ObsoleteEventInfo.Message}}("{{ObsoleteEventInfo.Message}}"{{#ObsoleteEventInfo.IsError}}, true{{/ObsoleteEventInfo.IsError}}){{/ObsoleteEventInfo.Message}}] -{{/ObsoleteEventInfo}} - public IObservable<{{EventArgsType}}> {{Name}} => - Observable.FromEventPattern<{{EventHandlerType}}, {{EventArgsType}}>(x => _this.{{Name}} += x, x => _this.{{Name}} -= x).Select(x => x.EventArgs); - {{/Events}} - } - {{/Types}} -} - -{{/Namespaces}} -{{#DelegateNamespaces}} - -namespace {{Name}}.Rx -{ - {{#Types}} - public {{Abstract}} partial class {{Name}}Rx : {{Name}} - { - {{#ZeroParameterMethods}} - private readonly SingleAwaitSubject _{{Name}} = new SingleAwaitSubject(); - - /// - /// An observable sequence of signals. - /// - public IObservable {{Name}}Obs => _{{Name}}; - - /// - public override void {{Name}}() - { - _{{Name}}.OnNext(Unit.Default); - } - - {{/ZeroParameterMethods}} - {{#SingleParameterMethods}} - private readonly SingleAwaitSubject<{{ParameterType}}> - _{{Name}} = new SingleAwaitSubject<{{ParameterType}}>(); - - /// - /// An observable sequence of {{ParameterType}}. - /// - public IObservable<{{ParameterType}}> {{Name}}Obs => _{{Name}}; - - /// - public override void {{Name}}({{ParameterType}} {{ParameterName}}) - { - _{{Name}}.OnNext({{ParameterName}}); - } - - {{/SingleParameterMethods}} - - {{#MultiParameterMethods}} - private readonly SingleAwaitSubject> _{{Name}} = new SingleAwaitSubject>(); - - /// - /// An observable sequence of elements. - /// - public IObservable> {{Name}}Obs => _{{Name}}; - - /// - public override void {{Name}}({{ParameterList}}) - { - _{{Name}}.OnNext(Tuple.Create({{ParameterNameList}})); - } - - {{/MultiParameterMethods}} - } - {{/Types}} -} -{{/DelegateNamespaces}} - -#pragma warning restore 1591,0618,0105,0672,0108,SA1402,SA1200,SA1514,SA1615,SA1210,SA1001,SA1403,SA1201,SA1306,SA1601,SA1513,SA1004,SA1516,SA1508,SA1629,SA1507,SA1121,SA1208 diff --git a/src/EventBuilder/Entities/MultiParameterMethod.cs b/src/EventBuilder/Entities/MultiParameterMethod.cs deleted file mode 100644 index d7e66364b2..0000000000 --- a/src/EventBuilder/Entities/MultiParameterMethod.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder.Entities -{ - /// - /// Respresents a method with a mutiple parameters. - /// - public class MultiParameterMethod - { - /// - /// Gets or sets the name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the parameter list. - /// - public string ParameterList { get; set; } // "FooType foo, BarType bar, BazType baz" - - /// - /// Gets or sets the parameter type list. - /// - public string ParameterTypeList { get; set; } // "FooType, BarType, BazType" - - /// - /// Gets or sets the parameter name list. - /// - public string ParameterNameList { get; set; } // "foo, bar, baz" - } -} diff --git a/src/EventBuilder/Entities/NamespaceInfo.cs b/src/EventBuilder/Entities/NamespaceInfo.cs deleted file mode 100644 index 8d5d0610c2..0000000000 --- a/src/EventBuilder/Entities/NamespaceInfo.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; - -namespace EventBuilder.Entities -{ - /// - /// Respresents namespace information. - /// - public class NamespaceInfo - { - /// - /// Gets or sets the name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the types. - /// - public IEnumerable Types { get; set; } - } -} diff --git a/src/EventBuilder/Entities/ObsoleteEventInfo.cs b/src/EventBuilder/Entities/ObsoleteEventInfo.cs deleted file mode 100644 index 6cbaae1f01..0000000000 --- a/src/EventBuilder/Entities/ObsoleteEventInfo.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder.Entities -{ - /// - /// Represents an obsolete event. - /// - public class ObsoleteEventInfo - { - /// - /// Gets or sets the message. - /// - public string Message { get; set; } - - /// - /// Gets or sets a value indicating whether the obsolete event is an error. - /// - public bool IsError { get; set; } - } -} diff --git a/src/EventBuilder/Entities/ParentInfo.cs b/src/EventBuilder/Entities/ParentInfo.cs deleted file mode 100644 index 76bdaeec0f..0000000000 --- a/src/EventBuilder/Entities/ParentInfo.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder.Entities -{ - /// - /// Parent information. - /// - public class ParentInfo - { - /// - /// Gets or sets the name. - /// - public string Name { get; set; } - } -} diff --git a/src/EventBuilder/Entities/PublicEventInfo.cs b/src/EventBuilder/Entities/PublicEventInfo.cs deleted file mode 100644 index ec34fd3ee6..0000000000 --- a/src/EventBuilder/Entities/PublicEventInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder.Entities -{ - /// - /// Represents a public event. - /// - public class PublicEventInfo - { - /// - /// Gets or sets the name of the public event. - /// - public string Name { get; set; } - - /// - /// Gets or sets the type of the event handler. - /// - public string EventHandlerType { get; set; } - - /// - /// Gets or sets the type of the event arguments. - /// - public string EventArgsType { get; set; } - - /// - /// Gets or sets the obsolete event information. - /// - public ObsoleteEventInfo ObsoleteEventInfo { get; set; } - } -} diff --git a/src/EventBuilder/Entities/PublicTypeInfo.cs b/src/EventBuilder/Entities/PublicTypeInfo.cs deleted file mode 100644 index 52fbf71ea3..0000000000 --- a/src/EventBuilder/Entities/PublicTypeInfo.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using Mono.Cecil; - -namespace EventBuilder.Entities -{ - /// - /// Represents public type information. - /// - public class PublicTypeInfo - { - /// - /// Gets or sets the name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the abstract. - /// - public string Abstract { get; set; } - - /// - /// Gets or sets the type. - /// - public TypeDefinition Type { get; set; } - - /// - /// Gets or sets the parent. - /// - public ParentInfo Parent { get; set; } - - /// - /// Gets or sets the events. - /// - public IEnumerable Events { get; set; } - - /// - /// Gets or sets the zero parameter methods. - /// - public IEnumerable ZeroParameterMethods { get; set; } - - /// - /// Gets or sets the single parameter methods. - /// - public IEnumerable SingleParameterMethods { get; set; } - - /// - /// Gets or sets the multi parameter methods. - /// - public IEnumerable MultiParameterMethods { get; set; } - } -} diff --git a/src/EventBuilder/Entities/SingleParameterMethod.cs b/src/EventBuilder/Entities/SingleParameterMethod.cs deleted file mode 100644 index ff2d9b59e2..0000000000 --- a/src/EventBuilder/Entities/SingleParameterMethod.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder.Entities -{ - /// - /// Respresents a method with a single parameter. - /// - public class SingleParameterMethod - { - /// - /// Gets or sets the name. - /// - public string Name { get; set; } - - /// - /// Gets or sets the type of the parameter. - /// - public string ParameterType { get; set; } - - /// - /// Gets or sets the name of the parameter. - /// - public string ParameterName { get; set; } - } -} diff --git a/src/EventBuilder/EventBuilder.csproj b/src/EventBuilder/EventBuilder.csproj deleted file mode 100644 index 879f267df5..0000000000 --- a/src/EventBuilder/EventBuilder.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - Exe - netcoreapp2.1 - EventBuilder - EventBuilder - latest - false - - - - - PreserveNewest - - - PreserveNewest - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/EventBuilder/EventBuilder.sln b/src/EventBuilder/EventBuilder.sln deleted file mode 100644 index 2438ddbb8f..0000000000 --- a/src/EventBuilder/EventBuilder.sln +++ /dev/null @@ -1,31 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.9 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EventBuilder", "EventBuilder.csproj", "{A6B86E12-057F-4591-98A3-FD50E9CEAE69}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|x86.ActiveCfg = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Debug|x86.Build.0 = Debug|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|Any CPU.Build.0 = Release|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|x86.ActiveCfg = Release|Any CPU - {A6B86E12-057F-4591-98A3-FD50E9CEAE69}.Release|x86.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {8AD09057-1163-45D2-A260-CB034E6DFD07} - EndGlobalSection -EndGlobal diff --git a/src/EventBuilder/ExitCode.cs b/src/EventBuilder/ExitCode.cs deleted file mode 100644 index 19823af6c5..0000000000 --- a/src/EventBuilder/ExitCode.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace EventBuilder -{ - /// - /// The exit/return code (aka %ERRORLEVEL%) on application exit. - /// - public enum ExitCode - { - /// - /// Success - /// - Success = 0, - - /// - /// Error - /// - Error = 1, - } -} diff --git a/src/EventBuilder/NuGet/NuGetLogger.cs b/src/EventBuilder/NuGet/NuGetLogger.cs deleted file mode 100644 index 57e60018df..0000000000 --- a/src/EventBuilder/NuGet/NuGetLogger.cs +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Threading.Tasks; -using NuGet.Common; - -namespace EventBuilder.NuGet -{ - /// - /// A logger provider for the NuGet clients API. - /// - internal class NuGetLogger : ILogger - { - /// - public void Log(LogLevel level, string data) - { - switch (level) - { - case LogLevel.Warning: - Serilog.Log.Warning(data); - break; - case LogLevel.Error: - Serilog.Log.Error(data); - break; - case LogLevel.Information: - Serilog.Log.Information(data); - break; - case LogLevel.Debug: - Serilog.Log.Debug(data); - break; - default: - Serilog.Log.Verbose(data); - break; - } - } - - /// - public void Log(ILogMessage message) - { - Log(message.Level, message.Message); - } - - /// - public Task LogAsync(LogLevel level, string data) - { - Log(level, data); - return Task.CompletedTask; - } - - /// - public Task LogAsync(ILogMessage message) - { - Log(message); - return Task.CompletedTask; - } - - /// - public void LogDebug(string data) - { - Serilog.Log.Debug(data); - } - - /// - public void LogError(string data) - { - Serilog.Log.Error(data); - } - - /// - public void LogInformation(string data) - { - Serilog.Log.Information(data); - } - - /// - public void LogInformationSummary(string data) - { - Serilog.Log.Information(data); - } - - /// - public void LogMinimal(string data) - { - Serilog.Log.Information(data); - } - - /// - public void LogVerbose(string data) - { - Serilog.Log.Verbose(data); - } - - /// - public void LogWarning(string data) - { - Serilog.Log.Warning(data); - } - } -} diff --git a/src/EventBuilder/NuGet/NuGetPackageHelper.cs b/src/EventBuilder/NuGet/NuGetPackageHelper.cs deleted file mode 100644 index c9ff2aa0ba..0000000000 --- a/src/EventBuilder/NuGet/NuGetPackageHelper.cs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using NuGet.Configuration; -using NuGet.Frameworks; -using NuGet.PackageManagement; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.ProjectManagement; -using NuGet.Protocol.Core.Types; -using NuGet.Resolver; -using Polly; -using Serilog; - -namespace EventBuilder.NuGet -{ - /// - /// A helper class for handling NuGet packages. - /// - public static class NuGetPackageHelper - { - /// - /// Installs a nuget package into the specified directory. - /// - /// The identities of the packages to find. - /// The name of the platform. - /// Optional framework parameter which will force NuGet to evaluate as the specified Framework. If null it will use .NET Standard 2.0. - /// The directory where the NuGet packages are unzipped to. - public static async Task InstallPackages(IEnumerable packageIdentities, AutoPlatform platform, NuGetFramework framework = null) - { - var packageUnzipPath = Path.Combine(Path.GetTempPath(), "EventBuilder.NuGet", platform.ToString()); - if (!Directory.Exists(packageUnzipPath)) - { - Directory.CreateDirectory(packageUnzipPath); - } - - await Task.WhenAll(packageIdentities.Select(x => InstallPackage(x, packageUnzipPath, framework))).ConfigureAwait(false); - - return packageUnzipPath; - } - - private static async Task InstallPackage(PackageIdentity packageIdentity, string packageRoot, NuGetFramework framework) - { - var packagesPath = Path.Combine(packageRoot, "packages"); - var settings = Settings.LoadDefaultSettings(packageRoot, null, new XPlatMachineWideSetting()); - var sourceRepositoryProvider = new SourceRepositoryProvider(settings); - var folder = new FolderNuGetProject(packageRoot, new PackagePathResolver(packageRoot), framework ?? FrameworkConstants.CommonFrameworks.NetStandard20); - var packageManager = new NuGetPackageManager(sourceRepositoryProvider, settings, packagesPath) - { - PackagesFolderNuGetProject = folder - }; - - var resolutionContext = new ResolutionContext( - DependencyBehavior.Lowest, - includePrelease: false, - includeUnlisted: false, - VersionConstraints.None); - var projectContext = new NuGetProjectContext(settings); - - var retryPolicy = Policy - .Handle() - .WaitAndRetryAsync( - 5, - retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), - (exception, _, __) => - { - Log.Warning( - "An exception was thrown whilst retrieving or installing {0}: {1}", - packageIdentity, - exception); - }); - - await retryPolicy.ExecuteAsync(async () => - { - await packageManager.InstallPackageAsync( - packageManager.PackagesFolderNuGetProject, - packageIdentity, - resolutionContext, - projectContext, - sourceRepositoryProvider.GetDefaultRepositories(), - Array.Empty(), - CancellationToken.None).ConfigureAwait(false); - }).ConfigureAwait(false); - } - } -} diff --git a/src/EventBuilder/NuGet/NuGetProjectContext.cs b/src/EventBuilder/NuGet/NuGetProjectContext.cs deleted file mode 100644 index 82a38077aa..0000000000 --- a/src/EventBuilder/NuGet/NuGetProjectContext.cs +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Xml.Linq; -using NuGet.Configuration; -using NuGet.Packaging; -using NuGet.Packaging.Signing; -using NuGet.ProjectManagement; - -namespace EventBuilder.NuGet -{ - /// - /// Context for handling logging inside the nuget project system. - /// - internal class NuGetProjectContext : INuGetProjectContext - { - public NuGetProjectContext(ISettings settings) - { - var nuGetLogger = new NuGetLogger(); - PackageExtractionContext = new PackageExtractionContext( - PackageSaveMode.Files, - XmlDocFileSaveMode.None, - ClientPolicyContext.GetClientPolicy(settings, nuGetLogger), - nuGetLogger); - } - - /// - public PackageExtractionContext PackageExtractionContext { get; set; } - - /// - public XDocument OriginalPackagesConfig { get; set; } - - /// - public NuGetActionType ActionType { get; set; } - - /// - public Guid OperationId { get; set; } - - /// - public ISourceControlManagerProvider SourceControlManagerProvider => null; - - /// - public ExecutionContext ExecutionContext => null; - - /// - public void Log(MessageLevel level, string message, params object[] args) - { - switch (level) - { - case MessageLevel.Warning: - Serilog.Log.Warning(message, args); - break; - case MessageLevel.Error: - Serilog.Log.Error(message, args); - break; - case MessageLevel.Info: - Serilog.Log.Information(message, args); - break; - case MessageLevel.Debug: - Serilog.Log.Debug(message, args); - break; - default: - Serilog.Log.Verbose(message, args); - break; - } - } - - /// - public FileConflictAction ResolveFileConflict(string message) => FileConflictAction.Ignore; - - /// - public void ReportError(string message) - { - Serilog.Log.Error(message); - } - } -} diff --git a/src/EventBuilder/NuGet/SourceRepositoryProvider.cs b/src/EventBuilder/NuGet/SourceRepositoryProvider.cs deleted file mode 100644 index b2b9bc8b97..0000000000 --- a/src/EventBuilder/NuGet/SourceRepositoryProvider.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using NuGet.Configuration; -using NuGet.Protocol; -using NuGet.Protocol.Core.Types; - -namespace EventBuilder.NuGet -{ - /// - /// Based off Dave Glick's articles here: https://daveaglick.com/posts/exploring-the-nuget-v3-libraries-part-3 - /// Creates and caches SourceRepository objects, which are - /// the combination of PackageSource instances with a set - /// of supported resource providers. It also manages the set - /// of default source repositories. - /// - internal class SourceRepositoryProvider : ISourceRepositoryProvider - { - private static readonly string[] DefaultSources = - { - "https://api.nuget.org/v3/index.json" - }; - - private readonly List _defaultRepositories = new List(); - - private readonly ConcurrentDictionary _repositoryCache - = new ConcurrentDictionary(); - - private readonly List> _resourceProviders; - - public SourceRepositoryProvider(ISettings settings) - { - // Create the package source provider (needed primarily to get default sources) - PackageSourceProvider = new PackageSourceProvider(settings); - - // Add the v3 provider as default - _resourceProviders = new List>(); - _resourceProviders.AddRange(Repository.Provider.GetCoreV3()); - - AddGlobalDefaults(); - AddDefaultPackageSources(); - } - - /// - public IPackageSourceProvider PackageSourceProvider { get; } - - /// - /// Add the global sources to the default repositories. - /// - public void AddGlobalDefaults() - { - _defaultRepositories.AddRange(PackageSourceProvider.LoadPackageSources() - .Where(x => x.IsEnabled) - .Select(x => new SourceRepository(x, _resourceProviders))); - } - - public void AddDefaultPackageSources() - { - foreach (string defaultSource in DefaultSources) - { - AddDefaultRepository(defaultSource); - } - } - - /// - /// Adds a default source repository to the front of the list. - /// - public void AddDefaultRepository(string packageSource) => _defaultRepositories.Insert(0, CreateRepository(packageSource)); - - public IEnumerable GetDefaultRepositories() => _defaultRepositories; - - /// - /// Creates or gets a non-default source repository. - /// - public SourceRepository CreateRepository(string packageSource) => CreateRepository(new PackageSource(packageSource), FeedType.Undefined); - - /// - /// Creates or gets a non-default source repository by PackageSource. - /// - public SourceRepository CreateRepository(PackageSource packageSource) => CreateRepository(packageSource, FeedType.Undefined); - - /// - /// Creates or gets a non-default source repository by PackageSource. - /// - public SourceRepository CreateRepository(PackageSource packageSource, FeedType feedType) => - _repositoryCache.GetOrAdd(packageSource, x => new SourceRepository(packageSource, _resourceProviders)); - - /// - /// Gets all cached repositories. - /// - public IEnumerable GetRepositories() => _repositoryCache.Values; - } -} diff --git a/src/EventBuilder/PlatformHelper.cs b/src/EventBuilder/PlatformHelper.cs deleted file mode 100644 index e8e8dede5d..0000000000 --- a/src/EventBuilder/PlatformHelper.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; - -namespace EventBuilder -{ - /// - /// Platform helper methods. - /// - public static class PlatformHelper - { - private static readonly Lazy _IsRunningOnMono = new Lazy(() => !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); - - /// - /// Determines whether the platform is running on mono. - /// - /// - /// true if [is running on mono]; otherwise, false. - /// - public static bool IsRunningOnMono() - { - return _IsRunningOnMono.Value; - } - } -} diff --git a/src/EventBuilder/Platforms/Android.cs b/src/EventBuilder/Platforms/Android.cs deleted file mode 100644 index c2285ab2c6..0000000000 --- a/src/EventBuilder/Platforms/Android.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// - /// The Android platform. - /// - /// - public class Android : BasePlatform - { - private const string DesiredVersion = "v8.1"; - - private readonly string _referenceAssembliesLocation; - - /// - /// Initializes a new instance of the class. - /// - /// The reference assemblies location. - public Android(string referenceAssembliesLocation) - { - _referenceAssembliesLocation = referenceAssembliesLocation; - } - - /// - public override AutoPlatform Platform => AutoPlatform.Android; - - /// - public override Task Extract() - { - var sdks = new List(); - if (PlatformHelper.IsRunningOnMono()) - { - CecilSearchDirectories.Add( - "/Library/Frameworks/Xamarin.Android.framework/Libraries/xbuild-frameworks/MonoAndroid/v1.0"); - - sdks.AddRange(Directory.GetFiles( - "/Library/Frameworks/Xamarin.Android.framework/Libraries/xbuild-frameworks/MonoAndroid", - "Mono.Android.dll", - SearchOption.AllDirectories)); - } - else - { - CecilSearchDirectories.Add(Path.Combine(_referenceAssembliesLocation, "MonoAndroid", "v1.0")); - sdks.AddRange(Directory.GetFiles( - Path.Combine(_referenceAssembliesLocation, "MonoAndroid"), - "Mono.Android.dll", - SearchOption.AllDirectories)); - } - - // Pin to a particular framework version https://github.com/reactiveui/ReactiveUI/issues/1517 - var latestVersion = sdks.Last(x => x.Contains(DesiredVersion, StringComparison.InvariantCulture)); - Assemblies.Add(latestVersion); - CecilSearchDirectories.Add(Path.GetDirectoryName(latestVersion)); - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/BasePlatform.cs b/src/EventBuilder/Platforms/BasePlatform.cs deleted file mode 100644 index aeaa9bf9e1..0000000000 --- a/src/EventBuilder/Platforms/BasePlatform.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// Base platform. - /// - /// - public abstract class BasePlatform : IPlatform - { - /// - /// Initializes a new instance of the class. - /// - protected BasePlatform() - { - Assemblies = new List(); - CecilSearchDirectories = new List(); - } - - /// - public abstract AutoPlatform Platform { get; } - - /// - public List Assemblies { get; } - - /// - public List CecilSearchDirectories { get; } - - /// - public abstract Task Extract(); - } -} diff --git a/src/EventBuilder/Platforms/Bespoke.cs b/src/EventBuilder/Platforms/Bespoke.cs deleted file mode 100644 index a02d3e52b6..0000000000 --- a/src/EventBuilder/Platforms/Bespoke.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// - /// The Bespoke platform. - /// - /// - public class Bespoke : BasePlatform - { - /// - public override AutoPlatform Platform => AutoPlatform.None; - - /// - public override Task Extract() - { - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/Essentials.cs b/src/EventBuilder/Platforms/Essentials.cs deleted file mode 100644 index 91ec97eb74..0000000000 --- a/src/EventBuilder/Platforms/Essentials.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using EventBuilder.NuGet; -using NuGet.Packaging.Core; -using NuGet.Versioning; -using Serilog; - -namespace EventBuilder.Platforms -{ - /// - /// Xamarin Essentials platform. - /// - /// - public class Essentials : BasePlatform - { - private readonly PackageIdentity[] _packageNames = new[] - { - new PackageIdentity("Xamarin.Essentials", new NuGetVersion("1.0.1")), - new PackageIdentity("NetStandard.Library", new NuGetVersion("2.0.0")), - }; - - /// - public override AutoPlatform Platform => AutoPlatform.Essentials; - - /// - public override async Task Extract() - { - var packageUnzipPath = await NuGetPackageHelper.InstallPackages(_packageNames, Platform).ConfigureAwait(false); - - Log.Debug($"Package unzip path is {packageUnzipPath}"); - - var xamarinForms = - Directory.GetFiles( - packageUnzipPath, - "Xamarin.Essentials.dll", - SearchOption.AllDirectories); - - var latestVersion = xamarinForms.First(x => x.Contains("netstandard2.0", StringComparison.InvariantCulture)); - Assemblies.Add(latestVersion); - - foreach (var directory in Directory.GetDirectories(packageUnzipPath, "*.*", SearchOption.AllDirectories)) - { - CecilSearchDirectories.Add(directory); - } - } - } -} diff --git a/src/EventBuilder/Platforms/IPlatform.cs b/src/EventBuilder/Platforms/IPlatform.cs deleted file mode 100644 index 41dbeae0ca..0000000000 --- a/src/EventBuilder/Platforms/IPlatform.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// Interface representing a platform assemblies and events. - /// - public interface IPlatform - { - /// - /// Gets the event builder platform. - /// - AutoPlatform Platform { get; } - - /// - /// Gets the assemblies. - /// - List Assemblies { get; } - - /// - /// Gets the cecil search directories. - /// Cecil when run on Mono needs some direction as to the location of the platform specific MSCORLIB. - /// - List CecilSearchDirectories { get; } - - /// - /// Extract details about the platform. - /// - /// A task to monitor the progress. - Task Extract(); - } -} diff --git a/src/EventBuilder/Platforms/Mac.cs b/src/EventBuilder/Platforms/Mac.cs deleted file mode 100644 index fc1de51c1e..0000000000 --- a/src/EventBuilder/Platforms/Mac.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// Mac platform assemblies and events. - /// - /// - // ReSharper disable once InconsistentNaming - public class Mac : BasePlatform - { - private readonly string _referenceAssembliesLocation; - - /// - /// Initializes a new instance of the class. - /// - /// The reference assemblies location. - public Mac(string referenceAssembliesLocation) - { - _referenceAssembliesLocation = referenceAssembliesLocation; - } - - /// - public override AutoPlatform Platform => AutoPlatform.Mac; - - /// - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - var assembly = - @"/Library/Frameworks/Xamarin.Mac.framework/Versions/Current/lib/mono/Xamarin.Mac/Xamarin.Mac.dll"; - Assemblies.Add(assembly); - - CecilSearchDirectories.Add(Path.GetDirectoryName(assembly)); - } - else - { - var assemblies = - Directory.GetFiles( - Path.Combine(_referenceAssembliesLocation, "Xamarin.Mac"), - "Xamarin.Mac.dll", - SearchOption.AllDirectories); - - var latestVersion = assemblies.Last(); - Assemblies.Add(latestVersion); - - CecilSearchDirectories.Add(Path.GetDirectoryName(latestVersion)); - } - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/Tizen.cs b/src/EventBuilder/Platforms/Tizen.cs deleted file mode 100644 index c21708b62a..0000000000 --- a/src/EventBuilder/Platforms/Tizen.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.IO; -using System.Threading.Tasks; -using EventBuilder.NuGet; -using NuGet.Frameworks; -using NuGet.Packaging.Core; -using NuGet.Versioning; -using Serilog; - -namespace EventBuilder.Platforms -{ - /// - /// Tizen platform assemblies and events. - /// - /// - public class Tizen : BasePlatform - { - private readonly PackageIdentity[] _packageNames = new[] - { - new PackageIdentity("Tizen.Net", new NuGetVersion("5.0.0.14562")), - new PackageIdentity("NetStandard.Library", new NuGetVersion("2.0.0")), - }; - - /// - public override AutoPlatform Platform => AutoPlatform.Tizen4; - - /// - public override async Task Extract() - { - var packageUnzipPath = await NuGetPackageHelper.InstallPackages(_packageNames, Platform, FrameworkConstants.CommonFrameworks.Tizen4).ConfigureAwait(false); - - Log.Debug($"Package unzip path is {packageUnzipPath}"); - - Assemblies.AddRange(Directory.GetFiles(packageUnzipPath, "ElmSharp*.dll", SearchOption.AllDirectories)); - Assemblies.AddRange(Directory.GetFiles(packageUnzipPath, "Tizen*.dll", SearchOption.AllDirectories)); - - foreach (var directory in Directory.GetDirectories(packageUnzipPath, "*.*", SearchOption.AllDirectories)) - { - CecilSearchDirectories.Add(directory); - } - } - } -} diff --git a/src/EventBuilder/Platforms/UWP.cs b/src/EventBuilder/Platforms/UWP.cs deleted file mode 100644 index f55b770d3d..0000000000 --- a/src/EventBuilder/Platforms/UWP.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// UWP platform assemblies and events. - /// - /// - public class UWP : BasePlatform - { - /// - public override AutoPlatform Platform => AutoPlatform.UWP; - - /// - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - throw new NotSupportedException("Building events for UWP on Mac is not implemented yet."); - } - - Assemblies.Add(@"C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.17763.0\Windows.winmd"); - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/WPF.cs b/src/EventBuilder/Platforms/WPF.cs deleted file mode 100644 index d1a01b8074..0000000000 --- a/src/EventBuilder/Platforms/WPF.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// WPF platform assemblies and events. - /// - /// - public class WPF : BasePlatform - { - /// - public override AutoPlatform Platform => AutoPlatform.WPF; - - /// - /// Building events for WPF on Mac is not implemented. - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - throw new NotSupportedException("Building events for WPF on Mac is not implemented."); - } - - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\WindowsBase.dll"); - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationCore.dll"); - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\PresentationFramework.dll"); - - CecilSearchDirectories.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1"); - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/Winforms.cs b/src/EventBuilder/Platforms/Winforms.cs deleted file mode 100644 index 58c2878aff..0000000000 --- a/src/EventBuilder/Platforms/Winforms.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// Win Forms platform assemblies and events. - /// - /// - public class Winforms : BasePlatform - { - /// - public override AutoPlatform Platform => AutoPlatform.Winforms; - - /// - /// Building events for Winforms on Mac is not implemented. - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - throw new NotSupportedException("Building events for Winforms on Mac is not implemented."); - } - - // BackgroundWorker - // EventLog - // FileSystemWatcher - // PerformanceCounter - // Process - // SerialPort - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.dll"); - - // DataSet - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Data.dll"); - - // DirectoryEntry - // DirectorySearcher - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.DirectoryServices.dll"); - - // PrintDocument - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll"); - - // MessageQueue - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Messaging.dll"); - - // BindingNavigator - // ToolStripButton - // ToolStripLabel - // ToolStripButton - // ToolStripButton - // ToolStripButton - // ToolStripSeparator - // ToolStripTextBox - // ToolStripSeparator - // ToolStripButton - // ToolStripButton - // ToolStripSeparator - // BindingSource - // Button - // CheckBox - // CheckedListBox - // ColorDialog - // ComboBox - // ContextMenuStrip - // DataGridView - // DateTimePicker - // DomainUpDown - // ErrorProvider - // WebBrowser - // VScrollBar - // TreeView - // ToolStripContainer - // TrackBar - // ToolStrip - // SplitContainer - // TabControl - // TabPage - // TableLayoutPanel - // TextBox - // TabPage - // StatusStrip - // Splitter - // RichTextBox - // RadioButton - // PropertyGrid - // ProgressBar - // PrintPreviewControl - // PictureBox - // Panel - // NumericUpDown - // MonthCalendar - // MaskedTextBox - // ListView - // ListBox - // LinkLabel - // Label - // HScrollBar - // GroupBox - // FlowLayoutPanel - // MenuStrip - // FolderBrowserDialog - // FontDialog - // HelpProvider - // ImageList - // NotifyIcon - // OpenFileDialog - // PageSetupDialog - // PrintDialog - // PrintPreviewDialog - // SaveFileDialog - // Timer - // ToolTip - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Windows.Forms.dll"); - - // Chart - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Windows.Forms.DataVisualization.dll"); - - // ServiceController - Assemblies.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.ServiceProcess.dll"); - - CecilSearchDirectories.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1"); - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/XamForms.cs b/src/EventBuilder/Platforms/XamForms.cs deleted file mode 100644 index cdc409aa43..0000000000 --- a/src/EventBuilder/Platforms/XamForms.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using EventBuilder.NuGet; -using NuGet.Packaging.Core; -using NuGet.Versioning; -using Serilog; - -namespace EventBuilder.Platforms -{ - /// - /// Xamarin Forms assemblies and events. - /// - /// - public class XamForms : BasePlatform - { - private readonly PackageIdentity[] _packageNames = new[] - { - new PackageIdentity("Xamarin.Forms", new NuGetVersion("3.6.0.220655")), - }; - - /// - public override AutoPlatform Platform => AutoPlatform.XamForms; - - /// - public override async Task Extract() - { - var packageUnzipPath = await NuGetPackageHelper.InstallPackages(_packageNames, Platform).ConfigureAwait(false); - - Log.Debug($"Package unzip path is {packageUnzipPath}"); - - var xamarinForms = - Directory.GetFiles( - packageUnzipPath, - "Xamarin.Forms.Core.dll", - SearchOption.AllDirectories); - - var latestVersion = xamarinForms.Last(); - Assemblies.Add(latestVersion); - - if (PlatformHelper.IsRunningOnMono()) - { - CecilSearchDirectories.Add( - @"/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/xbuild-frameworks/.NETPortable/v4.5/Profile/Profile111"); - CecilSearchDirectories.Add(@"/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/Facades"); - } - else - { - CecilSearchDirectories.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2\Facades"); - } - } - } -} diff --git a/src/EventBuilder/Platforms/iOS.cs b/src/EventBuilder/Platforms/iOS.cs deleted file mode 100644 index 529e8ce876..0000000000 --- a/src/EventBuilder/Platforms/iOS.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// - /// iOS platform assemblies and events. - /// - /// - // ReSharper disable once InconsistentNaming -#pragma warning disable IDE1006 // Naming Styles -#pragma warning disable SA1300 // Element should begin with upper-case letter - public class iOS : BasePlatform -#pragma warning restore SA1300 // Element should begin with upper-case letter -#pragma warning restore IDE1006 // Naming Styles - { - private readonly string _referenceAssembliesLocation; - - /// - /// Initializes a new instance of the class. - /// - /// The reference assemblies location. - public iOS(string referenceAssembliesLocation) - { - _referenceAssembliesLocation = referenceAssembliesLocation; - } - - /// - public override AutoPlatform Platform => AutoPlatform.iOS; - - /// - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - var assembly = - @"/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/Xamarin.iOS/Xamarin.iOS.dll"; - Assemblies.Add(assembly); - - CecilSearchDirectories.Add(Path.GetDirectoryName(assembly)); - } - else - { - var assemblies = - Directory.GetFiles( - Path.Combine(_referenceAssembliesLocation, "Xamarin.iOS"), - "Xamarin.iOS.dll", - SearchOption.AllDirectories); - - var latestVersion = assemblies.Last(); - Assemblies.Add(latestVersion); - - CecilSearchDirectories.Add(Path.GetDirectoryName(latestVersion)); - } - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Platforms/tvOS.cs b/src/EventBuilder/Platforms/tvOS.cs deleted file mode 100644 index fb2e821ce6..0000000000 --- a/src/EventBuilder/Platforms/tvOS.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.IO; -using System.Linq; -using System.Threading.Tasks; - -namespace EventBuilder.Platforms -{ - /// - /// TV OS platform assemblies and events. - /// - /// - // ReSharper disable once InconsistentNaming - public class TVOS : BasePlatform - { - private readonly string _referenceAssembliesLocation; - - /// - /// Initializes a new instance of the class. - /// - /// The reference assemblies location. - public TVOS(string referenceAssembliesLocation) - { - _referenceAssembliesLocation = referenceAssembliesLocation; - } - - /// - public override AutoPlatform Platform => AutoPlatform.TVOS; - - /// - public override Task Extract() - { - if (PlatformHelper.IsRunningOnMono()) - { - var assembly = - @"/Library/Frameworks/Xamarin.iOS.framework/Versions/Current/lib/mono/Xamarin.TVOS/Xamarin.TVOS.dll"; - Assemblies.Add(assembly); - - CecilSearchDirectories.Add(Path.GetDirectoryName(assembly)); - } - else - { - var assemblies = - Directory.GetFiles( - Path.Combine(_referenceAssembliesLocation, "Xamarin.TVOS"), - "Xamarin.TVOS.dll", - SearchOption.AllDirectories); - - var latestVersion = assemblies.Last(); - Assemblies.Add(latestVersion); - - CecilSearchDirectories.Add(Path.GetDirectoryName(latestVersion)); - } - - return Task.CompletedTask; - } - } -} diff --git a/src/EventBuilder/Program.cs b/src/EventBuilder/Program.cs deleted file mode 100644 index 46c524883b..0000000000 --- a/src/EventBuilder/Program.cs +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using CommandLine; -using EventBuilder.Cecil; -using EventBuilder.Platforms; -using Mono.Cecil; -using Serilog; -using Stubble.Core.Builders; -using Parser = CommandLine.Parser; - -namespace EventBuilder -{ - internal static class Program - { - private static string _mustacheTemplate = "DefaultTemplate.mustache"; - private static string _referenceAssembliesLocation = PlatformHelper.IsRunningOnMono() ? - @"/Library⁩/Frameworks⁩/Libraries/⁨mono⁩" : - @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework"; - - public static async Task Main(string[] args) - { - Log.Logger = new LoggerConfiguration() - .ReadFrom.AppSettings() - .CreateLogger(); - - // allow app to be debugged in visual studio. - if (Debugger.IsAttached) - { - args = "--platform=android --output-path=test.txt".Split(' '); - } - - await new Parser(parserSettings => parserSettings.CaseInsensitiveEnumValues = true).ParseArguments(args).MapResult( - async options => - { - try - { - if (!string.IsNullOrWhiteSpace(options.Template)) - { - _mustacheTemplate = options.Template; - - Log.Debug("Using {template} instead of the default template.", _mustacheTemplate); - } - - if (!string.IsNullOrWhiteSpace(options.ReferenceAssemblies)) - { - _referenceAssembliesLocation = options.ReferenceAssemblies; - Log.Debug($"Using {_referenceAssembliesLocation} instead of the default reference assemblies location."); - } - - IPlatform platform = null; - switch (options.Platform) - { - case AutoPlatform.None: - if (options.Assemblies.Any() == false) - { - throw new Exception("Assemblies to be used for manual generation were not specified."); - } - - platform = new Bespoke(); - platform.Assemblies.AddRange(options.Assemblies); - - if (PlatformHelper.IsRunningOnMono()) - { - platform.CecilSearchDirectories.AddRange(platform.Assemblies.Select(Path.GetDirectoryName).Distinct().ToList()); - } - else - { - platform.CecilSearchDirectories.Add(@"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5"); - } - - break; - - case AutoPlatform.Android: - platform = new Android(_referenceAssembliesLocation); - break; - - case AutoPlatform.iOS: - platform = new iOS(_referenceAssembliesLocation); - break; - - case AutoPlatform.Mac: - platform = new Mac(_referenceAssembliesLocation); - break; - - case AutoPlatform.TVOS: - platform = new TVOS(_referenceAssembliesLocation); - break; - - case AutoPlatform.WPF: - platform = new WPF(); - break; - - case AutoPlatform.XamForms: - platform = new XamForms(); - break; - - case AutoPlatform.Tizen4: - platform = new Tizen(); - break; - - case AutoPlatform.UWP: - platform = new UWP(); - break; - - case AutoPlatform.Winforms: - platform = new Winforms(); - break; - - case AutoPlatform.Essentials: - platform = new Essentials(); - _mustacheTemplate = "XamarinEssentialsTemplate.mustache"; - break; - - default: - throw new ArgumentException($"Platform not {options.Platform} supported"); - } - - await ExtractEventsFromAssemblies(options.OutputPath, platform).ConfigureAwait(false); - - Environment.Exit((int)ExitCode.Success); - } - catch (Exception ex) - { - Log.Fatal(ex.ToString()); - - if (Debugger.IsAttached) - { - Debugger.Break(); - } - } - - Environment.Exit((int)ExitCode.Error); - }, - _ => Task.CompletedTask).ConfigureAwait(false); - } - - [SuppressMessage("Globalization", "CA1307: Specify StringComparison", Justification = "Replace overload is for .NET Standard only")] - private static async Task ExtractEventsFromAssemblies(string outputPath, IPlatform platform) - { - await platform.Extract().ConfigureAwait(false); - - Log.Debug("Extracting events from the following assemblies: {assemblies}", platform.Assemblies); - - Log.Debug("Using the following search directories: {assemblies}", platform.CecilSearchDirectories); - var targetAssemblyDirs = platform.CecilSearchDirectories; - - var rp = new ReaderParameters - { - AssemblyResolver = new PathSearchAssemblyResolver(targetAssemblyDirs.ToArray()) - }; - - var targetAssemblies = platform.Assemblies.Select(x => AssemblyDefinition.ReadAssembly(x, rp)).ToArray(); - - Log.Debug("Using {template} as the mustache template", _mustacheTemplate); - - var namespaceData = Array.Empty(); - - switch (platform.Platform) - { - case AutoPlatform.Essentials: - namespaceData = StaticEventTemplateInformation.Create(targetAssemblies); - break; - default: - namespaceData = EventTemplateInformation.Create(targetAssemblies); - break; - } - - var delegateData = DelegateTemplateInformation.Create(targetAssemblies); - - using (var streamReader = new StreamReader(_mustacheTemplate, Encoding.UTF8)) - { - var template = await streamReader.ReadToEndAsync().ConfigureAwait(false); - var stubble = new StubbleBuilder().Build(); - var result = (await stubble.RenderAsync(template, new { Namespaces = namespaceData, DelegateNamespaces = delegateData }).ConfigureAwait(false)) - .Replace("System.String", "string") - .Replace("System.Object", "object") - .Replace("<", "<") - .Replace(">", ">") - .Replace("`1", string.Empty) - .Replace("`2", string.Empty) - .Replace("`3", string.Empty); - - await File.WriteAllTextAsync(outputPath, result).ConfigureAwait(false); - } - } - } -} diff --git a/src/EventBuilder/XamarinEssentialsTemplate.mustache b/src/EventBuilder/XamarinEssentialsTemplate.mustache deleted file mode 100644 index 3f19c975ed..0000000000 --- a/src/EventBuilder/XamarinEssentialsTemplate.mustache +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -//------------------------------------------------------------------------------ -// -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -//------------------------------------------------------------------------------ - -#pragma warning disable 1591,0618,0105,0672,0108,SA1402,SA1200,SA1514,SA1615,SA1210,SA1001,SA1403,SA1201,SA1306,SA1601,SA1513,SA1004,SA1516,SA1508,SA1629,SA1507,SA1121,SA1208 - -using System; -using System.Reactive; -using System.Reactive.Linq; -using System.Reactive.Subjects; - -{{#Namespaces}} -using {{Name}}; -{{/Namespaces}} -{{#DelegateNamespaces}} -using {{Name}}; -{{/DelegateNamespaces}} - -{{#Namespaces}} -namespace {{Name}} -{ - public static class Events - { - -{{#Types}} -{{#Events}} - public static IObservable<{{EventArgsType}}> - {{#Type}}{{Name}}{{/Type}}{{Name}}() => - Observable.FromEventPattern<{{EventArgsType}}>( - x => {{#Type}}{{Name}}{{/Type}}.{{Name}} += x, - x => {{#Type}}{{Name}}{{/Type}}.{{Name}} -= x) - .Select(x => x.EventArgs); - - {{/Events}} - {{/Types}} - } - } - {{/Namespaces}} \ No newline at end of file diff --git a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj index b39539f464..7fa338b6b2 100644 --- a/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj +++ b/src/ReactiveUI.Events.WPF/ReactiveUI.Events.WPF.csproj @@ -12,8 +12,7 @@ - - + diff --git a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj index cc2914e4da..3d174711ce 100644 --- a/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj +++ b/src/ReactiveUI.Events.Winforms/ReactiveUI.Events.Winforms.csproj @@ -13,9 +13,8 @@ - - - + + diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index edfefdc0c4..b7dac04f68 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -12,8 +12,7 @@ - - + @@ -23,7 +22,7 @@ Windows Mobile Extensions for the UWP - + @@ -31,11 +30,12 @@ - + + - + @@ -43,11 +43,8 @@ - - - - + diff --git a/src/ReactiveUI.Events/SingleAwaitSubject.cs b/src/ReactiveUI.Events/SingleAwaitSubject.cs deleted file mode 100644 index 634641484a..0000000000 --- a/src/ReactiveUI.Events/SingleAwaitSubject.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System; -using System.Reactive.Linq; -using System.Reactive.Subjects; - -namespace ReactiveUI.Events -{ - internal sealed class SingleAwaitSubject : ISubject, IDisposable - { - private readonly Subject _inner = new Subject(); - - public AsyncSubject GetAwaiter() - { - return _inner.Take(1).GetAwaiter(); - } - - public void OnNext(T value) - { - _inner.OnNext(value); - } - - public void OnError(Exception error) - { - _inner.OnError(error); - } - - public void OnCompleted() - { - _inner.OnCompleted(); - } - - public IDisposable Subscribe(IObserver observer) - { - return _inner.Subscribe(observer); - } - - /// - public void Dispose() - { - _inner?.Dispose(); - } - } -} diff --git a/tools/nuget/nuget.exe b/tools/nuget/nuget.exe deleted file mode 100644 index 1ada5b2b67..0000000000 --- a/tools/nuget/nuget.exe +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1051f2053643a9fb5d8bf9ba7cf638164a3118541e90a671442cf3499c9606ef -size 5688608 From e2aee37194710642d0c4f6b828d4fed3168af816 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sat, 15 Jun 2019 01:35:38 +1000 Subject: [PATCH 41/61] Release ReactiveUI v9.17 --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index a5022a45b4..fcff7f18ca 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "9.16", + "version": "9.17", "publicReleaseRefSpec": [ "^refs/heads/master$", // we release out of master "^refs/heads/develop$", // we release out of develop From f0474ebf739a599d692fa93aba7c9acd0085193b Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 16 Jun 2019 03:30:08 +1000 Subject: [PATCH 42/61] Update ReactiveUI.Events.XamEssentials.csproj --- .../ReactiveUI.Events.XamEssentials.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj index 028af7c1fa..b978c5df29 100644 --- a/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj +++ b/src/ReactiveUI.Events.XamEssentials/ReactiveUI.Events.XamEssentials.csproj @@ -10,6 +10,7 @@ - + + - \ No newline at end of file + From 418a9929154c9dbb7c81a6cfd50c8a7f3434f5dd Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 16 Jun 2019 03:30:56 +1000 Subject: [PATCH 43/61] Update ReactiveUI.Events.XamForms.csproj --- .../ReactiveUI.Events.XamForms.csproj | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj index 68aaa6a20b..e9febdd1f9 100644 --- a/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj +++ b/src/ReactiveUI.Events.XamForms/ReactiveUI.Events.XamForms.csproj @@ -10,6 +10,7 @@ - - - \ No newline at end of file + + + + From fe0a22f912b5b277fa029089d0aab7f92cc461ea Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 16 Jun 2019 03:31:32 +1000 Subject: [PATCH 44/61] Update ReactiveUI.Events.csproj --- src/ReactiveUI.Events/ReactiveUI.Events.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Events/ReactiveUI.Events.csproj b/src/ReactiveUI.Events/ReactiveUI.Events.csproj index b7dac04f68..61a29ac5db 100644 --- a/src/ReactiveUI.Events/ReactiveUI.Events.csproj +++ b/src/ReactiveUI.Events/ReactiveUI.Events.csproj @@ -40,7 +40,7 @@ - + From 0bf99fee10cb369d50befe09fafdd8b0ed5759bf Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 16 Jun 2019 18:24:52 +1000 Subject: [PATCH 45/61] housekeeping: move Kent to the alumni section. I asked him before doing it. He was cool with getting moved over. --- README.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 67f335b236..534d529813 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,9 @@ 🔨 Get Started 🛍 Install Packages 🎞 Watch Videos 🎓 View Samples 🎤 Discuss ReactiveUI +

Book

+There has been a excellent book written by our Alumni maintainer Kent Boogart. +

Introduction to Reactive Programming

Long ago, when computer programming first came to be, machines had to be programmed quite manually. If the technician entered the correct sequence of machine codes in the correct order, then the resulting program behavior would satisfy the business requirements. Instead of telling a computer how to do its job, which error-prone and relies too heavily on the infallibility of the programmer, why don't we just tell it what it's job is and let it figure the rest out? @@ -301,12 +304,6 @@ ReactiveUI is part of the [.NET Foundation](https://www.dotnetfoundation.org/). Geoffrey Huntley

Sydney, Australia

- - -
- Kent Boogaart -

Adelaide, Australia

-
@@ -342,6 +339,12 @@ The following have been core team members in the past. +
+ +
+ Kent Boogaart +

Adelaide, Australia

+

From e6e8b3cdc7060b9cc44d37aaf3e6530283ab09aa Mon Sep 17 00:00:00 2001 From: Kent Boogaart Date: Mon, 17 Jun 2019 09:51:42 +1000 Subject: [PATCH 46/61] housekeeping: minor tweaks to readme (#2074) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 534d529813..1ed01c905c 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ 🔨 Get Started 🛍 Install Packages 🎞 Watch Videos 🎓 View Samples 🎤 Discuss ReactiveUI

Book

-There has been a excellent book written by our Alumni maintainer Kent Boogart. +There has been an excellent book written by our Alumni maintainer Kent Boogart.

Introduction to Reactive Programming

@@ -343,7 +343,7 @@ The following have been core team members in the past.
Kent Boogaart -

Adelaide, Australia

+

Brisbane, Australia

From b420e1bac016d2847711bd52fba4ca9521edf9c5 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Tue, 18 Jun 2019 14:49:11 +1000 Subject: [PATCH 47/61] housekeeping: update .gitignore with latest --- .gitignore | 151 ++++++++++++++++++++++++++++++++++++------ tools/packages.config | 4 ++ 2 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 tools/packages.config diff --git a/.gitignore b/.gitignore index c88ebe9bf7..d5ff53b4b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore # User-specific files +*.rsuser *.suo *.user *.userosscache @@ -10,6 +13,9 @@ # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -17,18 +23,20 @@ [Rr]eleases/ x64/ x86/ -build/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ +[Ll]og/ -# Visual Studio 2015 cache/options directory +# Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ -# Visual Studio code -.vscode/ +# Visual Studio 2017 auto generated files +Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ @@ -37,26 +45,35 @@ bld/ # NUNIT *.VisualState.xml TestResult.xml +nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c -# DNX -*.lock.json +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json artifacts/ -*.nuget.props -*.nuget.targets +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio *_i.c *_p.c -*_i.h +*_h.h *.ilk *.meta *.obj +*.iobj *.pch *.pdb +*.ipdb *.pgc *.pgd *.rsp @@ -66,6 +83,7 @@ artifacts/ *.tlh *.tmp *.tmp_proj +*_wpftmp.csproj *.log *.vspscc *.vssscc @@ -73,7 +91,6 @@ artifacts/ *.pidb *.svclog *.scc -*.binlog # Chutzpah Test files _Chutzpah* @@ -86,6 +103,8 @@ ipch/ *.opensdf *.sdf *.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess @@ -93,6 +112,9 @@ ipch/ *.vspx *.sap +# Visual Studio Trace Files +*.e2e + # TFS 2012 Local Workspace $tf/ @@ -113,6 +135,14 @@ _TeamCity* # DotCover is a Code Coverage Tool *.dotCover +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + # NCrunch _NCrunch_* .*crunch*.local.xml @@ -144,37 +174,52 @@ publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml -# TODO: Comment the next line if you want to checkin your web deploy settings +# Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + # NuGet Packages *.nupkg +# NuGet Symbol Packages +*.snupkg # The packages folder can be ignored because of Package Restore -**/packages/* +**/[Pp]ackages/* # except build/, which is used as an MSBuild target. -!**/packages/build/ +!**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets -# Windows Azure Build Output +# Microsoft Azure Build Output csx/ *.build.csdef -# Windows Azure Emulator +# Microsoft Azure Emulator ecf/ rcf/ -# Windows Store app package directory +# Windows Store app package directories and files AppPackages/ BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache -!*.[Cc]ache/ +!?*.[Cc]ache/ # Others ClientBin/ @@ -182,11 +227,19 @@ ClientBin/ *~ *.dbmdl *.dbproj.schemaview +*.jfm *.pfx *.publishsettings -node_modules/ orleans.codegen.cs +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + # RIA/Silverlight projects Generated_Code/ @@ -197,15 +250,22 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak # SQL Server files *.mdf *.ldf +*.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ @@ -215,6 +275,7 @@ FakesAssemblies/ # Node.js Tools for Visual Studio .ntvs_analysis.dat +node_modules/ # Visual Studio 6 build log *.plg @@ -222,6 +283,9 @@ FakesAssemblies/ # Visual Studio 6 workspace options file *.opt +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts @@ -232,12 +296,57 @@ _Pvt_Extensions # Paket dependency manager .paket/paket.exe +paket-files/ # FAKE - F# Make .fake/ -# Tools -tools/ +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +tools/** +!tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ # ReactiveUI artifacts/ diff --git a/tools/packages.config b/tools/packages.config new file mode 100644 index 0000000000..945c3e86ac --- /dev/null +++ b/tools/packages.config @@ -0,0 +1,4 @@ + + + + From f9cb151f508d0f7498c75cd2b414a87eb76bc448 Mon Sep 17 00:00:00 2001 From: Shimmy <2716316+weitzhandler@users.noreply.github.com> Date: Tue, 18 Jun 2019 10:12:19 +0300 Subject: [PATCH 48/61] feature: Add ReactivePage for WPF/UWP (#2078) --- .../ApiApprovalTests.Wpf.net461.approved.txt | 8 ++ .../Platforms/windows-common/ReactivePage.cs | 114 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 src/ReactiveUI/Platforms/windows-common/ReactivePage.cs diff --git a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt index fb471e4e7d..d308bde040 100644 --- a/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt +++ b/src/ReactiveUI.Tests/Platforms/wpf/API/ApiApprovalTests.Wpf.net461.approved.txt @@ -44,6 +44,14 @@ namespace ReactiveUI public PlatformOperations() { } public string GetOrientation() { } } + public abstract class ReactivePage : System.Windows.Controls.Page, ReactiveUI.IActivatable, ReactiveUI.IViewFor, ReactiveUI.IViewFor + where TViewModel : class + { + public static readonly System.Windows.DependencyProperty ViewModelProperty; + protected ReactivePage() { } + public TViewModel BindingRoot { get; } + public TViewModel ViewModel { get; set; } + } public abstract class ReactiveUserControl : System.Windows.Controls.UserControl, ReactiveUI.IActivatable, ReactiveUI.IViewFor, ReactiveUI.IViewFor where TViewModel : class { diff --git a/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs b/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs new file mode 100644 index 0000000000..2a98bafeae --- /dev/null +++ b/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs @@ -0,0 +1,114 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace ReactiveUI +{ + using System.Diagnostics.CodeAnalysis; +#if NETFX_CORE || HAS_UNO + using Windows.UI.Xaml; + using Windows.UI.Xaml.Controls; +#else + using System.Windows; + using System.Windows.Controls; +#endif + + /// + /// A that is reactive. + /// + /// + /// + /// This class is a that is also reactive. That is, it implements . + /// You can extend this class to get an implementation of rather than writing one yourself. + /// + /// + /// Note that the XAML for your control must specify the same base class, including the generic argument you provide for your view + /// model. To do this, use the TypeArguments attribute as follows: + /// + /// + /// + /// + /// ]]> + /// + /// + /// + /// Note that UWP projects do not support the TypeArguments attribute. The XAML designer window in WPF projects also does not + /// support generic types. To use in XAML documents you need to create a base class + /// where you derive from with the type argument filled in. + /// + /// { /* No code needed here */ } + /// + /// public partial class YourView : YourViewBase + /// { + /// /* Your code */ + /// } + /// ]]> + /// + /// Then you can use this base class as root in your XAML document. + /// + /// + /// + /// + /// ]]> + /// + /// + /// + /// + /// The type of the view model backing the view. + /// + [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] + public abstract class ReactivePage : + Page, IViewFor + where TViewModel : class + { + /// + /// The view model dependency property. + /// + public static readonly DependencyProperty ViewModelProperty = + DependencyProperty.Register( + "ViewModel", + typeof(TViewModel), + typeof(ReactivePage), + new PropertyMetadata(null)); + + /// + /// Gets the binding root view model. + /// + public TViewModel BindingRoot => ViewModel; + + /// + public TViewModel ViewModel + { + get => (TViewModel)GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + /// + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (TViewModel)value; + } + } +} From 59da6e63e4d89dc5b5a486a175fac04929fbcd64 Mon Sep 17 00:00:00 2001 From: Colt <6819362+cabauman@users.noreply.github.com> Date: Tue, 18 Jun 2019 22:36:33 +0900 Subject: [PATCH 49/61] Fix: Restore case-insensitive WireUpControls feature (#2080) --- .../ControlFetcherMixin.cs | 201 +----------------- .../Platforms/android/ControlFetcherMixin.cs | 126 ++++------- 2 files changed, 52 insertions(+), 275 deletions(-) diff --git a/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs b/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs index 9ae2b19aa2..b7da77fa45 100644 --- a/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs +++ b/src/ReactiveUI.AndroidSupport/ControlFetcherMixin.cs @@ -4,13 +4,8 @@ // See the LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using Android.App; using Android.Views; -using Java.Interop; +using static ReactiveUI.ControlFetcherMixin; using Fragment = Android.Support.V4.App.Fragment; namespace ReactiveUI.AndroidSupport @@ -20,99 +15,8 @@ namespace ReactiveUI.AndroidSupport /// Fragments via property names, similar to Butter Knife, as well as allows /// you to fetch controls manually. /// - public static class ControlFetcherMixin + public static class ControlFetcherMixin { - private static readonly ConditionalWeakTable> viewCache = - new ConditionalWeakTable>(); - - static ControlFetcherMixin() - { - } - - /// - /// Gets the control from an activity. - /// - /// The control type. - /// The activity. - /// The property name. - /// The return view. - public static T GetControl(this Activity activity, [CallerMemberName] string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, activity, () => activity - .FindViewById(GetResourceId(activity, propertyName)) - .JavaCast()); - - /// - /// Gets the control from an activity. - /// - /// The control type. - /// The view. - /// The property. - /// The return view. - public static T GetControl(this View view, [CallerMemberName] string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, view, () => view - .FindViewById(GetResourceId(view, propertyName)) - .JavaCast()); - - /// - /// Gets the control from an activity. - /// - /// The control type. - /// The fragment. - /// The property name. - /// The return view. - public static T GetControl(this Fragment fragment, [CallerMemberName] string propertyName = null) - where T : View => GetControl(fragment.View, propertyName); - - /// - /// Wires a control to a property. - /// - /// The layout view host. - /// The resolve members. - public static void WireUpControls(this ILayoutViewHost layoutHost, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) - { - var members = layoutHost.GetWireUpMembers(resolveMembers).ToList(); - foreach (var member in members) - { - try - { - var view = layoutHost.View.GetControlInternal(member.GetResourceName()); - member.SetValue(layoutHost, view); - } - catch (Exception ex) - { - throw new - MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); - } - } - } - - /// - /// Wires a control to a property. - /// - /// The view. - /// The resolve members. - public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) - { - var members = view.GetWireUpMembers(resolveMembers); - - foreach (var member in members) - { - try - { - // Find the android control with the same name - var currentView = view.GetControlInternal(member.GetResourceName()); - - // Set the activity field's value to the view with that identifier - member.SetValue(view, currentView); - } - catch (Exception ex) - { - throw new - MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); - } - } - } - /// /// Wires a control to a property. /// This should be called in the Fragment's OnCreateView, with the newly inflated layout. @@ -120,8 +24,7 @@ public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin /// The fragment. /// The inflated view. /// The resolve members. - public static void WireUpControls(this Fragment fragment, View inflatedView, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = - ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) + public static void WireUpControls(this Fragment fragment, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) { var members = fragment.GetWireUpMembers(resolveMembers); @@ -130,7 +33,7 @@ public static void WireUpControls(this Fragment fragment, View inflatedView, Rea try { // Find the android control with the same name from the view - var view = inflatedView.GetControlInternal(member.GetResourceName()); + var view = inflatedView.GetControl(fragment.GetType().Assembly, member.GetResourceName()); // Set the activity field's value to the view with that identifier member.SetValue(fragment, view); @@ -142,99 +45,5 @@ public static void WireUpControls(this Fragment fragment, View inflatedView, Rea } } } - - /// - /// Wires a control to a property. - /// - /// The Activity. - /// The resolve members. - public static void WireUpControls(this Activity activity, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) - { - var members = activity.GetWireUpMembers(resolveMembers); - - foreach (var member in members) - { - try - { - // Find the android control with the same name - var view = activity.GetControlInternal(member.GetResourceName()); - - // Set the activity field's value to the view with that identifier - member.SetValue(activity, view); - } - catch (Exception ex) - { - throw new - MissingFieldException("Failed to wire up the Property " + member.Name + " to a View in your layout with a corresponding identifier", ex); - } - } - } - - private static View GetControlInternal(this View parent, string resourceName) - { - var context = parent.Context; - var res = context.Resources; - var id = res.GetIdentifier(resourceName, "id", context.PackageName); - return parent.FindViewById(id); - } - - private static View GetControlInternal(this Activity parent, string resourceName) - { - return parent.FindViewById(GetResourceId(parent, resourceName)); - } - - private static int GetResourceId(Activity activity, string resourceName) - { - var res = activity.Resources; - return res.GetIdentifier(resourceName, "id", activity.PackageName); - } - - private static int GetResourceId(View view, string resourceName) - { - var res = view.Context.Resources; - return res.GetIdentifier(resourceName, "id", view.Context.PackageName); - } - - private static View GetCachedControl(string propertyName, object rootView, Func fetchControlFromView) - { - View ret; - var ourViewCache = viewCache.GetOrCreateValue(rootView); - - if (ourViewCache.TryGetValue(propertyName, out ret)) - { - return ret; - } - - ret = fetchControlFromView(); - - ourViewCache.Add(propertyName, ret); - return ret; - } - - private static string GetResourceName(this PropertyInfo member) - { - var resourceNameOverride = member.GetCustomAttribute()?.ResourceNameOverride; - return resourceNameOverride ?? member.Name; - } - - private static IEnumerable GetWireUpMembers(this object @this, ReactiveUI.ControlFetcherMixin.ResolveStrategy - resolveStrategy) - { - var members = @this.GetType().GetRuntimeProperties(); - - switch (resolveStrategy) - { - default: // Implicit matches the Default. - return members.Where(member => member.PropertyType.IsSubclassOf(typeof(View)) - || member.GetCustomAttribute(true) != null); - - case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptIn: - return members.Where(member => member.GetCustomAttribute(true) != null); - - case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptOut: - return members.Where(member => typeof(View).IsAssignableFrom(member.PropertyType) - && member.GetCustomAttribute(true) == null); - } - } } -} \ No newline at end of file +} diff --git a/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs b/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs index 434d7ac7a1..83bdebb565 100644 --- a/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs +++ b/src/ReactiveUI/Platforms/android/ControlFetcherMixin.cs @@ -4,13 +4,13 @@ // See the LICENSE file in the project root for full license information. using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using Android.App; using Android.Views; -using Java.Interop; namespace ReactiveUI { @@ -21,66 +21,44 @@ namespace ReactiveUI /// public static partial class ControlFetcherMixin { - private static readonly ConditionalWeakTable> viewCache = - new ConditionalWeakTable>(); + private static readonly ConcurrentDictionary> _controlIds + = new ConcurrentDictionary>(); - private static readonly MethodInfo getControlActivity; - private static readonly MethodInfo getControlView; - - static ControlFetcherMixin() - { - var type = typeof(ControlFetcherMixin); - getControlActivity = type.GetMethod("GetControl", new[] { typeof(Activity), typeof(string) }); - getControlView = type.GetMethod("GetControl", new[] { typeof(View), typeof(string) }); - } + private static readonly ConditionalWeakTable> viewCache + = new ConditionalWeakTable>(); /// /// Gets the control from an activity. /// - /// The control type. /// The activity. /// The property name. /// The return view. - public static T GetControl(this Activity activity, [CallerMemberName] string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, activity, () => activity - .FindViewById(GetResourceId(activity, propertyName)) - .JavaCast()); + public static View GetControl(this Activity activity, [CallerMemberName] string propertyName = null) + => GetCachedControl(propertyName, activity, () => activity.FindViewById(GetControlIdByName(activity.GetType().Assembly, propertyName))); /// - /// Gets the control from an activity. + /// Gets the control from a view. /// - /// The control type. /// The view. + /// The assembly containing the user-defined view. /// The property. /// The return view. - public static T GetControl(this View view, [CallerMemberName] string propertyName = null) - where T : View => (T)GetCachedControl(propertyName, view, () => view - .FindViewById(GetResourceId(view, propertyName)) - .JavaCast()); - - /// - /// Gets the control from an activity. - /// - /// The control type. - /// The fragment. - /// The property name. - /// The return view. - public static T GetControl(this Fragment fragment, [CallerMemberName] string propertyName = null) - where T : View => GetControl(fragment.View, propertyName); + public static View GetControl(this View view, Assembly assembly, [CallerMemberName] string propertyName = null) + => GetCachedControl(propertyName, view, () => view.FindViewById(GetControlIdByName(assembly, propertyName))); /// /// Wires a control to a property. /// /// The layout view host. /// The resolve members. - public static void WireUpControls(this ILayoutViewHost layoutHost, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) + public static void WireUpControls(this ILayoutViewHost layoutHost, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) { var members = layoutHost.GetWireUpMembers(resolveMembers).ToList(); foreach (var member in members) { try { - var view = layoutHost.View.GetControlInternal(member.PropertyType, member.GetResourceName()); + var view = layoutHost.View.GetControl(layoutHost.GetType().Assembly, member.GetResourceName()); member.SetValue(layoutHost, view); } catch (Exception ex) @@ -96,7 +74,7 @@ public static void WireUpControls(this ILayoutViewHost layoutHost, ReactiveUI.Co /// /// The view. /// The resolve members. - public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) + public static void WireUpControls(this View view, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) { var members = view.GetWireUpMembers(resolveMembers); @@ -105,7 +83,7 @@ public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin try { // Find the android control with the same name - var currentView = view.GetControlInternal(member.PropertyType, member.GetResourceName()); + var currentView = view.GetControl(view.GetType().Assembly, member.GetResourceName()); // Set the activity field's value to the view with that identifier member.SetValue(view, currentView); @@ -125,8 +103,7 @@ public static void WireUpControls(this View view, ReactiveUI.ControlFetcherMixin /// The fragment. /// The inflated view. /// The resolve members. - public static void WireUpControls(this Fragment fragment, View inflatedView, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = - ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) + public static void WireUpControls(this Fragment fragment, View inflatedView, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) { var members = fragment.GetWireUpMembers(resolveMembers); @@ -135,7 +112,7 @@ public static void WireUpControls(this Fragment fragment, View inflatedView, Rea try { // Find the android control with the same name from the view - var view = inflatedView.GetControlInternal(member.PropertyType, member.GetResourceName()); + var view = inflatedView.GetControl(fragment.GetType().Assembly, member.GetResourceName()); // Set the activity field's value to the view with that identifier member.SetValue(fragment, view); @@ -153,7 +130,7 @@ public static void WireUpControls(this Fragment fragment, View inflatedView, Rea /// /// The Activity. /// The resolve members. - public static void WireUpControls(this Activity activity, ReactiveUI.ControlFetcherMixin.ResolveStrategy resolveMembers = ReactiveUI.ControlFetcherMixin.ResolveStrategy.Implicit) + public static void WireUpControls(this Activity activity, ResolveStrategy resolveMembers = ResolveStrategy.Implicit) { var members = activity.GetWireUpMembers(resolveMembers); @@ -162,7 +139,7 @@ public static void WireUpControls(this Activity activity, ReactiveUI.ControlFetc try { // Find the android control with the same name - var view = activity.GetControlInternal(member.PropertyType, member.GetResourceName()); + var view = activity.GetControl(member.GetResourceName()); // Set the activity field's value to the view with that identifier member.SetValue(activity, view); @@ -175,28 +152,29 @@ public static void WireUpControls(this Activity activity, ReactiveUI.ControlFetc } } - private static View GetControlInternal(this View parent, Type viewType, string name) + internal static IEnumerable GetWireUpMembers(this object @this, ResolveStrategy resolveStrategy) { - var memberInfo = getControlView.MakeGenericMethod(new[] { viewType }); - return (View)memberInfo.Invoke(null, new object[] { parent, name }); - } + var members = @this.GetType().GetRuntimeProperties(); - private static View GetControlInternal(this Activity parent, Type viewType, string name) - { - var memberInfo = getControlActivity.MakeGenericMethod(new[] { viewType }); - return (View)memberInfo.Invoke(null, new object[] { parent, name }); - } + switch (resolveStrategy) + { + default: // Implicit matches the Default. + return members.Where(member => member.PropertyType.IsSubclassOf(typeof(View)) + || member.GetCustomAttribute(true) != null); - private static int GetResourceId(Activity activity, string resourceName) - { - var res = activity.Resources; - return res.GetIdentifier(resourceName, "id", activity.PackageName); + case ResolveStrategy.ExplicitOptIn: + return members.Where(member => member.GetCustomAttribute(true) != null); + + case ResolveStrategy.ExplicitOptOut: + return members.Where(member => typeof(View).IsAssignableFrom(member.PropertyType) + && member.GetCustomAttribute(true) == null); + } } - private static int GetResourceId(View view, string resourceName) + internal static string GetResourceName(this PropertyInfo member) { - var res = view.Context.Resources; - return res.GetIdentifier(resourceName, "id", view.Context.PackageName); + var resourceNameOverride = member.GetCustomAttribute()?.ResourceNameOverride; + return resourceNameOverride ?? member.Name; } private static View GetCachedControl(string propertyName, object rootView, Func fetchControlFromView) @@ -215,30 +193,20 @@ private static View GetCachedControl(string propertyName, object rootView, Func< return ret; } - private static string GetResourceName(this PropertyInfo member) + private static int GetControlIdByName(Assembly assembly, string name) { - var resourceNameOverride = member.GetCustomAttribute()?.ResourceNameOverride; - return resourceNameOverride ?? member.Name; - } - - private static IEnumerable GetWireUpMembers(this object @this, ReactiveUI.ControlFetcherMixin.ResolveStrategy - resolveStrategy) - { - var members = @this.GetType().GetRuntimeProperties(); - - switch (resolveStrategy) - { - default: // Implicit matches the Default. - return members.Where(member => member.PropertyType.IsSubclassOf(typeof(View)) - || member.GetCustomAttribute(true) != null); + var ids = _controlIds.GetOrAdd( + assembly, + currentAssembly => + { + var resources = currentAssembly.GetModules().SelectMany(x => x.GetTypes()).First(x => x.Name == "Resource"); - case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptIn: - return members.Where(member => member.GetCustomAttribute(true) != null); + return resources.GetNestedType("Id").GetFields() + .Where(x => x.FieldType == typeof(int)) + .ToDictionary(k => k.Name, v => (int)v.GetRawConstantValue(), StringComparer.InvariantCultureIgnoreCase); + }); - case ReactiveUI.ControlFetcherMixin.ResolveStrategy.ExplicitOptOut: - return members.Where(member => typeof(View).IsAssignableFrom(member.PropertyType) - && member.GetCustomAttribute(true) == null); - } + return ids[name]; } } } From 22ed35094defb2a1da471e4bc2cc02af95eae598 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Fri, 21 Jun 2019 19:41:09 +1000 Subject: [PATCH 50/61] housekeeping: update readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ed01c905c..02be2fb064 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@

- +

What is ReactiveUI?

From 03a2ac649691cfa9c121390523350ea672560ed7 Mon Sep 17 00:00:00 2001 From: Glenn <5834289+glennawatson@users.noreply.github.com> Date: Sun, 23 Jun 2019 17:57:36 +1000 Subject: [PATCH 51/61] housekeeping: Update the directory.build.props (#2082) --- directory.build.props | 16 ---- src/Directory.build.props | 42 ++++++---- ...provalTests.ReactiveUI.net461.approved.txt | 84 +++++++++---------- ...ests.ReactiveUI.netcoreapp2.0.approved.txt | 84 +++++++++---------- 4 files changed, 111 insertions(+), 115 deletions(-) delete mode 100644 directory.build.props diff --git a/directory.build.props b/directory.build.props deleted file mode 100644 index 1d4ece3727..0000000000 --- a/directory.build.props +++ /dev/null @@ -1,16 +0,0 @@ - - - .NET Foundation and Contributors - Copyright (c) .NET Foundation and Contributors - MIT - https://reactiveui.net - https://github.com/reactiveui/styleguide/blob/master/logo/main.png?raw=true - xanaisbettsx;ghuntley - ReactiveUI ($(TargetFramework)) - mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen - https://github.com/reactiveui/ReactiveUI/releases - https://github.com/reactiveui/reactiveui - git - true - - diff --git a/src/Directory.build.props b/src/Directory.build.props index b0e4deb9eb..9d798df9df 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -1,24 +1,38 @@ - xanaisbettsx;ghuntley - mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen - https://reactiveui.net/blog/ true $(NoWarn);1591;1701;1702;1705;VSX1000 AnyCPU $(MSBuildProjectName.Contains('Tests')) embedded + $(MSBuildThisFileDirectory)analyzers.ruleset + + .NET Foundation and Contributors + Copyright (c) .NET Foundation and Contributors + MIT + https://reactiveui.net + https://github.com/reactiveui/styleguide/blob/master/logo/main.png?raw=true + A MVVM framework that integrates with the Reactive Extensions for .NET to create elegant, testable User Interfaces that run on any mobile or desktop platform. Supports Xamarin.iOS, Xamarin.Android, Xamarin.Mac, Xamarin Forms, Xamarin.TVOS, Tizen, WPF, Windows Forms, Windows Store and Universal Windows Platform (UWP). + xanaisbettsx;ghuntley + mvvm;reactiveui;rx;reactive extensions;observable;LINQ;events;frp;xamarin;android;ios;mac;forms;monodroid;monotouch;xamarin.android;xamarin.ios;xamarin.forms;xamarin.mac;xamarin.tvos;wpf;net;netstandard;net461;uwp;tizen + https://github.com/reactiveui/ReactiveUI/releases + https://github.com/reactiveui/reactiveui + git + + + false + $(EnableSourceLink) true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - $(MSBuildThisFileDirectory)analyzers.ruleset + - - false - $(EnableSourceLink) + + + Full @@ -27,14 +41,14 @@ - + - + - + @@ -42,7 +56,7 @@ - + @@ -54,18 +68,16 @@ - + - + - - diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt index ac55188c65..6b7eb626dc 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt @@ -186,35 +186,19 @@ namespace ReactiveUI void RegisterScheduler(System.Reactive.Concurrency.IScheduler scheduler, string contract = null); void SendMessage(T message, string contract = null); } - public interface INotifyCollectionChanging - { - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; - } - public interface INotifyPropertyChanging - { - public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; - } public class INPCObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger { public INPCObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged, bool suppressWarnings = False) { } } - public class Interaction + public interface INotifyCollectionChanging { - public Interaction(System.Reactive.Concurrency.IScheduler handlerScheduler = null) { } - protected System.Func<, >[] GetHandlers() { } - public virtual System.IObservable Handle(TInput input) { } - public System.IDisposable RegisterHandler(System.Action> handler) { } - public System.IDisposable RegisterHandler(System.Func, System.Threading.Tasks.Task> handler) { } - public System.IDisposable RegisterHandler(System.Func, System.IObservable> handler) { } + public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; } - public sealed class InteractionContext + public interface INotifyPropertyChanging { - public TInput Input { get; } - public bool IsHandled { get; } - public TOutput GetOutput() { } - public void SetOutput(TOutput output) { } + public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; } public interface IObservedChange { @@ -248,6 +232,12 @@ namespace ReactiveUI { bool ExecuteHook(object source, object target, System.Func[]> getCurrentViewModelProperties, System.Func[]> getCurrentViewProperties, ReactiveUI.BindingDirection direction); } + public class IROObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger + { + public IROObservableForProperty() { } + public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } + public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } + } public interface IReactiveBinding : System.IDisposable where out TView : ReactiveUI.IViewFor where out TViewModel : class @@ -289,12 +279,6 @@ namespace ReactiveUI string PropertyName { get; } TSender Sender { get; } } - public class IROObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger - { - public IROObservableForProperty() { } - public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } - public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } - } public interface IRoutableViewModel : ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, Splat.IEnableLogger, System.ComponentModel.INotifyPropertyChanged { ReactiveUI.IScreen HostScreen { get; } @@ -343,6 +327,22 @@ namespace ReactiveUI ReactiveUI.IViewFor ResolveView(T viewModel, string contract = null) where T : class; } + public sealed class InteractionContext + { + public TInput Input { get; } + public bool IsHandled { get; } + public TOutput GetOutput() { } + public void SetOutput(TOutput output) { } + } + public class Interaction + { + public Interaction(System.Reactive.Concurrency.IScheduler handlerScheduler = null) { } + protected System.Func<, >[] GetHandlers() { } + public virtual System.IObservable Handle(TInput input) { } + public System.IDisposable RegisterHandler(System.Action> handler) { } + public System.IDisposable RegisterHandler(System.Func, System.Threading.Tasks.Task> handler) { } + public System.IDisposable RegisterHandler(System.Func, System.IObservable> handler) { } + } public class MessageBus : ReactiveUI.IMessageBus, Splat.IEnableLogger { public MessageBus() { } @@ -410,17 +410,17 @@ namespace ReactiveUI public static System.Collections.Generic.IComparer OrderByDescending(System.Func selector) { } public static System.Collections.Generic.IComparer OrderByDescending(System.Func selector, System.Collections.Generic.IComparer comparer) { } } - public class PlatformRegistrations - { - public PlatformRegistrations() { } - public void Register(System.Action, System.Type> registerFunction) { } - } public class POCOObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger { public POCOObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } } + public class PlatformRegistrations + { + public PlatformRegistrations() { } + public void Register(System.Action, System.Type> registerFunction) { } + } public class PropertyBinderImplementation : ReactiveUI.IPropertyBinderImplementation, Splat.IEnableLogger { public PropertyBinderImplementation() { } @@ -486,16 +486,6 @@ namespace ReactiveUI public static ReactiveUI.ReactiveCommand CreateFromTask(System.Func execute, System.IObservable canExecute = null, System.Reactive.Concurrency.IScheduler outputScheduler = null) { } public static ReactiveUI.ReactiveCommand CreateFromTask(System.Func execute, System.IObservable canExecute = null, System.Reactive.Concurrency.IScheduler outputScheduler = null) { } } - public class ReactiveCommand : ReactiveUI.ReactiveCommandBase - { - protected internal ReactiveCommand(System.Func> execute, System.IObservable canExecute, System.Reactive.Concurrency.IScheduler outputScheduler) { } - public override System.IObservable CanExecute { get; } - public override System.IObservable IsExecuting { get; } - public override System.IObservable ThrownExceptions { get; } - protected override void Dispose(bool disposing) { } - public override System.IObservable Execute(TParam parameter = null) { } - public override System.IDisposable Subscribe(System.IObserver observer) { } - } public abstract class ReactiveCommandBase : ReactiveUI.IHandleObservableErrors, ReactiveUI.IReactiveCommand, System.IDisposable, System.IObservable, System.Windows.Input.ICommand { protected ReactiveCommandBase() { } @@ -520,6 +510,16 @@ namespace ReactiveUI public static System.IDisposable InvokeCommand(this System.IObservable @this, TTarget target, System.Linq.Expressions.Expression>> commandProperty) where TTarget : class { } } + public class ReactiveCommand : ReactiveUI.ReactiveCommandBase + { + protected internal ReactiveCommand(System.Func> execute, System.IObservable canExecute, System.Reactive.Concurrency.IScheduler outputScheduler) { } + public override System.IObservable CanExecute { get; } + public override System.IObservable IsExecuting { get; } + public override System.IObservable ThrownExceptions { get; } + protected override void Dispose(bool disposing) { } + public override System.IObservable Execute(TParam parameter = null) { } + public override System.IDisposable Subscribe(System.IObserver observer) { } + } public class static ReactiveNotifyPropertyChangedMixin { public static System.IObservable> ObservableForProperty(this TSender @this, System.Linq.Expressions.Expression> property, bool beforeChange = False, bool skipInitial = True) { } @@ -908,8 +908,8 @@ namespace ReactiveUI.Legacy public System.IObservable BeforeItemsAdded { get; } public System.IObservable> BeforeItemsMoved { get; } public System.IObservable BeforeItemsRemoved { get; } - public System.IObservable Changed { get; } public bool ChangeTrackingEnabled { get; set; } + public System.IObservable Changed { get; } public System.IObservable Changing { get; } public int Count { get; } public System.IObservable CountChanged { get; } diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt index 74db8a926b..26820301a8 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt @@ -180,35 +180,19 @@ namespace ReactiveUI void RegisterScheduler(System.Reactive.Concurrency.IScheduler scheduler, string contract = null); void SendMessage(T message, string contract = null); } - public interface INotifyCollectionChanging - { - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; - } - public interface INotifyPropertyChanging - { - public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; - } public class INPCObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger { public INPCObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged, bool suppressWarnings = False) { } } - public class Interaction + public interface INotifyCollectionChanging { - public Interaction(System.Reactive.Concurrency.IScheduler handlerScheduler = null) { } - protected System.Func<, >[] GetHandlers() { } - public virtual System.IObservable Handle(TInput input) { } - public System.IDisposable RegisterHandler(System.Action> handler) { } - public System.IDisposable RegisterHandler(System.Func, System.Threading.Tasks.Task> handler) { } - public System.IDisposable RegisterHandler(System.Func, System.IObservable> handler) { } + public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; } - public sealed class InteractionContext + public interface INotifyPropertyChanging { - public TInput Input { get; } - public bool IsHandled { get; } - public TOutput GetOutput() { } - public void SetOutput(TOutput output) { } + public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; } public interface IObservedChange { @@ -242,6 +226,12 @@ namespace ReactiveUI { bool ExecuteHook(object source, object target, System.Func[]> getCurrentViewModelProperties, System.Func[]> getCurrentViewProperties, ReactiveUI.BindingDirection direction); } + public class IROObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger + { + public IROObservableForProperty() { } + public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } + public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } + } public interface IReactiveBinding : System.IDisposable where out TView : ReactiveUI.IViewFor where out TViewModel : class @@ -283,12 +273,6 @@ namespace ReactiveUI string PropertyName { get; } TSender Sender { get; } } - public class IROObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger - { - public IROObservableForProperty() { } - public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } - public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } - } public interface IRoutableViewModel : ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, Splat.IEnableLogger, System.ComponentModel.INotifyPropertyChanged { ReactiveUI.IScreen HostScreen { get; } @@ -337,6 +321,22 @@ namespace ReactiveUI ReactiveUI.IViewFor ResolveView(T viewModel, string contract = null) where T : class; } + public sealed class InteractionContext + { + public TInput Input { get; } + public bool IsHandled { get; } + public TOutput GetOutput() { } + public void SetOutput(TOutput output) { } + } + public class Interaction + { + public Interaction(System.Reactive.Concurrency.IScheduler handlerScheduler = null) { } + protected System.Func<, >[] GetHandlers() { } + public virtual System.IObservable Handle(TInput input) { } + public System.IDisposable RegisterHandler(System.Action> handler) { } + public System.IDisposable RegisterHandler(System.Func, System.Threading.Tasks.Task> handler) { } + public System.IDisposable RegisterHandler(System.Func, System.IObservable> handler) { } + } public class MessageBus : ReactiveUI.IMessageBus, Splat.IEnableLogger { public MessageBus() { } @@ -404,17 +404,17 @@ namespace ReactiveUI public static System.Collections.Generic.IComparer OrderByDescending(System.Func selector) { } public static System.Collections.Generic.IComparer OrderByDescending(System.Func selector, System.Collections.Generic.IComparer comparer) { } } - public class PlatformRegistrations - { - public PlatformRegistrations() { } - public void Register(System.Action, System.Type> registerFunction) { } - } public class POCOObservableForProperty : ReactiveUI.ICreatesObservableForProperty, Splat.IEnableLogger { public POCOObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } } + public class PlatformRegistrations + { + public PlatformRegistrations() { } + public void Register(System.Action, System.Type> registerFunction) { } + } public class PropertyBinderImplementation : ReactiveUI.IPropertyBinderImplementation, Splat.IEnableLogger { public PropertyBinderImplementation() { } @@ -480,16 +480,6 @@ namespace ReactiveUI public static ReactiveUI.ReactiveCommand CreateFromTask(System.Func execute, System.IObservable canExecute = null, System.Reactive.Concurrency.IScheduler outputScheduler = null) { } public static ReactiveUI.ReactiveCommand CreateFromTask(System.Func execute, System.IObservable canExecute = null, System.Reactive.Concurrency.IScheduler outputScheduler = null) { } } - public class ReactiveCommand : ReactiveUI.ReactiveCommandBase - { - protected internal ReactiveCommand(System.Func> execute, System.IObservable canExecute, System.Reactive.Concurrency.IScheduler outputScheduler) { } - public override System.IObservable CanExecute { get; } - public override System.IObservable IsExecuting { get; } - public override System.IObservable ThrownExceptions { get; } - protected override void Dispose(bool disposing) { } - public override System.IObservable Execute(TParam parameter = null) { } - public override System.IDisposable Subscribe(System.IObserver observer) { } - } public abstract class ReactiveCommandBase : ReactiveUI.IHandleObservableErrors, ReactiveUI.IReactiveCommand, System.IDisposable, System.IObservable, System.Windows.Input.ICommand { protected ReactiveCommandBase() { } @@ -514,6 +504,16 @@ namespace ReactiveUI public static System.IDisposable InvokeCommand(this System.IObservable @this, TTarget target, System.Linq.Expressions.Expression>> commandProperty) where TTarget : class { } } + public class ReactiveCommand : ReactiveUI.ReactiveCommandBase + { + protected internal ReactiveCommand(System.Func> execute, System.IObservable canExecute, System.Reactive.Concurrency.IScheduler outputScheduler) { } + public override System.IObservable CanExecute { get; } + public override System.IObservable IsExecuting { get; } + public override System.IObservable ThrownExceptions { get; } + protected override void Dispose(bool disposing) { } + public override System.IObservable Execute(TParam parameter = null) { } + public override System.IDisposable Subscribe(System.IObserver observer) { } + } public class static ReactiveNotifyPropertyChangedMixin { public static System.IObservable> ObservableForProperty(this TSender @this, System.Linq.Expressions.Expression> property, bool beforeChange = False, bool skipInitial = True) { } @@ -902,8 +902,8 @@ namespace ReactiveUI.Legacy public System.IObservable BeforeItemsAdded { get; } public System.IObservable> BeforeItemsMoved { get; } public System.IObservable BeforeItemsRemoved { get; } - public System.IObservable Changed { get; } public bool ChangeTrackingEnabled { get; set; } + public System.IObservable Changed { get; } public System.IObservable Changing { get; } public int Count { get; } public System.IObservable CountChanged { get; } From 6092224afcbcbad9e6c7c5ac0c43adc24538f2da Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2019 02:13:00 +1000 Subject: [PATCH 52/61] build(deps): bump Fody from 5.0.6 to 5.1.0 (#2086) Bumps [Fody](https://github.com/Fody/Fody) from 5.0.6 to 5.1.0. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot-preview[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index 4a819622e0..a836ff1d7c 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -14,7 +14,7 @@ - + From c4d268969e85e81e14cb2a5d523e104f317d97b2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2019 02:14:07 +1000 Subject: [PATCH 53/61] build(deps): bump FodyHelpers from 5.0.6 to 5.1.0 (#2084) Bumps [FodyHelpers](https://github.com/Fody/Fody) from 5.0.6 to 5.1.0. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot-preview[bot] --- src/ReactiveUI.Fody/ReactiveUI.Fody.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj index b98b86f887..6a4dbea8c0 100644 --- a/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj +++ b/src/ReactiveUI.Fody/ReactiveUI.Fody.csproj @@ -7,6 +7,6 @@ - + \ No newline at end of file From f02616bcc8b7f8ff6d595f51f83437b4e9063a2a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 25 Jun 2019 02:14:36 +1000 Subject: [PATCH 54/61] build(deps): bump FodyPackaging from 5.0.6 to 5.1.0 (#2085) Bumps [FodyPackaging](https://github.com/Fody/Fody) from 5.0.6 to 5.1.0. - [Release notes](https://github.com/Fody/Fody/releases) - [Commits](https://github.com/Fody/Fody/commits) Signed-off-by: dependabot-preview[bot] --- src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index a836ff1d7c..dda795dc48 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -15,7 +15,7 @@ - + From 121458e7c1c425649b253546c7bda7873e00f644 Mon Sep 17 00:00:00 2001 From: Shimmy <2716316+weitzhandler@users.noreply.github.com> Date: Wed, 26 Jun 2019 07:46:52 +0300 Subject: [PATCH 55/61] feature: Added Uno support (#2067) --- build.cake | 1 + ...provalTests.ReactiveUI.net461.approved.txt | 1 + ...ests.ReactiveUI.netcoreapp2.0.approved.txt | 1 + .../ActivationForViewFetcher.cs | 66 +++++ src/ReactiveUI.Uno/CoreDispatcherScheduler.cs | 251 ++++++++++++++++++ src/ReactiveUI.Uno/PlatformRegistrations.cs | 42 +++ src/ReactiveUI.Uno/ReactiveUI.Uno.csproj | 43 +++ src/ReactiveUI.Uno/WinRTAppDataDriver.cs | 74 ++++++ src/ReactiveUI.sln | 67 ++++- .../Mixins/DependencyResolverMixins.cs | 5 +- .../Platforms/uap/ActivationForViewFetcher.cs | 4 +- .../uap/TransitioningContentControl.Empty.cs | 8 +- .../AutoDataTemplateBindingHook.cs | 11 +- .../windows-common/BooleanToVisibilityHint.cs | 4 +- .../BooleanToVisibilityTypeConverter.cs | 4 +- .../windows-common/PlatformOperations.cs | 2 +- .../Platforms/windows-common/ReactivePage.cs | 10 +- .../windows-common/ReactiveUserControl.cs | 14 +- .../windows-common/RoutedViewHost.cs | 10 +- .../windows-common/ViewModelViewHost.cs | 15 +- src/ReactiveUI/Properties/AssemblyInfo.cs | 1 + 21 files changed, 603 insertions(+), 31 deletions(-) create mode 100644 src/ReactiveUI.Uno/ActivationForViewFetcher.cs create mode 100644 src/ReactiveUI.Uno/CoreDispatcherScheduler.cs create mode 100644 src/ReactiveUI.Uno/PlatformRegistrations.cs create mode 100644 src/ReactiveUI.Uno/ReactiveUI.Uno.csproj create mode 100644 src/ReactiveUI.Uno/WinRTAppDataDriver.cs diff --git a/build.cake b/build.cake index 0c0e13e2fb..f5c7106f7e 100644 --- a/build.cake +++ b/build.cake @@ -24,6 +24,7 @@ var packageWhitelist = new List MakeAbsolute(File("./src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj")), MakeAbsolute(File("./src/ReactiveUI.AndroidSupport/ReactiveUI.AndroidSupport.csproj")), MakeAbsolute(File("./src/ReactiveUI.XamForms/ReactiveUI.XamForms.csproj")), + MakeAbsolute(File("./src/ReactiveUI.Uno/ReactiveUI.Uno.csproj")), }; if (IsRunningOnWindows()) diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt index 6b7eb626dc..b3963ee25d 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt @@ -1,5 +1,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.AndroidSupport")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Uno")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Winforms")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Wpf")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.XamForms")] diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt index 26820301a8..1d7945ae69 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt @@ -1,5 +1,6 @@ [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.AndroidSupport")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Uno")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Winforms")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Wpf")] [assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.XamForms")] diff --git a/src/ReactiveUI.Uno/ActivationForViewFetcher.cs b/src/ReactiveUI.Uno/ActivationForViewFetcher.cs new file mode 100644 index 0000000000..2c0304a17f --- /dev/null +++ b/src/ReactiveUI.Uno/ActivationForViewFetcher.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Reactive; +using System.Reactive.Linq; +using System.Reflection; + +using Windows.Foundation; +using Windows.UI.Xaml; + +namespace ReactiveUI +{ + /// + /// ActiveationForViewFetcher is how ReactiveUI determine when a + /// View is activated or deactivated. This is usually only used when porting + /// ReactiveUI to a new UI framework. + /// + public class ActivationForViewFetcher : IActivationForViewFetcher + { + /// + public int GetAffinityForView(Type view) + { + return typeof(FrameworkElement).GetTypeInfo().IsAssignableFrom(view.GetTypeInfo()) ? 10 : 0; + } + + /// + public IObservable GetActivationForView(IActivatable view) + { + var fe = view as FrameworkElement; + + if (fe == null) + { + return Observable.Empty; + } + +#pragma warning disable SA1114 // Parameter list after. +#if NETSTANDARD || MAC + var viewLoaded = Observable.FromEvent( +#else + var viewLoaded = Observable.FromEvent, bool>( +#endif + eventHandler => (_, __) => eventHandler(true), + x => fe.Loading += x, + x => fe.Loading -= x); + + var viewUnloaded = Observable.FromEvent( + handler => + { + void EventHandler(object sender, RoutedEventArgs e) => handler(false); + return EventHandler; + }, + x => fe.Unloaded += x, + x => fe.Unloaded -= x); + + return viewLoaded + .Merge(viewUnloaded) + .Select(b => b ? fe.WhenAnyValue(x => x.IsHitTestVisible).SkipWhile(x => !x) : Observables.False) + .Switch() + .DistinctUntilChanged(); + } + } +} diff --git a/src/ReactiveUI.Uno/CoreDispatcherScheduler.cs b/src/ReactiveUI.Uno/CoreDispatcherScheduler.cs new file mode 100644 index 0000000000..de999eff51 --- /dev/null +++ b/src/ReactiveUI.Uno/CoreDispatcherScheduler.cs @@ -0,0 +1,251 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +// + +using System; +using System.Collections.Generic; +using System.Reactive.Disposables; +using System.Runtime.ExceptionServices; +using System.Text; +using System.Threading; + +using Windows.UI.Core; +using Windows.UI.Xaml; + +namespace System.Reactive.Concurrency +{ + /// + /// Represents an object that schedules units of work on a . + /// + /// + /// This scheduler type is typically used indirectly through the and methods that use the current Dispatcher. + /// + [CLSCompliant(false)] + public sealed class CoreDispatcherScheduler : LocalScheduler, ISchedulerPeriodic + { + /// + /// Constructs a that schedules units of work on the given . + /// + /// Dispatcher to schedule work on. + /// is null. + public CoreDispatcherScheduler(CoreDispatcher dispatcher) + { + Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher)); + Priority = CoreDispatcherPriority.Normal; + } + + /// + /// Constructs a that schedules units of work on the given with the given priority. + /// + /// Dispatcher to schedule work on. + /// Priority for scheduled units of work. + /// is null. + public CoreDispatcherScheduler(CoreDispatcher dispatcher, CoreDispatcherPriority priority) + { + Dispatcher = dispatcher ?? throw new ArgumentNullException(nameof(dispatcher)); + Priority = priority; + } + + /// + /// Gets the scheduler that schedules work on the associated with the current Window. + /// + public static CoreDispatcherScheduler Current + { + get + { + var window = Window.Current; + if (window == null) + { + throw new InvalidOperationException("There is no current window that has been created."); + } + + return new CoreDispatcherScheduler(window.Dispatcher); + } + } + + /// + /// Gets the associated with the . + /// + public CoreDispatcher Dispatcher { get; } + + /// + /// Gets the priority at which work is scheduled. + /// + public CoreDispatcherPriority Priority { get; } + + /// + /// Schedules an action to be executed on the dispatcher. + /// + /// The type of the state passed to the scheduled action. + /// State passed to the action to be executed. + /// Action to be executed. + /// The disposable object used to cancel the scheduled action (best effort). + /// is null. + public override IDisposable Schedule(TState state, Func action) + { + if (action == null) + { + throw new ArgumentNullException(nameof(action)); + } + + var d = new SingleAssignmentDisposable(); + + var res = Dispatcher.RunAsync(Priority, () => + { + if (!d.IsDisposed) + { + try + { + d.Disposable = action(this, state); + } + catch (Exception ex) + { + // + // Work-around for the behavior of throwing from RunAsync not propagating + // the exception to the Application.UnhandledException event (as of W8RP) + // as our users have come to expect from previous XAML stacks using Rx. + // + // If we wouldn't do this, there'd be an observable behavioral difference + // between scheduling with TimeSpan.Zero or using this overload. + // + // For scheduler implementation guidance rules, see TaskPoolScheduler.cs + // in System.Reactive.PlatformServices\Reactive\Concurrency. + // + var timer = new DispatcherTimer + { + Interval = TimeSpan.Zero + }; + timer.Tick += (o, e) => + { + timer.Stop(); + ExceptionDispatchInfo.Capture(ex).Throw(); + }; + + timer.Start(); + } + } + }); + + return StableCompositeDisposable.Create( + d, + Disposable.Create(res, _ => _.Cancel()) + ); + } + + /// + /// Schedules an action to be executed after on the dispatcher, using a object. + /// + /// The type of the state passed to the scheduled action. + /// State passed to the action to be executed. + /// Action to be executed. + /// Relative time after which to execute the action. + /// The disposable object used to cancel the scheduled action (best effort). + /// is null. + public override IDisposable Schedule(TState state, TimeSpan dueTime, Func action) + { + if (action == null) + { + throw new ArgumentNullException(nameof(action)); + } + + var dt = Scheduler.Normalize(dueTime); + if (dt.Ticks == 0) + { + return Schedule(state, action); + } + + return ScheduleSlow(state, dt, action); + } + + private IDisposable ScheduleSlow(TState state, TimeSpan dueTime, Func action) + { + var d = new MultipleAssignmentDisposable(); + + var timer = new DispatcherTimer(); + + timer.Tick += (o, e) => + { + var t = Interlocked.Exchange(ref timer, null); + if (t != null) + { + try + { + d.Disposable = action(this, state); + } + finally + { + t.Stop(); + action = null; + } + } + }; + + timer.Interval = dueTime; + timer.Start(); + + d.Disposable = Disposable.Create(() => + { + var t = Interlocked.Exchange(ref timer, null); + if (t != null) + { + t.Stop(); + action = (_, __) => Disposable.Empty; + } + }); + + return d; + } + + /// + /// Schedules a periodic piece of work on the dispatcher, using a object. + /// + /// The type of the state passed to the scheduled action. + /// Initial state passed to the action upon the first iteration. + /// Period for running the work periodically. + /// Action to be executed, potentially updating the state. + /// The disposable object used to cancel the scheduled recurring action (best effort). + /// is null. + /// is less than . + public IDisposable SchedulePeriodic(TState state, TimeSpan period, Func action) + { + // + // According to MSDN documentation, the default is TimeSpan.Zero, so that's definitely valid. + // Empirical observation - negative values seem to be normalized to TimeSpan.Zero, but let's not go there. + // + if (period < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(period)); + } + + if (action == null) + { + throw new ArgumentNullException(nameof(action)); + } + + var timer = new DispatcherTimer(); + + var state1 = state; + + timer.Tick += (o, e) => + { + state1 = action(state1); + }; + + timer.Interval = period; + timer.Start(); + + return Disposable.Create(() => + { + var t = Interlocked.Exchange(ref timer, null); + if (t != null) + { + t.Stop(); + action = _ => _; + } + }); + } + } +} diff --git a/src/ReactiveUI.Uno/PlatformRegistrations.cs b/src/ReactiveUI.Uno/PlatformRegistrations.cs new file mode 100644 index 0000000000..3da21b3400 --- /dev/null +++ b/src/ReactiveUI.Uno/PlatformRegistrations.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.Reactive.Concurrency; +using System.Reactive.PlatformServices; + +namespace ReactiveUI +{ + /// + /// UWP platform registrations. + /// + /// + public class PlatformRegistrations : IWantsToRegisterStuff + { + /// + public void Register(Action, Type> registerFunction) + { + registerFunction(() => new PlatformOperations(), typeof(IPlatformOperations)); + registerFunction(() => new ActivationForViewFetcher(), typeof(IActivationForViewFetcher)); + registerFunction(() => new DependencyObjectObservableForProperty(), typeof(ICreatesObservableForProperty)); + registerFunction(() => new BooleanToVisibilityTypeConverter(), typeof(IBindingTypeConverter)); + registerFunction(() => new AutoDataTemplateBindingHook(), typeof(IPropertyBindingHook)); + registerFunction(() => new WinRTAppDataDriver(), typeof(ISuspensionDriver)); + +#if NETSTANDARD + if (WasmPlatformEnlightenmentProvider.IsWasm) + { + RxApp.TaskpoolScheduler = WasmScheduler.Default; + RxApp.MainThreadScheduler = WasmScheduler.Default; + } + else +#endif + { + RxApp.TaskpoolScheduler = TaskPoolScheduler.Default; + RxApp.MainThreadScheduler = new WaitForDispatcherScheduler(() => CoreDispatcherScheduler.Current); + } + } + } +} diff --git a/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj b/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj new file mode 100644 index 0000000000..df310a8c91 --- /dev/null +++ b/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj @@ -0,0 +1,43 @@ + + + netstandard20;MonoAndroid81;MonoAndroid90;Xamarin.iOS10;Xamarin.Mac20 + ReactiveUI.Uno + Uno Platform specific extensions for ReactiveUI + HAS_UNO + $(NoWarn);SA1648;CA1816;CA1001;CS0108;CS0114;CS3021;CS1574;CA1303 + + + + HAS_UNO;WASM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/ReactiveUI.Uno/WinRTAppDataDriver.cs b/src/ReactiveUI.Uno/WinRTAppDataDriver.cs new file mode 100644 index 0000000000..0c36002ff0 --- /dev/null +++ b/src/ReactiveUI.Uno/WinRTAppDataDriver.cs @@ -0,0 +1,74 @@ +// Copyright (c) 2019 .NET Foundation and Contributors. All rights reserved. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reactive; +using System.Reactive.Concurrency; +using System.Reactive.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Serialization; +using Windows.Storage; +using UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding; + +namespace ReactiveUI +{ + /// + /// Loads and saves state to persistent storage. + /// + public class WinRTAppDataDriver : ISuspensionDriver + { + /// + public IObservable LoadState() + { + return Observable.FromAsync(() => ApplicationData.Current.RoamingFolder.GetFileAsync("appData.xmlish").AsTask()) + .SelectMany(x => FileIO.ReadTextAsync(x, UnicodeEncoding.Utf8).AsTask()) + .SelectMany(x => + { + var line = x.IndexOf('\n'); + var typeName = x.Substring(0, line - 1); // -1 for CR + var serializer = new DataContractSerializer(Type.GetType(typeName)); + + // NB: WinRT is terrible + var obj = serializer.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(x.Substring(line + 1)))); + return Observable.Return(obj); + }); + } + + /// + public IObservable SaveState(object state) + { + try + { + var ms = new MemoryStream(); + var writer = new StreamWriter(ms, Encoding.UTF8); + var serializer = new DataContractSerializer(state.GetType()); + writer.WriteLine(state.GetType().AssemblyQualifiedName); + writer.Flush(); + + serializer.WriteObject(ms, state); + + return Observable.FromAsync(() => ApplicationData.Current.RoamingFolder.CreateFileAsync("appData.xmlish", CreationCollisionOption.ReplaceExisting).AsTask()) + .SelectMany(x => Observable.FromAsync(() => FileIO.WriteBytesAsync(x, ms.ToArray()).AsTask())); + } + catch (Exception ex) + { + return Observable.Throw(ex); + } + } + + /// + public IObservable InvalidateState() + { + return Observable.FromAsync(() => ApplicationData.Current.RoamingFolder.GetFileAsync("appData.xmlish").AsTask()) + .SelectMany(x => Observable.FromAsync(() => x.DeleteAsync().AsTask())); + } + } +} diff --git a/src/ReactiveUI.sln b/src/ReactiveUI.sln index f9c29ccc32..9fcb731103 100644 --- a/src/ReactiveUI.sln +++ b/src/ReactiveUI.sln @@ -1,6 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.15 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29001.49 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BD9762CF-E104-481C-96A6-26E624B86283}" ProjectSection(SolutionItems) = preProject @@ -38,7 +39,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Fody.Tests", "Re EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Splat.Tests", "ReactiveUI.Splat.Tests\ReactiveUI.Splat.Tests.csproj", "{7ED6D69F-138F-40BD-9F37-3E4050E4D19B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Uno", "ReactiveUI.Uno\ReactiveUI.Uno.csproj", "{36FC3269-B7D0-4D79-A54A-B26B6190E8A2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -816,6 +819,62 @@ Global {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x64.Build.0 = Release|Any CPU {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.ActiveCfg = Release|Any CPU {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|ARM.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Mixed Platforms.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Mixed Platforms.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|x64.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|x64.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|x86.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|Any CPU.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|ARM.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|ARM.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|iPhone.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|iPhone.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|Mixed Platforms.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|Mixed Platforms.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|x64.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|x64.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|x86.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.AppStore|x86.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|ARM.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|ARM.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|iPhone.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|iPhone.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|x64.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|x64.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Debug|x86.Build.0 = Debug|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|Any CPU.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|ARM.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|ARM.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|iPhone.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|iPhone.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x64.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x64.Build.0 = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x86.ActiveCfg = Release|Any CPU + {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/ReactiveUI/Mixins/DependencyResolverMixins.cs b/src/ReactiveUI/Mixins/DependencyResolverMixins.cs index 8f500dabb5..6cb135c258 100644 --- a/src/ReactiveUI/Mixins/DependencyResolverMixins.cs +++ b/src/ReactiveUI/Mixins/DependencyResolverMixins.cs @@ -31,7 +31,8 @@ public static void InitializeReactiveUI(this IMutableDependencyResolver resolver { "ReactiveUI.XamForms", "ReactiveUI.Winforms", - "ReactiveUI.Wpf" + "ReactiveUI.Wpf", + "ReactiveUI.Uno" }; // Set up the built-in registration @@ -90,7 +91,7 @@ private static void RegisterType(IMutableDependencyResolver resolver, TypeInfo t [SuppressMessage("Redundancy", "CA1801: Redundant parameter", Justification = "Used on some platforms")] private static Func TypeFactory(TypeInfo typeInfo) { -#if PORTABLE +#if PORTABLE && !WASM throw new Exception("You are referencing the Portable version of ReactiveUI in an App. Reference the platform-specific version."); #else return Expression.Lambda>(Expression.New( diff --git a/src/ReactiveUI/Platforms/uap/ActivationForViewFetcher.cs b/src/ReactiveUI/Platforms/uap/ActivationForViewFetcher.cs index c2070d81de..b9ed713dda 100644 --- a/src/ReactiveUI/Platforms/uap/ActivationForViewFetcher.cs +++ b/src/ReactiveUI/Platforms/uap/ActivationForViewFetcher.cs @@ -7,8 +7,6 @@ using System.Linq; using System.Reactive.Linq; using System.Reflection; -using System.Windows; - using Windows.UI.Xaml; namespace ReactiveUI @@ -51,4 +49,4 @@ public IObservable GetActivationForView(IActivatable view) .DistinctUntilChanged(); } } -} \ No newline at end of file +} diff --git a/src/ReactiveUI/Platforms/uap/TransitioningContentControl.Empty.cs b/src/ReactiveUI/Platforms/uap/TransitioningContentControl.Empty.cs index 7d6707470c..0771c0478f 100644 --- a/src/ReactiveUI/Platforms/uap/TransitioningContentControl.Empty.cs +++ b/src/ReactiveUI/Platforms/uap/TransitioningContentControl.Empty.cs @@ -3,6 +3,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using System.Diagnostics.CodeAnalysis; using Windows.UI.Xaml.Controls; namespace ReactiveUI @@ -10,7 +11,12 @@ namespace ReactiveUI /// /// A control with a single transition. /// - public class TransitioningContentControl : ContentControl + [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] + public +#if HAS_UNO + partial +#endif + class TransitioningContentControl : ContentControl { } } diff --git a/src/ReactiveUI/Platforms/windows-common/AutoDataTemplateBindingHook.cs b/src/ReactiveUI/Platforms/windows-common/AutoDataTemplateBindingHook.cs index 9625e81af3..66488417ee 100644 --- a/src/ReactiveUI/Platforms/windows-common/AutoDataTemplateBindingHook.cs +++ b/src/ReactiveUI/Platforms/windows-common/AutoDataTemplateBindingHook.cs @@ -6,7 +6,7 @@ using System; using System.Linq; -#if NETFX_CORE +#if NETFX_CORE || HAS_UNO using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Markup; @@ -30,10 +30,11 @@ public class AutoDataTemplateBindingHook : IPropertyBindingHook /// public static Lazy DefaultItemTemplate { get; } = new Lazy(() => { -#if NETFX_CORE - const string template = "" + - "" + - ""; +#if NETFX_CORE || HAS_UNO + const string template = +@" + +"; return (DataTemplate)XamlReader.Load(template); #else const string template = " Inverse = 1 << 1, -#if !NETFX_CORE +#if !NETFX_CORE && !HAS_UNO /// /// Use the hidden version rather than the Collapsed. /// diff --git a/src/ReactiveUI/Platforms/windows-common/BooleanToVisibilityTypeConverter.cs b/src/ReactiveUI/Platforms/windows-common/BooleanToVisibilityTypeConverter.cs index a93f03c301..9836336249 100644 --- a/src/ReactiveUI/Platforms/windows-common/BooleanToVisibilityTypeConverter.cs +++ b/src/ReactiveUI/Platforms/windows-common/BooleanToVisibilityTypeConverter.cs @@ -4,7 +4,7 @@ // See the LICENSE file in the project root for full license information. using System; -#if NETFX_CORE +#if NETFX_CORE || HAS_UNO using Windows.UI.Xaml; #else using System.Windows; @@ -44,7 +44,7 @@ public bool TryConvert(object from, Type toType, object conversionHint, out obje if (toType == typeof(Visibility)) { var fromAsBool = hint.HasFlag(BooleanToVisibilityHint.Inverse) ? !(bool)@from : (bool)from; -#if !NETFX_CORE +#if !NETFX_CORE && !HAS_UNO var notVisible = hint.HasFlag(BooleanToVisibilityHint.UseHidden) ? Visibility.Hidden : Visibility.Collapsed; #else var notVisible = Visibility.Collapsed; diff --git a/src/ReactiveUI/Platforms/windows-common/PlatformOperations.cs b/src/ReactiveUI/Platforms/windows-common/PlatformOperations.cs index dd872681f5..85146be577 100644 --- a/src/ReactiveUI/Platforms/windows-common/PlatformOperations.cs +++ b/src/ReactiveUI/Platforms/windows-common/PlatformOperations.cs @@ -19,7 +19,7 @@ public class PlatformOperations : IPlatformOperations /// public string GetOrientation() { -#if NETFX_CORE +#if NETFX_CORE || HAS_UNO return Windows.Graphics.Display.DisplayInformation.GetForCurrentView().CurrentOrientation.ToString(); #else return null; diff --git a/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs b/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs index 2a98bafeae..7a69a74ea9 100644 --- a/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs +++ b/src/ReactiveUI/Platforms/windows-common/ReactivePage.cs @@ -78,9 +78,13 @@ namespace ReactiveUI /// The type of the view model backing the view. /// [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] - public abstract class ReactivePage : - Page, IViewFor - where TViewModel : class + public abstract +#if HAS_UNO + partial +#endif + class ReactivePage : + Page, IViewFor + where TViewModel : class { /// /// The view model dependency property. diff --git a/src/ReactiveUI/Platforms/windows-common/ReactiveUserControl.cs b/src/ReactiveUI/Platforms/windows-common/ReactiveUserControl.cs index a9b7b2a705..5514a7fdba 100755 --- a/src/ReactiveUI/Platforms/windows-common/ReactiveUserControl.cs +++ b/src/ReactiveUI/Platforms/windows-common/ReactiveUserControl.cs @@ -5,7 +5,8 @@ namespace ReactiveUI { -#if NETFX_CORE + using System.Diagnostics.CodeAnalysis; +#if NETFX_CORE || HAS_UNO using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else @@ -76,9 +77,14 @@ namespace ReactiveUI /// /// The type of the view model backing the view. /// - public abstract class ReactiveUserControl : - UserControl, IViewFor - where TViewModel : class + [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] + public abstract +#if HAS_UNO + partial +#endif + class ReactiveUserControl : + UserControl, IViewFor + where TViewModel : class { /// /// The view model dependency property. diff --git a/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs b/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs index e48eb30616..e32fe5b870 100644 --- a/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs +++ b/src/ReactiveUI/Platforms/windows-common/RoutedViewHost.cs @@ -5,13 +5,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reactive.Linq; using System.Windows; using ReactiveUI; using Splat; -#if NETFX_CORE +#if NETFX_CORE || HAS_UNO using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else @@ -25,7 +26,12 @@ namespace ReactiveUI /// the View and wire up the ViewModel whenever a new ViewModel is /// navigated to. Put this control as the only control in your Window. /// - public class RoutedViewHost : TransitioningContentControl, IActivatable, IEnableLogger + [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] + public +#if HAS_UNO + partial +#endif + class RoutedViewHost : TransitioningContentControl, IActivatable, IEnableLogger { /// /// The router dependency property. diff --git a/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs b/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs index 3f7ccf1154..cf1845a752 100644 --- a/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs +++ b/src/ReactiveUI/Platforms/windows-common/ViewModelViewHost.cs @@ -4,6 +4,7 @@ // See the LICENSE file in the project root for full license information. using System; +using System.Diagnostics.CodeAnalysis; using System.Reactive; using System.Reactive.Disposables; using System.Reactive.Linq; @@ -11,7 +12,7 @@ using System.Windows; using Splat; -#if NETFX_CORE +#if NETFX_CORE || HAS_UNO using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else @@ -25,7 +26,17 @@ namespace ReactiveUI /// the ViewModel property and display it. This control is very useful /// inside a DataTemplate to display the View associated with a ViewModel. /// - public class ViewModelViewHost : TransitioningContentControl, IViewFor, IEnableLogger, IDisposable + [SuppressMessage("Design", "CA1010:Collections should implement generic interface", Justification = "Deliberate usage")] + public +#if HAS_UNO + partial +#endif + class ViewModelViewHost : TransitioningContentControl, IViewFor, IEnableLogger +#if !HAS_UNO +#pragma warning disable SA1001 // Commas should be spaced correctly + , IDisposable +#pragma warning restore SA1001 // Commas should be spaced correctly +#endif { /// /// The default content dependency property. diff --git a/src/ReactiveUI/Properties/AssemblyInfo.cs b/src/ReactiveUI/Properties/AssemblyInfo.cs index a4cc641e82..2ae17c8332 100644 --- a/src/ReactiveUI/Properties/AssemblyInfo.cs +++ b/src/ReactiveUI/Properties/AssemblyInfo.cs @@ -10,3 +10,4 @@ [assembly: InternalsVisibleTo("ReactiveUI.Wpf")] [assembly: InternalsVisibleTo("ReactiveUI.XamForms")] [assembly: InternalsVisibleTo("ReactiveUI.AndroidSupport")] +[assembly: InternalsVisibleTo("ReactiveUI.Uno")] From ef1dc8958495cb5dfed099fe3c51ecc026484564 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:07:39 +1000 Subject: [PATCH 56/61] Fix --- src/Directory.build.props | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Directory.build.props b/src/Directory.build.props index 16ad35447a..dfc3fd9dff 100644 --- a/src/Directory.build.props +++ b/src/Directory.build.props @@ -46,11 +46,7 @@ -<<<<<<< HEAD -======= - ->>>>>>> master From 07368f4a3035a1f0477edf0582bb86b19cd70a89 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:08:50 +1000 Subject: [PATCH 57/61] fix --- src/ReactiveUI.sln | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/ReactiveUI.sln b/src/ReactiveUI.sln index 03215696a8..a7465b342a 100644 --- a/src/ReactiveUI.sln +++ b/src/ReactiveUI.sln @@ -39,13 +39,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Fody.Tests", "Re EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Splat.Tests", "ReactiveUI.Splat.Tests\ReactiveUI.Splat.Tests.csproj", "{7ED6D69F-138F-40BD-9F37-3E4050E4D19B}" EndProject -<<<<<<< HEAD -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}" -======= Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveUI.Testing.Tests", "ReactiveUI.Testing.Tests\ReactiveUI.Testing.Tests.csproj", "{CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.Uno", "ReactiveUI.Uno\ReactiveUI.Uno.csproj", "{36FC3269-B7D0-4D79-A54A-B26B6190E8A2}" ->>>>>>> master EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 79018cb5900e13a25b154c5fb21bd2c9a91cd6c4 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:10:10 +1000 Subject: [PATCH 58/61] fix --- src/ReactiveUI.sln | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ReactiveUI.sln b/src/ReactiveUI.sln index a7465b342a..9fcb731103 100644 --- a/src/ReactiveUI.sln +++ b/src/ReactiveUI.sln @@ -819,8 +819,6 @@ Global {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x64.Build.0 = Release|Any CPU {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.ActiveCfg = Release|Any CPU {CD8B19A9-316E-4FBC-8F0C-87ADC6AAD684}.Release|x86.Build.0 = Release|Any CPU -<<<<<<< HEAD -======= {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Ad-Hoc|ARM.ActiveCfg = Debug|Any CPU @@ -877,7 +875,6 @@ Global {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x64.Build.0 = Release|Any CPU {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x86.ActiveCfg = Release|Any CPU {36FC3269-B7D0-4D79-A54A-B26B6190E8A2}.Release|x86.Build.0 = Release|Any CPU ->>>>>>> master EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 73046a548e52b555df409aa7868e3eddb88b5ba8 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:11:29 +1000 Subject: [PATCH 59/61] fix --- src/ReactiveUI/ReactiveUI.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReactiveUI/ReactiveUI.csproj b/src/ReactiveUI/ReactiveUI.csproj index d4b0182ffd..2a559313e9 100644 --- a/src/ReactiveUI/ReactiveUI.csproj +++ b/src/ReactiveUI/ReactiveUI.csproj @@ -11,7 +11,7 @@ - + From 14781d511f01b75d39b0207556736a44bb7783c5 Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:13:18 +1000 Subject: [PATCH 60/61] fix --- src/ReactiveUI.Testing/ReactiveUI.Testing.csproj | 2 +- src/ReactiveUI.Uno/ReactiveUI.Uno.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj b/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj index c5d3abf429..cb61ef3b56 100644 --- a/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj +++ b/src/ReactiveUI.Testing/ReactiveUI.Testing.csproj @@ -9,7 +9,7 @@ - + diff --git a/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj b/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj index df310a8c91..15883551a8 100644 --- a/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj +++ b/src/ReactiveUI.Uno/ReactiveUI.Uno.csproj @@ -13,7 +13,7 @@ - + From 648de0f93359e5470d6683196ff260b6fdde79db Mon Sep 17 00:00:00 2001 From: Glenn Watson Date: Wed, 26 Jun 2019 19:22:42 +1000 Subject: [PATCH 61/61] fix --- ...provalTests.ReactiveUI.net461.approved.txt | 156 ------------------ ...ests.ReactiveUI.netcoreapp2.0.approved.txt | 156 ------------------ ...ApprovalTests.Winforms.net461.approved.txt | 45 ----- 3 files changed, 357 deletions(-) diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt index a69f919de7..c6f379e389 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.net461.approved.txt @@ -192,13 +192,6 @@ namespace ReactiveUI public INPCObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged, bool suppressWarnings = False) { } -<<<<<<< HEAD -======= - } - public interface INotifyCollectionChanging - { - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; ->>>>>>> master } public interface INotifyPropertyChanging { @@ -819,155 +812,6 @@ namespace ReactiveUI where TSender : class { } } } -<<<<<<< HEAD -======= -namespace ReactiveUI.Legacy -{ - public interface IMoveInfo - { - int From { get; } - System.Collections.Generic.IEnumerable MovedItems { get; } - int To { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveCollection : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - void Reset(); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveDerivedList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, ReactiveUI.Legacy.IReadOnlyReactiveList, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged, System.IDisposable { } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - bool IsEmpty { get; } - void AddRange(System.Collections.Generic.IEnumerable collection); - void InsertRange(int index, System.Collections.Generic.IEnumerable collection); - void RemoveAll(System.Collections.Generic.IEnumerable items); - void RemoveRange(int index, int count); - void Sort(System.Collections.Generic.IComparer comparer = null); - void Sort(System.Comparison comparison); - void Sort(int index, int count, System.Collections.Generic.IComparer comparer); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveNotifyCollectionChanged - { - System.IObservable BeforeItemsAdded { get; } - System.IObservable> BeforeItemsMoved { get; } - System.IObservable BeforeItemsRemoved { get; } - System.IObservable Changed { get; } - System.IObservable Changing { get; } - System.IObservable CountChanged { get; } - System.IObservable CountChanging { get; } - System.IObservable IsEmptyChanged { get; } - System.IObservable ItemsAdded { get; } - System.IObservable> ItemsMoved { get; } - System.IObservable ItemsRemoved { get; } - System.IObservable ShouldReset { get; } - System.IDisposable SuppressChangeNotifications(); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveNotifyCollectionItemChanged - { - bool ChangeTrackingEnabled { get; set; } - System.IObservable> ItemChanged { get; } - System.IObservable> ItemChanging { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReadOnlyReactiveCollection : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged { } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReadOnlyReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - bool IsEmpty { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class static ObservableCollectionMixin - { - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Action onRemoved, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Action onRemoved, System.Func filter = null, System.Func orderer = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Func filter = null, System.Func orderer = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class static ReactiveCollectionMixins - { - public static ReactiveUI.Legacy.IReactiveDerivedList CreateCollection(this System.IObservable fromObservable, System.Reactive.Concurrency.IScheduler scheduler) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateCollection(this System.IObservable fromObservable, System.Nullable withDelay = null, System.Action onError = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - } - [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")] - [System.Diagnostics.DebuggerTypeProxyAttribute(typeof(ReactiveUI.Legacy.CollectionDebugView<>))] - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class ReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveList, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, ReactiveUI.Legacy.IReadOnlyReactiveList, Splat.IEnableLogger, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - public ReactiveList() { } - public ReactiveList(System.Collections.Generic.IEnumerable initialContents) { } - public ReactiveList(System.Collections.Generic.IEnumerable initialContents = null, double resetChangeThreshold = 0.3, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public System.IObservable BeforeItemsAdded { get; } - public System.IObservable> BeforeItemsMoved { get; } - public System.IObservable BeforeItemsRemoved { get; } - public bool ChangeTrackingEnabled { get; set; } - public System.IObservable Changed { get; } - public System.IObservable Changing { get; } - public int Count { get; } - public System.IObservable CountChanged { get; } - public System.IObservable CountChanging { get; } - public bool IsEmpty { get; } - public System.IObservable IsEmptyChanged { get; } - public virtual bool IsReadOnly { get; } - public virtual T this[int index] { get; set; } - public System.IObservable> ItemChanged { get; } - public System.IObservable> ItemChanging { get; } - public System.IObservable ItemsAdded { get; } - public System.IObservable> ItemsMoved { get; } - public System.IObservable ItemsRemoved { get; } - [System.Runtime.Serialization.IgnoreDataMemberAttribute()] - public double ResetChangeThreshold { get; set; } - public System.IObservable ShouldReset { get; } - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged; - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; - public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; - public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; - public virtual void Add(T item) { } - public virtual void AddRange(System.Collections.Generic.IEnumerable collection) { } - public int BinarySearch(T item) { } - public int BinarySearch(T item, System.Collections.Generic.IComparer comparer) { } - public int BinarySearch(int index, int count, T item, System.Collections.Generic.IComparer comparer) { } - public virtual void Clear() { } - protected void ClearItems() { } - public bool Contains(T item) { } - public void CopyTo(T[] array, int arrayIndex) { } - public System.Collections.Generic.IEnumerator GetEnumerator() { } - public int IndexOf(T item) { } - public virtual void Insert(int index, T item) { } - protected void InsertItem(int index, T item) { } - public virtual void InsertRange(int index, System.Collections.Generic.IEnumerable collection) { } - public virtual void Move(int oldIndex, int newIndex) { } - protected void MoveItem(int oldIndex, int newIndex) { } - protected virtual void RaiseCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { } - protected virtual void RaiseCollectionChanging(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { } - public virtual bool Remove(T item) { } - public virtual void RemoveAll(System.Collections.Generic.IEnumerable items) { } - public virtual void RemoveAt(int index) { } - protected void RemoveItem(int index) { } - public virtual void RemoveRange(int index, int count) { } - public virtual void Reset() { } - protected void SetItem(int index, T item) { } - public virtual void Sort(int index, int count, System.Collections.Generic.IComparer comparer) { } - public virtual void Sort(System.Comparison comparison) { } - public virtual void Sort(System.Collections.Generic.IComparer comparer = null) { } - public System.IDisposable SuppressChangeNotifications() { } - } -} ->>>>>>> master namespace System.Reactive.Disposables { public class static DisposableMixins { } diff --git a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt index 5d644945c0..8451c49469 100644 --- a/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt +++ b/src/ReactiveUI.Tests/API/ApiApprovalTests.ReactiveUI.netcoreapp2.0.approved.txt @@ -186,13 +186,6 @@ namespace ReactiveUI public INPCObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged, bool suppressWarnings = False) { } -<<<<<<< HEAD -======= - } - public interface INotifyCollectionChanging - { - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; ->>>>>>> master } public interface INotifyPropertyChanging { @@ -813,155 +806,6 @@ namespace ReactiveUI where TSender : class { } } } -<<<<<<< HEAD -======= -namespace ReactiveUI.Legacy -{ - public interface IMoveInfo - { - int From { get; } - System.Collections.Generic.IEnumerable MovedItems { get; } - int To { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveCollection : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - void Reset(); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveDerivedList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, ReactiveUI.Legacy.IReadOnlyReactiveList, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged, System.IDisposable { } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - bool IsEmpty { get; } - void AddRange(System.Collections.Generic.IEnumerable collection); - void InsertRange(int index, System.Collections.Generic.IEnumerable collection); - void RemoveAll(System.Collections.Generic.IEnumerable items); - void RemoveRange(int index, int count); - void Sort(System.Collections.Generic.IComparer comparer = null); - void Sort(System.Comparison comparison); - void Sort(int index, int count, System.Collections.Generic.IComparer comparer); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveNotifyCollectionChanged - { - System.IObservable BeforeItemsAdded { get; } - System.IObservable> BeforeItemsMoved { get; } - System.IObservable BeforeItemsRemoved { get; } - System.IObservable Changed { get; } - System.IObservable Changing { get; } - System.IObservable CountChanged { get; } - System.IObservable CountChanging { get; } - System.IObservable IsEmptyChanged { get; } - System.IObservable ItemsAdded { get; } - System.IObservable> ItemsMoved { get; } - System.IObservable ItemsRemoved { get; } - System.IObservable ShouldReset { get; } - System.IDisposable SuppressChangeNotifications(); - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveNotifyCollectionItemChanged - { - bool ChangeTrackingEnabled { get; set; } - System.IObservable> ItemChanged { get; } - System.IObservable> ItemChanging { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReadOnlyReactiveCollection : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged { } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReadOnlyReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.IEnumerable, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - bool IsEmpty { get; } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class static ObservableCollectionMixin - { - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Action onRemoved, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Action onRemoved, System.Func filter = null, System.Func orderer = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateDerivedCollection(this System.Collections.Generic.IEnumerable @this, System.Func selector, System.Func filter = null, System.Func orderer = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class static ReactiveCollectionMixins - { - public static ReactiveUI.Legacy.IReactiveDerivedList CreateCollection(this System.IObservable fromObservable, System.Reactive.Concurrency.IScheduler scheduler) { } - public static ReactiveUI.Legacy.IReactiveDerivedList CreateCollection(this System.IObservable fromObservable, System.Nullable withDelay = null, System.Action onError = null, System.Reactive.Concurrency.IScheduler scheduler = null) { } - } - [System.Diagnostics.DebuggerDisplayAttribute("Count = {Count}")] - [System.Diagnostics.DebuggerTypeProxyAttribute(typeof(ReactiveUI.Legacy.CollectionDebugView<>))] - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class ReactiveList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveList, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, ReactiveUI.Legacy.IReadOnlyReactiveList, Splat.IEnableLogger, System.Collections.Generic.ICollection, System.Collections.Generic.IEnumerable, System.Collections.Generic.IList, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.INotifyPropertyChanged - { - public ReactiveList() { } - public ReactiveList(System.Collections.Generic.IEnumerable initialContents) { } - public ReactiveList(System.Collections.Generic.IEnumerable initialContents = null, double resetChangeThreshold = 0.3, System.Reactive.Concurrency.IScheduler scheduler = null) { } - public System.IObservable BeforeItemsAdded { get; } - public System.IObservable> BeforeItemsMoved { get; } - public System.IObservable BeforeItemsRemoved { get; } - public bool ChangeTrackingEnabled { get; set; } - public System.IObservable Changed { get; } - public System.IObservable Changing { get; } - public int Count { get; } - public System.IObservable CountChanged { get; } - public System.IObservable CountChanging { get; } - public bool IsEmpty { get; } - public System.IObservable IsEmptyChanged { get; } - public virtual bool IsReadOnly { get; } - public virtual T this[int index] { get; set; } - public System.IObservable> ItemChanged { get; } - public System.IObservable> ItemChanging { get; } - public System.IObservable ItemsAdded { get; } - public System.IObservable> ItemsMoved { get; } - public System.IObservable ItemsRemoved { get; } - [System.Runtime.Serialization.IgnoreDataMemberAttribute()] - public double ResetChangeThreshold { get; set; } - public System.IObservable ShouldReset { get; } - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged; - public event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanging; - public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; - public event ReactiveUI.PropertyChangingEventHandler PropertyChanging; - public virtual void Add(T item) { } - public virtual void AddRange(System.Collections.Generic.IEnumerable collection) { } - public int BinarySearch(T item) { } - public int BinarySearch(T item, System.Collections.Generic.IComparer comparer) { } - public int BinarySearch(int index, int count, T item, System.Collections.Generic.IComparer comparer) { } - public virtual void Clear() { } - protected void ClearItems() { } - public bool Contains(T item) { } - public void CopyTo(T[] array, int arrayIndex) { } - public System.Collections.Generic.IEnumerator GetEnumerator() { } - public int IndexOf(T item) { } - public virtual void Insert(int index, T item) { } - protected void InsertItem(int index, T item) { } - public virtual void InsertRange(int index, System.Collections.Generic.IEnumerable collection) { } - public virtual void Move(int oldIndex, int newIndex) { } - protected void MoveItem(int oldIndex, int newIndex) { } - protected virtual void RaiseCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { } - protected virtual void RaiseCollectionChanging(System.Collections.Specialized.NotifyCollectionChangedEventArgs args) { } - public virtual bool Remove(T item) { } - public virtual void RemoveAll(System.Collections.Generic.IEnumerable items) { } - public virtual void RemoveAt(int index) { } - protected void RemoveItem(int index) { } - public virtual void RemoveRange(int index, int count) { } - public virtual void Reset() { } - protected void SetItem(int index, T item) { } - public virtual void Sort(int index, int count, System.Collections.Generic.IComparer comparer) { } - public virtual void Sort(System.Comparison comparison) { } - public virtual void Sort(System.Collections.Generic.IComparer comparer = null) { } - public System.IDisposable SuppressChangeNotifications() { } - } -} ->>>>>>> master namespace System.Reactive.Disposables { public class static DisposableMixins { } diff --git a/src/ReactiveUI.Tests/Platforms/winforms/API/ApiApprovalTests.Winforms.net461.approved.txt b/src/ReactiveUI.Tests/Platforms/winforms/API/ApiApprovalTests.Winforms.net461.approved.txt index b64b3da149..a5e6feb60b 100644 --- a/src/ReactiveUI.Tests/Platforms/winforms/API/ApiApprovalTests.Winforms.net461.approved.txt +++ b/src/ReactiveUI.Tests/Platforms/winforms/API/ApiApprovalTests.Winforms.net461.approved.txt @@ -105,50 +105,5 @@ namespace ReactiveUI.Winforms public WinformsCreatesObservableForProperty() { } public int GetAffinityForObject(System.Type type, string propertyName, bool beforeChanged = False) { } public System.IObservable> GetNotificationForProperty(object sender, System.Linq.Expressions.Expression expression, string propertyName, bool beforeChanged = False, bool suppressWarnings = False) { } -<<<<<<< HEAD -======= - } -} -namespace ReactiveUI.Winforms.Legacy -{ - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public interface IReactiveDerivedBindingList : ReactiveUI.INotifyCollectionChanging, ReactiveUI.INotifyPropertyChanging, ReactiveUI.IReactiveObject, ReactiveUI.Legacy.IReactiveCollection, ReactiveUI.Legacy.IReactiveDerivedList, ReactiveUI.Legacy.IReactiveNotifyCollectionChanged, ReactiveUI.Legacy.IReactiveNotifyCollectionItemChanged, ReactiveUI.Legacy.IReadOnlyReactiveCollection, ReactiveUI.Legacy.IReadOnlyReactiveList, Splat.IEnableLogger, System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.Generic.IReadOnlyList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Specialized.INotifyCollectionChanged, System.ComponentModel.IBindingList, System.ComponentModel.INotifyPropertyChanged, System.IDisposable { } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class static ObservableCollectionMixin - { - public static ReactiveUI.Winforms.Legacy.IReactiveDerivedBindingList CreateDerivedBindingList(this System.Collections.Generic.IEnumerable collection, System.Func selector, System.Action removed, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null) { } - public static ReactiveUI.Winforms.Legacy.IReactiveDerivedBindingList CreateDerivedBindingList(this System.Collections.Generic.IEnumerable collection, System.Func selector, System.Func filter = null, System.Func orderer = null, System.IObservable signalReset = null) { } - public static ReactiveUI.Winforms.Legacy.IReactiveDerivedBindingList CreateDerivedBindingList(this System.Collections.Generic.IEnumerable collection, System.Func selector, System.Action removed, System.Func filter = null, System.Func orderer = null) { } - public static ReactiveUI.Winforms.Legacy.IReactiveDerivedBindingList CreateDerivedBindingList(this System.Collections.Generic.IEnumerable collection, System.Func selector, System.Func filter = null, System.Func orderer = null) { } - } - [System.ObsoleteAttribute("ReactiveList is no longer supported. We suggest replacing it with DynamicData htt" + - "ps://github.com/rolandpheasant/dynamicdata")] - public class ReactiveBindingList : ReactiveUI.Legacy.ReactiveList, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.ComponentModel.IBindingList, System.ComponentModel.ICancelAddNew, System.ComponentModel.IRaiseItemChangedEvents - { - public ReactiveBindingList() { } - public ReactiveBindingList(System.Collections.Generic.IEnumerable items) { } - public bool AllowEdit { get; } - public bool AllowNew { get; } - public bool AllowRemove { get; } - public bool IsSorted { get; } - public bool RaisesItemChangedEvents { get; } - public System.ComponentModel.ListSortDirection SortDirection { get; } - public System.ComponentModel.PropertyDescriptor SortProperty { get; } - public bool SupportsChangeNotification { get; } - public bool SupportsSearching { get; } - public bool SupportsSorting { get; } - public event System.ComponentModel.ListChangedEventHandler ListChanged; - public void AddIndex(System.ComponentModel.PropertyDescriptor property) { } - public object AddNew() { } - public void ApplySort(System.ComponentModel.PropertyDescriptor property, System.ComponentModel.ListSortDirection direction) { } - public void CancelNew(int itemIndex) { } - public void EndNew(int itemIndex) { } - public int Find(System.ComponentModel.PropertyDescriptor property, object key) { } - protected override void RaiseCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { } - public void RemoveIndex(System.ComponentModel.PropertyDescriptor property) { } - public void RemoveSort() { } ->>>>>>> master } } \ No newline at end of file