提交 91084507 编写于 作者: L Lucas Trzesniewski

Use global properties to iterate over TFMs in MSBuildWorkspace

This ensures that conditions based on the TFM work correctly in MSBuild files
which are included early, like in NuGet props files for instance.

Fixes #39724
上级 89317c67
......@@ -56,13 +56,12 @@ public async Task<ImmutableArray<ProjectFileInfo>> GetProjectFileInfosAsync(Canc
// In this case, we need to iterate through the <TargetFrameworks>, set <TargetFramework> with
// each value, and build the project.
var hasTargetFrameworkProp = _loadedProject.GetProperty(PropertyNames.TargetFramework) != null;
var targetFrameworks = targetFrameworksValue.Split(';');
var results = ImmutableArray.CreateBuilder<ProjectFileInfo>(targetFrameworks.Length);
foreach (var targetFramework in targetFrameworks)
{
_loadedProject.SetProperty(PropertyNames.TargetFramework, targetFramework);
_loadedProject.SetGlobalProperty(PropertyNames.TargetFramework, targetFramework);
_loadedProject.ReevaluateIfNecessary();
var projectFileInfo = await BuildProjectFileInfoAsync(cancellationToken).ConfigureAwait(false);
......@@ -70,18 +69,7 @@ public async Task<ImmutableArray<ProjectFileInfo>> GetProjectFileInfosAsync(Canc
results.Add(projectFileInfo);
}
// Remove the <TargetFramework> property if it didn't exist in the file before we set it.
// Otherwise, set it back to it's original value.
if (!hasTargetFrameworkProp)
{
var targetFrameworkProp = _loadedProject.GetProperty(PropertyNames.TargetFramework);
_loadedProject.RemoveProperty(targetFrameworkProp);
}
else
{
_loadedProject.SetProperty(PropertyNames.TargetFramework, targetFrameworkValue);
}
_loadedProject.RemoveGlobalProperty(PropertyNames.TargetFramework);
_loadedProject.ReevaluateIfNecessary();
return results.ToImmutable();
......
......@@ -213,6 +213,50 @@ public async Task TestOpenProject_NetCoreMultiTFM()
}
}
[ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))]
[Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)]
[Trait(Traits.Feature, Traits.Features.NetCore)]
public async Task TestOpenProject_NetCoreMultiTFM_ExtensionWithConditionOnTFM()
{
CreateFiles(GetNetCoreMultiTFMFiles_ExtensionWithConditionOnTFM());
var projectFilePath = GetSolutionFileName("Project.csproj");
DotNetRestore("Project.csproj");
using (var workspace = CreateMSBuildWorkspace())
{
await workspace.OpenProjectAsync(projectFilePath);
// Assert that three projects have been loaded, one for each TFM.
Assert.Equal(3, workspace.CurrentSolution.ProjectIds.Count);
// Assert the TFM is accessible from project extensions.
// The test project extension sets the default namespace based on the TFM.
foreach (var project in workspace.CurrentSolution.Projects)
{
switch (project.Name)
{
case "Project(netcoreapp2.1)":
Assert.Equal("Project.NetCore", project.DefaultNamespace);
break;
case "Project(netstandard2.0)":
Assert.Equal("Project.NetStandard", project.DefaultNamespace);
break;
case "Project(net461)":
Assert.Equal("Project.NetFramework", project.DefaultNamespace);
break;
default:
Assert.True(false, $"Unexpected project: {project.Name}");
break;
}
}
}
}
[ConditionalFact(typeof(VisualStudioMSBuildInstalled), typeof(DotNetCoreSdk.IsAvailable))]
[Trait(Traits.Feature, Traits.Features.MSBuildWorkspace)]
[Trait(Traits.Feature, Traits.Features.NetCore)]
......
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp2.1;netstandard2.0;net461</TargetFrameworks>
</PropertyGroup>
</Project>
<Project>
<PropertyGroup>
<RootNamespace Condition="'$(TargetFramework)' == 'netcoreapp2.1'">Project.NetCore</RootNamespace>
<RootNamespace Condition="'$(TargetFramework)' == 'netstandard2.0'">Project.NetStandard</RootNamespace>
<RootNamespace Condition="'$(TargetFramework)' == 'net461'">Project.NetFramework</RootNamespace>
</PropertyGroup>
</Project>
......@@ -138,6 +138,8 @@ public static class CSharp
public static string NetCoreApp2AndTwoLibraries_Library1 => GetText("NetCoreApp2AndTwoLibraries.Library1.csproj");
public static string NetCoreApp2AndTwoLibraries_Library2 => GetText("NetCoreApp2AndTwoLibraries.Library2.csproj");
public static string NetCoreMultiTFM_Project => GetText("NetCoreMultiTFM.Project.csproj");
public static string NetCoreMultiTFM_ExtensionWithConditionOnTFM_Project => GetText("NetCoreMultiTFM_ExtensionWithConditionOnTFM.Project.csproj");
public static string NetCoreMultiTFM_ExtensionWithConditionOnTFM_ProjectTestProps => GetText("NetCoreMultiTFM_ExtensionWithConditionOnTFM.Project.csproj.test.props");
public static string NetCoreMultiTFM_ProjectReference_Library => GetText("NetCoreMultiTFM_ProjectReference.Library.csproj");
public static string NetCoreMultiTFM_ProjectReference_Project => GetText("NetCoreMultiTFM_ProjectReference.Project.csproj");
public static string NetCoreMultiTFM_ProjectReferenceToFSharp_CSharpLib = GetText("NetCoreMultiTFM_ProjectReferenceToFSharp.csharplib.csharplib.csproj");
......
......@@ -153,6 +153,16 @@ protected FileSet GetNetCoreMultiTFMFiles()
(@"Program.cs", Resources.SourceFiles.CSharp.NetCoreApp2_Program));
}
protected FileSet GetNetCoreMultiTFMFiles_ExtensionWithConditionOnTFM()
{
return new FileSet(
(@"NuGet.Config", Resources.NuGet_Config),
(@"Directory.Build.props", Resources.Directory_Build_props),
(@"Directory.Build.targets", Resources.Directory_Build_targets),
(@"Project.csproj", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_ExtensionWithConditionOnTFM_Project),
(@"obj\Project.csproj.test.props", Resources.ProjectFiles.CSharp.NetCoreMultiTFM_ExtensionWithConditionOnTFM_ProjectTestProps));
}
protected FileSet GetNetCoreMultiTFMFiles_ProjectReference()
{
return new FileSet(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册