/// <summary> /// Constructor called by derived classes, except from ProjectRootElement. /// Parameters may not be null, except parent. /// </summary> internal ProjectElement(XmlElement xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) { ErrorUtilities.VerifyThrowArgumentNull(xmlElement, "xmlElement"); ProjectXmlUtilities.VerifyThrowProjectValidNamespace((XmlElementWithLocation)xmlElement); ErrorUtilities.VerifyThrowArgumentNull(containingProject, "containingProject"); this.XmlElement = (XmlElementWithLocation)xmlElement; _parent = parent; this.ContainingProject = containingProject; }
/// <summary> /// Initialize a parented ProjectImportElement /// </summary> internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Initialize a parented ProjectChooseElement /// </summary> internal ProjectChooseElement(XmlElement xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Initialize a parented UsingTaskParameterGroupElement /// </summary> internal UsingTaskParameterGroupElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); VerifyCorrectParent(parent); }
/// <summary> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { VerifyCorrectParent(parent); }
/// <summary> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.VerifyThrowInvalidOperation(parent.Parent is ProjectTargetElement || (Include.Length > 0 || Update.Length > 0 || Remove.Length > 0), "OM_ItemsOutsideTargetMustHaveIncludeOrUpdateOrRemove"); ErrorUtilities.VerifyThrowInvalidOperation(parent.Parent is ProjectRootElement || parent.Parent is ProjectTargetElement || parent.Parent is ProjectWhenElement || parent.Parent is ProjectOtherwiseElement, "OM_CannotAcceptParent"); }
/// <summary> /// Dummy required implementation /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.ThrowInternalErrorUnreachable(); }
/// <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> /// Called after a new parent is set. Parent may be null. /// By default does nothing. /// </summary> internal virtual void OnAfterParentChanged(ProjectElementContainer newParent) { }
/// <summary> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal abstract void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer proposedParent, ProjectElement previousSibling, ProjectElement nextSibling);
/// <summary> /// Initialize a parented ProjectMetadataElement /// </summary> internal ProjectMetadataElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Parse a ProjectItemGroupElement /// </summary> private ProjectItemGroupElement ParseProjectItemGroupElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, s_validAttributesOnlyConditionAndLabel); ProjectItemGroupElement itemGroup = new ProjectItemGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectItemElement item = ParseProjectItemElement(childElement, itemGroup); itemGroup.AppendParentedChildNoChecks(item); } return itemGroup; }
/// <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> /// Constructor called by derived classes, except from ProjectRootElement. /// Parameters may not be null, except parent. /// </summary> /// <comment> /// Should ideally be protected+internal. /// </comment> internal ProjectElementContainer(XmlElement xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { }
/// <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 ProjectOtherwiseElement /// </summary> internal ProjectOtherwiseElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement project) : base(xmlElement, parent, project) { ErrorUtilities.VerifyThrowArgumentNull(parent, nameof(parent)); }
/// <summary> /// Initialize a parented ProjectImportElement /// </summary> internal ProjectImportElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject, SdkReference sdkReference = null) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); ParsedSdkReference = sdkReference; }
/// <summary> /// Overridden to update the parent's children-have-no-wildcards flag. /// </summary> internal override void OnAfterParentChanged(ProjectElementContainer parent) { base.OnAfterParentChanged(parent); if (parent != null) { // This is our indication that we just got attached to a parent // Update its children-with-wildcards flag ProjectItemGroupElement groupParent = parent as ProjectItemGroupElement; if (groupParent != null && groupParent.DefinitelyAreNoChildrenWithWildcards && IncludeHasWildcards) { groupParent.DefinitelyAreNoChildrenWithWildcards = false; } } }
/// <summary> /// Initialize a parented ProjectPropertyGroupElement /// </summary> internal ProjectPropertyGroupElement(XmlElementWithLocation xmlElement, ProjectElementContainer parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ErrorUtilities.VerifyThrowArgumentNull(parent, "parent"); }
/// <summary> /// Verify the parent is a usingTaskElement and that the taskFactory attribute is set /// </summary> private static void VerifyCorrectParent(ProjectElementContainer parent) { ProjectUsingTaskElement parentUsingTask = parent as ProjectUsingTaskElement; ErrorUtilities.VerifyThrowInvalidOperation(parentUsingTask != null, "OM_CannotAcceptParent"); // Now since there is not goign to be a TaskElement on the using task we need to validate and make sure there is a TaskFactory attribute on the parent element and // that it is not empty if (parentUsingTask.TaskFactory.Length == 0) { ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(parent.XmlElement, "TaskFactory"); } // UNDONE: Do check to make sure the parameter group is the first child }
private ProjectPropertyGroupElement ParseProjectPropertyGroupElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnlyConditionAndLabel); ProjectPropertyGroupElement propertyGroup = new ProjectPropertyGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectXmlUtilities.VerifyThrowProjectAttributes(childElement, ValidAttributesOnlyConditionAndLabel); XmlUtilities.VerifyThrowProjectValidElementName(childElement); ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(childElement.Name) && !ReservedPropertyNames.IsReservedProperty(childElement.Name), childElement.Location, "CannotModifyReservedProperty", childElement.Name); // All children inside a property are ignored, since they are only part of its value ProjectPropertyElement property = new ProjectPropertyElement(childElement, propertyGroup, _project); propertyGroup.AppendParentedChildNoChecks(property); } return(propertyGroup); }
/// <summary> /// Sets the parent of this element if it is a valid parent, /// otherwise throws. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.VerifyThrowInvalidOperation(parent is ProjectRootElement || parent is ProjectWhenElement || parent is ProjectOtherwiseElement, "OM_CannotAcceptParent"); int nestingDepth = 0; ProjectElementContainer immediateParent = parent; while (parent != null) { parent = parent.Parent; nestingDepth++; // This should really be an OM error, with no error number. But it's so obscure, it's not worth a new string. ProjectErrorUtilities.VerifyThrowInvalidProject(nestingDepth <= ProjectParser.MaximumChooseNesting, immediateParent.Location, "ChooseOverflow", ProjectParser.MaximumChooseNesting); } }
private ProjectItemGroupElement ParseProjectItemGroupElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnlyConditionAndLabel); ProjectItemGroupElement itemGroup = new ProjectItemGroupElement(element, parent, _project); foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectItemElement item = ParseProjectItemElement(childElement, itemGroup); itemGroup.AppendParentedChildNoChecks(item); } return(itemGroup); }
private ProjectMetadataElement ParseProjectMetadataElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectXmlUtilities.VerifyThrowProjectAttributes(element, 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.ReservedItemNames.Contains(element.Name), 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> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.VerifyThrowInvalidOperation(parent is ProjectRootElement || parent is ProjectImportGroupElement, "OM_CannotAcceptParent"); }
private ProjectImportElement ParseProjectImportElement(XmlElementWithLocation element, ProjectElementContainer parent) { ProjectErrorUtilities.VerifyThrowInvalidProject ( parent is ProjectRootElement || parent is ProjectImportGroupElement, element.Location, "UnrecognizedParentElement", parent, element ); ProjectXmlUtilities.VerifyThrowProjectAttributes(element, ValidAttributesOnImport); ProjectXmlUtilities.VerifyThrowProjectRequiredAttribute(element, XMakeAttributes.project); ProjectXmlUtilities.VerifyThrowProjectNoChildElements(element); SdkReference sdk = null; if (element.HasAttribute(XMakeAttributes.sdk)) { sdk = new SdkReference( ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.sdk, nullIfNotExists: true), ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.sdkVersion, nullIfNotExists: true), ProjectXmlUtilities.GetAttributeValue(element, XMakeAttributes.sdkMinimumVersion, nullIfNotExists: true)); } return(new ProjectImportElement(element, parent, _project, sdk)); }
/// <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; }
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 { ProjectXmlUtilities.VerifyThrowProjectAttributes(childElement, ValidAttributesOnUsingTaskParameter); XmlUtilities.VerifyThrowProjectValidElementName(childElement); ProjectUsingTaskParameterElement parameter = new ProjectUsingTaskParameterElement(childElement, parameterGroup, _project); 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 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; }
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 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> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.VerifyThrowInvalidOperation(parent is ProjectChooseElement, "OM_CannotAcceptParent"); ErrorUtilities.VerifyThrowInvalidOperation(!(nextSibling is ProjectWhenElement) && !(previousSibling is ProjectOtherwiseElement) && !(nextSibling is ProjectOtherwiseElement), "OM_NoOtherwiseBeforeWhenOrOtherwise"); }
/// <summary> /// Overridden to verify that the potential parent and siblings /// are acceptable. Throws InvalidOperationException if they are not. /// </summary> internal override void VerifyThrowInvalidOperationAcceptableLocation(ProjectElementContainer parent, ProjectElement previousSibling, ProjectElement nextSibling) { ErrorUtilities.VerifyThrowInvalidOperation(parent is ProjectTaskElement, "OM_CannotAcceptParent"); }
/// <summary> /// Returns a clone of this project element and all its children. /// </summary> /// <param name="factory">The factory to use for creating the new instance.</param> /// <param name="parent">The parent to append the cloned element to as a child.</param> /// <returns>The cloned element.</returns> protected internal virtual ProjectElementContainer DeepClone(ProjectRootElement factory, ProjectElementContainer parent) { var clone = (ProjectElementContainer)this.Clone(factory); if (parent != null) { parent.AppendChild(clone); } foreach (var child in this.Children) { var childContainer = child as ProjectElementContainer; if (childContainer != null) { childContainer.DeepClone(clone.ContainingProject, clone); } else { clone.AppendChild(child.Clone(clone.ContainingProject)); } } return(clone); }