ErrorProne.NET icon indicating copy to clipboard operation
ErrorProne.NET copied to clipboard

[DoNotUseDefaultConstruction] not working

Open bert2 opened this issue 3 years ago • 7 comments

The analyzer that should warn about default constructed structs doesn't seem to work.

namespace ClassLibrary1 {
    using System;

    public class Class1 {
        public void Foo() {
            var s = new MyS();
            Console.WriteLine(s.MyF);
        }
    }

    [DoNotUseDefaultConstruction]
    public readonly struct MyS {
        public readonly int MyF;
        public MyS(int f) => MyF = f;
    }

    public struct OtherS { } // EPS01: Struct 'OtherS' can be made readonly

    [AttributeUsage(AttributeTargets.Struct)]
    public class DoNotUseDefaultConstructionAttribute : Attribute { }
}
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="ErrorProne.NET.CoreAnalyzers" Version="0.1.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="ErrorProne.NET.Structs" Version="0.1.2">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
  </ItemGroup>
</Project>

I'm seeing EPS01 in the above example, so I assume that the struct analyzers are generally working. However I'm not seeing a diagnostic for the line var s = new MyS(); which clearly default-constructs MyS().

Am I doing something wrong?

I also tried the two preview versions: 0.2.0-beta.7 made no difference and 0.3.0-beta.0 crashed:

image

Thanks!

bert2 avatar Jan 10 '21 17:01 bert2

Looking through the source I found that the attribute has to be named NonDefaultableAttribute now. Is that correct?

bert2 avatar Jan 10 '21 17:01 bert2

Even with NonDefaultableAttribute I still don't see that diagnostic. Also tried targeting net5.0, but same outcome.

bert2 avatar Jan 10 '21 17:01 bert2

Ok, I cloned the repo and debugged the NonDefaultableStructsConstructionAnalyzer locally.

When I started the analyzers in the experimental instance I noticed the same behavior: EPS01 was reported, but EPS10 was not. This is because during startup an exception is thrown multiple times for a bunch of analyzers:

FileNotFoundException: 'Could not load file or assembly 'RuntimeContracts, Version=0.1.0.0, Culture=neutral, PublicKeyToken=3d487639874b2199' or one of its dependencies. The system cannot find the file specified.'

The NonDefaultableStructsConstructionAnalyzer is among them, because it derives from DiagnosticAnalyzerBase which uses RuntimeContracts.

No such exception was thrown during the load of MakeStructReadOnlyAnalyzer.

When I comment the line that calls into RuntimeContracts...

https://github.com/SergeyTeplyakov/ErrorProne.NET/blob/775522226c2d17018e4379c2280d18ddfca06888/src/ErrorProne.NET.Core/DiagnosticAnalyzerBase.cs#L43

...then all analyzers are loaded and EPS10 is reported correctly.


It makes sense that RuntimeContracts cannot be found, because it's not part of the VSIX package, the VS installation, or the GAC. However, the VSIX is only for local testing and has nothing to do with the NuGet package that delivers the analyzers, right? In fact, RuntimeContracts.dll is part of both NuGet packages, so I don't understand how VS could run into the same error when loading the analyzers from the package.

So it seems like I was able to reproduce the issue with the experimental instance, but it might just be a coincidence and the actual problem is something else 😐

Is there some kind of log that could show us if there are any assembly load exceptions in the real VS instance?


BTW I had to change the NuGet.config to this in order to build the solution:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="NuGetOrg" value="https://api.nuget.org/v3/index.json" />
    <!-- <add key="roslyn-analyzers" value="https://dotnet.myget.org/F/roslyn-analyzers/api/v3/index.json" /> -->
    <add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
  </packageSources>
</configuration>

bert2 avatar Jan 11 '21 16:01 bert2

I'll take a look into his issue and as a workaround I'll try using ILMerge to avoid any runtime dependencies to RuntomeContracts.dll.

SergeyTeplyakov avatar Jan 11 '21 20:01 SergeyTeplyakov

Could you check with version in master? I ILMerge RuntimeContracts.dll into the analyzer and the issue with the RuntimeContracts.dll should not be happening any more.

SergeyTeplyakov avatar Sep 13 '21 04:09 SergeyTeplyakov

Yup, everything works as expected in the VS experimental instance:

image

Thanks!

bert2 avatar Sep 14 '21 09:09 bert2

The 0.4.0-beta.1 package now works too:

image

Even though it definitely showed those analyzers crashes among the warnings before I tried the master branch in the experimental instance...?

bert2 avatar Sep 14 '21 09:09 bert2