Skip to content

Commit

Permalink
Fix setting ProjectMetadataElement.Name
Browse files Browse the repository at this point in the history
  • Loading branch information
dfederm committed Sep 17, 2024
1 parent 332df0e commit 685cba3
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/Build.OM.UnitTests/Construction/ConstructionEditing_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3137,6 +3137,44 @@ public void AddMetadataAsAttributeAndAsElement()
Helpers.VerifyAssertProjectContent(expected, project);
}

[Fact]
public void SetMetadataName()
{
var project = ProjectRootElement.Create();
var itemGroup = project.AddItemGroup();

var item = itemGroup.AddItem("i1", "i");
var attributeMetadata = item.AddMetadata("A", "value_a", expressAsAttribute: true);
var elementMetadata = item.AddMetadata("B", "value_b", expressAsAttribute: false);

string expected = """
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<i1 Include="i" A="value_a">
<B>value_b</B>
</i1>
</ItemGroup>
</Project>
""";

Helpers.VerifyAssertProjectContent(expected, project);

attributeMetadata.Name = "A2";
elementMetadata.Name = "B2";

expected = """
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<i1 Include="i" A2="value_a">
<B2>value_b</B2>
</i1>
</ItemGroup>
</Project>
""";

Helpers.VerifyAssertProjectContent(expected, project);
}

/// <summary>
/// Legally modify a child whose parent is not parented (should not throw)
/// </summary>
Expand Down
18 changes: 18 additions & 0 deletions src/Build/Construction/ProjectElementContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Diagnostics;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Build.Collections;
using Microsoft.Build.Internal;
using Microsoft.Build.ObjectModelRemoting;
using Microsoft.Build.Shared;
Expand Down Expand Up @@ -448,6 +450,22 @@ private void SetElementAsAttributeValue(ProjectElement child)
ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, child.XmlElement.Name, value);
}

/// <summary>
/// If child "element" is actually represented as an attribute, update the name in the corresponding Xml attribute
/// </summary>
/// <param name="child">A child element which might be represented as an attribute</param>
internal void UpdateElementName(ProjectElement child, string oldName)
{
ErrorUtilities.VerifyThrow(Link == null, "External project");

if (child.ExpressedAsAttribute)
{
// To rename an attribute, we have to fully remove the old one and add a new one.
XmlElement.RemoveAttribute(oldName);
SetElementAsAttributeValue(child);
}
}

/// <summary>
/// If child "element" is actually represented as an attribute, update the value in the corresponding Xml attribute
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions src/Build/Construction/ProjectMetadataElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,14 @@ internal void ChangeName(string newName)
ValidateValidMetadataAsAttributeName(newName, Parent.ElementName, Parent.Location);
}

string oldName = XmlElement.Name;

// Because the element was created from our special XmlDocument, we know it's
// an XmlElementWithLocation.
XmlElementWithLocation newElement = XmlUtilities.RenameXmlElement(XmlElement, newName, XmlElement.NamespaceURI);

ReplaceElement(newElement);
Parent.UpdateElementName(this, oldName);
}

internal static void ValidateValidMetadataAsAttributeName(string name, string parentName, IElementLocation parentLocation)
Expand Down

0 comments on commit 685cba3

Please sign in to comment.