| File: Construction\ProjectItemDefinitionElement.cs | Web Access |
| Project: src\msbuild\src\Build\Microsoft.Build.csproj (Microsoft.Build) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Diagnostics; using System.Xml; using Microsoft.Build.ObjectModelRemoting; using Microsoft.Build.Shared; #nullable disable namespace Microsoft.Build.Construction { /// <summary> /// ProjectItemDefinitionElement class represents the Item Definition element in the MSBuild project. /// </summary> [DebuggerDisplay("{ItemType} #Metadata={Count} Condition={Condition}")] public class ProjectItemDefinitionElement : ProjectElementContainer { /// <summary> /// External projects support /// </summary> internal ProjectItemDefinitionElement(ProjectItemDefinitionElementLink link) : base(link) { } /// <summary> /// Initialize a ProjectItemDefinitionElement instance from a node read from a project file /// </summary> internal ProjectItemDefinitionElement(XmlElement xmlElement, ProjectItemDefinitionGroupElement parent, ProjectRootElement containingProject) : base(xmlElement, parent, containingProject) { ArgumentNullException.ThrowIfNull(parent); } /// <summary> /// Initialize a ProjectItemDefinitionElement instance from a node read from a project file /// </summary> private ProjectItemDefinitionElement(XmlElement xmlElement, ProjectRootElement containingProject) : base(xmlElement, null, containingProject) { } /// <summary> /// Gets the definition's type. /// </summary> public string ItemType => ElementName; /// <summary> /// Get any child metadata definitions. /// </summary> public ICollection<ProjectMetadataElement> Metadata => GetChildrenOfType<ProjectMetadataElement>(); /// <summary> /// Convenience method to add a piece of metadata to this item definition. /// Adds after any existing metadata. Does not modify any existing metadata. /// </summary> public ProjectMetadataElement AddMetadata(string name, string unevaluatedValue) { return AddMetadata(name, unevaluatedValue, false); } /// <summary> /// Convenience method to add a piece of metadata to this item definition. /// Adds after any existing metadata. Does not modify any existing metadata. /// </summary> /// <param name="name">The name of the metadata to add</param> /// <param name="unevaluatedValue">The value of the metadata to add</param> /// <param name="expressAsAttribute">If true, then the metadata will be expressed as an attribute instead of a child element, for example /// <Content CopyToOutputDirectory="PreserveNewest" /> /// </param> public ProjectMetadataElement AddMetadata(string name, string unevaluatedValue, bool expressAsAttribute) { ArgumentException.ThrowIfNullOrEmpty(name); ArgumentNullException.ThrowIfNull(unevaluatedValue); if (expressAsAttribute) { ProjectMetadataElement.ValidateValidMetadataAsAttributeName(name, ElementName, Location); } ProjectMetadataElement metadata = ContainingProject.CreateMetadataElement(name); metadata.Value = unevaluatedValue; metadata.ExpressedAsAttribute = expressAsAttribute; AppendChild(metadata); return metadata; } /// <summary> /// Creates an unparented ProjectItemDefinitionElement, wrapping an unparented XmlElement. /// Caller should then ensure the element is added to a parent. /// </summary> internal static ProjectItemDefinitionElement CreateDisconnected(string itemType, ProjectRootElement containingProject) { XmlUtilities.VerifyThrowArgumentValidElementName(itemType); // 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. XmlElementWithLocation element = containingProject.CreateElement(itemType); return new ProjectItemDefinitionElement(element, containingProject); } /// <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 ProjectItemDefinitionGroupElement, "OM_CannotAcceptParent"); } /// <inheritdoc /> protected override ProjectElement CreateNewInstance(ProjectRootElement owner) { return owner.CreateItemDefinitionElement(ItemType); } /// <summary> /// Do not clone attributes which can be metadata. The corresponding expressed as attribute project elements are responsible for adding their attribute /// </summary> protected override bool ShouldCloneXmlAttribute(XmlAttribute attribute) => !ProjectMetadataElement.AttributeNameIsValidMetadataName(attribute.LocalName); internal override bool ShouldCloneXmlAttribute(XmlAttributeLink attributeLink) => !ProjectMetadataElement.AttributeNameIsValidMetadataName(attributeLink.LocalName); } }