/// <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)); } }
/// <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)); } }
/// <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))); }
/// <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); }