0

I have the following pragma in one of the generated C# class and it is used to ignore a CLSCompliant warning

#pragma warning disable 3021

This works perfectly when compiling with msbuild 12. After upgrading my project to use msbuild 14, this warning is enabled again.

It seems to happen with partial class. This how I reproduce:

  1. Create empty project in visual studio 2013(ToolsVersion=12.0)

  2. Add new file TestPragmaFile1.cs with this content:

    namespace TestPragma
    {
        public partial class TestPragma
        {
        }
    }
    
  3. Add new file TestPragmaFile2.cs with this content:

    namespace TestPragma
    {
    
    #pragma warning disable 3021
        [System.CLSCompliant(false)]
        public partial class TestPragma
        {
        }
    }
    

4.Compile by executing this command in the project directory(directory that contains csproj file):

"C:\Program Files (x86)\MSBuild\14.0\Bin\msbuild" /T:Clean;Build

Result:

"C:\Users\me\Documents\Visual Studio 2013\Projects\TestPragma\TestPragma\TestPragma.csproj" (Clean;Build target) (1) -> (CoreCompile target) -> TestPragmaFile1.cs(5,26): warning CS3021: 'TestPragma' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute [C:\Users\me\Documents\Visual Studio 2013\Projects\TestPragma\TestPragma\TestPrag ma.csproj]

1 Warning(s)
0 Error(s)

Can you please help understand why this happens? Is it normal ? how to fix it ?

Mohamed BOUZIDI
  • 125
  • 1
  • 7
  • I can't reproduce this, the `#pragma` works fine for me with MSBuild 14.0.25420.1. Can you share code and maybe also project file that demonstrates this issue? – svick Jul 14 '17 at 23:05
  • Hi @svick, I updated the question with a sample that reproduces what I've seen in a complicated project. It seems to happen when there is partial class defined in more that one file, and the pragma is added where the [System.CLSCompliant(false)] is used. FYI, I cannot remove the generated ClsCompliant attribute since it is generated by ANTLR4. – Mohamed BOUZIDI Jul 18 '17 at 17:30
  • 1
    Here's a crazy thought: why not just give your assembly an `[assembly:CLSCompliant(false)]` attribute? The attribute is generated by default; there seems to be no compelling reason for leaving it out. That should get rid of the warning in the most natural way. – Jeroen Mostert Jul 19 '17 at 14:55
  • I know that if add [assembly:CLSCompliant(false)] to the assembly, it fixes the warning. But I think this a bug in visual studio 2015 compiler since the pragma doesn't work as expected in (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-pragma). – Mohamed BOUZIDI Jul 19 '17 at 15:03
  • The pragma works fine -- the warning is issued for the file that does *not* contain it. The bug (if you can call it that) is that the compiler apparently merges the partial class definitions (including the attributes) and then proceeds to issue the warning on *every* PCD, regardless of whether that has the attribute or not. If you duplicate the pragma in `TestPragmaFile1`, you'll see the warning disappear. – Jeroen Mostert Jul 19 '17 at 15:15
  • 2
    Actually, it's a bit more subtle than that because the compiler will only ever issue the warning once -- but it will issue it for *a* partial class definition, not necessarily the one where you defined the attribute. There may be a method to the definition selected by the compiler, or it may be non-deterministic. The core issue is that attribute definitions are processed across files, but pragmas are specific to particular files, so there's no telling where the warning will happen. Suppressing it on every definition of the class is a viable workaround. (Or just globally, who cares about 3201?) – Jeroen Mostert Jul 19 '17 at 15:29
  • The workaround that I choosed is to add the pragma in both files where the partial class is defined. Thank you @JeroenMostert for your help :) – Mohamed BOUZIDI Jul 19 '17 at 16:04
  • @JeroenMostert You might want to post that as an answer. – svick Jul 20 '17 at 10:12

1 Answers1

0

I solved the issue by adding #pragma warning disable 3021 to the first cs file(TestPragmaFile1.cs).

You may also want to try @JeroenMostert solution by adding [assembly:CLSCompliant(false)] to the assembly.

Mohamed BOUZIDI
  • 125
  • 1
  • 7