-
-
Notifications
You must be signed in to change notification settings - Fork 39
Support traversal projects #207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
3a7a3fa
to
f5a4453
Compare
match pi.GetProperty "IsTraversal" with | ||
| null -> doDesignTimeBuild () | ||
| p when Boolean.Parse(p.EvaluatedValue) = false -> doDesignTimeBuild () | ||
| _ -> yieldTraversalProject () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The core change for the 'classic' workspace loader is here - depending on what kind of project this is we pivot behavior to just finding projectreferences, or doing a full design-time-build.
let getP2PRefs (project) = | ||
match project with | ||
| TraversalProject p -> | ||
let references = | ||
p.Items | ||
|> Seq.filter (fun p -> p.ItemType = "ProjectReference") | ||
|> Seq.toList | ||
|
||
let mappedItems = ResizeArray() | ||
|
||
for item in references do | ||
let relativePath = item.EvaluatedInclude | ||
let fullPath = Path.GetFullPath(relativePath, item.Project.Directory) | ||
|
||
{ | ||
RelativePath = relativePath | ||
ProjectFileName = fullPath | ||
TargetFramework = "" | ||
} | ||
|> mappedItems.Add | ||
|
||
let tfms = | ||
if p.HasMetadata "TargetFramework" then | ||
p.GetMetadataValue "TargetFramework" | ||
Seq.toList mappedItems | ||
|
||
| StandardProject p -> | ||
p.Items | ||
|> Seq.choose (fun p -> | ||
if | ||
p.ItemType | ||
<> "_MSBuildProjectReferenceExistent" | ||
then | ||
None | ||
else | ||
p.GetMetadataValue "TargetFrameworks" | ||
let relativePath = p.EvaluatedInclude | ||
let path = p.GetMetadataValue "FullPath" | ||
|
||
{ | ||
RelativePath = relativePath | ||
ProjectFileName = path | ||
TargetFramework = tfms | ||
} | ||
) | ||
let tfms = | ||
if p.HasMetadata "TargetFramework" then | ||
p.GetMetadataValue "TargetFramework" | ||
else | ||
p.GetMetadataValue "TargetFrameworks" | ||
|
||
let getCompileItems (LoadedProject project) = | ||
project.Items | ||
Some { | ||
RelativePath = relativePath | ||
ProjectFileName = path | ||
TargetFramework = tfms | ||
} | ||
) | ||
|> Seq.toList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only logical operation that we need for Traversal Projects is finding ProjectReferences, which is pretty much just a lookup for ProjectReference
items. Unlike in a 'normal' project, these are able to be used because we don't really have to handle the intricacies of the ProjectReference protocol
|> Seq.choose (fun pn -> | ||
match pn.ProjectInstance.GetProperty("IsTraversal") with | ||
| null -> | ||
ProjectGraphEntryPoint pn.ProjectInstance.FullPath | ||
|> Some | ||
| p -> | ||
match bool.TryParse(p.EvaluatedValue) with | ||
| true, true -> None | ||
| true, false -> | ||
ProjectGraphEntryPoint pn.ProjectInstance.FullPath | ||
|> Some | ||
| false, _ -> None | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the main impact for the graph build loader - if any of the project nodes are traversal projects, editors won't really know what to do with them so just...don't report them.
let referencedProjects = | ||
match project with | ||
| ProjectLoader.LoadedProjectInfo.StandardProjectInfo p -> p.ReferencedProjects | ||
| ProjectLoader.LoadedProjectInfo.TraversalProjectInfo p -> p |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similarly for the standard loader, once we load the outer project if it was a traversal project we can just walk its ProjectReferences instead of creating an entirely new ProjectOptions structure to hold the .ReferencedProjects
member.
Traversal projects are a nice alternative to solutions, but they don't have great IDE support because they lack many of the targets/properties that 'normal' projects have. This PR introduces support for traversal projects basically by detecting them just enough to get their ProjectReferences, and then doing nothing else with them.