Skip to content

Commit

Permalink
Merge branches 'dev/mipavlik/fix-binlog-outofmemory', 'perf-xml-child…
Browse files Browse the repository at this point in the history
…-enumeration', 'backport/pr-8870-to-vs17.7' and 'dev/michaelshea/sln' into vs17.7
  • Loading branch information
rainersigwald committed Jul 12, 2023
4 parents 4cf11b4 + 4f2a020 + 8ebc5ca + 657005a commit 971bf70
Show file tree
Hide file tree
Showing 32 changed files with 398 additions and 122 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.props
Expand Up @@ -2,7 +2,7 @@
<!-- 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. -->
<Project>
<PropertyGroup>
<VersionPrefix>17.7.0</VersionPrefix><DotNetFinalVersionKind>release</DotNetFinalVersionKind>
<VersionPrefix>17.7.1</VersionPrefix><DotNetFinalVersionKind>release</DotNetFinalVersionKind>
<PackageValidationBaselineVersion>17.6.3</PackageValidationBaselineVersion>
<AssemblyVersion>15.1.0.0</AssemblyVersion>
<PreReleaseVersionLabel>preview</PreReleaseVersionLabel>
Expand Down
1 change: 1 addition & 0 deletions src/BannedSymbols.txt
@@ -1 +1,2 @@
M:System.Globalization.CompareInfo.IndexOf(System.String,System.Char);CompareInfo.IndexOf can unexpectedly allocate strings--use string.IndexOf
P:Microsoft.Build.Construction.ProjectElementContainer.Children;Use ChildrenEnumerable instead to avoid boxing
Expand Up @@ -28,7 +28,7 @@ public void ReadNone()
{
ProjectRootElement project = ProjectRootElement.Create();

Assert.Null(project.Imports.GetEnumerator().Current);
Assert.Empty(project.Imports);
}

/// <summary>
Expand Down
Expand Up @@ -143,7 +143,7 @@ public void ReadNone()
{
ProjectRootElement project = ProjectRootElement.Create();

Assert.Null(project.Imports.GetEnumerator().Current);
Assert.Empty(project.Imports);
}

/// <summary>
Expand All @@ -162,7 +162,7 @@ public void ReadNoChild()

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

Assert.Null(project.Imports.GetEnumerator().Current);
Assert.Empty(project.Imports);
Assert.Equal(0, Helpers.Count(importGroup.Imports));
}

Expand Down
Expand Up @@ -24,7 +24,7 @@ public void ReadNone()
{
ProjectRootElement project = ProjectRootElement.Create();
Assert.Equal(0, Helpers.Count(project.Children));
Assert.Null(project.ItemDefinitionGroups.GetEnumerator().Current);
Assert.Empty(project.ItemDefinitionGroups);
}

/// <summary>
Expand Down
Expand Up @@ -24,7 +24,7 @@ public void ReadNoItemGroup()
{
ProjectRootElement project = ProjectRootElement.Create();
Assert.Equal(0, Helpers.Count(project.Children));
Assert.Null(project.ItemGroups.GetEnumerator().Current);
Assert.Empty(project.ItemGroups);
}

/// <summary>
Expand Down
Expand Up @@ -23,7 +23,7 @@ public void ReadNoPropertyGroup()
{
ProjectRootElement project = ProjectRootElement.Create();
Assert.Equal(0, Helpers.Count(project.Children));
Assert.Null(project.PropertyGroups.GetEnumerator().Current);
Assert.Empty(project.PropertyGroups);
}

/// <summary>
Expand Down
Expand Up @@ -41,7 +41,7 @@ public void AddTargetInvalidName()
public void ReadNoTarget()
{
ProjectRootElement project = ProjectRootElement.Create();
Assert.Null(project.Targets.GetEnumerator().Current);
Assert.Empty(project.Targets);
}

/// <summary>
Expand Down
Expand Up @@ -25,7 +25,7 @@ public void ReadNone()
{
ProjectRootElement project = ProjectRootElement.Create();

Assert.Null(project.UsingTasks.GetEnumerator().Current);
Assert.Empty(project.UsingTasks);
}

/// <summary>
Expand Down
Expand Up @@ -65,7 +65,7 @@ public void ReadEmptyParameterGroup()
UsingTaskParameterGroupElement parameterGroup = GetParameterGroupXml(s_contentEmptyParameterGroup);
Assert.NotNull(parameterGroup);
Assert.Equal(0, parameterGroup.Count);
Assert.Null(parameterGroup.Parameters.GetEnumerator().Current);
Assert.Empty(parameterGroup.Parameters);
}

/// <summary>
Expand Down
99 changes: 98 additions & 1 deletion src/Build.UnitTests/Graph/GetCompatiblePlatformGraph_Tests.cs
Expand Up @@ -27,7 +27,7 @@ namespace Microsoft.Build.Graph.UnitTests
/// <summary>
/// Performs SetPlatform negotiation for all project references when opted
/// in via the EnableDynamicPlatformResolution property.
///
///
/// The static graph mirrors the negotiation during build to determine plartform for each node.
/// These tests mirror GetCompatiblePlatform_Tests.cs in order to make sure they both are in sync.
/// </summary>
Expand Down Expand Up @@ -351,5 +351,102 @@ public void PlatformIsChosenAsDefault()
GetFirstNodeWithProjectNumber(graph, 2).ProjectInstance.GetPropertyValue("Platform").ShouldBe(GetFirstNodeWithProjectNumber(graph, 1).ProjectInstance.GetPropertyValue("Platform"));
}
}

// Validate configurations are defined in project reference protocol
[Fact]
public void SolutionWithoutAllConfigurations()
{
using (TestEnvironment testEnvironment = TestEnvironment.Create())
{
var firstProjectName = "1";
var secondProjectName = "2";
var thirdProjectName = "3";
TransientTestFolder folder = testEnvironment.CreateFolder(createFolder: true);
TransientTestFolder project1Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, firstProjectName), createFolder: true);
TransientTestFolder project1SubFolder = testEnvironment.CreateFolder(Path.Combine(project1Folder.Path, firstProjectName), createFolder: true);
TransientTestFile project1 = testEnvironment.CreateFile(project1SubFolder, $"{firstProjectName}.csproj",
@"<Project>
<PropertyGroup>
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
<Platform>x64</Platform>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include=""$(MSBuildThisFileDirectory)\..\..\2\2\2.proj"" />
<ProjectReference Include=""$(MSBuildThisFileDirectory)\..\..\3\3\3.proj"" />
</ItemGroup>
</Project>
");

TransientTestFolder project2Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, secondProjectName), createFolder: true);
TransientTestFolder project2SubFolder = testEnvironment.CreateFolder(Path.Combine(project2Folder.Path, secondProjectName), createFolder: true);
TransientTestFile project2 = testEnvironment.CreateFile(project2SubFolder, $"{secondProjectName}.proj",
@"<Project>
<PropertyGroup>
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
</Project>
");

TransientTestFolder project3Folder = testEnvironment.CreateFolder(Path.Combine(folder.Path, thirdProjectName), createFolder: true);
TransientTestFolder project3SubFolder = testEnvironment.CreateFolder(Path.Combine(project3Folder.Path, thirdProjectName), createFolder: true);
TransientTestFile project3 = testEnvironment.CreateFile(project3SubFolder, $"{thirdProjectName}.proj",
@"<Project>
<PropertyGroup>
<EnableDynamicPlatformResolution>true</EnableDynamicPlatformResolution>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
</Project>
");


// Slashes here (and in the .slnf) are hardcoded as backslashes intentionally to support the common case.
TransientTestFile solutionFile = testEnvironment.CreateFile(folder, "SimpleProject.sln",
@"
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29326.124
MinimumVisualStudioVersion = 10.0.40219.1
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""Project1"", ""1\1\1.csproj"", ""{79B5EBA6-5D27-4976-BC31-14422245A59A}""
EndProject
Project(""{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"") = ""2"", ""2\2\2.proj"", ""{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}""
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Debug|x64.ActiveCfg = Debug|x64
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Debug|x64.Build.0 = Debug|x64
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Release|x64.ActiveCfg = Release|x64
{79B5EBA6-5D27-4976-BC31-14422245A59A}.Release|x64.Build.0 = Release|x64
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Debug|x64.ActiveCfg = Debug|Any CPU
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Debug|x64.Build.0 = Debug|Any CPU
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Release|x64.ActiveCfg = Release|Any CPU
{8EFCCA22-9D51-4268-90F7-A595E11FCB2D}.Release|x64.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DE7234EC-0C4D-4070-B66A-DCF1B4F0CFEF}
EndGlobalSection
EndGlobal
");

ProjectCollection projectCollection = testEnvironment.CreateProjectCollection().Collection;
MockLogger logger = new();
projectCollection.RegisterLogger(logger);
ProjectGraphEntryPoint entryPoint = new(solutionFile.Path, new Dictionary<string, string>());

// We want to make sure negotiation respects configuration if defined but negotiates if not.
ProjectGraph graphFromSolution = new(entryPoint, projectCollection);
logger.AssertNoErrors();
GetFirstNodeWithProjectNumber(graphFromSolution, 2).ProjectInstance.GetPropertyValue("Platform").ShouldBe("AnyCPU", "Project2 should have followed the sln config to AnyCPU");
GetFirstNodeWithProjectNumber(graphFromSolution, 3).ProjectInstance.GetPropertyValue("Platform").ShouldBe("x64", "Project3 isn't in the solution so it should have negotiated to x64 to match Project1");
}
}
}
}
12 changes: 9 additions & 3 deletions src/Build/BackEnd/TaskExecutionHost/TaskExecutionHost.cs
Expand Up @@ -1395,9 +1395,15 @@ private void GatherTaskItemOutputs(bool outputTargetIsItem, string outputTargetN
// Setting an item spec expects the escaped value, as does setting metadata.
newItem = new ProjectItemInstance(_projectInstance, outputTargetName, EscapingUtilities.Escape(output.ItemSpec), parameterLocationEscaped);

newItem.SetMetadataOnTaskOutput(output.CloneCustomMetadata()
.Cast<DictionaryEntry>()
.Select(x => new KeyValuePair<string, string>((string)x.Key, EscapingUtilities.Escape((string)x.Value))));
newItem.SetMetadataOnTaskOutput(EnumerateMetadata(output.CloneCustomMetadata()));

static IEnumerable<KeyValuePair<string, string>> EnumerateMetadata(IDictionary customMetadata)
{
foreach (DictionaryEntry de in customMetadata)
{
yield return new KeyValuePair<string, string>((string)de.Key, EscapingUtilities.Escape((string)de.Value));
}
}
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/Build/Construction/ProjectChooseElement.cs
Expand Up @@ -3,9 +3,7 @@

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Xml;
using Microsoft.Build.Collections;
using Microsoft.Build.ObjectModelRemoting;
using Microsoft.Build.Shared;

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

/// <summary>
/// Get any Otherwise child.
Expand Down

0 comments on commit 971bf70

Please sign in to comment.