Skip to content

Commit 971bf70

Browse files
committed
Merge branches 'dev/mipavlik/fix-binlog-outofmemory', 'perf-xml-child-enumeration', 'backport/pr-8870-to-vs17.7' and 'dev/michaelshea/sln' into vs17.7
4 parents 4cf11b4 + 4f2a020 + 8ebc5ca + 657005a commit 971bf70

32 files changed

+398
-122
lines changed

eng/Versions.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the MIT license. See License.txt in the project root for full license information. -->
33
<Project>
44
<PropertyGroup>
5-
<VersionPrefix>17.7.0</VersionPrefix><DotNetFinalVersionKind>release</DotNetFinalVersionKind>
5+
<VersionPrefix>17.7.1</VersionPrefix><DotNetFinalVersionKind>release</DotNetFinalVersionKind>
66
<PackageValidationBaselineVersion>17.6.3</PackageValidationBaselineVersion>
77
<AssemblyVersion>15.1.0.0</AssemblyVersion>
88
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>

src/BannedSymbols.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
M:System.Globalization.CompareInfo.IndexOf(System.String,System.Char);CompareInfo.IndexOf can unexpectedly allocate strings--use string.IndexOf
2+
P:Microsoft.Build.Construction.ProjectElementContainer.Children;Use ChildrenEnumerable instead to avoid boxing

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public void ReadNone()
2828
{
2929
ProjectRootElement project = ProjectRootElement.Create();
3030

31-
Assert.Null(project.Imports.GetEnumerator().Current);
31+
Assert.Empty(project.Imports);
3232
}
3333

3434
/// <summary>

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public void ReadNone()
143143
{
144144
ProjectRootElement project = ProjectRootElement.Create();
145145

146-
Assert.Null(project.Imports.GetEnumerator().Current);
146+
Assert.Empty(project.Imports);
147147
}
148148

149149
/// <summary>
@@ -162,7 +162,7 @@ public void ReadNoChild()
162162

163163
ProjectImportGroupElement importGroup = (ProjectImportGroupElement)Helpers.GetFirst(project.ImportGroups);
164164

165-
Assert.Null(project.Imports.GetEnumerator().Current);
165+
Assert.Empty(project.Imports);
166166
Assert.Equal(0, Helpers.Count(importGroup.Imports));
167167
}
168168

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void ReadNone()
2424
{
2525
ProjectRootElement project = ProjectRootElement.Create();
2626
Assert.Equal(0, Helpers.Count(project.Children));
27-
Assert.Null(project.ItemDefinitionGroups.GetEnumerator().Current);
27+
Assert.Empty(project.ItemDefinitionGroups);
2828
}
2929

3030
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public void ReadNoItemGroup()
2424
{
2525
ProjectRootElement project = ProjectRootElement.Create();
2626
Assert.Equal(0, Helpers.Count(project.Children));
27-
Assert.Null(project.ItemGroups.GetEnumerator().Current);
27+
Assert.Empty(project.ItemGroups);
2828
}
2929

3030
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void ReadNoPropertyGroup()
2323
{
2424
ProjectRootElement project = ProjectRootElement.Create();
2525
Assert.Equal(0, Helpers.Count(project.Children));
26-
Assert.Null(project.PropertyGroups.GetEnumerator().Current);
26+
Assert.Empty(project.PropertyGroups);
2727
}
2828

2929
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public void AddTargetInvalidName()
4141
public void ReadNoTarget()
4242
{
4343
ProjectRootElement project = ProjectRootElement.Create();
44-
Assert.Null(project.Targets.GetEnumerator().Current);
44+
Assert.Empty(project.Targets);
4545
}
4646

4747
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public void ReadNone()
2525
{
2626
ProjectRootElement project = ProjectRootElement.Create();
2727

28-
Assert.Null(project.UsingTasks.GetEnumerator().Current);
28+
Assert.Empty(project.UsingTasks);
2929
}
3030

3131
/// <summary>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void ReadEmptyParameterGroup()
6565
UsingTaskParameterGroupElement parameterGroup = GetParameterGroupXml(s_contentEmptyParameterGroup);
6666
Assert.NotNull(parameterGroup);
6767
Assert.Equal(0, parameterGroup.Count);
68-
Assert.Null(parameterGroup.Parameters.GetEnumerator().Current);
68+
Assert.Empty(parameterGroup.Parameters);
6969
}
7070

7171
/// <summary>

src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ namespace Microsoft.Build.Graph.UnitTests
2727
/// <summary>
2828
/// Performs SetPlatform negotiation for all project references when opted
2929
/// in via the EnableDynamicPlatformResolution property.
30-
///
30+
///
3131
/// The static graph mirrors the negotiation during build to determine plartform for each node.
3232
/// These tests mirror GetCompatiblePlatform_Tests.cs in order to make sure they both are in sync.
3333
/// </summary>
@@ -351,5 +351,102 @@ public void PlatformIsChosenAsDefault()
351351
GetFirstNodeWithProjectNumber(graph, 2).ProjectInstance.GetPropertyValue("Platform").ShouldBe(GetFirstNodeWithProjectNumber(graph, 1).ProjectInstance.GetPropertyValue("Platform"));
352352
}
353353
}
354+
355+
// Validate configurations are defined in project reference protocol
356+
[Fact]
357+
public void SolutionWithoutAllConfigurations()
358+
{
359+
using (TestEnvironment testEnvironment = TestEnvironment.Create())
360+
{
361+
var firstProjectName = "1";
362+
var secondProjectName = "2";
363+
var thirdProjectName = "3";
364+
TransientTestFolder folder = testEnvironment.CreateFolder(createFolder: true);
365+
TransientTestFolder project1Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, firstProjectName), createFolder: true);
366+
TransientTestFolder project1SubFolder = testEnvironment.CreateFolder(Path.Combine(project1Folder.Path, firstProjectName), createFolder: true);
367+
TransientTestFile project1 = testEnvironment.CreateFile(project1SubFolder, $"{firstProjectName}.csproj",
368+
@"<Project>
369+
<PropertyGroup>
370+
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
371+
<Platform>x64</Platform>
372+
</PropertyGroup>
373+
<ItemGroup>
374+
<ProjectReference Include=""$(MSBuildThisFileDirectory)\..\..\2\2\2.proj"" />
375+
<ProjectReference Include=""$(MSBuildThisFileDirectory)\..\..\3\3\3.proj"" />
376+
</ItemGroup>
377+
</Project>
378+
");
379+
380+
TransientTestFolder project2Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, secondProjectName), createFolder: true);
381+
TransientTestFolder project2SubFolder = testEnvironment.CreateFolder(Path.Combine(project2Folder.Path, secondProjectName), createFolder: true);
382+
TransientTestFile project2 = testEnvironment.CreateFile(project2SubFolder, $"{secondProjectName}.proj",
383+
@"<Project>
384+
<PropertyGroup>
385+
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
386+
<Platforms>AnyCPU;x64</Platforms>
387+
</PropertyGroup>
388+
</Project>
389+
");
390+
391+
TransientTestFolder project3Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, thirdProjectName), createFolder: true);
392+
TransientTestFolder project3SubFolder = testEnvironment.CreateFolder(Path.Combine(project3Folder.Path, thirdProjectName), createFolder: true);
393+
TransientTestFile project3 = testEnvironment.CreateFile(project3SubFolder, $"{thirdProjectName}.proj",
394+
@"<Project>
395+
<PropertyGroup>
396+
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
397+
<Platforms>AnyCPU;x64</Platforms>
398+
</PropertyGroup>
399+
</Project>
400+
");
401+
402+
403+
// Slashes here (and in the .slnf) are hardcoded as backslashes intentionally to support the common case.
404+
TransientTestFile solutionFile = testEnvironment.CreateFile(folder, "SimpleProject.sln",
405+
@"
406+
Microsoft Visual Studio Solution File, Format Version 12.00
407+
# Visual Studio Version 16
408+
VisualStudioVersion = 16.0.29326.124
409+
MinimumVisualStudioVersion = 10.0.40219.1
410+
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""Project1"", ""1\1\1.csproj"", ""{79B5EBA6-5D27-4976-BC31-14422245A59A}""
411+
EndProject
412+
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""2"", ""2\2\2.proj"", ""{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}""
413+
EndProject
414+
Global
415+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
416+
Debug|x64 = Debug|x64
417+
Release|x64 = Release|x64
418+
EndGlobalSection
419+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
420+
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Debug|x64.ActiveCfg = Debug|x64
421+
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Debug|x64.Build.0 = Debug|x64
422+
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Release|x64.ActiveCfg = Release|x64
423+
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Release|x64.Build.0 = Release|x64
424+
425+
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Debug|x64.ActiveCfg = Debug|Any CPU
426+
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Debug|x64.Build.0 = Debug|Any CPU
427+
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Release|x64.ActiveCfg = Release|Any CPU
428+
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Release|x64.Build.0 = Release|Any CPU
429+
EndGlobalSection
430+
GlobalSection(SolutionProperties) = preSolution
431+
HideSolutionNode = FALSE
432+
EndGlobalSection
433+
GlobalSection(ExtensibilityGlobals) = postSolution
434+
SolutionGuid = {DE7234EC-0C4D-4070-B66A-DCF1B4F0CFEF}
435+
EndGlobalSection
436+
EndGlobal
437+
");
438+
439+
ProjectCollection projectCollection = testEnvironment.CreateProjectCollection().Collection;
440+
MockLogger logger = new();
441+
projectCollection.RegisterLogger(logger);
442+
ProjectGraphEntryPoint entryPoint = new(solutionFile.Path, new Dictionary<string, string>());
443+
444+
// We want to make sure negotiation respects configuration if defined but negotiates if not.
445+
ProjectGraph graphFromSolution = new(entryPoint, projectCollection);
446+
logger.AssertNoErrors();
447+
GetFirstNodeWithProjectNumber(graphFromSolution, 2).ProjectInstance.GetPropertyValue("Platform").ShouldBe("AnyCPU", "Project2 should have followed the sln config to AnyCPU");
448+
GetFirstNodeWithProjectNumber(graphFromSolution, 3).ProjectInstance.GetPropertyValue("Platform").ShouldBe("x64", "Project3 isn't in the solution so it should have negotiated to x64 to match Project1");
449+
}
450+
}
354451
}
355452
}

src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,9 +1395,15 @@ private void GatherTaskItemOutputs(bool outputTargetIsItem, string outputTargetN
13951395
// Setting an item spec expects the escaped value, as does setting metadata.
13961396
newItem = new ProjectItemInstance(_projectInstance, outputTargetName, EscapingUtilities.Escape(output.ItemSpec), parameterLocationEscaped);
13971397

1398-
newItem.SetMetadataOnTaskOutput(output.CloneCustomMetadata()
1399-
.Cast<DictionaryEntry>()
1400-
.Select(x => new KeyValuePair<string, string>((string)x.Key, EscapingUtilities.Escape((string)x.Value))));
1398+
newItem.SetMetadataOnTaskOutput(EnumerateMetadata(output.CloneCustomMetadata()));
1399+
1400+
static IEnumerable<KeyValuePair<string, string>> EnumerateMetadata(IDictionary customMetadata)
1401+
{
1402+
foreach (DictionaryEntry de in customMetadata)
1403+
{
1404+
yield return new KeyValuePair<string, string>((string)de.Key, EscapingUtilities.Escape((string)de.Value));
1405+
}
1406+
}
14011407
}
14021408
}
14031409

src/Build/Construction/ProjectChooseElement.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.Diagnostics;
6-
using System.Linq;
76
using System.Xml;
8-
using Microsoft.Build.Collections;
97
using Microsoft.Build.ObjectModelRemoting;
108
using Microsoft.Build.Shared;
119

@@ -60,7 +58,7 @@ public override string Condition
6058
/// Get the When children.
6159
/// Will contain at least one entry.
6260
/// </summary>
63-
public ICollection<ProjectWhenElement> WhenElements => new ReadOnlyCollection<ProjectWhenElement>(Children.OfType<ProjectWhenElement>());
61+
public ICollection<ProjectWhenElement> WhenElements => GetChildrenOfType<ProjectWhenElement>();
6462

6563
/// <summary>
6664
/// Get any Otherwise child.

0 commit comments

Comments
 (0)