// public static JsExpression RemoveTopObservables(JsExpression expression) // { // foreach (var leaf in expression.GetLeafResultNodes()) // { // JsExpression replacement = null; // if (leaf is JsInvocationExpression invocation && invocation.Annotation<ObservableUnwrapInvocationAnnotation>() != null) // { // replacement = invocation.Target; // } // else if (leaf is JsMemberAccessExpression member && member.MemberName == "$data" && member.Target is JsSymbolicParameter par && par.Symbol == JavascriptTranslator.KnockoutContextParameter || // leaf is JsSymbolicParameter param && param.Symbol == JavascriptTranslator.KnockoutViewModelParameter) // { // replacement = new JsSymbolicParameter(KnockoutContextParameter).Member("$rawData") // .WithAnnotation(leaf.Annotation<ViewModelInfoAnnotation>()); // } // if (replacement != null) // { // if (leaf.Parent == null) expression = replacement; // else leaf.ReplaceWith(replacement); // } // } // return expression; // } public static (JsExpression context, JsExpression data) GetKnockoutContextParameters(int dataContextLevel) { JsExpression currentContext = new JsSymbolicParameter(KnockoutContextParameter); for (int i = 0; i < dataContextLevel; i++) { currentContext = currentContext.Member("$parentContext"); } var currentData = dataContextLevel == 0 ? new JsSymbolicParameter(KnockoutContextParameter).Member("$data") : dataContextLevel == 1 ? new JsSymbolicParameter(KnockoutContextParameter).Member("$parent") : new JsSymbolicParameter(KnockoutContextParameter).Member("$parents").Indexer(new JsLiteral(dataContextLevel - 1)); return(currentContext, currentData); }
private void AssertFormatting(string expectedString, JsNode node) { Assert.AreEqual(expectedString, node.Clone().FormatScript()); foreach (var dd in node.Descendants.OfType <JsExpression>()) { var symbol = new JsSymbolicParameter(new CodeSymbolicParameter()); dd.ReplaceWith(symbol); var parametrized = node.Clone().FormatParametrizedScript(); var resolved = parametrized.ToString(o => o == symbol.Symbol ? CodeParameterAssignment.FromExpression(dd) : throw new Exception()); Assert.AreEqual(expectedString, resolved, $"Replaced expression: {dd.FormatScript()}"); symbol.ReplaceWith(dd); } }
protected void ProcessTargetedExpression(JsExpression expression, JsExpression defaultValue) { var target = expression.GetChildByRole(JsTreeRoles.TargetExpression); if (target.HasAnnotation <MayBeNullAnnotation>()) { // A().B -> (A() || {}).B if (defaultValue != null && (expression.HasAnnotation <MayBeNullAnnotation>() || expression.IsRootResultExpression()) && target.IsComplexType() && IntroduceVariableFor(target, 1)) { target.ReplaceWith(_ => new JsBinaryExpression(target, BinaryOperatorType.ConditionalOr, defaultValue)); } // {A().B}.MORESTUFF -> (a=A()) == null : null ? a.B.MORESTUFF else { var dependentExpression = GetDependentAncestorNode(expression); if (IntroduceVariableFor(target)) { var variable = new JsSymbolicParameter(new JsTemporaryVariableParameter()); target.ReplaceWith(variable); target = new JsAssignmentExpression(variable.Clone(), target); } else { target = target.Clone(); } ReplaceOrEmit(dependentExpression, _ => { return(CreateNullCondition(target, dependentExpression).WithAnnotation(MayBeNullAnnotation.Instance)); }); } } }