Skip to content
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

Make CA1852 aware of InternalsVisibleTo #5972

Merged
merged 1 commit into from
Apr 21, 2022

Conversation

stephentoub
Copy link
Member

Without this there are too many false positives in libraries that use InternalsVisibleTo, in particular to tests.

cc: @GrabYourPitchforks, @mavasani

Without this there are too many false positives in libraries that use InternalsVisibleTo, in particular to tests.
@stephentoub stephentoub requested a review from a team as a code owner April 20, 2022 20:00
@codecov
Copy link

codecov bot commented Apr 20, 2022

Codecov Report

Merging #5972 (9c9f82b) into main (890b7e8) will increase coverage by 0.00%.
The diff coverage is 100.00%.

@@           Coverage Diff           @@
##             main    #5972   +/-   ##
=======================================
  Coverage   96.04%   96.04%           
=======================================
  Files        1325     1325           
  Lines      306082   306091    +9     
  Branches     9693     9694    +1     
=======================================
+ Hits       293973   293985   +12     
+ Misses       9773     9770    -3     
  Partials     2336     2336           

@sharwell
Copy link
Member

💭 It seems like this would negate much of what this rule could be valuable for. In cases where we blanket disable a rule for an entire project, why would it not be reasonable to expect the project with IVTs to just set the severity of this rule to none?

@stephentoub
Copy link
Member Author

It seems like this would negate much of what this rule could be valuable for. In cases where we blanket disable a rule for an entire project, why would it not be reasonable to expect the project with IVTs to just set the severity of this rule to none?

If you're forced to disable the rule for a project that uses IVTs because of false positives, then IMO it's better the rule is disabled to avoid those false positives in the first place. If we wanted to special-case private, we could, but nested types are also the minority here. IVT simply isn't friendly to many such analyses, e.g. the .NET trimmer effectively gives up on internals for IVT assemblies as well.

This is also directly based on the precedent in CA1812:

// If the assembly being built by this compilation exposes its internals to
// any other assembly, don't report any "uninstantiated internal class" errors.
// If we were to report an error for an internal type that is not instantiated
// by this assembly, and then it turned out that the friend assembly did
// instantiate the type, that would be a false positive. We've decided it's
// better to have false negatives (which would happen if the type were *not*
// instantiated by any friend assembly, but we didn't report the issue) than
// to have false positives.
var internalsVisibleToAttributeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesInternalsVisibleToAttribute);
if (compilation.Assembly.HasAttribute(internalsVisibleToAttributeSymbol))
{
return;
}

@sharwell
Copy link
Member

If you're forced to disable the rule for a project that uses IVTs because of false positives

This might apply to some cases. However, I can think of entire solutions (StyleCop Analyzers) where projects have IVT attributes but there are no derived types defined in the test projects. The proposal here forcibly disables a rule in all projects with these characteristics instead of using the existing mechanisms to change the rule severity.

This is also directly based on the precedent in CA1812:

I'm not confident this issue is as common as the one in CA1812. I'm also not sure an automatic exclusion in CA1812 was the right approach either; it does seem to be a documented case though.

@mavasani
Copy link
Contributor

mavasani commented Apr 21, 2022

IMO, these set of analyzers belong to "solution" level or "workspace" level analyzers that we have talked about in the past. Otherwise, these will either be too aggressive (many false positives) or too restrictive (many false negatives).

Until, we can support such category of analyzers, I believe the approach chosen here and in CA1812 to reduce false positives seems reasonable. I also think we should create an editorconfig option (probably also settable via some MSBuildProperty) to bulk configure all or individual IVT based rules to switch from restrictive to aggressive: https://github.com/dotnet/roslyn-analyzers/blob/main/docs/Analyzer%20Configuration.md. @stephentoub can you please create an issue to track adding such an option and an MSBuild property?

@stephentoub stephentoub merged commit 2813545 into dotnet:main Apr 21, 2022
@stephentoub stephentoub deleted the ca1852internals branch April 21, 2022 11:44
@github-actions github-actions bot added this to the vNext milestone Apr 21, 2022
@stephentoub
Copy link
Member Author

@stephentoub can you please create an issue to track adding such an option and an MSBuild property?

Opened #5973

@jmarolf jmarolf modified the milestones: vNext, .NET 7.x Nov 15, 2022
@geeknoid
Copy link
Member

Unfortunately, this change makes the rule nearly useless in our environment :-(

The majority of our components have InternalsVisibleTo for tests, yet near 0% of the tests intend to derive from classes defined in the SUT (which I would expect is the case in most code bases). In effect, this change nullifies the diagnostic for most real-world code bases.

We've had a work item open for a long time to explicitly run a build of our sources with InternalsVisibleTo disabled in order to help dead code analysis, and potentially other analyzers like this one. I guess we need to get that change done...

@stephentoub
Copy link
Member Author

I guess we need to get that change done...

And/or help with #5973 to make it configurable whether IVT is taken into account...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants