Support Multi-TFM Projects (#13)

This commit is contained in:
Matt Parker
2025-11-18 23:16:13 +10:00
committed by GitHub
parent d17fcb5636
commit e021a2c723
2 changed files with 40 additions and 2 deletions

View File

@@ -23,6 +23,7 @@ using Microsoft.CodeAnalysis.Rename;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Microsoft.Extensions.Logging;
using NuGet.Frameworks;
using Roslyn.LanguageServer.Protocol;
using SharpIDE.Application.Features.Analysis.FixLoaders;
using SharpIDE.Application.Features.Analysis.Razor;
@@ -233,6 +234,7 @@ public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildSe
// The ProjectIds will not match however, so we need to match on FilePath
// Since the ProjectIds don't match, we also need to remap all ProjectReferences to the existing ProjectIds
// same for documents
// TODO: Handle multiple TFMs - loadedProjectInfos would contain multiple projects with the same FilePath
var projectInfosToUpdateWith = loadedProjectInfos.Select(loadedProjectInfo =>
{
var existingProject = _workspace.CurrentSolution.Projects.Single(p => p.FilePath == loadedProjectInfo.FilePath);
@@ -1008,7 +1010,37 @@ public class RoslynAnalysis(ILogger<RoslynAnalysis> logger, BuildService buildSe
private static Project GetProjectForSharpIdeProjectModel(SharpIdeProjectModel projectModel)
{
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == projectModel.FilePath);
return project;
var projectsForProjectPath = _workspace!.CurrentSolution.Projects.Where(s => s.FilePath == projectModel.FilePath).ToList();
if (projectsForProjectPath.Count is 0) throw new InvalidOperationException($"No project found in workspace for project path '{projectModel.FilePath}'");
if (projectsForProjectPath.Count is 1)
{
return projectsForProjectPath[0];
}
// Multiple projects with same path, different TFMs
var projectAndFrameworkList = projectsForProjectPath
.Select(s =>
{
var flavor = s.State.NameAndFlavor.flavor!;
var framework = NuGetFramework.Parse(flavor);
return (Project: s, Framework: framework);
})
.Where(s => s.Framework.IsDesktop() is false) // Exclude .NET Framework projects
.ToList();
if (projectAndFrameworkList.Any(s => s.Framework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp)) // .NET Core project // I would prefer to use Framework.IsNet5Era
{
// remove .net standard projects
projectAndFrameworkList = projectAndFrameworkList
.Where(s => s.Framework.Framework == FrameworkConstants.FrameworkIdentifiers.NetCoreApp)
.ToList();
}
var selectedProject = projectAndFrameworkList
.OrderByDescending(s => s.Framework, NuGetFrameworkSorter.Instance)
.Select(s => s.Project)
.First();
return selectedProject;
}
}

View File

@@ -14,6 +14,12 @@ public static class IntermediateMapper
var serializer = SolutionSerializers.GetSerializerByMoniker(solutionFilePath);
Guard.Against.Null(serializer, nameof(serializer));
var vsSolution = await serializer.OpenAsync(solutionFilePath, cancellationToken);
// Remove any projects that aren't csproj, TODO: Instead of removing, display in the solution explorer that the project type isn't supported
foreach (var vsSolutionSolutionProject in vsSolution.SolutionProjects.Where(s => s.Extension is not ".csproj").ToList())
{
vsSolution.RemoveProject(vsSolutionSolutionProject);
}
var rootFolders = vsSolution.SolutionFolders
.Where(f => f.Parent is null)