Roslyn: Project.WithProjectReferences and friends allows you to give duplicate references

Created on 20 Jun 2016  路  7Comments  路  Source: dotnet/roslyn

We guard against duplicate references being created in Project.AddProjectReferences and similar APIs, but no similar guarding is done if you call WithProjectReferences. It seems the checks should be added there instead.

Area-IDE Bug Concept-Continuous Improvement help wanted

All 7 comments

There are incorrectly authored projects out there with duplicate project references. SourceBrowser is "finding" them in droves (by hitting the key already exists exception in CompilationTracker).

What's the best way to fix it to not break existing incorrectly authored projects? Dedup the references in WithProjectReferences/AddProjectReferences?

I've already filed a project system suggestion to issue a warning on duplicate references:
https://github.com/dotnet/roslyn-project-system/issues/311

I would say AddProjectReferences/WithProjectReferences should throw (since it's bad data), and MSBuildWorkspace can do the dedup there.

If it helps, this is what I wrote to work around the crash (and it seems to have helped):

        private Solution DeduplicateProjectReferences(Solution solution)
        {
            foreach (var projectId in solution.ProjectIds.ToArray())
            {
                var project = solution.GetProject(projectId);

                var distinctProjectReferences = project.AllProjectReferences.Distinct().ToArray();
                if (distinctProjectReferences.Length < project.AllProjectReferences.Count)
                {
                    var newProject = project.WithProjectReferences(distinctProjectReferences);
                    solution = newProject.Solution;
                }
            }

            return solution;
        }

@mattwar maybe Matt can look into fixing MSBuildWorkspace? I'd send a PR myself but I'm on vacation. Also it probably needs a test.

Alas @KirillOsenkov I am also on vacation.

@KirillOsenkov thanks for the workaround, I was getting this same "task was canceled" error mentioned here https://github.com/dotnet/roslyn/issues/12872.
So I turned on first chance exceptions and caught a System.ArgumentException in mscorlib.dll!System.Collections.Generic.Dictionary.Insert(...) and ended up here.
So, 12872 can be due to duplicate references, @pieroci

Interesting - tagging @CyrusNajmabadi too.

Pulling this back in as we've realized it does actually cause problems.

Was this page helpful?
0 / 5 - 0 ratings