diff --git a/src/Framework/Framework/Compilation/Javascript/Ast/JsAstHelpers.cs b/src/Framework/Framework/Compilation/Javascript/Ast/JsAstHelpers.cs index 11bdce52b8..98c7de01b5 100644 --- a/src/Framework/Framework/Compilation/Javascript/Ast/JsAstHelpers.cs +++ b/src/Framework/Framework/Compilation/Javascript/Ast/JsAstHelpers.cs @@ -73,6 +73,8 @@ public static ParametrizedCode FormatParametrizedScript(this JsNode node, bool n { if (node is null) throw new ArgumentNullException(nameof(node)); + // FixParenthesis modifies the tree in-place; if the node is frozen we must clone it first + if (node.IsFrozen) node = node.Clone(); node = node.FixParenthesis(); var visitor = new JsFormattingVisitor(niceMode, indent); node.AcceptVisitor(visitor); diff --git a/src/Tests/Binding/JavascriptCompilationTests.cs b/src/Tests/Binding/JavascriptCompilationTests.cs index 1b480c61cf..84a524c127 100644 --- a/src/Tests/Binding/JavascriptCompilationTests.cs +++ b/src/Tests/Binding/JavascriptCompilationTests.cs @@ -1,23 +1,26 @@ -using DotVVM.Framework.Binding; -using DotVVM.Framework.Controls; -using DotVVM.Framework.Runtime; -using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; using System.Linq; +using System.Linq.Expressions; +using System.Text.Json.Serialization; using System.Threading.Tasks; +using DotVVM.Framework.Binding; +using DotVVM.Framework.Binding.Expressions; +using DotVVM.Framework.Binding.Properties; using DotVVM.Framework.Compilation; using DotVVM.Framework.Compilation.Binding; using DotVVM.Framework.Compilation.ControlTree; using DotVVM.Framework.Compilation.Javascript; using DotVVM.Framework.Compilation.Javascript.Ast; -using DotVVM.Framework.Testing; using DotVVM.Framework.Configuration; -using System.Linq.Expressions; -using Microsoft.Extensions.DependencyInjection; +using DotVVM.Framework.Controls; +using DotVVM.Framework.Runtime; +using DotVVM.Framework.Testing; using DotVVM.Framework.Utils; using DotVVM.Framework.ViewModel; -using System.Text.Json.Serialization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using static DotVVM.Framework.Configuration.FreezableUtils; namespace DotVVM.Framework.Tests.Binding { @@ -1511,6 +1514,19 @@ public void JavascriptCompilation_StringFunctions(string input, string expected) Assert.AreEqual(expected, result); } + [TestMethod] + [DataRow("VmArray.Where(v => string.IsNullOrEmpty(v.SomeString)).ToList()")] + [DataRow("VmArray.Where(v => string.IsNullOrWhiteSpace(v.SomeString)).ToList()")] + // Regression test: FormatParametrizedScript was called on a frozen JsBinaryExpression (from string.IsNullOrEmpty/IsNullOrWhiteSpace + // translation) causing ObjectIsFrozenException when computing SimplePathExpressionBindingProperty. + public void JavascriptCompilation_IsNullOrEmpty_InWhereLambda_DoesNotThrowOnSimplePathExpression(string expression) + { + var binding = bindingHelper.ValueBinding>( + expression, + new[] { typeof(TestViewModel) }); + var simplePath = binding.GetProperty(typeof(SimplePathExpressionBindingProperty), ErrorHandlingMode.ThrowException); + } + [TestMethod] public void JavascriptCompilation_CustomPrimitiveToString() {