/// <summary> /// Gets child elements, ignoring whitespace and comments. /// Verifies xml namespace of elements is the MSBuild namespace. /// Throws InvalidProjectFileException for elements in the wrong namespace, and (if parameter is set) unexpected XML node types /// </summary> private static List<XmlElementWithLocation> GetChildElements(XmlElementWithLocation element, bool throwForInvalidNodeTypes) { List<XmlElementWithLocation> children = new List<XmlElementWithLocation>(); foreach (XmlNode child in element) { switch (child.NodeType) { case XmlNodeType.Comment: case XmlNodeType.Whitespace: // These are legal, and ignored break; case XmlNodeType.Element: XmlElementWithLocation childElement = (XmlElementWithLocation)child; VerifyThrowProjectValidNamespace(childElement); children.Add(childElement); break; default: if (throwForInvalidNodeTypes) { ThrowProjectInvalidChildElement(child.Name, element.Name, element.Location); } break; } } return children; }
/// <summary> /// This method renames an XML element. Well, actually you can't directly /// rename an XML element using the DOM, so what you have to do is create /// a brand new XML element with the new name, and copy over all the attributes /// and children. This method returns the new XML element object. /// If the name is the same, does nothing and returns the element passed in. /// </summary> /// <param name="oldElement"></param> /// <param name="newElementName"></param> /// <param name="xmlNamespace">Can be null if global namespace.</param> /// <returns>new/renamed element</returns> internal static XmlElementWithLocation RenameXmlElement(XmlElementWithLocation oldElement, string newElementName, string xmlNamespace) { if (String.Equals(oldElement.Name, newElementName, StringComparison.Ordinal) && String.Equals(oldElement.NamespaceURI, xmlNamespace, StringComparison.Ordinal)) { return oldElement; } XmlElementWithLocation newElement = (xmlNamespace == null) ? (XmlElementWithLocation)oldElement.OwnerDocument.CreateElement(newElementName) : (XmlElementWithLocation)oldElement.OwnerDocument.CreateElement(newElementName, xmlNamespace); // Copy over all the attributes. foreach (XmlAttribute oldAttribute in oldElement.Attributes) { XmlAttribute newAttribute = (XmlAttribute)oldAttribute.CloneNode(true); newElement.SetAttributeNode(newAttribute); } // Move over all the child nodes - no need to change their identity while (oldElement.HasChildNodes) { // This conveniently updates FirstChild and HasChildNodes on oldElement. newElement.AppendChild(oldElement.FirstChild); } if (oldElement.ParentNode != null) { // Add the new element in the same place the old element was. oldElement.ParentNode.ReplaceChild(newElement, oldElement); } return newElement; }
/// <summary> /// Throw an invalid project exception if there are any child elements at all /// </summary> internal static void VerifyThrowProjectNoChildElements(XmlElementWithLocation element) { List<XmlElementWithLocation> childElements = GetVerifyThrowProjectChildElements(element); if (childElements.Count > 0) { ThrowProjectInvalidChildElement(element.FirstChild.Name, element.Name, element.Location); } }
/// <summary> /// Gets child elements, ignoring whitespace and comments. /// Verifies xml namespace of elements is the MSBuild namespace. /// Throws InvalidProjectFileException for elements in the wrong namespace, and (if parameter is set) unexpected XML node types /// </summary> private static List<XmlElementWithLocation> GetChildElements(XmlElementWithLocation element, bool throwForInvalidNodeTypes) { List<XmlElementWithLocation> children = new List<XmlElementWithLocation>(); foreach (XmlNode child in element) { switch (child.NodeType) { case XmlNodeType.Comment: case XmlNodeType.Whitespace: // These are legal, and ignored break; case XmlNodeType.Element: XmlElementWithLocation childElement = (XmlElementWithLocation)child; VerifyThrowProjectValidNamespace(childElement); children.Add(childElement); break; default: if (child.NodeType == XmlNodeType.Text && String.IsNullOrWhiteSpace(child.InnerText)) { // If the text is greather than 4k and only contains whitespace, the XML reader will assume it's a text node // instead of ignoring it. Our call to String.IsNullOrWhiteSpace() can be a little slow if the text is // large but this should be extremely rare. break; } if (throwForInvalidNodeTypes) { ThrowProjectInvalidChildElement(child.Name, element.Name, element.Location); } break; } } return children; }
/// <summary> /// Parse a ProjectRootElement from an element /// </summary> private void ParseProjectElement(XmlElementWithLocation element) { // 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); ParseProjectRootElementChildren(element); }
/// <summary> /// Parse a ProjectTargetElement /// </summary> private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnTarget); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.name); // Orcas compat: all target names are automatically unescaped string targetName = EscapingUtilities.UnescapeAll(ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.name)); int indexOfSpecialCharacter = targetName.IndexOfAny(XMakeElements.InvalidTargetNameCharacters); if (indexOfSpecialCharacter >= 0) { ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.name), "NameInvalid", targetName, targetName[indexOfSpecialCharacter]); } ProjectTargetElement target = new ProjectTargetElement(element, _project, _project); ProjectOnErrorElement onError = null; foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.propertyGroup: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectPropertyGroupElement(childElement, target); break; case XMakeElements.itemGroup: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectItemGroupElement(childElement, target); break; case XMakeElements.onError: // Previous OM accidentally didn't verify ExecuteTargets on parse, // but we do, as it makes no sense ProjectXmlUtilities.VerifyThrowProjectAttributes(childElement, ValidAttributesOnOnError); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(childElement, XMakeAttributes.executeTargets); ProjectXmlUtilities.VerifyThrowProjectNoChildElements(childElement); child = onError = new ProjectOnErrorElement(childElement, target, _project); break; case XMakeElements.itemDefinitionGroup: ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ItemDefinitionGroupNotLegalInsideTarget", childElement.Name); break; default: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectTaskElement(childElement, target); break; } target.AppendParentedChildNoChecks(child); } return(target); }
/// <summary> /// Initialize a parented ProjectImportElement /// </summary> internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Parse a ProjectWhenElement /// </summary> private ProjectWhenElement ParseProjectWhenElement(XmlElementWithLocation element, ProjectChooseElement parent, int nestingDepth) { ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.condition); ProjectWhenElement when = new ProjectWhenElement(element, parent, _project); ParseWhenOtherwiseChildren(element, when, nestingDepth); return when; }
/// <summary> /// Called only by the parser to tell the ProjectRootElement its backing XmlElement and its own parent project (itself) /// This can't be done during construction, as it hasn't loaded the document at that point and it doesn't have a 'this' pointer either. /// </summary> internal void SetProjectRootElementFromParser(XmlElementWithLocation xmlElement, ProjectRootElement projectRootElement) { this.XmlElement = xmlElement; this.ContainingProject = projectRootElement; }
/// <summary> /// Initialize an unparented ProjectOnErrorElement /// </summary> private ProjectOnErrorElement(XmlElementWithLocation xmlElement, ProjectRootElement project) : base(xmlElement, null, project) { }
/// <summary> /// Parse a ProjectOnErrorElement /// </summary> private ProjectOnErrorElement ParseProjectOnErrorElement(XmlElementWithLocation element, ProjectTargetElement parent) { // Previous OM accidentally didn't verify ExecuteTargets on parse, // but we do, as it makes no sense ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnOnError); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.executeTargets); ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); return new ProjectOnErrorElement(element, parent, _project); }
internal ProjectOtherwiseElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
private ProjectOtherwiseElement(XmlElementWithLocation xmlElement, ProjectRootElement project) : base(xmlElement, null, project) { }
/// <summary> /// Parse the child of a ProjectRootElement /// </summary> private void ParseProjectRootElementChildren(XmlElementWithLocation element) { foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.propertyGroup: child = ParseProjectPropertyGroupElement(childElement, _project); break; case XMakeElements.itemGroup: child = ParseProjectItemGroupElement(childElement, _project); break; case XMakeElements.importGroup: child = ParseProjectImportGroupElement(childElement, _project); break; case XMakeElements.import: child = ParseProjectImportElement(childElement, _project); break; case XMakeElements.usingTask: child = ParseProjectUsingTaskElement(childElement); break; case XMakeElements.target: child = ParseProjectTargetElement(childElement); break; case XMakeElements.itemDefinitionGroup: child = ParseProjectItemDefinitionGroupElement(childElement); break; case XMakeElements.choose: child = ParseProjectChooseElement(childElement, _project, 0 /* nesting depth */); break; case XMakeElements.projectExtensions: child = ParseProjectExtensionsElement(childElement); break; case XMakeElements.sdk: child = 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; } _project.AppendParentedChildNoChecks(child); } }
/// <summary> /// Parse a UsingTaskParameterElement from the element /// </summary> private ProjectUsingTaskParameterElement ParseUsingTaskParameterElement(XmlElementWithLocation element, UsingTaskParameterGroupElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnUsingTaskParameter); XmlUtilities.VerifyThrowProjectValidElementName(element); return(new ProjectUsingTaskParameterElement(element, parent, _project)); }
internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject, SdkReference sdkReference = null) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); SdkReference = sdkReference; }
/// <summary> /// Initialize a parented ProjectPropertyGroupElement /// </summary> internal ProjectPropertyGroupElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Parse a ProjectPropertyGroupElement from the element /// </summary> private ProjectPropertyGroupElement ParseProjectPropertyGroupElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); ProjectPropertyGroupElement propertyGroup = new ProjectPropertyGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectPropertyElement property = ParseProjectPropertyElement(childElement, propertyGroup); propertyGroup.AppendParentedChildNoChecks(property); } return propertyGroup; }
/// <summary> /// Creates an unparented ProjectExtensionsElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent /// </summary> internal static ProjectExtensionsElement CreateDisconnected(ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.projectExtensions); return(new ProjectExtensionsElement(element, containingProject)); }
/// <summary> /// Parse a ProjectItemElement /// </summary> private ProjectItemElement ParseProjectItemElement(XmlElementWithLocation element, ProjectItemGroupElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnItem); bool belowTarget = parent.Parent is ProjectTargetElement; string itemType = element.Name; string include = element.GetAttribute(XMakeAttributes.include); string exclude = element.GetAttribute(XMakeAttributes.exclude); string remove = element.GetAttribute(XMakeAttributes.remove); string update = element.GetAttribute(XMakeAttributes.update); var exclusiveItemOperation = ""; int exclusiveAttributeCount = 0; if (element.HasAttribute(XMakeAttributes.include)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.include; } if (element.HasAttribute(XMakeAttributes.remove)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.remove; } if (element.HasAttribute(XMakeAttributes.update)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.update; } // At most one of the include, remove, or update attributes may be specified if (exclusiveAttributeCount > 1) { XmlAttributeWithLocation errorAttribute = remove.Length > 0 ? (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.remove] : (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.update]; ProjectErrorUtilities.ThrowInvalidProject(errorAttribute.Location, "InvalidAttributeExclusive"); } // Include, remove, or update must be present unless inside a target ProjectErrorUtilities.VerifyThrowInvalidProject(exclusiveAttributeCount == 1 || belowTarget, element.Location, "MissingRequiredAttribute", exclusiveItemOperation, itemType); // Exclude must be missing, unless Include exists ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(exclude.Length == 0 || include.Length > 0, (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.exclude]); // If we have an Include attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(include.Length > 0 || element.Attributes[XMakeAttributes.include] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.include, itemType); // If we have a Remove attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(remove.Length > 0 || element.Attributes[XMakeAttributes.remove] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.remove, itemType); // If we have an Update attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(update.Length > 0 || element.Attributes[XMakeAttributes.update] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.update, itemType); XmlUtilities.VerifyThrowProjectValidElementName(element); ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[itemType] == null, element.Location, "CannotModifyReservedItem", itemType); ProjectItemElement item = new ProjectItemElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectMetadataElement metadatum = ParseProjectMetadataElement(childElement, item); item.AppendParentedChildNoChecks(metadatum); } return item; }
/// <summary> /// Initialize a parented ProjectUsingTaskBodyElement /// </summary> internal ProjectUsingTaskBodyElement(XmlElementWithLocation xmlElement, ProjectUsingTaskElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); VerifyCorrectParent(parent); }
/// <summary> /// Parse a ProjectTaskElement /// </summary> private ProjectTaskElement ParseProjectTaskElement(XmlElementWithLocation element, ProjectTargetElement parent) { foreach (XmlAttributeWithLocation attribute in element.Attributes) { ProjectErrorUtilities.VerifyThrowInvalidProject ( !XMakeAttributes.IsBadlyCasedSpecialTaskAttribute(attribute.Name), attribute.Location, "BadlyCasedSpecialTaskAttribute", attribute.Name, element.Name, element.Name ); } ProjectTaskElement task = new ProjectTaskElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectErrorUtilities.VerifyThrowInvalidProject(childElement.Name == XMakeElements.output, childElement.Location, "UnrecognizedChildElement", childElement.Name, task.Name); ProjectOutputElement output = ParseProjectOutputElement(childElement, task); task.AppendParentedChildNoChecks(output); } return task; }
/// <summary> /// Initialize a parented ProjectMetadataElement /// </summary> internal ProjectMetadataElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Pasre a ProjectItemDefinitionElement /// </summary> private ProjectItemDefinitionElement ParseProjectItemDefinitionXml(XmlElementWithLocation element, ProjectItemDefinitionGroupElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); // Orcas inadvertently did not check for reserved item types (like "Choose") in item definitions, // as we do for item types in item groups. So we do not have a check here. // Although we could perhaps add one, as such item definitions couldn't be used // since no items can have the reserved itemType. ProjectItemDefinitionElement itemDefinition = new ProjectItemDefinitionElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectMetadataElement metadatum = ParseProjectMetadataElement(childElement, itemDefinition); itemDefinition.AppendParentedChildNoChecks(metadatum); } return itemDefinition; }
/// <summary> /// Initialize an unparented ProjectMetadataElement /// </summary> private ProjectMetadataElement(XmlElementWithLocation xmlElement, ProjectRootElement project) : base(xmlElement, null, project) { }
/// <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> /// Initialize a parented ProjectTargetElement /// </summary> internal ProjectTargetElement(XmlElementWithLocation xmlElement, ProjectRootElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Creates a ProjectExtensionsElement parented by a project /// </summary> internal static ProjectExtensionsElement CreateParented(XmlElementWithLocation element, ProjectRootElement parent, ProjectRootElement containingProject) { return(new ProjectExtensionsElement(element, parent, containingProject)); }
/// <summary> /// Parse a ProjectItemDefinitionGroupElement /// </summary> private ProjectItemDefinitionGroupElement ParseProjectItemDefinitionGroupElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnlyConditionAndLabel); ProjectItemDefinitionGroupElement itemDefinitionGroup = new ProjectItemDefinitionGroupElement(element, _project, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectItemDefinitionElement itemDefinition = ParseProjectItemDefinitionXml(childElement, itemDefinitionGroup); itemDefinitionGroup.AppendParentedChildNoChecks(itemDefinition); } return(itemDefinitionGroup); }
/// <summary> /// Initialize an unparented ProjectPropertyElement /// </summary> private ProjectPropertyElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <summary> /// Initialize an unparented ProjectImportElement /// </summary> private ProjectImportElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <summary> /// Parse a ProjectImportGroupElement /// </summary> /// <param name="element">The XML element to parse</param> /// <returns>A ProjectImportGroupElement derived from the XML element passed in</returns> private ProjectImportGroupElement ParseProjectImportGroupElement(XmlElementWithLocation element, ProjectRootElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); ProjectImportGroupElement importGroup = new ProjectImportGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectErrorUtilities.VerifyThrowInvalidProject ( childElement.Name == XMakeElements.import, childElement.Location, "UnrecognizedChildElement", childElement.Name, element.Name ); ProjectImportElement item = ParseProjectImportElement(childElement, importGroup); importGroup.AppendParentedChildNoChecks(item); } return importGroup; }
/// <summary> /// Parse the child of a ProjectRootElement /// </summary> private void ParseProjectRootElementChildren(XmlElementWithLocation element) { foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.propertyGroup: child = ParseProjectPropertyGroupElement(childElement, _project); break; case XMakeElements.itemGroup: child = ParseProjectItemGroupElement(childElement, _project); break; case XMakeElements.importGroup: child = ParseProjectImportGroupElement(childElement, _project); break; case XMakeElements.import: child = ParseProjectImportElement(childElement, _project); break; case XMakeElements.usingTask: child = ParseProjectUsingTaskElement(childElement); break; case XMakeElements.target: child = ParseProjectTargetElement(childElement); break; case XMakeElements.itemDefinitionGroup: child = ParseProjectItemDefinitionGroupElement(childElement); break; case XMakeElements.choose: child = ParseProjectChooseElement(childElement, _project, 0 /* nesting depth */); break; case XMakeElements.projectExtensions: child = ParseProjectExtensionsElement(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; } _project.AppendParentedChildNoChecks(child); } }
/// <summary> /// Parse a UsingTaskParameterGroupElement from the element /// </summary> private UsingTaskParameterGroupElement ParseUsingTaskParameterGroupElement(XmlElementWithLocation element, ProjectElementContainer parent) { // There should be no attributes ProjectXmlUtilities.VerifyThrowProjectNoAttributes(element); UsingTaskParameterGroupElement parameterGroup = new UsingTaskParameterGroupElement(element, parent, _project); HashSet<String> listOfChildElementNames = new HashSet<string>(); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { // The parameter already exists this means there is a duplicate child item. Throw an exception. if (listOfChildElementNames.Contains(childElement.Name)) { ProjectXmlUtilities.ThrowProjectInvalidChildElementDueToDuplicate(childElement); } else { ProjectUsingTaskParameterElement parameter = ParseUsingTaskParameterElement(childElement, parameterGroup); parameterGroup.AppendParentedChildNoChecks(parameter); // Add the name of the child element to the hashset so we can check for a duplicate child element listOfChildElementNames.Add(childElement.Name); } } return parameterGroup; }
/// <summary> /// Parse a ProjectPropertyElement from the element /// </summary> private ProjectPropertyElement ParseProjectPropertyElement(XmlElementWithLocation element, ProjectPropertyGroupElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); XmlUtilities.VerifyThrowProjectValidElementName(element); ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[element.Name] == null && !ReservedPropertyNames.IsReservedProperty(element.Name), element.Location, "CannotModifyReservedProperty", element.Name); // All children inside a property are ignored, since they are only part of its value return new ProjectPropertyElement(element, parent, _project); }
/// <summary> /// Parse a ProjectUsingTaskElement /// </summary> private ProjectUsingTaskElement ParseProjectUsingTaskElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_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); } child = ParseUsingTaskBodyElement(childElement, usingTask); foundTaskElement = true; break; default: ProjectXmlUtilities.ThrowProjectInvalidChildElement(childElement.Name, element.Name, element.Location); break; } usingTask.AppendParentedChildNoChecks(child); } return usingTask; }
/// <summary> /// Parse a ProjectMetadataElement /// </summary> private ProjectMetadataElement ParseProjectMetadataElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); XmlUtilities.VerifyThrowProjectValidElementName(element); ProjectErrorUtilities.VerifyThrowInvalidProject(!(parent is ProjectItemElement) || ((ProjectItemElement)parent).Remove.Length == 0, element.Location, "ChildElementsBelowRemoveNotAllowed", element.Name); ProjectErrorUtilities.VerifyThrowInvalidProject(!FileUtilities.ItemSpecModifiers.IsItemSpecModifier(element.Name), element.Location, "ItemSpecModifierCannotBeCustomMetadata", element.Name); ProjectErrorUtilities.VerifyThrowInvalidProject(XMakeElements.IllegalItemPropertyNames[element.Name] == null, element.Location, "CannotModifyReservedItemMetadata", element.Name); ProjectMetadataElement metadatum = new ProjectMetadataElement(element, parent, _project); // If the parent is an item definition, we don't allow expressions like @(foo) in the value, as no items exist at that point if (parent is ProjectItemDefinitionElement) { bool containsItemVector = Expander.ExpressionContainsItemVector(metadatum.Value); ProjectErrorUtilities.VerifyThrowInvalidProject(!containsItemVector, element.Location, "MetadataDefinitionCannotContainItemVectorExpression", metadatum.Value, metadatum.Name); } return metadatum; }
/// <summary> /// Initialize a parented ProjectOnErrorElement /// </summary> internal ProjectOnErrorElement(XmlElementWithLocation xmlElement, ProjectTargetElement parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
/// <summary> /// Parse a ProjectImportElement that is contained in an ImportGroup /// </summary> private ProjectImportElement ParseProjectImportElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectErrorUtilities.VerifyThrowInvalidProject ( parent is ProjectRootElement || parent is ProjectImportGroupElement, element.Location, "UnrecognizedParentElement", parent, element ); ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnImport); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.project); ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); return new ProjectImportElement(element, parent, _project); }
/// <summary> /// Initialize a parented ProjectImportGroupElement /// </summary> internal ProjectImportGroupElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
/// <summary> /// Parse a UsingTaskParameterElement from the element /// </summary> private ProjectUsingTaskParameterElement ParseUsingTaskParameterElement(XmlElementWithLocation element, UsingTaskParameterGroupElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnUsingTaskParameter); XmlUtilities.VerifyThrowProjectValidElementName(element); return new ProjectUsingTaskParameterElement(element, parent, _project); }
/// <summary> /// Initialize an unparented ProjectImportGroupElement /// </summary> private ProjectImportGroupElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <summary> /// Parse a ProjectTargetElement /// </summary> private ProjectTargetElement ParseProjectTargetElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnTarget); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.name); string targetName = ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.name); // Orcas compat: all target names are automatically unescaped targetName = EscapingUtilities.UnescapeAll(targetName); int indexOfSpecialCharacter = targetName.IndexOfAny(XMakeElements.illegalTargetNameCharacters); if (indexOfSpecialCharacter >= 0) { ProjectErrorUtilities.ThrowInvalidProject(element.GetAttributeLocation(XMakeAttributes.name), "NameInvalid", targetName, targetName[indexOfSpecialCharacter]); } ProjectTargetElement target = new ProjectTargetElement(element, _project, _project); ProjectOnErrorElement onError = null; foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectElement child = null; switch (childElement.Name) { case XMakeElements.propertyGroup: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectPropertyGroupElement(childElement, target); break; case XMakeElements.itemGroup: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectItemGroupElement(childElement, target); break; case XMakeElements.onError: onError = ParseProjectOnErrorElement(childElement, target); child = onError; break; case XMakeElements.itemDefinitionGroup: ProjectErrorUtilities.ThrowInvalidProject(childElement.Location, "ItemDefinitionGroupNotLegalInsideTarget", childElement.Name); break; default: if (onError != null) { ProjectErrorUtilities.ThrowInvalidProject(onError.Location, "NodeMustBeLastUnderElement", XMakeElements.onError, XMakeElements.target, childElement.Name); } child = ParseProjectTaskElement(childElement, target); break; } target.AppendParentedChildNoChecks(child); } return target; }
/// <summary> /// Creates an unparented ProjectImportGroupElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent /// </summary> internal static ProjectImportGroupElement CreateDisconnected(ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.importGroup); return(new ProjectImportGroupElement(element, containingProject)); }
/// <summary> /// Parse a ProjectOutputElement /// </summary> private ProjectOutputElement ParseProjectOutputElement(XmlElementWithLocation element, ProjectTaskElement parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnOutput); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.taskParameter); ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); string taskParameter = element.GetAttribute(XMakeAttributes.taskParameter); string itemName = element.GetAttribute(XMakeAttributes.itemName); string propertyName = element.GetAttribute(XMakeAttributes.propertyName); ProjectErrorUtilities.VerifyThrowInvalidProject ( (itemName.Length > 0 || propertyName.Length > 0) && (itemName.Length == 0 || propertyName.Length == 0), element.Location, "InvalidTaskOutputSpecification", parent.Name ); ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, XMakeAttributes.itemName); ProjectXmlUtilities.VerifyThrowProjectAttributeEitherMissingOrNotEmpty(element, XMakeAttributes.propertyName); ProjectErrorUtilities.VerifyThrowInvalidProject(!ReservedPropertyNames.IsReservedProperty(propertyName), element.Location, "CannotModifyReservedProperty", propertyName); return new ProjectOutputElement(element, parent, _project); }
/// <summary> /// Initialize a parented UsingTaskParameterElement instance /// </summary> internal ProjectUsingTaskParameterElement(XmlElementWithLocation xmlElement, UsingTaskParameterGroupElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
/// <summary> /// Parse a ProjectItemDefinitionGroupElement /// </summary> private ProjectItemDefinitionGroupElement ParseProjectItemDefinitionGroupElement(XmlElementWithLocation element) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); ProjectItemDefinitionGroupElement itemDefinitionGroup = new ProjectItemDefinitionGroupElement(element, _project, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectItemDefinitionElement itemDefinition = ParseProjectItemDefinitionXml(childElement, itemDefinitionGroup); itemDefinitionGroup.AppendParentedChildNoChecks(itemDefinition); } return itemDefinitionGroup; }
/// <summary> /// Initialize an unparented UsingTaskParameterElement instance /// </summary> private ProjectUsingTaskParameterElement(XmlElementWithLocation xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { }
/// <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); } nestingDepth--; ProjectErrorUtilities.VerifyThrowInvalidProject(foundWhen, element.Location, "ChooseMustContainWhen"); return choose; }
/// <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; } } }
/// <summary> /// Parse a ProjectOtherwiseElement /// </summary> private ProjectOtherwiseElement ParseProjectOtherwiseElement(XmlElementWithLocation element, ProjectChooseElement parent, int nestingDepth) { ProjectXmlUtilities.VerifyThrowProjectNoAttributes(element); ProjectOtherwiseElement otherwise = new ProjectOtherwiseElement(element, parent, _project); ParseWhenOtherwiseChildren(element, otherwise, nestingDepth); return otherwise; }
/// <summary> /// Parse a ProjectItemElement /// </summary> private ProjectItemElement ParseProjectItemElement(XmlElementWithLocation element, ProjectItemGroupElement parent) { bool belowTarget = parent.Parent is ProjectTargetElement; string itemType = element.Name; string include = element.GetAttribute(XMakeAttributes.include); string exclude = element.GetAttribute(XMakeAttributes.exclude); string remove = element.GetAttribute(XMakeAttributes.remove); string update = element.GetAttribute(XMakeAttributes.update); var exclusiveItemOperation = ""; int exclusiveAttributeCount = 0; if (element.HasAttribute(XMakeAttributes.include)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.include; } if (element.HasAttribute(XMakeAttributes.remove)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.remove; } if (element.HasAttribute(XMakeAttributes.update)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.update; } // At most one of the include, remove, or update attributes may be specified if (exclusiveAttributeCount > 1) { XmlAttributeWithLocation errorAttribute = remove.Length > 0 ? (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.remove] : (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.update]; ProjectErrorUtilities.ThrowInvalidProject(errorAttribute.Location, "InvalidAttributeExclusive"); } // Include, remove, or update must be present unless inside a target ProjectErrorUtilities.VerifyThrowInvalidProject(exclusiveAttributeCount == 1 || belowTarget, element.Location, "IncludeRemoveOrUpdate", exclusiveItemOperation, itemType); // Exclude must be missing, unless Include exists ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(exclude.Length == 0 || include.Length > 0, (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.exclude]); // If we have an Include attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(include.Length > 0 || element.Attributes[XMakeAttributes.include] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.include, itemType); // If we have a Remove attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(remove.Length > 0 || element.Attributes[XMakeAttributes.remove] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.remove, itemType); // If we have an Update attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(update.Length > 0 || element.Attributes[XMakeAttributes.update] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.update, itemType); XmlUtilities.VerifyThrowProjectValidElementName(element); ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(itemType), element.Location, "CannotModifyReservedItem", itemType); ProjectItemElement item = new ProjectItemElement(element, parent, _project); foreach (XmlAttributeWithLocation attribute in element.Attributes) { bool isKnownAttribute; bool isValidMetadataNameInAttribute; CheckMetadataAsAttributeName(attribute.Name, out isKnownAttribute, out isValidMetadataNameInAttribute); if (!isKnownAttribute && !isValidMetadataNameInAttribute) { ProjectXmlUtilities.ThrowProjectInvalidAttribute(attribute); } else if (isValidMetadataNameInAttribute) { ProjectMetadataElement metadatum = _project.CreateMetadataElement(attribute.Name, attribute.Value); metadatum.ExpressedAsAttribute = true; metadatum.Parent = item; item.AppendParentedChildNoChecks(metadatum); } } foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectMetadataElement metadatum = ParseProjectMetadataElement(childElement, item); item.AppendParentedChildNoChecks(metadatum); } return(item); }
/// <summary> /// Parse a ProjectExtensionsElement /// </summary> private ProjectExtensionsElement ParseProjectExtensionsElement(XmlElementWithLocation element) { // ProjectExtensions are only found in the main project file - in fact, the code used to ignore them in imported // files. We don't. ProjectXmlUtilities.VerifyThrowProjectNoAttributes(element); ProjectErrorUtilities.VerifyThrowInvalidProject(!_seenProjectExtensions, element.Location, "DuplicateProjectExtensions"); _seenProjectExtensions = true; // All children inside ProjectExtensions are ignored, since they are only part of its value return new ProjectExtensionsElement(element, _project, _project); }
/// <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> /// Called by a DERIVED CLASS to indicate its XmlElement has changed. /// This normally shouldn't happen, so it's broken out into an explicit method. /// An example of when it has to happen is when an item's type is changed. /// We trust the caller to have fixed up the XmlDocument properly. /// We ASSUME that attributes were copied verbatim. If this is not the case, /// any cached attribute values would have to be cleared. /// If the new element is actually the existing element, does nothing, and does /// not mark the project dirty. /// </summary> /// <remarks> /// This should be protected, but "protected internal" means "OR" not "AND", /// so this is not possible. /// </remarks> internal void ReplaceElement(XmlElementWithLocation newElement) { if (Object.ReferenceEquals(newElement, XmlElement)) { return; } XmlElement = newElement; MarkDirty("Replace element {0}", newElement.Name); }
/// <summary> /// Creates an unparented ProjectOtherwiseElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent. /// </summary> internal static ProjectOtherwiseElement CreateDisconnected(ProjectRootElement containingProject) { XmlElementWithLocation element = containingProject.CreateElement(XMakeElements.otherwise); return(new ProjectOtherwiseElement(element, containingProject)); }