Exemple #1
0
        /// <summary>
        /// Evaluates a string representing a condition from a "condition" attribute.
        /// If the condition is a malformed string, it throws an InvalidProjectFileException.
        /// This method uses cached expression trees to avoid generating them from scratch every time it's called.
        /// This method is thread safe and is called from engine and task execution module threads
        /// </summary>
        /// <param name="condition">Can be null</param>
        /// <param name="conditionAttribute">XML attribute on which the condition is evaluated</param>
        /// <param name="expander">All the data available for expanding embedded properties, metadata, and items</param>
        /// <param name="conditionedPropertiesTable">Can be null</param>
        /// <param name="itemListOptions"></param>
        /// <param name="loggingServices">Can be null</param>
        /// <param name="buildEventContext"> contains contextual information for logging events</param>
        /// <returns>true, if the expression evaluates to true, otherwise false</returns>
        internal static bool EvaluateCondition
        (
            string condition,
            XmlAttribute conditionAttribute,
            Expander expander,
            Hashtable conditionedPropertiesTable,
            ParserOptions itemListOptions,
            EngineLoggingServices loggingServices,
            BuildEventContext buildEventContext
        )
        {
            ErrorUtilities.VerifyThrow((conditionAttribute != null) || (condition.Length == 0),
                                       "If condition is non-empty, you must provide the XML node representing the condition.");

            // An empty condition is equivalent to a "true" condition.
            if ((null == condition) || (condition.Length == 0))
            {
                return(true);
            }

            Hashtable cachedExpressionTreesForCurrentOptions = cachedExpressionTrees[(int)itemListOptions];

            // Try and see if we have an expression tree for this condition already
            GenericExpressionNode parsedExpression = (GenericExpressionNode)cachedExpressionTreesForCurrentOptions[condition];

            if (parsedExpression == null)
            {
                Parser conditionParser = new Parser();

                #region REMOVE_COMPAT_WARNING
                conditionParser.LoggingServices      = loggingServices;
                conditionParser.LogBuildEventContext = buildEventContext;
                #endregion

                parsedExpression = conditionParser.Parse(condition, conditionAttribute, itemListOptions);

                // It's possible two threads will add a different tree to the same entry in the hashtable,
                // but it should be rare and it's not a problem - the previous entry will be thrown away.
                // We could ensure no dupes with double check locking but it's not really necessary here.
                // Also, we don't want to lock on every read.
                lock (cachedExpressionTreesForCurrentOptions)
                {
                    cachedExpressionTreesForCurrentOptions[condition] = parsedExpression;
                }
            }

            ConditionEvaluationState state = new ConditionEvaluationState(conditionAttribute, expander, conditionedPropertiesTable, condition);
            bool result;

            // We are evaluating this expression now and it can cache some state for the duration,
            // so we don't want multiple threads working on the same expression
            lock (parsedExpression)
            {
                result = parsedExpression.Evaluate(state);
                parsedExpression.ResetState();
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// If any expression nodes cache any state for the duration of evaluation,
        /// now's the time to clean it up
        /// </summary>
        internal override void ResetState()
        {
            if (leftChild != null)
            {
                leftChild.ResetState();
            }

            if (rightChild != null)
            {
                rightChild.ResetState();
            }
        }
Exemple #3
0
        /// <summary>
        /// If any expression nodes cache any state for the duration of evaluation,
        /// now's the time to clean it up
        /// </summary>
        internal override void ResetState()
        {
            leftChild?.ResetState();

            rightChild?.ResetState();
        }