/// <summary>
        /// Evaluate as boolean
        /// </summary>
        internal override bool BoolEvaluate(IConditionEvaluationState state)
        {
            bool isLeftNum      = LeftChild.CanNumericEvaluate(state);
            bool isLeftVersion  = LeftChild.CanVersionEvaluate(state);
            bool isRightNum     = RightChild.CanNumericEvaluate(state);
            bool isRightVersion = RightChild.CanVersionEvaluate(state);
            bool isNumeric      = isLeftNum && isRightNum;
            bool isVersion      = isLeftVersion && isRightVersion;

            // If the values identify as numeric, make that comparison instead of the Version comparison since numeric has a stricter definition
            if (isNumeric)
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.NumericEvaluate(state)));
            }
            else if (isVersion)
            {
                return(Compare(LeftChild.VersionEvaluate(state), RightChild.VersionEvaluate(state)));
            }

            // If the numbers are of a mixed type, call that specific Compare method
            if (isLeftNum && isRightVersion)
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.VersionEvaluate(state)));
            }
            else if (isLeftVersion && isRightNum)
            {
                return(Compare(LeftChild.VersionEvaluate(state), RightChild.NumericEvaluate(state)));
            }

            // Throw error here as this code should be unreachable
            ErrorUtilities.ThrowInternalErrorUnreachable();
            return(false);
        }
        /// <summary>
        /// Evaluates as boolean and evaluates children as boolean, numeric, or string.
        /// Order in which comparisons are attempted is numeric, boolean, then string.
        /// Updates conditioned properties table.
        /// </summary>
        internal override bool BoolEvaluate(IConditionEvaluationState state)
        {
            // It's sometimes possible to bail out of expansion early if we just need to know whether
            // the result is empty string.
            // If at least one of the left or the right hand side will evaluate to empty,
            // and we know which do, then we already have enough information to evaluate this expression.
            // That means we don't have to fully expand a condition like " '@(X)' == '' "
            // which is a performance advantage if @(X) is a huge item list.
            if (LeftChild.EvaluatesToEmpty(state) || RightChild.EvaluatesToEmpty(state))
            {
                UpdateConditionedProperties(state);

                return(Compare(LeftChild.EvaluatesToEmpty(state), RightChild.EvaluatesToEmpty(state)));
            }

            if (LeftChild.CanNumericEvaluate(state) && RightChild.CanNumericEvaluate(state))
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.NumericEvaluate(state)));
            }
            else if (LeftChild.CanBoolEvaluate(state) && RightChild.CanBoolEvaluate(state))
            {
                return(Compare(LeftChild.BoolEvaluate(state), RightChild.BoolEvaluate(state)));
            }
            else // string comparison
            {
                string leftExpandedValue  = LeftChild.GetExpandedValue(state);
                string rightExpandedValue = RightChild.GetExpandedValue(state);

                UpdateConditionedProperties(state);

                return(Compare(leftExpandedValue, rightExpandedValue));
            }
        }
Пример #3
0
        /// <summary>
        /// Evaluates as boolean and evaluates children as boolean, numeric, or string.
        /// Order in which comparisons are attempted is numeric, boolean, then string.
        /// Updates conditioned properties table.
        /// </summary>
        internal override bool BoolEvaluate(ConditionEvaluationState state)
        {
            ProjectErrorUtilities.VerifyThrowInvalidProject
                (LeftChild != null && RightChild != null,
                state.conditionAttribute,
                "IllFormedCondition",
                state.parsedCondition);

            if (LeftChild.CanNumericEvaluate(state) && RightChild.CanNumericEvaluate(state))
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.NumericEvaluate(state)));
            }
            else if (LeftChild.CanBoolEvaluate(state) && RightChild.CanBoolEvaluate(state))
            {
                return(Compare(LeftChild.BoolEvaluate(state), RightChild.BoolEvaluate(state)));
            }
            else // string comparison
            {
                string leftExpandedValue  = LeftChild.GetExpandedValue(state);
                string rightExpandedValue = RightChild.GetExpandedValue(state);

                ProjectErrorUtilities.VerifyThrowInvalidProject
                    (leftExpandedValue != null && rightExpandedValue != null,
                    state.conditionAttribute,
                    "IllFormedCondition",
                    state.parsedCondition);

                if (!conditionedPropertiesUpdated)
                {
                    string leftUnexpandedValue  = LeftChild.GetUnexpandedValue(state);
                    string rightUnexpandedValue = RightChild.GetUnexpandedValue(state);

                    if (leftUnexpandedValue != null)
                    {
                        Utilities.UpdateConditionedPropertiesTable
                            (state.conditionedPropertiesInProject,
                            leftUnexpandedValue,
                            rightExpandedValue);
                    }

                    if (rightUnexpandedValue != null)
                    {
                        Utilities.UpdateConditionedPropertiesTable
                            (state.conditionedPropertiesInProject,
                            rightUnexpandedValue,
                            leftExpandedValue);
                    }

                    conditionedPropertiesUpdated = true;
                }

                return(Compare(leftExpandedValue, rightExpandedValue));
            }
        }
Пример #4
0
        /// <summary>
        /// Evaluate as boolean
        /// </summary>
        internal override bool BoolEvaluate(ConditionEvaluationState state)
        {
            ProjectErrorUtilities.VerifyThrowInvalidProject
                (LeftChild.CanNumericEvaluate(state) && RightChild.CanNumericEvaluate(state),
                state.conditionAttribute,
                "ComparisonOnNonNumericExpression",
                state.parsedCondition,
                /* helpfully display unexpanded token and expanded result in error message */
                (LeftChild.CanNumericEvaluate(state) ? RightChild.GetUnexpandedValue(state) : LeftChild.GetUnexpandedValue(state)),
                (LeftChild.CanNumericEvaluate(state) ? RightChild.GetExpandedValue(state) : LeftChild.GetExpandedValue(state)));

            return(Compare(LeftChild.NumericEvaluate(state), RightChild.NumericEvaluate(state)));
        }
Пример #5
0
        /// <summary>
        /// Evaluate as boolean
        /// </summary>
        internal override bool BoolEvaluate(ConditionEvaluator.IConditionEvaluationState state)
        {
            bool isLeftNum         = LeftChild.CanNumericEvaluate(state);
            bool isLeftVersion     = LeftChild.CanVersionEvaluate(state);
            bool isRightNum        = RightChild.CanNumericEvaluate(state);
            bool isRightVersion    = RightChild.CanVersionEvaluate(state);
            bool isNumeric         = isLeftNum && isRightNum;
            bool isVersion         = isLeftVersion && isRightVersion;
            bool isValidComparison = isNumeric || isVersion || (isLeftNum && isRightVersion) || (isLeftVersion && isRightNum);

            ProjectErrorUtilities.VerifyThrowInvalidProject
                (isValidComparison,
                state.ElementLocation,
                "ComparisonOnNonNumericExpression",
                state.Condition,
                /* helpfully display unexpanded token and expanded result in error message */
                LeftChild.CanNumericEvaluate(state) ? RightChild.GetUnexpandedValue(state) : LeftChild.GetUnexpandedValue(state),
                LeftChild.CanNumericEvaluate(state) ? RightChild.GetExpandedValue(state) : LeftChild.GetExpandedValue(state));

            // If the values identify as numeric, make that comparison instead of the Version comparison since numeric has a stricter definition
            if (isNumeric)
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.NumericEvaluate(state)));
            }
            else if (isVersion)
            {
                return(Compare(LeftChild.VersionEvaluate(state), RightChild.VersionEvaluate(state)));
            }

            // If the numbers are of a mixed type, call that specific Compare method
            if (isLeftNum && isRightVersion)
            {
                return(Compare(LeftChild.NumericEvaluate(state), RightChild.VersionEvaluate(state)));
            }
            else if (isLeftVersion && isRightNum)
            {
                return(Compare(LeftChild.VersionEvaluate(state), RightChild.NumericEvaluate(state)));
            }

            // Throw error here as this code should be unreachable
            ErrorUtilities.ThrowInternalErrorUnreachable();
            return(false);
        }