Skip to content

Move Unused Reference analysis out of proc#54935

Merged
JoeRobich merged 10 commits intodotnet:release/dev16.11from
JoeRobich:unused-reference-oop
Jul 21, 2021
Merged

Move Unused Reference analysis out of proc#54935
JoeRobich merged 10 commits intodotnet:release/dev16.11from
JoeRobich:unused-reference-oop

Conversation

@JoeRobich
Copy link
Copy Markdown
Member

@JoeRobich JoeRobich commented Jul 19, 2021

Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1358121 (microsoft)

The issue was caused by dependencies with deep transitive reference trees. The fix was to avoid building a list of all assemblies brought into the compilation by the dependency and to instead traverse the tree checking for various conditions.

@JoeRobich JoeRobich requested review from a team as code owners July 19, 2021 18:05
@ghost ghost added the Area-IDE label Jul 19, 2021
Copy link
Copy Markdown
Contributor

@ryzngard ryzngard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, with minor feedback

Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated
autoReferences ??= ImmutableHashSet<string>.Empty;

var targetLibraryKeys = projectAssets.Targets
.ToImmutableDictionary(t => t.Key, t => t.Value.ToImmutableDictionary(l => l.Key.Split('/')[0], l => l.Key));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this def needs a comment. plus, just blindly splitting/indexing scares me. how do we know this is safe?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment to the effect of "Targets contain a hashmap of Libraries keyed by {LibraryName}/{LibraryVersion} we need to split these keys and create a mapping of LibraryName to the complete library key."

Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/ProjectAssets/ProjectAssetsReader.cs Outdated

if (referenceType == ReferenceType.Package && itemSpecification == ".NETStandard.Library")
{
// This depenedency is large and not useful in determining whether the parent reference has been used.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't really understand the comment. why is this reference not useful in determining if the parent reference was used?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will update the comment, but the way I am thinking about it is that the .NETStandard.Library brings in the entire BCL as dependencies. So, if I reference Newtonsoft.Json and it references .NETStandard.Library, then it isn't useful that I would consider any use of BCL assemblies as a use of Newtonsoft.Json.


builtReferences.Add(reference.ItemSpecification, reference);

return reference;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit of a strange API in that it reference both the reference, but also adds it to a dictionary. i do not like that at all :D can you just return the reference and have someone higher up add to the dictionary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue with moving it is that this method is recursively invoked when building the dependencies list.

Comment thread src/Features/Core/Portable/UnusedReferences/SerializableReferenceInfo.cs Outdated
HashSet<string> usedProjectFileNames = new();

foreach (var project in projects)
var getCompilationTasks = projects.Select(project => project.GetCompilationAsync(cancellationToken));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, ideally parallize on the project, not the compilation level. Here's why, if you do it at the compilation level, then once we're done processing that compilation, we still can't let go of it due to the task holding onto it. If we only hold onto the projec,t the project can release the compilation if not needed.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've decided to revert this change for now and will revisit performance in the future.

Comment thread src/Features/Core/Portable/UnusedReferences/UnusedReferencesRemover.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/UnusedReferencesRemover.cs Outdated
Comment thread src/Features/Core/Portable/UnusedReferences/UnusedReferencesRemover.cs Outdated
Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done with pass.

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

please dont' merge prior to addressing or responding to the updated feedback. thanks! :)

@JoeRobich
Copy link
Copy Markdown
Member Author

@CyrusNajmabadi Thanks for the feedback! I think it is ready for another round when you have time.

@JoeRobich JoeRobich dismissed CyrusNajmabadi’s stale review July 20, 2021 19:30

Addressed Feedback

@JoeRobich JoeRobich merged commit d37aab1 into dotnet:release/dev16.11 Jul 21, 2021
@JoeRobich JoeRobich deleted the unused-reference-oop branch March 14, 2025 23:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants