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

Compiler does not report unused imports when XML doc comments are disabled #41640

Open
mavasani opened this issue Feb 13, 2020 · 44 comments
Open
Assignees
Labels
Area-IDE Bug Need Design Review The end user experience design needs to be reviewed and approved.
Milestone

Comments

@mavasani
Copy link
Contributor

mavasani commented Feb 13, 2020

#41363 moves the "Remove unnecessary usings" IDE analyzer into the CodeStyle NuGet package, so this analyzer can execute on CI. This analyzer depends on the compiler layer reporting hidden diagnostics (CS8019) for unused usings:

protected override ImmutableArray<SyntaxNode> GetUnnecessaryImports(
SemanticModel model, SyntaxNode root,
Func<SyntaxNode, bool> predicate, CancellationToken cancellationToken)
{
predicate ??= Functions<SyntaxNode>.True;
var diagnostics = model.GetDiagnostics(cancellationToken: cancellationToken);
if (diagnostics.IsEmpty)
{
return ImmutableArray<SyntaxNode>.Empty;
}
var unnecessaryImports = new HashSet<SyntaxNode>();
foreach (var diagnostic in diagnostics)
{
if (diagnostic.Id == "CS8019")
{
if (root.FindNode(diagnostic.Location.SourceSpan) is UsingDirectiveSyntax node && predicate(node))
{
unnecessaryImports.Add(node);
}
}
}
return unnecessaryImports.ToImmutableArray();
}
.

However, the logic in compiler layer that reports these unused usings is guarded on XML doc comments being enabled:

internal override void ReportUnusedImports(SyntaxTree? filterTree, DiagnosticBag diagnostics, CancellationToken cancellationToken)
{
if (_lazyImportInfos != null && filterTree?.Options.DocumentationMode != DocumentationMode.None)
{
foreach (ImportInfo info in _lazyImportInfos)
{
cancellationToken.ThrowIfCancellationRequested();
SyntaxTree infoTree = info.Tree;
if ((filterTree == null || filterTree == infoTree) && infoTree.Options.DocumentationMode != DocumentationMode.None)
{
TextSpan infoSpan = info.Span;
if (!this.IsImportDirectiveUsed(infoTree, infoSpan.Start))
{
ErrorCode code = info.Kind == SyntaxKind.ExternAliasDirective
? ErrorCode.HDN_UnusedExternAlias
: ErrorCode.HDN_UnusedUsingDirective;
diagnostics.Add(code, infoTree.GetLocation(infoSpan));
}
}
}
}
CompleteTrees(filterTree);
}

This logic seems to work fine for IDE-only purpose as XML doc comments are explicitly force enabled in the IDE. However, it breaks down for this same analyzer from command line when XML doc comments are disabled.

I presume this was done as a performance optimization to prevent this code from executing on default command line builds, when XML doc comments are disabled. I see 2 options to retain this performance optimization while fixing the command line case:

  1. Expose a new public API on Compilation or SemanticModel to for unused usings. The existing compiler code can invoke the same functionality wrapped around the XML documentation mode check, and we can move the IDE's unnecessary usings analyzer to use this new API instead of CS8019 diagnostics.
  2. Loosen the compiler layer's guard around the above code to also execute this code when the effective severity of IDE0005 (unnecessary usings IDE diagnostic) is warning or above. This seems more simpler, but also more fragile change.

IMO, option 1. is a much better approach.

@mavasani
Copy link
Contributor Author

Tagging @jcouv @sharwell as they seem to have good context on this IDE analyzer by looking at past issues.

@CyrusNajmabadi
Copy link
Member

I thought we had a flag here to at least tell the compiler to bind the docs, even if we don't want errors or xml generation for them. That way our symbolic information is all correct, regardless of what emit behavior the user specifies.

@sharwell
Copy link
Member

@mavasani The underlying compiler diagnostic (CS8019) is not accurate if XML documentation parsing is disabled. Currently the project can only specify DocumentationMode.None or DocumentationMode.Diagnose. To enable IDE0005 in command line scenarios without enabling XML documentation file output, we need a way to set the documentation mode to DocumentationMode.Parse.

@mavasani
Copy link
Contributor Author

Ah, maybe in that case we can enhance the unused usings analyzer to report a separate diagnostic when IDE0005 is bumped to warning/error but documentation mode is None, which informs the user that XML documentation comments need to be enabled for the project to get accurate IDE0005 on CI. Does that sound reasonable? If so, we can move this issue to Area-IDE.

@jnm2
Copy link
Contributor

jnm2 commented Dec 3, 2021

For people wondering why command-line/CI builds are letting unused usings through, this is what you need to paste into your csproj or Directory.Build.props after adding <EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild> and editorconfig dotnet_diagnostic.IDE0005.severity = warning/error:

    <!-- Workaround for https://github.com/dotnet/roslyn/issues/41640 -->
    <PropertyGroup>
      <GenerateDocumentationFile>true</GenerateDocumentationFile>
      <NoWarn>$(NoWarn);CS1591;CS1573</NoWarn>
    </PropertyGroup>

mavasani added a commit to mavasani/roslyn that referenced this issue Jan 13, 2022
…ngs) on build

Due to dotnet#41640, enabling IDE0005 on build requires users to enable generation of XML documentation comments. Even though this is documented with a note on IDE0005's [doc page](https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005), we have had numerous reports of users not figuring this out and spending lot of cycles fighting with this, especially given other IDE diagnostics work just fine on build. We have had many user reports of the same: dotnet#58103, dotnet#53720, dotnet#57539, OpenRA/OpenRA#19747 and numerous other offline queries.

This change enhances the IDE0005 analyzer to now detect the case when IDE0005 is being reported as a warning or an error in the IDE, but `GenerateDocumentationFile` is `false` for the project, which would mean IDE0005 wouldn't be reported on build. The analyzer reports a special helper diagnostic for this case, which recommends  the user to set this property to `true` in their project file to enable IDE0005 on build. This should reduce the pain for customers who try to enforce IDE0005 on build and get hit by this issue.
@justinmchase
Copy link

dotnet_diagnostic.CS8619.severity = error

Shows up as an error in the IDE but is not reported as an error during the build, even with GenerateDocumentationFile set to true.

Screen Shot 2022-04-07 at 10 03 39 PM

@jnm2
Copy link
Contributor

jnm2 commented Apr 8, 2022

@justinmchase I wouldn't expect GenerateDocumentationFile to have anything to do with that diagnostic. On a side note, does setting https://docs.microsoft.com/en-us/dotnet/core/project-sdk/msbuild-props#enforcecodestyleinbuild in your csproj help?

@justinmchase
Copy link

<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>

Does not cause build errors when the above rule is set to severity = error

HansKindberg added a commit to RegionOrebroLan/Platina-Data that referenced this issue Oct 23, 2023
HansKindberg added a commit to RegionOrebroLan/Organization-Data that referenced this issue Oct 23, 2023
avanwaas added a commit to enigmatry/entry-building-blocks that referenced this issue Oct 24, 2023
…ackages in the building blocks

- disable warning EnableGenerateDocumentationFile introduced in VS 2022 17.7.5 (dotnet/roslyn#41640)
- update packages related to unit testing and code analysis
- fix new code analysis warnings
avanwaas added a commit to enigmatry/entry-building-blocks that referenced this issue Oct 27, 2023
https://enigmatry.atlassian.net/browse/BP-634 Update all .NET nuget packages in the building blocks

- Disable warning EnableGenerateDocumentationFile introduced in VS 2022 17.7.5 (dotnet/roslyn#41640)
- Remove unused packages from Directory.Packages.props
- Remove unused dependency FluentValidation.AspNetCore
- Remove deprecated dependency Microsoft.Rest.ClientRuntime
- Update dependencies:
  * AspNetCore.HealthChecks.System to 7.0.0
  * AutoMapper to 12.0.1
  * Azure.Identity to 1.10.3
  * Azure.Storage.Blobs to 12.18.0
  * CachingFramework.Redis to 15.0.2
  * CachingFramework.Redis.NewtonsoftJson to 15.0.2
  * coverlet.collector to 6.0.0
  * coverlet.msbuild to 6.0.0
  * CsvHelper to 30.0.1
  * EmailValidation to 1.0.10
  * FakeItEasy to 7.4.0
  * FakeItEasy.Analyzer.CSharp to 6.1.1
  * FluentAssertions to 6.12.0
  * FluentValidation to 11.8.0
  * JetBrains.Annotations to 2023.2.0
  * MailKit to 4.2.0
  * MediatR to 12.1.1
  * Microsoft.AspNet.WebApi.Client to 6.0.0
  * Microsoft.AspNetCore.Mvc.NewtonsoftJson to 7.0.13
  * Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation to 7.0.13
  * Microsoft.AspNetCore.Mvc.Testing to 7.0.13
  * Microsoft.EntityFrameworkCore to 7.0.13
  * Microsoft.EntityFrameworkCore.SqlServer to 7.0.13
  * Microsoft.Extensions.Caching.Abstractions to 7.0.0
  * Microsoft.Extensions.Configuration to 7.0.0
  * Microsoft.Extensions.Configuration.Abstractions to 7.0.0
  * Microsoft.Extensions.Configuration.Binder to 7.0.4
  * Microsoft.Extensions.Configuration.EnvironmentVariables to 7.0.0
  * Microsoft.Extensions.Configuration.UserSecrets to 7.0.0
  * Microsoft.Extensions.DependencyInjection to 7.0.0
  * Microsoft.Extensions.FileProviders.Physical to 7.0.0
  * Microsoft.Extensions.Hosting.Abstractions to 7.0.0
  * Microsoft.Extensions.Logging to 7.0.0
  * Microsoft.Extensions.Logging.Abstractions to 7.0.1
  * Microsoft.Extensions.Logging.Console to 7.0.0
  * Microsoft.Extensions.Options to 7.0.1
  * Microsoft.Extensions.Options.ConfigurationExtensions to 7.0.0
  * Microsoft.NET.Test.Sdk to 17.7.2
  * MimeKit to 4.2.0
  * Newtonsoft.Json to 13.0.3
  * NSwag.AspNetCore to 13.20.0
  * NUnit.Analyzers to 3.8.0
  * NUnit3TestAdapter to 4.5.0
  * Polly to 8.0.0
  * Quartz to 3.7.0
  * Quartz.Extensions.DependencyInjection to 3.7.0
  * Quartz.Extensions.Hosting to 3.7.0
  * Serilog to 3.0.1
  * System.Linq.Dynamic.Core to 1.3.5
  * System.Net.Http.Json to 7.0.1
  * Verify.NUnit to 22.1.4
- Fix warnings
MarkMenchavez added a commit to MarkMenchavez/Referentials that referenced this issue Nov 10, 2023
julienasp pushed a commit to julienasp/MoreLINQ that referenced this issue Nov 14, 2023
alexrp added a commit to vezel-dev/zig-sdk that referenced this issue Jan 2, 2024
alexrp added a commit to vezel-dev/zig-sdk that referenced this issue Jan 2, 2024
@VictorioBerra
Copy link

I am struggling a bit. When I set to <GenerateDocumentationFile>true</GenerateDocumentationFile> I still get CS1573,CS1591,CS1712 errors even if I do:

<NoWarn Condition="'$(Language)' == 'C#'">$(NoWarn),1573,1591,1712</NoWarn>.

The only thing that fixes it for me without toggling GenerateDocumentationFile is just <NoWarn>IDE0005</NoWarn>.

What am I doing wrong?

@VictorioBerra
Copy link

VictorioBerra commented Jan 18, 2024

So this works:

<NoWarn>$(NoWarn),CS1591</NoWarn>

But this doesnt:

<NoWarn Condition="'$(Language)' == 'C#'">$(NoWarn),1573,1591,1712</NoWarn>

@sharwell what am I doing wrong?

@sharwell
Copy link
Member

@VictorioBerra I'm guessing you have that line earlier in the build than wherever $(Language) is defined.

@smkanadl
Copy link

@VictorioBerra $(Language) is not supported in a Directory.Build.props but only in a Directory.Build.targets file.

@jnm2
Copy link
Contributor

jnm2 commented Jan 19, 2024

If I remember right, I've used $(MSBuildProjectExtension) for this purpose.

andy840119 added a commit to andy840119/osu-framework-microphone that referenced this issue Feb 19, 2024
…teDocumentationFile: Set MSBuild property 'GenerateDocumentationFile' to 'true' in project file to enable IDE0005 (Remove unnecessary usings/imports) on build (dotnet/roslyn#41640) [/home/runner/work/osu-framework-microphone/osu-framework-microphone/osu.Framework.Microphone/osu.Framework.Microphone.csproj]" error

Also see:
https://github.com/ppy/osu-framework/pull/6169/files
@AraHaan
Copy link
Member

AraHaan commented Feb 21, 2024

I don't like this one but because I do not want things like documentation files to be output when:

I build an winforms project where everything is "internal" visibility

  • has dlls with apis that can be used to load a "plugin interface".
  • said plugin interface is then used to extend the winforms project to add new features to it (although limited) on what can be added to it.
    • plugins themselves are forced to not generate documentation files as well by an msbuild sdk they are then "required" to bring in for application plugin development.

And yes I have an application of this type and the csc warning from doing this annoys me a lot.

As such I feel that forcing a warning for people who WANT to enforce no documentation file to be generated would be a must, or at least a switch to skip copy on it from the intermediate -> output directory.

Edit:

  • It seems .editorconfig cannot be used to silence this warning (dotnet_diagnostic.EnableGenerateDocumentationFile.severity = silent). This is unacceptable.

@sharwell
Copy link
Member

sharwell commented Feb 21, 2024

It seems .editorconfig cannot be used to silence this warning. This is unacceptable.

This is intentional, similar to what would happen if you add the following to your project:

<ItemGroup>
  <Compile Include="ThisFileDoesNotExist.cs"/>
</ItemGroup>

By explicitly providing the compiler with an instruction to enforce IDE0005 at warning (or greater) severity, and then removing its ability to do so by disabling the documentation file output, the project is in an invalid state. Multiple solutions are provided above to return the project to a valid state (either disable the IDE0005 analysis by setting the severity to suggestion or lower, or enable the documentation output).

@AraHaan
Copy link
Member

AraHaan commented Feb 21, 2024

It seems .editorconfig cannot be used to silence this warning. This is unacceptable.

This is intentional, similar to what would happen if you add the following to your project:

<ItemGroup>
  <Compile Include="ThisFileDoesNotExist.cs"/>
</ItemGroup>

By explicitly providing the compiler with an instruction to enforce IDE0005 at warning (or greater) severity, and then removing its ability to do so by disabling the documentation file output, the project is in an invalid state. Multiple solutions are provided above to return the project to a valid state (either disable the IDE0005 analysis by setting the severity to suggestion or lower, or enable the documentation output).

Which is funny because I never really enabled that analysis on it specifically for outside of Visual Studio 😄.

@sharwell
Copy link
Member

sharwell commented Feb 21, 2024

Which is funny because I never really enabled that analysis on it specifically for outside of Visual Studio 😄.

IDE0005 is not enabled at warning severity or greater by default. There are many ways a project could be modified to increase its severity, so without a binlog its difficult to be more specific.

@mwasson74
Copy link

mwasson74 commented Mar 15, 2024

VS 17.9.2 17.9.3 and .NET 8 project and with all of the extra things added, the build is still not failing. Am I missing something?

Edit: Upgraded VS to 17.9.3 with the same results

image

@RenderMichael
Copy link
Contributor

Hi, I'm being affected by this:
image

More specifically, I am generating the documentation file on every project except the testing projects. In my Directory.Build.props file I have

<GenerateDocumentationFile>true</GenerateDocumentationFile>

Directly in the tests project I then set

<GenerateDocumentationFile>false</GenerateDocumentationFile>

Currently I can get around this by NoWarning on EnableGenerateDocumentationFile, but would it be possible to ignore this for projects where GenerateDocumentationFile is explicitly set to false?

@sharwell
Copy link
Member

sharwell commented Jun 13, 2024

@RenderMichael instead of disabling EnableGenerateDocumentationFile, you should either enable documentation output in your test projects or disable IDE0005 in your test projects. As it stands, your test projects have directly instructed the compiler to perform an operation which is not supported, and it is resulting in a warning.

@RenderMichael
Copy link
Contributor

Thanks for the response.

It's not clear from the user side that IDE0005 requires documentation files to be generated. Can the error message include something along the lines of IDE0005 requires documentation files to be generated. Please enable or disable both in this project?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-IDE Bug Need Design Review The end user experience design needs to be reviewed and approved.
Projects
Status: Need Update
IDE: Design review
  
Need Update
Development

No branches or pull requests