Skip to content

Commit 2935bcd

Browse files
authored
Fix setting ProjectMetadataElement.Name (#10673)
* Fix setting ProjectMetadataElement.Name * Fix xmldoc
1 parent 37c8fdb commit 2935bcd

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

src/Build.OM.UnitTests/Construction/ConstructionEditing_Tests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3137,6 +3137,44 @@ public void AddMetadataAsAttributeAndAsElement()
31373137
Helpers.VerifyAssertProjectContent(expected, project);
31383138
}
31393139

3140+
[Fact]
3141+
public void SetMetadataName()
3142+
{
3143+
var project = ProjectRootElement.Create();
3144+
var itemGroup = project.AddItemGroup();
3145+
3146+
var item = itemGroup.AddItem("i1", "i");
3147+
var attributeMetadata = item.AddMetadata("A", "value_a", expressAsAttribute: true);
3148+
var elementMetadata = item.AddMetadata("B", "value_b", expressAsAttribute: false);
3149+
3150+
string expected = """
3151+
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3152+
<ItemGroup>
3153+
<i1 Include="i" A="value_a">
3154+
<B>value_b</B>
3155+
</i1>
3156+
</ItemGroup>
3157+
</Project>
3158+
""";
3159+
3160+
Helpers.VerifyAssertProjectContent(expected, project);
3161+
3162+
attributeMetadata.Name = "A2";
3163+
elementMetadata.Name = "B2";
3164+
3165+
expected = """
3166+
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3167+
<ItemGroup>
3168+
<i1 Include="i" A2="value_a">
3169+
<B2>value_b</B2>
3170+
</i1>
3171+
</ItemGroup>
3172+
</Project>
3173+
""";
3174+
3175+
Helpers.VerifyAssertProjectContent(expected, project);
3176+
}
3177+
31403178
/// <summary>
31413179
/// Legally modify a child whose parent is not parented (should not throw)
31423180
/// </summary>

src/Build/Construction/ProjectElementContainer.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,23 @@ private void SetElementAsAttributeValue(ProjectElement child)
448448
ProjectXmlUtilities.SetOrRemoveAttribute(XmlElement, child.XmlElement.Name, value);
449449
}
450450

451+
/// <summary>
452+
/// If child "element" is actually represented as an attribute, update the name in the corresponding Xml attribute
453+
/// </summary>
454+
/// <param name="child">A child element which might be represented as an attribute</param>
455+
/// <param name="oldName">The old name for the child element</param>
456+
internal void UpdateElementName(ProjectElement child, string oldName)
457+
{
458+
ErrorUtilities.VerifyThrow(Link == null, "External project");
459+
460+
if (child.ExpressedAsAttribute)
461+
{
462+
// To rename an attribute, we have to fully remove the old one and add a new one.
463+
XmlElement.RemoveAttribute(oldName);
464+
SetElementAsAttributeValue(child);
465+
}
466+
}
467+
451468
/// <summary>
452469
/// If child "element" is actually represented as an attribute, update the value in the corresponding Xml attribute
453470
/// </summary>

src/Build/Construction/ProjectMetadataElement.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,14 @@ internal void ChangeName(string newName)
134134
ValidateValidMetadataAsAttributeName(newName, Parent.ElementName, Parent.Location);
135135
}
136136

137+
string oldName = XmlElement.Name;
138+
137139
// Because the element was created from our special XmlDocument, we know it's
138140
// an XmlElementWithLocation.
139141
XmlElementWithLocation newElement = XmlUtilities.RenameXmlElement(XmlElement, newName, XmlElement.NamespaceURI);
140142

141143
ReplaceElement(newElement);
144+
Parent.UpdateElementName(this, oldName);
142145
}
143146

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

0 commit comments

Comments
 (0)