Esempio n. 1
0
        /// <summary>
        /// Constructor for the Choose object.  Parses the contents of the Choose
        /// and sets up list of When blocks
        /// </summary>
        /// <remarks>
        /// </remarks>
        /// <owner>DavidLe</owner>
        /// <param name="parentProject"></param>
        /// <param name="parentGroupingCollection"></param>
        /// <param name="chooseElement"></param>
        /// <param name="importedFromAnotherProject"></param>
        /// <param name="nestingDepth">stack overflow guard</param>
        internal Choose
        (
            Project parentProject,
            GroupingCollection parentGroupingCollection,
            XmlElement chooseElement,
            bool importedFromAnotherProject,
            int nestingDepth
        )
        {
            whenClauseList = new ArrayList();

            error.VerifyThrow(chooseElement != null, "Need valid <Choose> element.");

            // Make sure this really is the <Choose> node.
            ProjectXmlUtilities.VerifyThrowElementName(chooseElement, XMakeElements.choose);

            // Stack overflow guard. The only way in the MSBuild file format that MSBuild elements can be
            // legitimately nested without limit is the <Choose> construct. So, enforce a nesting limit 
            // to avoid blowing our stack.
            nestingDepth++;
            ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= maximumChooseNesting, chooseElement, "ChooseOverflow", maximumChooseNesting);

            this.importedFromAnotherProject = importedFromAnotherProject;

            // This <Choose> is coming from an existing XML element, so
            // walk through all the attributes and child elements, creating the
            // necessary When objects.

            // No attributes on the <Choose> element, so don't allow any.
            ProjectXmlUtilities.VerifyThrowProjectNoAttributes(chooseElement);

            bool foundOtherwise = false;
            // Loop through the child nodes of the <Choose> element.
            foreach (XmlNode chooseChildNode in chooseElement)
            {
                switch (chooseChildNode.NodeType)
                {
                    // Handle XML comments under the <PropertyGroup> node (just ignore them).
                    case XmlNodeType.Comment:
                    // fall through
                    case XmlNodeType.Whitespace:
                        // ignore whitespace
                        break;

                    case XmlNodeType.Element:
                        // The only two types of child nodes that a <Choose> element can contain
                        // is are <When> elements and zero or one <Otherwise> elements.

                        ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElement)chooseChildNode);

                        if (chooseChildNode.Name == XMakeElements.when)
                        {
                            // don't allow <When> to follow <Otherwise>
                            ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise,
                                    chooseChildNode, "WhenNotAllowedAfterOtherwise");
                            When newWhen = new When(parentProject,
                                parentGroupingCollection,
                                (XmlElement)chooseChildNode,
                                importedFromAnotherProject,
                                When.Options.ProcessWhen,
                                nestingDepth);
                            this.whenClauseList.Add(newWhen);
                        }
                        else if (chooseChildNode.Name == XMakeElements.otherwise)
                        {
                            ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise,
                                        chooseChildNode, "MultipleOtherwise");
                            When newWhen = new When(parentProject,
                                parentGroupingCollection,
                                (XmlElement)chooseChildNode,
                                importedFromAnotherProject,
                                When.Options.ProcessOtherwise,
                                nestingDepth);
                            otherwiseClause = newWhen;
                            foundOtherwise = true;
                        }
                        else
                        {
                            ProjectXmlUtilities.ThrowProjectInvalidChildElement(chooseChildNode);
                        }
                        break;

                    default:
                        // Unrecognized child element.
                        ProjectXmlUtilities.ThrowProjectInvalidChildElement(chooseChildNode);
                        break;
                }
            }
            ProjectErrorUtilities.VerifyThrowInvalidProject(this.whenClauseList.Count != 0,
                    chooseElement, "ChooseMustContainWhen");
        }
Esempio n. 2
0
 /// <summary>
 /// Evaluates the Choose clause by stepping through each when and evaluating.
 /// </summary>
 /// <remarks>
 /// </remarks>
 /// <owner>DavidLe</owner>
 /// <param name="parentPropertyBag"></param>
 /// <param name="ignoreCondition"></param>
 /// <param name="honorCondition"></param>
 /// <param name="conditionedPropertiesTable"></param>
 /// <param name="pass"></param>
 internal void Evaluate
 (
     BuildPropertyGroup parentPropertyBag,
     bool ignoreCondition, bool honorCondition,
     Hashtable conditionedPropertiesTable,
     ProcessingPass pass
 )
 {
     if (pass == ProcessingPass.Pass1)
     {
         whenLastTaken = null;
         bool whenTaken = false;
         foreach (When currentWhen in this.whenClauseList)
         {
             if (currentWhen.EvaluateCondition(parentPropertyBag, conditionedPropertiesTable))
             {
                 whenTaken = true;
                 currentWhen.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass);
                 whenLastTaken = currentWhen;
                 break;
             }
         }
         if (!whenTaken && otherwiseClause != null)
         {
             // Process otherwise
             whenLastTaken = otherwiseClause;
             otherwiseClause.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass);
         }
     }
     else
     {
         ErrorUtilities.VerifyThrow(pass == ProcessingPass.Pass2, "ProcessingPass must be Pass1 or Pass2.");
         if (whenLastTaken != null)
         {
             whenLastTaken.Evaluate(parentPropertyBag, ignoreCondition, honorCondition, conditionedPropertiesTable, pass);
         }
     }
 }