How to disable compiler warnings in only generated code without editing file(s)
Asked Answered
R

3

6

I have some generated code that has a bunch of compiler warnings. I want to disable them in the generated file, but keep those warnings in the rest of the project so they can be fixed. I'm using Visual Studio 2019 Community Edition, with the generated files coming from Entity Framework and other NuGet packages.

I want to do this without changing the files, so I won't get the warnings back if they get regenerated. I also don't want to disable the warnings project wide, since they are normally useful warnings. I also don't want to edit the NuGet packages, since that would either require not upgrading them as newer releases are available or possibly having to make changes to the new version.

I've already done plenty of reading, but evidently posting the links is "too much", so I've removed them. Look in the edit history if you want to see them.

The file in question is a Reference.cs for a Connected Service. It has the namespace of Proxy.ProvisioningService and this one file contains a couple of dozen classes. I also have a couple of Entity Framework migration files that have the same problem in a completely different solution.

I have a GlobalSuppressions.cs file that I'd like to add the CS1591 (specifically) to, but my current entry isn't working. Other entries work for other warnings and I've tried variations of the below code to work, including trying to match the format of the other entries, but nothing is working so far. I've changed the "Build" from "Compile", removed the MessageId, changed Scope to be "module", "assembly", and "namespaceanddescendants", and I've tried a couple different ways to set the Target.

[assembly: SuppressMessage("Build", "CS1591:Missing XML comment for publicly visible type or member", Justification = "Generated code", MessageId = "CS1591", Scope = "namespaceanddescendants", Target = "Proxy.ProvisioningService")]

In one of the off-site links, it suggests that I right-click the error, go to Suppress -> In Suppression File, but that's not a listed option. Is that a clue that I can't do it in the GlobalSuppressions.cs file?

I've tried to have Visual Studio 2019 Community Edition automatically suppress the warning by the menu item Analyze -> Build And Suppress Active Issues -> For Project, but that just added a bunch of #pragma directives to the file, which would have to be replaced if the file was regenerated, which I want to avoid.

One of the linked answers suggested writing a script to add the #pragma directives on compile, but that script seems like a hack to me. I'd rather just not edit the generated code at all.

I also don't want to put it in the Project -> Properties -> Build -> Suppress Warnings section, since I want the hand written code to still throw these warnings.

Another SE/SO answer suggests using the GeneratedCodeAttribute attribute to prevent warning from generated files. Unfortunately, my file already has this and it's still throwing the warnings.

Another suggestion was to turn off warnings for these generated files:

To suppress warnings for generated code in a project

  1. Right-click the project in Solution Explorer and then click Properties.

  2. Choose the Code Analysis tab.

  3. Select the Suppress results from generated code check box.

Unfortunately, this option is already selected and not suppressing the CS1591 warning.

So my actual question is:

How can I suppress warnings, specifically CS1591, from generated code files without editing them and without suppressing the warning throughout the whole project?

Rolling answered 25/2, 2021 at 18:37 Comment(24)
You could write your own analyzer?Ietta
But ... you have an answer that works but you apparently dislike it ... which is to add the #pragma in a script. It's generated code anyway, so I don't see why you believe it's a hack. Maybe you should just start liking that approach? I mean, your boss is on your case. Is he going to ask if you fixed it with a "hack"?Nonsuch
@davidbak, no I already said why that's a nogo. If those files get regenerated, the #pragma goes away, so that's not a real solution.Rolling
I thought you said script. As in, part of the build process. Stick it in your makefile.Nonsuch
"If those files get regenerated, the #pragma goes away, so that's not a real solution" -- it's a real solution if you fix the code-gen so that it includes the #pragma as part of the generation, as the suggestion actually was given.Callipash
@PeterDuniho, if I get rid of my research, people will say that I didn't do research, just like the commenter in that other Q.Rolling
@davidbak, do you have a explanation on how to put it in my makefile? A link to an article or something? I've never done that.Rolling
First of all, "people" will say all kinds of things. So what? Secondly, as I have already explained you can share the results of your research adequately without giving us all of the gory details of every single link you visited. Honestly, you're just making the same mistakes you made before.Callipash
See github.com/dotnet/roslyn/issues/12702 maybe useful...Ietta
The search term you want is "makefile chain rules" if you're using make (or any variant).Nonsuch
This is a relevant answer on SO that I got via "makefile chain rules" but google/duckduckgo/etc have more elsewhere ...Nonsuch
@davidbak, I don't think "makefiles" are how I want to go about this. I'm using Visual Studio in a business setting with other devs and don't want to completely change the build process for one solution just to get rid of some warnings. #315053Rolling
Consider this but I bet you can do better ...Nonsuch
@davidbak, I have Visual Studio in my Question a couple of times, and it's a tag.Rolling
Lots of people use visual studio with makefiles or other build systems. Whatever. I believe a good way to proceed is to generate the file you want from the (generated) file you have. You can now look into it now that I've passed that idea to you.Nonsuch
@PeterDuniho, I've removed the links, but I don't know how I can make the explanations of why they didn't work more concise while adding the information you think is missing, which you don't saw what is missing while also saying you didn't read the whole Q. And I used the other person as an example of how using your advice will still get me DVs. You say a lot of generic stuff without providing any concrete info.Rolling
@PeterDuniho, also, how do I "fix the code-gen so that it includes the #pragma as part of the generation" when the code-gen is part of the EF framework? Wouldn't that mean I have to rewrite part of the NuGet package and then not be able to update it when necessary?Rolling
@Codexer, unfortunately that forum thread just goes over the same things I tried that didn't work, with other people having my same problem that didn't work over the 4 years people were making comments. At least I know I'm not the only one with this problem.Rolling
[SuppressMessage] only works for code analysis warnings, CS1591 is not, it is compiler warning. Which does require smarter code generation, either #pragma or a fix for the bad doc comment. Since that is obvious but not considered, global suppression is the likely outcome. Limit its impact by isolating the auto-generated code in its own assembly.Muskrat
@HansPassant, I've worked on solutions that have many different projects for even minor reasons, so I hesitate to split off part of a project for this reason, but it might be the only/best/foreseeable way to do it, since no other option seems to be useful. I still don't want to add #pragma to code-gen files because of the files possibly being regenerated and having to redo the work.Rolling
1) I think you might be able to go a whole career without seeing a Makefile in windows only VS projects (especially .NET ones), some industries definitely don't use them for .NET. 2) A possible solution to the "wall of text" problem is to just link research with a list of short links academic style like [0](link][1](link)[2](link) but it's hard to say. 3) I don't think there's anything wrong with a question of the form "I found this method for solving my problem but I don't like it", that's what research effort looks like honestly.Knotgrass
With that said... generated code is getting close to the kind of territory where a Makefile makes sense. I can sympathize with the annoyance at code generators that emit code that causes nuisance warnings (I have had a similar problem in C++). There wasn't really a solution other than to suppress the warning on the whole file or project (and I edited the CMake script to do just that).Knotgrass
You're in the unfortunate situation of having an obscure, uncool question which is the Roomba's natural prey. Obscure because it clearly has low SEO juice for whatever reason, uncool because the problem it solves is mundane (suppressing a nuisance warning in poorly designed third party code). The real answer is probably "bug the author of the code generator to fix their thing", and readers might be thinking this problem will go away when the code generator is updated. It's not "cool" to hack around somebody else's mistake, not as cool as a hot new language feature.Knotgrass
With that said, I'm not saying 1) it's practical to bug the generator author for a fix for this, 2) you shouldn't try and hack around it or that hacks aren't worth discussing, 3) you shouldn't care about warnings and try and get rid of them, 4) uncool or obscure questions are bad, or 5) what happened here is a good thing, I'm just telling you how it is, SO is vote based and like it or not popularity is a factor in a question's success. Sometimes getting answers to certain things on here is just a waste of time and research effort can't save a question by itself.Knotgrass
C
7

You said that you consider using a script to update the files to add #pragma a hack, but I can't think of another solution.

I think that you can do this easily with a MSBuild Task by adding something like this to your .csproj file:

<Target Name="DisableWarnings" BeforeTargets="CoreCompile">
    <ItemGroup>
        <AutoGeneratedFiles Include="**/*.Designer.cs" />
    </ItemGroup>
    <WriteLinesToFile File="%(AutoGeneratedFiles.FullPath)"
        Condition="!$([System.IO.File]::ReadAllText(%(AutoGeneratedFiles.FullPath)).StartsWith(&quot;#pragma warning&quot;))"
        Lines="$([System.String]::Concat(&quot;#pragma warning disable 1591&quot;,$([System.IO.File]::ReadAllText(%(AutoGeneratedFiles.FullPath))),&quot;#pragma warning restore 1591&quot;))"
        Overwrite="true"
        Encoding="Unicode" />
</Target>

Cleareyed answered 16/3, 2021 at 10:27 Comment(6)
I've added that to my csproj file, but I'm getting an error. I'm using .Net Core 3.1, if that matters. Error MSB4186 Invalid static method invocation syntax: "[System.IO.File]::ReadAllText().StartsWith("#pragma warning")". Method 'System.IO.File.ReadAllText' not found. Static method invocation should be of the form: $([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine(a, b)). Check that all parameters are defined, are of the correct type, and are specified in the right order.Rolling
I think you have this error because it could not find any AutoGeneratedFiles files. In the exemple I put *.Designer.cs to match files generated by resx, but you should change it to match the generated files of your projectCleareyed
Ok. It seems to not throw any errors in another project that definitely does have ".designer.cs" files, but unfortunately those aren't the files throwing the Warning. They are in the ".cs" file for Entity. I'll play around with this to see if I can get this to work. Ex: 20210122181917_Initial.cs I think I'll have to look for those underscores, since I don't think any other files have them except for Entity generated files.Rolling
I've got it working by adding a 2nd AutoGeneratedFiles to include "*/_*.cs" and the Concat first param to be "&quot;#pragma warning disable 1591&#xA;// &lt;auto-generated /&gt;&#xA;&#xA;&quot;". This gives me the auto-generated tag that prevents other warnings and also keeps using and namespace from being ignored as at the end of the pragma statement. If you update, or let me update, your Answer, you'll get the Bounty, unless someone (somehow) comes up with a better Answer. I still consider this a bit hacky, but it's far better than nothing. Thank you for the help!Rolling
I consider it hacky because I'll have to add it to every .csproj file I need it for and I don't like editing those files by hand. But just because I don't like it, it doesn't mean it can't be done or that it doesn't work.Rolling
Directory.Build.targets file in the root of the repo might be a good place for the code. It is included automatically in all the projects. learn.microsoft.com/en-us/visualstudio/msbuild/…Imperishable
I
6

The SuppressMessage attribute works only for code analysis warnings. Its summary goes:

Suppresses reporting of a specific code analysis rule violation, allowing multiple suppressions on a single code artifact. Does not apply to compiler diagnostics.

If there is a file name pattern identifying the generated code, compiler warnings can be suppressed in the generated code using EditorConfig. For example, this is how I disabled the warnings for using obsolete code elements in my generated code -- I still need to suppress the warnings in manually written code using #pragma.

[*.generated.cs]
dotnet_diagnostic.CS0612.severity = none
dotnet_diagnostic.CS0618.severity = none
Imperishable answered 4/4, 2022 at 7:22 Comment(0)
S
1

For a WCF connected service, the simplest solution is probably to not have the warning in the first place.

Since the CS1591 warning is about public types, you could use the dotnet-svcutil tool to generate your Reference.cs file and pass the --internal option so that the generated types are internal instead of public, thus getting rid of CS1591 altogether.

For other tools that generate code, look for a similar option to generate internal types instead of public types. For example, you would use the --assemblyVisible option with the xscgen tool.

Soult answered 9/11, 2022 at 16:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.