From 695ea4bf44328d6e0ba1154cc68b500cac3f5a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Standa=20Luke=C5=A1?= Date: Wed, 16 Oct 2024 13:10:35 +0200 Subject: [PATCH] Hot fix for missing ko.unwrap in Linq Last,First,ElementA translations This is a lighterweight alternative to #1870, which we might not want to merge to 4.3. This PR does only fixes the 4.3 regression, the problem with .Select(...).ToArray()[0] is not fixed --- .../JavascriptTranslatableMethodCollection.cs | 16 ++++++++-------- src/Tests/Binding/JavascriptCompilationTests.cs | 7 +++++++ .../Binding/StaticCommandCompilationTests.cs | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs index c9516a745f..c976c26680 100644 --- a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs +++ b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslatableMethodCollection.cs @@ -556,32 +556,32 @@ string GetDelegateReturnTypeHash(Type type) check: (method, target, arguments) => EnsureIsComparableInJavascript(method, ReflectionUtils.GetEnumerableType(arguments.First().Type).NotNull()))); AddMethodTranslator(() => Enumerable.Empty().ElementAt(0), - new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method))); + new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method).WithAnnotation(ResultMayBeObservableAnnotation.Instance))); AddMethodTranslator(() => Enumerable.Empty().ElementAtOrDefault(0), - new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method))); + new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method).WithAnnotation(ResultMayBeObservableAnnotation.Instance))); AddMethodTranslator(() => ImmutableArrayExtensions.ElementAt(default(ImmutableArray), 0), - new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method))); + new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method).WithAnnotation(ResultMayBeObservableAnnotation.Instance))); AddMethodTranslator(() => ImmutableArrayExtensions.ElementAtOrDefault(default(ImmutableArray), 0), - new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method))); + new GenericMethodCompiler((args, method) => BuildIndexer(args[1], args[2], method).WithAnnotation(ResultMayBeObservableAnnotation.Instance))); - var firstOrDefault = new GenericMethodCompiler((args, m) => BuildIndexer(args[1], new JsLiteral(0), m).WithAnnotation(MayBeNullAnnotation.Instance)); + var firstOrDefault = new GenericMethodCompiler((args, m) => BuildIndexer(args[1], new JsLiteral(0), m).WithAnnotation(MayBeNullAnnotation.Instance).WithAnnotation(ResultMayBeObservableAnnotation.Instance)); AddMethodTranslator(() => Enumerable.Empty().FirstOrDefault(), firstOrDefault); AddMethodTranslator(() => Enumerable.Empty().First(), firstOrDefault); AddMethodTranslator(() => ImmutableArrayExtensions.FirstOrDefault(default(ImmutableArray)), firstOrDefault); AddMethodTranslator(() => ImmutableArrayExtensions.First(default(ImmutableArray)), firstOrDefault); var firstOrDefaultPred = new GenericMethodCompiler(args => - args[1].Member("find").Invoke(args[2]).WithAnnotation(MayBeNullAnnotation.Instance)); + args[1].Member("find").Invoke(args[2]).WithAnnotation(MayBeNullAnnotation.Instance).WithAnnotation(ResultMayBeObservableAnnotation.Instance)); AddMethodTranslator(() => Enumerable.Empty().FirstOrDefault(_ => true), firstOrDefaultPred); AddMethodTranslator(() => Enumerable.Empty().First(_ => true), firstOrDefaultPred); AddMethodTranslator(() => ImmutableArrayExtensions.FirstOrDefault(default(ImmutableArray), _ => true), firstOrDefaultPred); AddMethodTranslator(() => ImmutableArrayExtensions.First(default(ImmutableArray), _ => true), firstOrDefaultPred); - var lastOrDefault = new GenericMethodCompiler(args => args[1].Member("at").Invoke(new JsLiteral(-1)).WithAnnotation(MayBeNullAnnotation.Instance)); + var lastOrDefault = new GenericMethodCompiler(args => args[1].Member("at").Invoke(new JsLiteral(-1)).WithAnnotation(MayBeNullAnnotation.Instance).WithAnnotation(ResultMayBeObservableAnnotation.Instance)); AddMethodTranslator(() => Enumerable.Empty().LastOrDefault(), lastOrDefault); AddMethodTranslator(() => ImmutableArrayExtensions.LastOrDefault(default(ImmutableArray)), lastOrDefault); var lastOrDefaultPred = new GenericMethodCompiler(args => - args[1].Member("findLast").Invoke(args[2]).WithAnnotation(MayBeNullAnnotation.Instance)); + args[1].Member("findLast").Invoke(args[2]).WithAnnotation(MayBeNullAnnotation.Instance).WithAnnotation(ResultMayBeObservableAnnotation.Instance)); AddMethodTranslator(() => Enumerable.Empty().LastOrDefault(_ => false), lastOrDefaultPred); AddMethodTranslator(() => ImmutableArrayExtensions.LastOrDefault(default(ImmutableArray), _ => false), lastOrDefaultPred); diff --git a/src/Tests/Binding/JavascriptCompilationTests.cs b/src/Tests/Binding/JavascriptCompilationTests.cs index d387558513..97458b41d0 100644 --- a/src/Tests/Binding/JavascriptCompilationTests.cs +++ b/src/Tests/Binding/JavascriptCompilationTests.cs @@ -773,6 +773,13 @@ public void JsTranslator_EnumerableLastOrDefaultParametrized(string binding) Assert.AreEqual("LongArray().findLast((item)=>ko.unwrap(item)>0)", result); } + [TestMethod] + public void JsTranslator_EnumerableLastOrDefaultObservable() + { + var result = CompileBinding("LongArray.LastOrDefault()==1", new[] { new NamespaceImport("System.Linq"), new NamespaceImport("System.Collections.Immutable") }, new[] { typeof(TestViewModel) }); + Assert.AreEqual("ko.unwrap(LongArray().at(-1))==1", result); + } + [TestMethod] [DataRow("Enumerable.Distinct(VmArray)", DisplayName = "Regular call of Enumerable.Distinct")] [DataRow("VmArray.Distinct()", DisplayName = "Syntax sugar - extension method")] diff --git a/src/Tests/Binding/StaticCommandCompilationTests.cs b/src/Tests/Binding/StaticCommandCompilationTests.cs index e38b2e0092..f1e19dd6d0 100644 --- a/src/Tests/Binding/StaticCommandCompilationTests.cs +++ b/src/Tests/Binding/StaticCommandCompilationTests.cs @@ -369,7 +369,7 @@ public void StaticCommandCompilation_LinqTranslations() Console.WriteLine(result); var expectedResult = @"{ let vm = options.viewModel; - vm.StringProp(vm.VmArray.state.filter((x) => ko.unwrap(x).ChildObject.SomeString == ""x"")[0].SomeString); + vm.StringProp(ko.unwrap(vm.VmArray.state.filter((x) => ko.unwrap(x).ChildObject.SomeString == ""x"")[0]).SomeString); }"; AreEqual(expectedResult, result);