Browse Source

fix: Handle SDK-style project references in WriteSolutionFile()

pull/3502/head
Peter Crabtree 4 months ago
parent
commit
67366fe77a
  1. 28
      ICSharpCode.Decompiler/Solution/SolutionCreator.cs

28
ICSharpCode.Decompiler/Solution/SolutionCreator.cs

@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler.Solution @@ -33,6 +33,7 @@ namespace ICSharpCode.Decompiler.Solution
/// <summary>
/// Writes a solution file to the specified <paramref name="targetFile"/>.
/// Also fixes intra-solution project references in the project files.
/// </summary>
/// <param name="targetFile">The full path of the file to write.</param>
/// <param name="projects">The projects contained in this solution.</param>
@ -164,22 +165,37 @@ namespace ICSharpCode.Decompiler.Solution @@ -164,22 +165,37 @@ namespace ICSharpCode.Decompiler.Solution
{
XDocument projectDoc = XDocument.Load(project.FilePath);
if (projectDoc.Root?.Name.LocalName != "Project")
{
throw new InvalidOperationException(
$"The file {project.FilePath} is not a valid project file, " +
$"no <Project> at the root; could not fix project references.");
}
var sdkStyle = projectDoc.Root.Attribute("Sdk") != null;
var itemGroupTagName = sdkStyle ? "ItemGroup" : ProjectFileNamespace + "ItemGroup";
var referenceTagName = sdkStyle ? "Reference" : ProjectFileNamespace + "Reference";
var referencesItemGroups = projectDoc.Root
.Elements(ProjectFileNamespace + "ItemGroup")
.Where(e => e.Elements(ProjectFileNamespace + "Reference").Any());
.Elements(itemGroupTagName)
.Where(e => e.Elements(referenceTagName).Any())
.ToList();
foreach (var itemGroup in referencesItemGroups)
{
FixProjectReferences(project.FilePath, itemGroup, projectsMap);
FixProjectReferences(project.FilePath, itemGroup, projectsMap, sdkStyle);
}
projectDoc.Save(project.FilePath);
}
}
private static void FixProjectReferences(string projectFilePath, XElement itemGroup, IDictionary<string, ProjectItem> projects)
static void FixProjectReferences(string projectFilePath, XElement itemGroup,
Dictionary<string, ProjectItem> projects, bool sdkStyle)
{
foreach (var item in itemGroup.Elements(ProjectFileNamespace + "Reference").ToList())
var referenceTagName = sdkStyle ? "Reference" : ProjectFileNamespace + "Reference";
foreach (var item in itemGroup.Elements(referenceTagName).ToList())
{
var assemblyName = item.Attribute("Include")?.Value;
if (assemblyName != null && projects.TryGetValue(assemblyName, out var referencedProject))
@ -187,7 +203,7 @@ namespace ICSharpCode.Decompiler.Solution @@ -187,7 +203,7 @@ namespace ICSharpCode.Decompiler.Solution
item.Remove();
var projectReference = new XElement(ProjectFileNamespace + "ProjectReference",
new XElement(ProjectFileNamespace + "Project", referencedProject.Guid.ToString("B").ToUpperInvariant()),
new XElement(ProjectFileNamespace + "Project", referencedProject.Guid.ToString("B").ToLowerInvariant()),
new XElement(ProjectFileNamespace + "Name", referencedProject.ProjectName));
projectReference.SetAttributeValue("Include", GetRelativePath(projectFilePath, referencedProject.FilePath));

Loading…
Cancel
Save