Skip to content

Commit

Permalink
Merge branch 'master' into update-build-tools-rc1
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeRobich committed Sep 1, 2020
2 parents a549aa5 + 433dd17 commit c165b5f
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/OmniSharp.MSBuild/ProjectFile/ProjectFileInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public static (ProjectFileInfo, ImmutableArray<MSBuildDiagnostic>, ProjectLoaded
return (null, ImmutableArray<MSBuildDiagnostic>.Empty, null);
}

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

public (ProjectFileInfo, ImmutableArray<MSBuildDiagnostic>, ProjectLoadedEventArgs) Reload(ProjectLoader loader)
{
var (projectInstance, project, diagnostics) = loader.BuildProject(FilePath);
var (projectInstance, project, diagnostics) = loader.BuildProject(FilePath, ProjectIdInfo?.SolutionConfiguration);
if (projectInstance == null)
{
return (null, diagnostics, null);
Expand Down
8 changes: 8 additions & 0 deletions src/OmniSharp.MSBuild/ProjectIdInfo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;

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

public ProjectId Id { get; set; }
public bool IsDefinedInSolution { get; set; }

/// <summary>
/// Project configurations as defined in solution.
/// Keys are solution build configuration in '$(Configuration)|$(Platform)' format,
/// values are according project configurations. Null if there is no solution.
/// </summary>
public IReadOnlyDictionary<string, string> SolutionConfiguration { get; set; }
}
}
36 changes: 32 additions & 4 deletions src/OmniSharp.MSBuild/ProjectLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,12 @@ private static Dictionary<string, string> CreateGlobalProperties(
return globalProperties;
}

public (MSB.Execution.ProjectInstance projectInstance, MSB.Evaluation.Project project, ImmutableArray<MSBuildDiagnostic> diagnostics) BuildProject(string filePath)
public (MSB.Execution.ProjectInstance projectInstance, MSB.Evaluation.Project project, ImmutableArray<MSBuildDiagnostic> diagnostics) BuildProject(
string filePath, IReadOnlyDictionary<string, string> configurationsInSolution)
{
using (_sdksPathResolver.SetSdksPathEnvironmentVariable(filePath))
{
var evaluatedProject = EvaluateProjectFileCore(filePath);
var evaluatedProject = EvaluateProjectFileCore(filePath, configurationsInSolution);

SetTargetFrameworkIfNeeded(evaluatedProject);

Expand Down Expand Up @@ -115,10 +116,37 @@ public MSB.Evaluation.Project EvaluateProjectFile(string filePath)
}
}

private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath)
private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath, IReadOnlyDictionary<string, string> projectConfigurationsInSolution = null)
{
var localProperties = new Dictionary<string, string>(_globalProperties);
if (projectConfigurationsInSolution != null
&& localProperties.TryGetValue(PropertyNames.Configuration, out string solutionConfiguration))
{
if (!localProperties.TryGetValue(PropertyNames.Platform, out string solutionPlatform))
{
solutionPlatform = "Any CPU";
}

var solutionSelector = $"{solutionConfiguration}|{solutionPlatform}.ActiveCfg";
_logger.LogDebug($"Found configuration `{solutionSelector}` in solution for '{filePath}'.");

if (projectConfigurationsInSolution.TryGetValue(solutionSelector, out string projectSelector))
{
var splitted = projectSelector.Split('|');
if (splitted.Length == 2)
{
var projectConfiguration = splitted[0];
localProperties[PropertyNames.Configuration] = projectConfiguration;
// NOTE: Solution often defines configuration as `Any CPU` whereas project relies on `AnyCPU`
var projectPlatform = splitted[1].Replace("Any CPU", "AnyCPU");
localProperties[PropertyNames.Platform] = projectPlatform;
_logger.LogDebug($"Using configuration from solution: `{projectConfiguration}|{projectPlatform}`");
}
}
}

// Evaluate the MSBuild project
var projectCollection = new MSB.Evaluation.ProjectCollection(_globalProperties);
var projectCollection = new MSB.Evaluation.ProjectCollection(localProperties);

var toolsVersion = _options.ToolsVersion;
if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))
Expand Down
27 changes: 27 additions & 0 deletions src/OmniSharp.MSBuild/ProjectSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,29 @@ private DotNetInfo GetDotNetInfo()
var processedProjects = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var result = new List<(string, ProjectIdInfo)>();

var solutionConfigurations = new Dictionary<ProjectId, Dictionary<string, string>>();
foreach (var globalSection in solutionFile.GlobalSections)
{
// Try parse project configurations if they are remapped in solution file
if (globalSection.Name == "ProjectConfigurationPlatforms")
{
_logger.LogDebug($"Parsing ProjectConfigurationPlatforms of '{solutionFilePath}'.");
foreach (var entry in globalSection.Properties)
{
var guid = Guid.Parse(entry.Name.Substring(0, 38));
var projId = ProjectId.CreateFromSerialized(guid);
var solutionConfig = entry.Name.Substring(39);

if (!solutionConfigurations.TryGetValue(projId, out var dict))
{
dict = new Dictionary<string, string>();
solutionConfigurations.Add(projId, dict);
}
dict.Add(solutionConfig, entry.Value);
}
}
}

foreach (var project in solutionFile.Projects)
{
if (project.IsNotSupported)
Expand All @@ -192,6 +215,10 @@ private DotNetInfo GetDotNetInfo()
if (string.Equals(Path.GetExtension(projectFilePath), ".csproj", StringComparison.OrdinalIgnoreCase))
{
var projectIdInfo = new ProjectIdInfo(ProjectId.CreateFromSerialized(new Guid(project.ProjectGuid)), true);
if (solutionConfigurations.TryGetValue(projectIdInfo.Id, out var configurations))
{
projectIdInfo.SolutionConfiguration = configurations;
}
result.Add((projectFilePath, projectIdInfo));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\Lib\Lib.csproj" />
</ItemGroup>

<PropertyGroup>
<Configurations>Debug1;Release1</Configurations>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release1|AnyCPU'">
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug1|AnyCPU'">
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace App
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System;

namespace Lib
{
public class Class1
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<Configurations>Debug2;Release2</Configurations>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release2|AnyCPU'">
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug2|AnyCPU'">
<TargetFramework>netstandard1.3</TargetFramework>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30204.135
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "App", "App\App.csproj", "{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lib", "Lib\Lib.csproj", "{CE41561B-5D13-4688-8686-EEFF744BE8B5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
DebugSln|Any CPU = DebugSln|Any CPU
ReleaseSln|Any CPU = ReleaseSln|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.DebugSln|Any CPU.ActiveCfg = Debug1|Any CPU
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.DebugSln|Any CPU.Build.0 = Debug1|Any CPU
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.ReleaseSln|Any CPU.ActiveCfg = Release1|Any CPU
{632DFE45-B56E-4158-8F27-45E2BA0BAFCF}.ReleaseSln|Any CPU.Build.0 = Release1|Any CPU
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.DebugSln|Any CPU.ActiveCfg = Debug2|Any CPU
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.DebugSln|Any CPU.Build.0 = Debug2|Any CPU
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.ReleaseSln|Any CPU.ActiveCfg = Release2|Any CPU
{CE41561B-5D13-4688-8686-EEFF744BE8B5}.ReleaseSln|Any CPU.Build.0 = Release2|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D5E71A6E-0C92-4CB1-8260-00DE6C30724F}
EndGlobalSection
EndGlobal
25 changes: 25 additions & 0 deletions tests/OmniSharp.MSBuild.Tests/WorkspaceInformationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,31 @@ public async Task TwoProjectsWithSolution()
}
}

[Fact]
public async Task TwoProjectsWithSolutionAndCustomConfigurations()
{
var configData = new Dictionary<string, string> { [$"MsBuild:{nameof(Options.MSBuildOptions.Configuration)}"] = "ReleaseSln" };
using (var testProject = await TestAssets.Instance.GetTestProjectAsync("TwoProjectsWithSolutionAndCustomConfigurations"))
using (var host = CreateMSBuildTestHost(testProject.Directory, configurationData: configData.ToConfiguration()))
{
var workspaceInfo = await host.RequestMSBuildWorkspaceInfoAsync();

Assert.Equal("TwoProjectsWithSolutionAndCustomConfigurations.sln", Path.GetFileName(workspaceInfo.SolutionPath));
Assert.NotNull(workspaceInfo.Projects);
Assert.Equal(2, workspaceInfo.Projects.Count);

var firstProject = workspaceInfo.Projects[0];
Assert.Equal("App.csproj", Path.GetFileName(firstProject.Path));
Assert.Equal(".NETCoreApp,Version=v2.1", firstProject.TargetFramework);
Assert.Equal("netcoreapp2.1", firstProject.TargetFrameworks[0].ShortName);

var secondProject = workspaceInfo.Projects[1];
Assert.Equal("Lib.csproj", Path.GetFileName(secondProject.Path));
Assert.Equal(".NETStandard,Version=v1.3", secondProject.TargetFramework);
Assert.Equal("netstandard1.3", secondProject.TargetFrameworks[0].ShortName);
}
}

[Fact]
public async Task TwoProjectWithGeneratedFile()
{
Expand Down

0 comments on commit c165b5f

Please sign in to comment.