dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.71k stars 3.98k forks source link

SourceGenerators: No file emit despite `EmitCompilerGeneratedFiles` & `CompilerGeneratedFilesOutputPath` #69417

Open DoctorVanGogh opened 11 months ago

DoctorVanGogh commented 11 months ago

Version Used: Visual Studio 17.6.5

Steps to Reproduce:

  1. Compile the attached demo solution. It contains & uses a "simple" incremental source generator which will output a Foo.generated.cs file that contains a class Bar which has a static void <..>() {} method for each line from Bar.txt where the text of the line is used as method names. Current lines are x, y & z. The text from the line is repeated for the method name as many times as the Repeats metadata on the AdditionalFiles item for the Bar.txt file. Initial Repeats value is 3, so the generated class will look like:

    public static class Bar {
    
        public static void xxx (){}
    
        public static void yyy (){}
    
        public static void zzz (){}
    
    }

    The source generator consuming project has definitions of

    <PropertyGroup>
        <EmitCompilerGeneratedFiles>True</EmitCompilerGeneratedFiles>               
        <CompilerGeneratedFilesOutputPath>GeneratedSource</CompilerGeneratedFilesOutputPath>                
    </PropertyGroup>

    to output the generated source to a defined location.

Expected Behavior: Compilation and emit of generated source to the file system in the defined subfolder GeneratedSource.

Actual Behavior: Compilation, creation of the GeneratedSource folder (which is initially "missing") but no persisted source files in that folder: Pre compilation: image Post (re)build: image

Additional observations The generated source is correctly displayed in the "Dependencies/Analyzers" node(s): image

The complete lack of persistent emits is a tad baffling, since I have another generator where emit on (re)build works just fine. 🤷 What I did observe though, was that emits do never work on DesignTimeBuilds:

  1. Open the generated source from the `Dependencies\Analyzer" node
  2. Open the metadata defining proj file (typically your csproj, here an imported AnalyzerClient.proj) in a split view: image
  3. Change the Repeats value from 3 to any other value (example 1). Save the edited projfile. This will trigger a DesignTimeBuild: image Note how the repetitions in the method name(s) have changed as well as the updated timestamp.

I have never been able to get an emit to work on design time builds. It always needed a rebuild for emits to work.

This can be quite confusing if you have set up your source generator to react to specific changes in attributes, have included your emitted source in a project and the internal intellisense state (and subsequent compilations) will reflect changes to those attributes, but your "on disc" source will not.

DoctorVanGogh commented 11 months ago

Well, I should probably actually attach that demo solution 😅

AnalyzerDemo.zip

shuaihuadu commented 3 months ago

Same problem, wait for an answer

jjonescz commented 3 months ago

Are you saying the sources are not emitted during design time builds but are emitted otherwise? That sounds like by design behavior.