提交 33be43fa 编写于 作者: C CyrusNajmabadi

Make loop O(n)

上级 d377f78b
...@@ -351,47 +351,33 @@ internal static class DependentTypeFinder ...@@ -351,47 +351,33 @@ internal static class DependentTypeFinder
IImmutableSet<Project> projects, IImmutableSet<Project> projects,
IEnumerable<ProjectId> projectsThatCouldReferenceType) IEnumerable<ProjectId> projectsThatCouldReferenceType)
{ {
var projectIds = projects.Select(p => p.Id).ToSet();
// We need to search all projects that could reference the type *and* which are
// referenced by some project in the project set.
var dependencyGraph = solution.GetProjectDependencyGraph(); var dependencyGraph = solution.GetProjectDependencyGraph();
foreach (var projectThatCouldReferenceType in projectsThatCouldReferenceType)
{
if (projectIds.Contains(projectThatCouldReferenceType))
{
// We were explicitly asked to search this project, and it's a project that
// could be referencing the type we care about. Definitely search this one.
yield return solution.GetProject(projectThatCouldReferenceType);
}
else if (AnyProjectDependsOn(projects, dependencyGraph, projectThatCouldReferenceType))
{
// While we were not explicitly asked to search 'projectThatCouldReferenceType',
// we do have some project we care about that depends on that project. Because of
// this we need to search 'projectThatCouldReferenceType' in case it introduces
// intermediate types that affect the projects we care about.
yield return solution.GetProject(projectThatCouldReferenceType);
}
}
// No point searching a project if it wasn't a project that could have referenced that
// type in the first place.
}
private static bool AnyProjectDependsOn( // Take the projects that were passed in, and find all the projects that
IImmutableSet<Project> projects, ProjectDependencyGraph dependencyGraph, // they depend on (including themselves). i.e. if we have a solution that
ProjectId projectThatCouldReferenceType) // looks like:
{ // A <- B <- C <- D
foreach (var project in projects) // /
{ // └
var projectsThisProjectDependsOn = dependencyGraph.GetProjectsThatThisProjectTransitivelyDependsOn(project.Id); // E
if (projectsThisProjectDependsOn.Contains(projectThatCouldReferenceType)) // and we're passed in 'B, C, E' as hte project to search, then this set
{ // will be A, B, C, E.
return true; var allProjectsThatTheseProjectsDependOn = projects
} .SelectMany(p => dependencyGraph.GetProjectsThatThisProjectTransitivelyDependsOn(p.Id))
} .Concat(projects.Select(p => p.Id)).ToSet();
return false; // We then intersect this set with the actual set of projects that could reference
// the type. Say this list is B, C, D. The intersection of this list and the above
// one will then be 'B' and 'C'.
//
// In other words, there is no point searching A and E (because they can't even
// reference the type). And there's no point searching 'D' because it can't contribute
// any information that would affect the result in the projects we are asked to search
// within.
return projectsThatCouldReferenceType.Intersect(allProjectsThatTheseProjectsDependOn)
.Select(solution.GetProject)
.ToList();
} }
private static async Task<IEnumerable<INamedTypeSymbol>> FindMetadataTypesInProjectAsync( private static async Task<IEnumerable<INamedTypeSymbol>> FindMetadataTypesInProjectAsync(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册