示例#1
0
 protected bool IntroduceVariableFor(JsExpression expression, int limit = 2)
 {
     if (expression is JsIdentifierExpression)
     {
         return(false);
     }
     if (expression is JsSymbolicParameter symbol)
     {
         return(false);
     }
     if (limit > 0 && (expression is JsMemberAccessExpression memberAccess ||
                       expression is JsInvocationExpression invocation && invocation.Arguments.Count == 0 && invocation.HasAnnotation <ObservableUnwrapInvocationAnnotation>()))
     {
         return(IntroduceVariableFor(expression.GetChildByRole(JsTreeRoles.TargetExpression), limit - 1));
     }
     return(true);
 }
示例#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));
                    });
                }
            }
        }