예제 #1
0
 JsExpression GetDependentAncestorNode(JsExpression expr)
 {
     while (expr.Parent is JsExpression parent && !expr.HasAnnotation <MayBeNullAnnotation>() && expr.Role == JsTreeRoles.TargetExpression)
     {
         expr = parent;
     }
     return(expr);
 }
예제 #2
0
        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));
                    });
                }
            }
        }