/// <summary> /// Constructor for the When block. Parses the contents of the When block (property /// groups, item groups, and nested chooses) and stores them. /// </summary> /// <remarks> /// </remarks> /// <owner>DavidLe</owner> /// <param name="parentProject"></param> /// <param name="parentGroupingCollection"></param> /// <param name="whenElement"></param> /// <param name="importedFromAnotherProject"></param> /// <param name="options"></param> /// <param name="nestingDepth">stack overflow guard</param> internal When( Project parentProject, GroupingCollection parentGroupingCollection, XmlElement whenElement, bool importedFromAnotherProject, Options options, int nestingDepth ) { // Make sure the <When> node has been given to us. error.VerifyThrow(whenElement != null, "Need valid (non-null) <When> element."); // Make sure this really is the <When> node. error.VerifyThrow(whenElement.Name == XMakeElements.when || whenElement.Name == XMakeElements.otherwise, "Expected <{0}> or <{1}> element; received <{2}> element.", XMakeElements.when, XMakeElements.otherwise, whenElement.Name); this.propertyAndItemLists = new GroupingCollection(parentGroupingCollection); this.parentProject = parentProject; string elementName = ((options == Options.ProcessWhen) ? XMakeElements.when : XMakeElements.otherwise); if (options == Options.ProcessWhen) { conditionAttribute = ProjectXmlUtilities.GetConditionAttribute(whenElement, /*verify sole attribute*/ true); ProjectErrorUtilities.VerifyThrowInvalidProject(conditionAttribute != null, whenElement, "MissingCondition", XMakeElements.when); } else { ProjectXmlUtilities.VerifyThrowProjectNoAttributes(whenElement); } ProcessWhenChildren(whenElement, parentProject, importedFromAnotherProject, nestingDepth); }
/// <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"); }