Skip to content

Support banning namespaces #6521

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

Merged
merged 1 commit into from
Apr 24, 2023
Merged

Support banning namespaces #6521

merged 1 commit into from
Apr 24, 2023

Conversation

Bouke
Copy link

@Bouke Bouke commented Mar 8, 2023

The BannedApiAnalyzer refers to "ID string format" for reference on what symbols to ban. One of those symbols is Namespaces, but this is not supported. As this has been requested before and is also something I ran into earlier today, it seems like a good fit to add to the project.

This will ban everything under namespace A, including child namespaces like A.B and A.B.C. Having an invocation like new A.B.C.D() will yield the error "The symbol 'A' is banned in this project":

N:A

I've chosen to report on the namespace of the symbol instead of the symbol itself for clarity. Reporting the symbol would yield the message "The symbol 'D' is banned in this project" which might be confusing as it is actually any parent namespace that is banned.

This PR should be further tested other than the provided unit tests. I've tried banning System.Threading in the tests, but that didn't work. Could it be that the INamespaceSymbol implements equality other than just a name comparison? Update: this also works now, thanks to @mavasani.

@Bouke Bouke requested a review from a team as a code owner March 8, 2023 22:01
@codecov
Copy link

codecov bot commented Mar 8, 2023

Codecov Report

Merging #6521 (8469f59) into main (fee402d) will decrease coverage by 0.01%.
The diff coverage is 99.30%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6521      +/-   ##
==========================================
- Coverage   96.43%   96.42%   -0.01%     
==========================================
  Files        1373     1373              
  Lines      320260   320477     +217     
  Branches    10296    10302       +6     
==========================================
+ Hits       308837   309029     +192     
- Misses       8969     8985      +16     
- Partials     2454     2463       +9     

@mavasani
Copy link

mavasani commented Mar 9, 2023

This PR should be further tested other than the provided unit tests. I've tried banning System.Threading in the tests, but that didn't work. Could it be that the INamespaceSymbol implements equality other than just a name comparison?

This might be due to the fact that it might be a merged namespace symbol. See https://github.com/dotnet/roslyn/blob/98a00a37e1a66501a1a7495b89853b466668c6b8/src/Compilers/Core/Portable/Symbols/INamespaceSymbol.cs#L49-L60

I think before yield return, you may want to check if namespace's ContainingCompilation matches the compilation being analyzed and if not, iterate ConstituentNamespaces and return the one whose ContainingCompilation matches.

@Bouke
Copy link
Author

Bouke commented Mar 9, 2023

This might be due to the fact that it might be a merged namespace symbol. See https://github.com/dotnet/roslyn/blob/98a00a37e1a66501a1a7495b89853b466668c6b8/src/Compilers/Core/Portable/Symbols/INamespaceSymbol.cs#L49-L60

Thank you for the suggestion. I've tried the code below, but it doesn't fix the problem. Did I misunderstand your suggestion, or could there be something else? Besides the compiled namespace, especially the banned namespace could be a constituent namespace. After expanding the banned namespaces the example with System.Threading works flawlessly.

I haven't went down the route of comparing ContainingCompilation; is there a reason I should be doing that?

@drewnoakes
Copy link
Member

I've chosen to report on the namespace of the symbol instead of the symbol itself for clarity.

Will this produce warnings on the generated code when using implicit global usings?

For example, if I ban Foo then add this to my project:

<ItemGroup>
  <Using Include="Foo"/>
</ItemGroup>

Then in a file like obj\Debug\net7.0\MyProject.GlobalUsings.g.cs there'll be code like:

// <auto-generated/>
global using global::Foo;

After which I can use symbols from the banned namespace in any source file.

If we provide the warning in the generated file, that's fine. But if not, then there is the chance of accidentally bits from banned namespaces.

@Bouke
Copy link
Author

Bouke commented Mar 25, 2023

@drewnoakes The detection of banned APIs doesn't change with this PR. Banning a namespace effectively means the same thing as banning all types within that namespace and its descendants. See also this example on what it means to ban a type. Merely referencing the namespace or a type within that namespace doesn't produce the warning. Only consuming a banned API produces the warning, e.g. invoking a method on a banned type.

@Bouke
Copy link
Author

Bouke commented Apr 6, 2023

I've rebased my PR with the lazy defer work changes from @CyrusNajmabadi. Is there anything else I can do to get this in a shape to be merged?

Copy link
Member

@drewnoakes drewnoakes left a comment

Choose a reason for hiding this comment

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

Thank you for picking this up. Looks good to me.

Copy link

@mavasani mavasani left a comment

Choose a reason for hiding this comment

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

LGTM. I can merge once you address/respond to the suggestions

@Bouke
Copy link
Author

Bouke commented Apr 14, 2023

@mavasani thank you for the review. There's one more thing to clear up and then the PR should be good to go.

@mavasani mavasani merged commit c017fce into dotnet:main Apr 24, 2023
@mavasani
Copy link

Thank you @Bouke!

@github-actions github-actions bot added this to the vNext milestone Apr 24, 2023
@jlaanstra
Copy link

@mavasani I don't think this is part of the latest 3.3.4 NuGet package? Any chance we can ship an update?

@mavasani
Copy link

mavasani commented Aug 8, 2023

@mavasani I don't think this is part of the latest 3.3.4 NuGet package? Any chance we can ship an update?

@jlaanstra That is correct, we'll work on shipping an updated package. Meanwhile, you can use the pre-release version from this feed: https://dev.azure.com/dnceng/public/_artifacts/feed/dotnet8/NuGet/Microsoft.CodeAnalysis.BannedApiAnalyzers/overview/3.11.0-beta1.23407.1

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.

5 participants