/// <summary> /// Parse the children of a When or Otherwise /// </summary> private void ParseWhenOtherwiseChildren(XmlElementWithLocation element, ProjectElementContainer parent, int nestingDepth) { foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.propertyGroup: child = ParseProjectPropertyGroupElement(childElement, parent); break; case XMakeElements.itemGroup: child = ParseProjectItemGroupElement(childElement, parent); break; case XMakeElements.choose: child = ParseProjectChooseElement(childElement, parent, nestingDepth); break; default: ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); break; } parent.AppendParentedChildNoChecks(child); } }
/// <summary> /// Parse a ProjectChooseElement /// </summary> private ProjectChooseElement ParseProjectChooseElement(XmlElementWithLocation element, ProjectElementContainer parent, int nestingDepth) { ProjectXmlUtilities.VerifyThrowProjectNoAttributes(element); ProjectChooseElement choose = new ProjectChooseElement(element, parent, _project); nestingDepth++; ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= MaximumChooseNesting, element.Location, "ChooseOverflow", MaximumChooseNesting); bool foundWhen = false; bool foundOtherwise = false; foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.when: ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement.Location, "WhenNotAllowedAfterOtherwise"); child = ParseProjectWhenElement(childElement, choose, nestingDepth); foundWhen = true; break; case XMakeElements.otherwise: ProjectErrorUtilities.VerifyThrowInvalidProject(!foundOtherwise, childElement.Location, "MultipleOtherwise"); foundOtherwise = true; child = ParseProjectOtherwiseElement(childElement, choose, nestingDepth); break; default: ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); break; } choose.AppendParentedChildNoChecks(child); } ProjectErrorUtilities.VerifyThrowInvalidProject(foundWhen, element.Location, "ChooseMustContainWhen"); return(choose); }
/// <summary> /// Parse a ProjectUsingTaskElement /// </summary> private ProjectUsingTaskElement ParseProjectUsingTaskElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnUsingTask); ProjectErrorUtilities.VerifyThrowInvalidProject(element.GetAttribute(XMakeAttributes.taskName).Length > 0, element.Location, "ProjectTaskNameEmpty"); string assemblyName = element.GetAttribute(XMakeAttributes.assemblyName); string assemblyFile = element.GetAttribute(XMakeAttributes.assemblyFile); ProjectErrorUtilities.VerifyThrowInvalidProject ( (assemblyName.Length > 0) ^ (assemblyFile.Length > 0), element.Location, "UsingTaskAssemblySpecification", XMakeElements.usingTask, XMakeAttributes.assemblyName, XMakeAttributes.assemblyFile ); ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, XMakeAttributes.assemblyName); ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, XMakeAttributes.assemblyFile); ProjectUsingTaskElement usingTask = new ProjectUsingTaskElement(element, _project, _project); bool foundTaskElement = false; bool foundParameterGroup = false; foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; string childElementName = childElement.Name; switch (childElementName) { case XMakeElements.usingTaskParameterGroup: if (foundParameterGroup) { ProjectXmlUtilities.ThrowProjectInvalidChildElementDueToDuplicate(childElement); } child = ParseUsingTaskParameterGroupElement(childElement, usingTask); foundParameterGroup = true; break; case XMakeElements.usingTaskBody: if (foundTaskElement) { ProjectXmlUtilities.ThrowProjectInvalidChildElementDueToDuplicate(childElement); } ProjectXmlUtilities.VerifyThrowProjectAttributes(childElement, ValidAttributesOnUsingTaskBody); child = new ProjectUsingTaskBodyElement(childElement, usingTask, _project); foundTaskElement = true; break; default: ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); break; } usingTask.AppendParentedChildNoChecks(child); } return(usingTask); }
/// <summary> /// Parses the project into the ProjectRootElement /// </summary> private void Parse() { // XML guarantees exactly one root element XmlElementWithLocation element = _document.DocumentElement as XmlElementWithLocation; ProjectErrorUtilities.VerifyThrowInvalidProject(element != null, ElementLocation.Create(_document.FullPath), "NoRootProjectElement", XMakeElements.project); ProjectErrorUtilities.VerifyThrowInvalidProject(element.Name != XMakeElements.visualStudioProject, element.Location, "ProjectUpgradeNeeded", _project.FullPath); ProjectErrorUtilities.VerifyThrowInvalidProject(element.LocalName == XMakeElements.project, element.Location, "UnrecognizedElement", element.Name); // If a namespace was specified it must be the default MSBuild namespace. if (!ProjectXmlUtilities.VerifyValidProjectNamespace(element)) { ProjectErrorUtilities.ThrowInvalidProject(element.Location, "ProjectMustBeInMSBuildXmlNamespace", XMakeAttributes.defaultXmlNamespace); } else { _project.XmlNamespace = element.NamespaceURI; } // Historically, we allow any attribute on the Project element // The element wasn't available to the ProjectRootElement constructor so we have to set it now _project.SetProjectRootElementFromParser(element, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { switch (childElement.Name) { case XMakeElements.propertyGroup: _project.AppendParentedChildNoChecks(ParseProjectPropertyGroupElement(childElement, _project)); break; case XMakeElements.itemGroup: _project.AppendParentedChildNoChecks(ParseProjectItemGroupElement(childElement, _project)); break; case XMakeElements.importGroup: _project.AppendParentedChildNoChecks(ParseProjectImportGroupElement(childElement, _project)); break; case XMakeElements.import: _project.AppendParentedChildNoChecks(ParseProjectImportElement(childElement, _project)); break; case XMakeElements.usingTask: _project.AppendParentedChildNoChecks(ParseProjectUsingTaskElement(childElement)); break; case XMakeElements.target: _project.AppendParentedChildNoChecks(ParseProjectTargetElement(childElement)); break; case XMakeElements.itemDefinitionGroup: _project.AppendParentedChildNoChecks(ParseProjectItemDefinitionGroupElement(childElement)); break; case XMakeElements.choose: _project.AppendParentedChildNoChecks(ParseProjectChooseElement(childElement, _project, 0 /* nesting depth */)); break; case XMakeElements.projectExtensions: _project.AppendParentedChildNoChecks(ParseProjectExtensionsElement(childElement)); break; case XMakeElements.sdk: _project.AppendParentedChildNoChecks(ParseProjectSdkElement(childElement)); break; // Obsolete case XMakeElements.error: case XMakeElements.warning: case XMakeElements.message: ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ErrorWarningMessageNotSupported", childElement.Name); break; default: ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, childElement.ParentNode.Name, childElement.Location); break; } } }