提交 9e714974 编写于 作者: K KirillOsenkov

Better support for reading ProjectReference items in MSBuildWorkspace.

When MSBuildWorkspace is reading .csproj/.vbproj files, it now doesn't crash if the <Project> metadata item (GUID) on a <ProjectReference> item is not set (there are some project references out there that don't specify a GUID). Since VS allows such project references, we should too.

Also, if <ReferenceOutputAssembly> is set to false, we will now just skip the reference. Earlier we were ignoring this metadata and always adding a reference. (changeset 1211532)
上级 47995fba
......@@ -66,9 +66,11 @@ protected override IEnumerable<ProjectFileReference> GetProjectReferences(Projec
private IEnumerable<ProjectFileReference> GetProjectReferencesCore(ProjectInstance executedProject)
{
foreach (var projectReference in executedProject.GetItems("ProjectReference"))
foreach (var projectReference in GetProjectReferenceItems(executedProject))
{
var guid = Guid.Parse(projectReference.GetMetadataValue("Project"));
Guid guid;
Guid.TryParse(projectReference.GetMetadataValue("Project"), out guid);
var filePath = projectReference.EvaluatedInclude;
string[] aliases;
......
......@@ -217,9 +217,25 @@ protected virtual string GetAssemblyName()
protected virtual IEnumerable<ProjectFileReference> GetProjectReferences(MSB.Execution.ProjectInstance executedProject)
{
return executedProject.GetItems("ProjectReference")
.Select(reference => new ProjectFileReference(Guid.Parse(reference.GetMetadataValue("Project")), reference.EvaluatedInclude))
.ToImmutableList();
var builder = ImmutableList.CreateBuilder<ProjectFileReference>();
foreach (var referenceItem in GetProjectReferenceItems(executedProject))
{
Guid guid;
Guid.TryParse(referenceItem.GetMetadataValue("Project"), out guid);
builder.Add(new ProjectFileReference(guid, referenceItem.EvaluatedInclude));
}
return builder.ToImmutable();
}
protected IEnumerable<ProjectItemInstance> GetProjectReferenceItems(ProjectInstance executedProject)
{
return executedProject
.GetItems("ProjectReference")
.Where(i => !string.Equals(
i.GetMetadataValue("ReferenceOutputAssembly"),
bool.FalseString,
StringComparison.OrdinalIgnoreCase));
}
protected virtual IEnumerable<MSB.Framework.ITaskItem> GetDocumentsFromModel(MSB.Execution.ProjectInstance executedProject)
......
......@@ -5,6 +5,7 @@
using System.IO;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Host;
......@@ -22,6 +23,8 @@ namespace Microsoft.CodeAnalysis.UnitTests
{
public partial class MSBuildWorkspaceTests : TestBase
{
private const string MSBuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestCreateWorkspace()
{
......@@ -1540,6 +1543,79 @@ public void TestProjectReferenceWithExternAlias()
}
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestProjectReferenceWithReferenceOutputAssemblyFalse()
{
var files = GetProjectReferenceSolutionFiles();
files = VisitProjectReferences(files, r =>
{
r.Add(new XElement(XName.Get("ReferenceOutputAssembly", MSBuildNamespace), "false"));
});
CreateFiles(files);
var fullPath = Path.Combine(this.solutionDirectory.Path, @"CSharpProjectReference.sln");
using (var ws = MSBuildWorkspace.Create())
{
var sol = ws.OpenSolutionAsync(fullPath).Result;
foreach (var project in sol.Projects)
{
Assert.Equal(0, project.ProjectReferences.Count());
}
}
}
private FileSet VisitProjectReferences(FileSet files, Action<XElement> visitProjectReference)
{
var result = new List<KeyValuePair<string, object>>();
foreach (var file in files)
{
string text = file.Value.ToString();
if (file.Key.EndsWith("proj", StringComparison.OrdinalIgnoreCase))
{
text = VisitProjectReferences(text, visitProjectReference);
}
result.Add(new KeyValuePair<string, object>(file.Key, text));
}
return new FileSet(result);
}
private string VisitProjectReferences(string projectFileText, Action<XElement> visitProjectReference)
{
var document = XDocument.Parse(projectFileText);
var projectReferenceItems = document.Descendants(XName.Get("ProjectReference", MSBuildNamespace));
foreach (var projectReferenceItem in projectReferenceItems)
{
visitProjectReference(projectReferenceItem);
}
return document.ToString();
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestProjectReferenceWithNoGuid()
{
var files = GetProjectReferenceSolutionFiles();
files = VisitProjectReferences(files, r =>
{
r.Elements(XName.Get("Project", MSBuildNamespace)).Remove();
});
CreateFiles(files);
var fullPath = Path.Combine(this.solutionDirectory.Path, @"CSharpProjectReference.sln");
using (var ws = MSBuildWorkspace.Create())
{
var sol = ws.OpenSolutionAsync(fullPath).Result;
foreach (var project in sol.Projects)
{
Assert.InRange(project.ProjectReferences.Count(), 0, 1);
}
}
}
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestLoadedProjectHasMetadataDocComments()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册