Skip to content

Commit b7c1343

Browse files
authored
Merge branch 'master' into update-roslyn-3.8.0-3
2 parents 2b8ba03 + 433dd17 commit b7c1343

File tree

10 files changed

+180
-6
lines changed

10 files changed

+180
-6
lines changed

src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ public static (ProjectFileInfo, ImmutableArray<MSBuildDiagnostic>, ProjectLoaded
113113
return (null, ImmutableArray<MSBuildDiagnostic>.Empty, null);
114114
}
115115

116-
var (projectInstance, project, diagnostics) = loader.BuildProject(filePath);
116+
var (projectInstance, project, diagnostics) = loader.BuildProject(filePath, projectIdInfo?.SolutionConfiguration);
117117
if (projectInstance == null)
118118
{
119119
return (null, diagnostics, null);
@@ -137,7 +137,7 @@ public static (ProjectFileInfo, ImmutableArray<MSBuildDiagnostic>, ProjectLoaded
137137

138138
public (ProjectFileInfo, ImmutableArray<MSBuildDiagnostic>, ProjectLoadedEventArgs) Reload(ProjectLoader loader)
139139
{
140-
var (projectInstance, project, diagnostics) = loader.BuildProject(FilePath);
140+
var (projectInstance, project, diagnostics) = loader.BuildProject(FilePath, ProjectIdInfo?.SolutionConfiguration);
141141
if (projectInstance == null)
142142
{
143143
return (null, diagnostics, null);

src/OmniSharp.MSBuild/ProjectIdInfo.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using Microsoft.CodeAnalysis;
34

45
namespace OmniSharp.MSBuild
@@ -13,5 +14,12 @@ public ProjectIdInfo(ProjectId id, bool isDefinedInSolution)
1314

1415
public ProjectId Id { get; set; }
1516
public bool IsDefinedInSolution { get; set; }
17+
18+
/// <summary>
19+
/// Project configurations as defined in solution.
20+
/// Keys are solution build configuration in '$(Configuration)|$(Platform)' format,
21+
/// values are according project configurations. Null if there is no solution.
22+
/// </summary>
23+
public IReadOnlyDictionary<string, string> SolutionConfiguration { get; set; }
1624
}
1725
}

src/OmniSharp.MSBuild/ProjectLoader.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ private static Dictionary<string, string> CreateGlobalProperties(
6767
return globalProperties;
6868
}
6969

70-
public (MSB.Execution.ProjectInstance projectInstance, MSB.Evaluation.Project project, ImmutableArray<MSBuildDiagnostic> diagnostics) BuildProject(string filePath)
70+
public (MSB.Execution.ProjectInstance projectInstance, MSB.Evaluation.Project project, ImmutableArray<MSBuildDiagnostic> diagnostics) BuildProject(
71+
string filePath, IReadOnlyDictionary<string, string> configurationsInSolution)
7172
{
7273
using (_sdksPathResolver.SetSdksPathEnvironmentVariable(filePath))
7374
{
74-
var evaluatedProject = EvaluateProjectFileCore(filePath);
75+
var evaluatedProject = EvaluateProjectFileCore(filePath, configurationsInSolution);
7576

7677
SetTargetFrameworkIfNeeded(evaluatedProject);
7778

@@ -115,10 +116,37 @@ public MSB.Evaluation.Project EvaluateProjectFile(string filePath)
115116
}
116117
}
117118

118-
private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath)
119+
private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath, IReadOnlyDictionary<string, string> projectConfigurationsInSolution = null)
119120
{
121+
var localProperties = new Dictionary<string, string>(_globalProperties);
122+
if (projectConfigurationsInSolution != null
123+
&& localProperties.TryGetValue(PropertyNames.Configuration, out string solutionConfiguration))
124+
{
125+
if (!localProperties.TryGetValue(PropertyNames.Platform, out string solutionPlatform))
126+
{
127+
solutionPlatform = "Any CPU";
128+
}
129+
130+
var solutionSelector = $"{solutionConfiguration}|{solutionPlatform}.ActiveCfg";
131+
_logger.LogDebug($"Found configuration `{solutionSelector}` in solution for '{filePath}'.");
132+
133+
if (projectConfigurationsInSolution.TryGetValue(solutionSelector, out string projectSelector))
134+
{
135+
var splitted = projectSelector.Split('|');
136+
if (splitted.Length == 2)
137+
{
138+
var projectConfiguration = splitted[0];
139+
localProperties[PropertyNames.Configuration] = projectConfiguration;
140+
// NOTE: Solution often defines configuration as `Any CPU` whereas project relies on `AnyCPU`
141+
var projectPlatform = splitted[1].Replace("Any CPU", "AnyCPU");
142+
localProperties[PropertyNames.Platform] = projectPlatform;
143+
_logger.LogDebug($"Using configuration from solution: `{projectConfiguration}|{projectPlatform}`");
144+
}
145+
}
146+
}
147+
120148
// Evaluate the MSBuild project
121-
var projectCollection = new MSB.Evaluation.ProjectCollection(_globalProperties);
149+
var projectCollection = new MSB.Evaluation.ProjectCollection(localProperties);
122150

123151
var toolsVersion = _options.ToolsVersion;
124152
if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))

src/OmniSharp.MSBuild/ProjectSystem.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,29 @@ private DotNetInfo GetDotNetInfo()
171171
var processedProjects = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
172172
var result = new List<(string, ProjectIdInfo)>();
173173

174+
var solutionConfigurations = new Dictionary<ProjectId, Dictionary<string, string>>();
175+
foreach (var globalSection in solutionFile.GlobalSections)
176+
{
177+
// Try parse project configurations if they are remapped in solution file
178+
if (globalSection.Name == "ProjectConfigurationPlatforms")
179+
{
180+
_logger.LogDebug($"Parsing ProjectConfigurationPlatforms of '{solutionFilePath}'.");
181+
foreach (var entry in globalSection.Properties)
182+
{
183+
var guid = Guid.Parse(entry.Name.Substring(0, 38));
184+
var projId = ProjectId.CreateFromSerialized(guid);
185+
var solutionConfig = entry.Name.Substring(39);
186+
187+
if (!solutionConfigurations.TryGetValue(projId, out var dict))
188+
{
189+
dict = new Dictionary<string, string>();
190+
solutionConfigurations.Add(projId, dict);
191+
}
192+
dict.Add(solutionConfig, entry.Value);
193+
}
194+
}
195+
}
196+
174197
foreach (var project in solutionFile.Projects)
175198
{
176199
if (project.IsNotSupported)
@@ -192,6 +215,10 @@ private DotNetInfo GetDotNetInfo()
192215
if (string.Equals(Path.GetExtension(projectFilePath), ".csproj", StringComparison.OrdinalIgnoreCase))
193216
{
194217
var projectIdInfo = new ProjectIdInfo(ProjectId.CreateFromSerialized(new Guid(project.ProjectGuid)), true);
218+
if (solutionConfigurations.TryGetValue(projectIdInfo.Id, out var configurations))
219+
{
220+
projectIdInfo.SolutionConfiguration = configurations;
221+
}
195222
result.Add((projectFilePath, projectIdInfo));
196223
}
197224

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<ItemGroup>
4+
<ProjectReference Include="..\Lib\Lib.csproj" />
5+
</ItemGroup>
6+
7+
<PropertyGroup>
8+
<Configurations>Debug1;Release1</Configurations>
9+
</PropertyGroup>
10+
11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release1|AnyCPU'">
12+
<OutputType>Exe</OutputType>
13+
<TargetFramework>netcoreapp2.1</TargetFramework>
14+
</PropertyGroup>
15+
16+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug1|AnyCPU'">
17+
<OutputType>Exe</OutputType>
18+
<TargetFramework>netcoreapp2.1</TargetFramework>
19+
</PropertyGroup>
20+
21+
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
3+
namespace App
4+
{
5+
class Program
6+
{
7+
static void Main(string[] args)
8+
{
9+
Console.WriteLine("Hello World!");
10+
}
11+
}
12+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System;
2+
3+
namespace Lib
4+
{
5+
public class Class1
6+
{
7+
}
8+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Configurations>Debug2;Release2</Configurations>
5+
</PropertyGroup>
6+
7+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release2|AnyCPU'">
8+
<TargetFramework>netstandard1.3</TargetFramework>
9+
</PropertyGroup>
10+
11+
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug2|AnyCPU'">
12+
<TargetFramework>netstandard1.3</TargetFramework>
13+
</PropertyGroup>
14+
15+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Microsoft Visual Studio Solution File, Format Version 12.00
2+
# Visual Studio Version 16
3+
VisualStudioVersion = 16.0.30204.135
4+
MinimumVisualStudioVersion = 15.0.26124.0
5+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}"
6+
EndProject
7+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{CE41561B-5D13-4688-8686-EEFF744BE8B5}"
8+
EndProject
9+
Global
10+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
11+
DebugSln|Any CPU = DebugSln|Any CPU
12+
ReleaseSln|Any CPU = ReleaseSln|Any CPU
13+
EndGlobalSection
14+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
15+
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.DebugSln|Any CPU.ActiveCfg = Debug1|Any CPU
16+
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.DebugSln|Any CPU.Build.0 = Debug1|Any CPU
17+
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.ReleaseSln|Any CPU.ActiveCfg = Release1|Any CPU
18+
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.ReleaseSln|Any CPU.Build.0 = Release1|Any CPU
19+
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.DebugSln|Any CPU.ActiveCfg = Debug2|Any CPU
20+
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.DebugSln|Any CPU.Build.0 = Debug2|Any CPU
21+
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.ReleaseSln|Any CPU.ActiveCfg = Release2|Any CPU
22+
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.ReleaseSln|Any CPU.Build.0 = Release2|Any CPU
23+
EndGlobalSection
24+
GlobalSection(SolutionProperties) = preSolution
25+
HideSolutionNode = FALSE
26+
EndGlobalSection
27+
GlobalSection(ExtensibilityGlobals) = postSolution
28+
SolutionGuid = {D5E71A6E-0C92-4CB1-8260-00DE6C30724F}
29+
EndGlobalSection
30+
EndGlobal

tests/OmniSharp.MSBuild.Tests/WorkspaceInformationTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,31 @@ public async Task TwoProjectsWithSolution()
124124
}
125125
}
126126

127+
[Fact]
128+
public async Task TwoProjectsWithSolutionAndCustomConfigurations()
129+
{
130+
var configData = new Dictionary<string, string> { [$"MsBuild:{nameof(Options.MSBuildOptions.Configuration)}"] = "ReleaseSln" };
131+
using (var testProject = await TestAssets.Instance.GetTestProjectAsync("TwoProjectsWithSolutionAndCustomConfigurations"))
132+
using (var host = CreateMSBuildTestHost(testProject.Directory, configurationData: configData.ToConfiguration()))
133+
{
134+
var workspaceInfo = await host.RequestMSBuildWorkspaceInfoAsync();
135+
136+
Assert.Equal("TwoProjectsWithSolutionAndCustomConfigurations.sln", Path.GetFileName(workspaceInfo.SolutionPath));
137+
Assert.NotNull(workspaceInfo.Projects);
138+
Assert.Equal(2, workspaceInfo.Projects.Count);
139+
140+
var firstProject = workspaceInfo.Projects[0];
141+
Assert.Equal("App.csproj", Path.GetFileName(firstProject.Path));
142+
Assert.Equal(".NETCoreApp,Version=v2.1", firstProject.TargetFramework);
143+
Assert.Equal("netcoreapp2.1", firstProject.TargetFrameworks[0].ShortName);
144+
145+
var secondProject = workspaceInfo.Projects[1];
146+
Assert.Equal("Lib.csproj", Path.GetFileName(secondProject.Path));
147+
Assert.Equal(".NETStandard,Version=v1.3", secondProject.TargetFramework);
148+
Assert.Equal("netstandard1.3", secondProject.TargetFrameworks[0].ShortName);
149+
}
150+
}
151+
127152
[Fact]
128153
public async Task TwoProjectWithGeneratedFile()
129154
{

0 commit comments

Comments
 (0)