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

Source Generators Not Generating Sources #49249

Open
daemogar opened this issue Nov 9, 2020 · 105 comments
Open

Source Generators Not Generating Sources #49249

daemogar opened this issue Nov 9, 2020 · 105 comments

Comments

@daemogar
Copy link

daemogar commented Nov 9, 2020

I am having trouble getting the source generators to run/work. I am not sure what is not working. I have been working on this off and on for several days, and then today when I open the solution it just had worked at some point. Not sure if it was while opening the project or what caused the success. I went and added a new file to create a new source generator and then nothing. Now when I build the project, I get the following warning when building:

warning CS8032: An instance of analyzer SampleSourceGenerators.HelloWorldGenerator cannot be created from C:\Users\daemogar\Source\Repos\BlazorSamples\SampleSourceGenerators\bin\Debug\net5.0\SampleSourceGenerators.dll : Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

I have added this project to my sample Blazor app github repo so the issue can be easily duplicated.
Sample Source Generator Project

I created this source generator project, added it to my solution, and modified the associated SampleSourceGenerators.csproj file to be as shown below. I also added the sample HelloWorldGenerator.cs by copy/paste from the online examples. I then went to the project where I wanted to use the generated source and added the modification shown below to the Website.Server.csproj.

I initially was using VSCode 1.51.0, but with source generators, I switched over to using Visual Studio 2019 Preview 6 since I am not aware of source generators working in VSCode yet. I am also using the .NET SDK framework 5.0.100-rc.2.20479.15.

Build Output Window

Build started...
1>------ Build started: Project: SampleSourceGenerators, Configuration: Debug Any CPU ------
1>You are using a preview version of .NET. See: https://aka.ms/dotnet-core-preview
1>SampleSourceGenerators -> C:\Users\daemogar\Source\Repos\BlazorSamples\SampleSourceGenerators\bin\Debug\net5.0\SampleSourceGenerators.dll
2>------ Build started: Project: WebSite.Server, Configuration: Debug Any CPU ------
2>CSC : warning CS8032: An instance of analyzer SampleSourceGenerators.HelloWorldGenerator cannot be created from C:\Users\daemogar\Source\Repos\BlazorSamples\SampleSourceGenerators\bin\Debug\net5.0\SampleSourceGenerators.dll : Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified..
2>CSC : warning CS8032: An instance of analyzer SampleSourceGenerators.HelloWorldGenerator cannot be created from C:\Users\daemogar\Source\Repos\BlazorSamples\SampleSourceGenerators\bin\Debug\net5.0\SampleSourceGenerators.dll : Could not load file or assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified..
2>WebSite.Server -> C:\Users\daemogar\Source\Repos\BlazorSamples\SampleHostedApplication\WebSite\Server\bin\Debug\net5.0\WebSite.Server.dll
2>WebSite.Server -> C:\Users\daemogar\Source\Repos\BlazorSamples\SampleHostedApplication\WebSite\Server\bin\Debug\net5.0\WebSite.Server.Views.dll
2>Done building project "WebSite.Server.csproj".
========== Build: 2 succeeded, 0 failed, 3 up-to-date, 0 skipped ==========

SampleSourceGenerators/SampleSourceGenerators.csproj

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>net5.0</TargetFramework>
		<LangVersion>preview</LangVersion>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0-5.final" PrivateAssets="all" />
		<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.1" PrivateAssets="all" />
	</ItemGroup>

</Project>

SampleHostedApplication/Website/Server/Website.Server.csproj

<ItemGroup>
	<ProjectReference Include="..\..\..\SampleSourceGenerators\SampleSourceGenerators.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

dotnet --info

.NET SDK (reflecting any global.json):
 Version:   5.0.100-rc.2.20479.15
 Commit:    da7dfa8840

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\5.0.100-rc.2.20479.15\

Host (useful for support):
  Version: 5.0.0-rc.2.20475.5
  Commit:  c5a3f49c88

.NET SDKs installed:
  1.0.0-preview1-002702 [C:\Program Files\dotnet\sdk]
  1.0.0-preview2-003121 [C:\Program Files\dotnet\sdk]
  1.0.0-preview2-003131 [C:\Program Files\dotnet\sdk]
  1.0.1 [C:\Program Files\dotnet\sdk]
  1.0.2 [C:\Program Files\dotnet\sdk]
  1.0.4 [C:\Program Files\dotnet\sdk]
  1.1.0 [C:\Program Files\dotnet\sdk]
  2.0.2 [C:\Program Files\dotnet\sdk]
  2.0.3 [C:\Program Files\dotnet\sdk]
  2.1.2 [C:\Program Files\dotnet\sdk]
  2.1.4 [C:\Program Files\dotnet\sdk]
  2.1.101 [C:\Program Files\dotnet\sdk]
  2.1.103 [C:\Program Files\dotnet\sdk]
  2.1.104 [C:\Program Files\dotnet\sdk]
  2.1.200 [C:\Program Files\dotnet\sdk]
  2.1.201 [C:\Program Files\dotnet\sdk]
  2.1.202 [C:\Program Files\dotnet\sdk]
  2.1.400 [C:\Program Files\dotnet\sdk]
  2.1.401 [C:\Program Files\dotnet\sdk]
  2.1.402 [C:\Program Files\dotnet\sdk]
  2.1.403 [C:\Program Files\dotnet\sdk]
  2.1.500 [C:\Program Files\dotnet\sdk]
  2.1.502 [C:\Program Files\dotnet\sdk]
  2.1.503 [C:\Program Files\dotnet\sdk]
  2.1.504 [C:\Program Files\dotnet\sdk]
  2.1.505 [C:\Program Files\dotnet\sdk]
  2.1.507 [C:\Program Files\dotnet\sdk]
  2.1.508 [C:\Program Files\dotnet\sdk]
  2.1.509 [C:\Program Files\dotnet\sdk]
  2.1.512 [C:\Program Files\dotnet\sdk]
  2.1.514 [C:\Program Files\dotnet\sdk]
  2.1.517 [C:\Program Files\dotnet\sdk]
  2.1.602 [C:\Program Files\dotnet\sdk]
  2.1.604 [C:\Program Files\dotnet\sdk]
  2.1.700 [C:\Program Files\dotnet\sdk]
  2.1.801 [C:\Program Files\dotnet\sdk]
  3.1.300 [C:\Program Files\dotnet\sdk]
  3.1.302 [C:\Program Files\dotnet\sdk]
  3.1.402 [C:\Program Files\dotnet\sdk]
  5.0.100-preview.8.20417.9 [C:\Program Files\dotnet\sdk]
  5.0.100-rc.1.20452.10 [C:\Program Files\dotnet\sdk]
  5.0.100-rc.2.20479.15 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.1.22 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.1.22 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0-preview.8.20414.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0-rc.1.20451.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.0-rc.2.20475.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 1.0.0-rc2-3002702 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.0.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.3-servicing-26724-03 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.12 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.13 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.16 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.18 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.1.22 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0-preview.8.20407.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0-rc.1.20451.14 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.0-rc.2.20475.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.0-preview.8.20411.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.0-rc.1.20452.2 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.0-rc.2.20475.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
@javiercn javiercn transferred this issue from dotnet/aspnetcore Nov 9, 2020
@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Nov 9, 2020
@sharwell
Copy link
Member

sharwell commented Nov 9, 2020

<TargetFramework>net5.0</TargetFramework>

Source generators must target netstandard2.0.

@sharwell
Copy link
Member

sharwell commented Nov 9, 2020

@jasonmalinowski @chsienki this seems like a case where the wrong error is getting reported for an incorrectly targeted source generator.

@sharwell sharwell added Bug Feature - Source Generators Source Generators and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Nov 9, 2020
@daemogar
Copy link
Author

The project has been updated to use netstandard2.0 and the error is gone; however, the generated source does not appear to be able, nor do I see it in the obj/bin folders (when I used net5.0 I saw the generated file in the obj folder).

@daemogar
Copy link
Author

I did more testing last night, and it appears that the sources are being generated (basically). Changes or new sources are not available until closing and reopening Visual Studio.

Once restarted, I have access to the generated source like in all the samples. I can [control]-[click] on it and it takes me to the generated source and I can see it even after making a change to the generator, it appears to update (most of the time, it is not reliable). That being said, it still requires me to relaunch Visual Studio to use the latest source.

Example Experience/Scenario

I have a generator that makes a class SampleClass with a static method SampleMethod() and all it does is Debug.WriteLine("test"); It never shows up in Visual Studio but I can tell it generates cause I will see issues in the output window. I have to clean the solution and build the project, close and reopen Visual Studio, and most of the time, the code is available. Now, I can use it in my project. All basically well. I decide to change the text "test" to "something else". I cannot tell if it worked or not, but clean and build again just in case (I have also tried skipping this step with the same results). When I [control]-[click] on the method where I use it, it shows the change, but when I run the code, it has not changed; however, when I restart Visual Studio it works just fine (the change is realized).

@jasonmalinowski
Copy link
Member

Source generators must target netstandard2.0.

So we outright blocked things targeting the .NET Framework; @chsienki I believe the block doesn't block .NET Core referencing ones, albeit it won't really work in VS for Windows?

I am not aware of source generators working in VSCode yet.

The experience is a bit rougher there, but as long as you have the latest C# Extension installed you should have basics working fine.

That being said, it still requires me to relaunch Visual Studio to use the latest source.

Yeah, the one limitation we have in VS due to .NET limitations is once we've loaded your generator into our process, we don't have a way to unload it at this point. #48083 is another example of that too.

@pr8x
Copy link

pr8x commented Dec 17, 2020

Experiencing the same problem. The source generator is definitely executed (verified with Debugger.Launch()), but the file is never generated. I am using the hello world example from here. Even searched the entire disk but couldn't find a file generated with the hint I gave it. Is there anything I am missing?

Visual Studio: Version 16.8.3
SDK: 5.0.101

@lidgren
Copy link

lidgren commented Dec 29, 2020

+1 I am also unable to generate any content after upgrading to latest visual studio.

@mstancombe
Copy link

So we outright blocked things targeting the .NET Framework; @chsienki I believe the block doesn't block .NET Core referencing ones, albeit it won't really work in VS for Windows?

@jasonmalinowski Will support for projects targeting .net 5 be coming in the future?

@jasonmalinowski
Copy link
Member

@mstancombe just to make it clear (since your question can be read two ways), a generator can run in a project targeting any framework. The generator itself must target netstandard2.0. The problem with moving that forward is generators today run in places that aren't .NET Core/.NET 5: they run in Visual Studio itself (which is still a .NET Framework app as of this writing), and other places. Do you have need for the generator to target something newer?

@mstancombe
Copy link

@jasonmalinowski I guess our issue was we wanted to use the source generator to use some classes in another internal library that was targetting net5, not .net standard, and as the source generator has to target netstandard 2.0, then the other internal library now has to target netstandard 2.0, which sets off a chain of retargetting.
I can see why you need to use netstandard 2.0 if they are to work in vs2019 as well as vscode. It was just a bit suprising that it didn't work. Thanks for clarifying why it targets net standard 2.0, and hopefully that clarifies why we wanted to target it to net5 :)

@AraHaan
Copy link
Member

AraHaan commented Mar 29, 2021

My source generator seems to have the problem despite calling ->

var generated = string.Format(
    CultureInfo.InvariantCulture,
    "// <autogenerated/>{0}{1}{0}{0}[assembly: GitInformationAttribute(\"{2}\", \"{3}\", \"{4}\", typeof({5}{6}))]{0}",
    Environment.NewLine,
    splittedLen > 0 && !string.Equals(
        gitinformationNamespace,
        usingStr.ToString(),
        StringComparison.Ordinal) ? $"using {usingStr};{Environment.NewLine}using {gitinformationNamespace};" : $"using {gitinformationNamespace};",
    this.RunGit("describe --all --always --dirty", Directory.GetParent(gitBuildInfoJsonFile.Path).FullName),
    this.RunGit("rev-parse --short HEAD", Directory.GetParent(gitBuildInfoJsonFile.Path).FullName),
    this.RunGit("name-rev --name-only HEAD", Directory.GetParent(gitBuildInfoJsonFile.Path).FullName),
    splittedLen > 0 ? splitted[splittedLen - 1] : options!.AssemblyType,
    options!.IsGeneric ? "<>" : string.Empty);
context.AddSource("GitAssemblyInfo.g.cs", SourceText.From(generated, Encoding.UTF8));

Yes I use manual string because I do not know how (other than UsingDelclarations for adding usings programmically using roslyn code instead of doing strings like this) to add attributes to be applied assembly level itself.

Yes I should use _ = context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.projectdir", out var projectdir); instead of Directory.GetParent(gitBuildInfoJsonFile.Path).FullName to get the value from the ProjectDir msbuild property.

A way to somehow fix this would be appreciated, for some reason cswin32 displays them but for me vs2019 16.10 preview says my source generator is not generating files.

And yes it uses System.Diagnostics.Process to run those git commands.

@sharwell
Copy link
Member

sharwell commented Mar 30, 2021

@AraHaan source generators must not perform file I/O, either directly (e.g. File.Read) or indirectly (e.g. through git). If your generator has any I/O, the resulting behavior is undefined.

A way to somehow fix this would be appreciated

You can use Nerdbank.GitVersioning to inject Git properties as build properties, that can then be declared as compiler-visible properties accessed through GlobalOptions. It is unlikely that it will ever be possible to invoke Git directly from a source generator.

@AraHaan
Copy link
Member

AraHaan commented Mar 30, 2021

@AraHaan source generators must not perform file I/O, either directly (e.g. File.Read) or indirectly (e.g. through git). If your generator has any I/O, the resulting behavior is undefined.

A way to somehow fix this would be appreciated

You can use Nerdbank.GitVersioning to inject Git properties as build properties, that can then be declared as compiler-visible properties accessed through GlobalOptions. It is unlikely that it will ever be possible to invoke Git directly from a source generator.

And it exposes the results of what the git describe --all --always --dirty (returns heads/(branch or tag name)(-dirty if it is dirty), git rev-parse --short HEAD (short 7 character commit hash), and git name-rev --name-only HEAD (only the tag or branch name that is being compiled for only if the repository was cloned) commands do as msbuild properties?

I guess I could use an inline build task to expose them as an msbuild property and then access it with the source generator if I absolutely needed to.

@sharwell
Copy link
Member

And it exposes the results of [commands] as msbuild properties?

It might not offer all of what you're after, but it probably does offer at least a subset, plus a solid example for how to implement any others you might need.

@AraHaan
Copy link
Member

AraHaan commented Mar 30, 2021

And it exposes the results of [commands] as msbuild properties?

It might not offer all of what you're after, but it probably does offer at least a subset, plus a solid example for how to implement any others you might need.

Alright removed all I/O and visual studio still says that it does not produce files even though I call context.AddSource in the code 🤔.

Edit: restarting VS2019 oddly made it show them up.

@spydacarnage
Copy link

Edit: restarting VS2019 oddly made it show them up.

I believe that due to the way source generators are loaded, the view in Solution Explorer, as well as any Intellisense, etc., is set when VS loads. You need to restart it to change that.

@canton7
Copy link
Contributor

canton7 commented Mar 30, 2021

I believe that due to the way source generators are loaded, the view in Solution Explorer, as well as any Intellisense, etc., is set when VS loads. You need to restart it to change that.

See #48083

@hammypants
Copy link

hammypants commented Sep 16, 2021

@AraHaan source generators must not perform file I/O, either directly (e.g. File.Read) or indirectly (e.g. through git). If your generator has any I/O, the resulting behavior is undefined.

???

https://github.com/dotnet/roslyn/blob/main/docs/features/source-generators.cookbook.md#additional-file-transformation

@CoenraadS
Copy link

CoenraadS commented Sep 17, 2021

I am experiencing this also, although my code-generator is already targeting 2.0:

Target project:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\Attributes\Attributes.csproj" />
    <ProjectReference Include="..\CodeGen\CodeGen.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
  </ItemGroup>

</Project>

CodeGenProject:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
    <PackageReference Include="Microsoft.CodeAnalysis" Version="3.11.0" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2"/>
    <ProjectReference Include="..\Attributes\Attributes.csproj" />
  </ItemGroup>

</Project>

CSC : warning CS8032: An instance of analyzer CodeGen.Class1 cannot be created from C:\Users\Coenraad\source\repos\ConsoleApp1\CodeGen\bin\Debug\netstandard2.0\CodeGen.dll : Could not load file or assembly 'Microsoft.CodeAnalysis, Version=3.11.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.

Microsoft Visual Studio Community 2019
Version 16.10.4
VisualStudio.16.Release/16.10.4+31515.178
Microsoft .NET Framework
Version 4.8.04084

Installed Version: Community

After I installed Visual Studio 2022 it works. I think it's related to the SDK version installed, it uses dlls from their (GAC) and not whatever is defined in the project. Very confusing.

@ChrML
Copy link

ChrML commented Sep 18, 2021

Is there a path towards allowing Source Generators to be written in .NET5/.NET6? .NETStandard 2.0 seems kinda obsolete for new code.

@AraHaan
Copy link
Member

AraHaan commented Sep 19, 2021

Not yet. Perhaps in 2 more years of waiting it can be done.

@ericwj
Copy link

ericwj commented Aug 6, 2022

These dependencies cannot be tracked. So we do not know when you rerun your generator.

Je ne comprendre pas. You run the generator when you run the generator. Nobody else will.

It also means we would not be able to run your generator in a protected environment that doesn't have unnecessary access to the rest of the system

Again, I don't get it. I will pack the dependency with the retarded netstandard2 project. It'll run on a dev machine or a build server. Where else?

@CyrusNajmabadi
Copy link
Member

You run the generator when you run the generator. Nobody else will.

We run the generator when inputs change. So we need to know what the inputs are. If you do additional io, then you are dependent on the result of that io and need to be rerun of that io would produce different results. But we don't know if that would happen since we don't know what io you performed

@CyrusNajmabadi
Copy link
Member

Where else?

An isolated sandbox that has no access to io whatsoever.

@ericwj
Copy link

ericwj commented Aug 6, 2022

An isolated sandbox that has no access to io whatsoever.

I'm not interested in that. I'm interested in escaping the netstandard chains and for this purpose I just need the native library to load anyway.

need to be rerun of that io would produce different results

OK, so its only about the up to date check, ty - I can reason about that and work with MSBuild to make it right if at all needed.

@CyrusNajmabadi
Copy link
Member

I'm not interested in that. I'm interested in escaping the netstandard chain

then:

the resulting behavior is undefined.

That's all we're saying. You can do whatever you want. We just do not support it and will not work to make it easy. It may also break badly in teh future. You're in 'undefined/unsupported' space. Effectively: "all bets are off".

@CyrusNajmabadi
Copy link
Member

I can reason about that and work with MSBuild to make it right if at all needed.

The problem here is taht we may assume fully anything about this (because you are doing defined behavior). So we may do things like cache previous results if we don't believe any of the inputs has changed. So, what may work today may break tomorrow.

@ericwj
Copy link

ericwj commented Aug 7, 2022

P/Invoke must stay - not to defeat a sandbox, but because it is so useful. The netstandard2.0 requirement is the biggest problem. I read this requirement may be dropped near end of 2023? Is there more specific information about this by now?

@CyrusNajmabadi
Copy link
Member

Where did you read that the requirement may be dropped? Can you link me?

@ericwj
Copy link

ericwj commented Aug 7, 2022

@AraHaan said something to that effect here in this thread on 19 September 2021.

And the docs are also suggestive of a pending improvement:

Important Currently only .NET Standard 2.0 assemblies can be used as Source Generators.

Emphasis mine.

@CyrusNajmabadi
Copy link
Member

Yeah, that's not a statement about 2023. That appears to be tongue-in-cheek. The statement about netstandard is true. It is the only thing currently supported. That may drop in the future. But there is no statement or plan to announce around a particular date.

@AraHaan
Copy link
Member

AraHaan commented Aug 7, 2022

What I said back then does not offer any guarantees that it will be done in the future, or ever. Also I am at no power to even make decisions for any of the teams for any of the repositories here and all of those are up to those that are in said teams (Not intending to be mean to anyone).

@ericwj
Copy link

ericwj commented Aug 7, 2022

Yeah sure, I think everyone understands what you both say. But it would still be such a huge benefit for what I'm planning to do and what many others are doing or will be doing that it would be very helpful to have an idea of the why and how so we can get an approximate idea of the when and decide whether it is worth waiting for or not and the amount of effort that is justified to work around this horrible issue.

@AraHaan
Copy link
Member

AraHaan commented Aug 7, 2022

The only way to allow source generators to target .NET 6 and newer would be for the IDE itself to migrate to .NET 6 and newer which will take probably a few more years for the Visual Studio team to do so and migrate .NET Framework specific code out of process (which is a lot of work to do). There is also the issues with the compiler that runs on the .NET Framework as well for those who want to use C# 8 or newer with their .NET Framework projects as well. With all this considered it might not be possible because of the compiler build that runs on .NET Framework as well in order to build .NET Framework projects.

@ericwj
Copy link

ericwj commented Aug 7, 2022

Yes, again, not much imagination needed to predict that to be the main reasons, but that also means it doesn't tell me anything new or specific enough.

it might not be possible because of the compiler build that runs on .NET Framework

I would seriously hope that most of the .NET ecosystem can evolve without being held hostage by this, whatever the implications on Roslyn itself are.

Could even think of VS loading a different MSBuild depending on compatibility of say the solution, seeing that most of it is already out of proc and there are many people by now like me who just dont have .NET Framework code anymore for a long time. And that population is growing rapidly. But yeah, I don't have to make that happen, so for me its an easy thing to say.

@CyrusNajmabadi
Copy link
Member

But it would still be such a huge benefit for what I'm planning to do and what many others are doing or will be doing

I can't imagine us ever supporting this. It's a genuine anti pattern. :-/

@ericwj
Copy link

ericwj commented Aug 7, 2022

I can't imagine us ever supporting this. It's a genuine anti pattern. :-/

Using net6.0 over netstandard2.0?

@CyrusNajmabadi
Copy link
Member

No. Doing io.

@ericwj
Copy link

ericwj commented Aug 8, 2022

You quoted me talking about targeting .NET 6 and when all the issues that I read about around here and that many people struggle will mostly just vanish.

Otherwise I just need the native lib. How is that an anti-pattern.

And today it runs from a Visual Studio extension and references half of a major solution. Doesn't matter how that became to be. It is how I found it. I have to fix it. Preferably quickly.

Don't talk from your high compiler tower. If you have useful guidance, give it. The genuine anti pattern is your snarking. Again.

@CyrusNajmabadi
Copy link
Member

Don't talk from your high compiler tower.

You asked earlier about what the issues are. I was just explaining. Stating that something is undefined behavior is just a way to explain what we are supporting versus what might be working today but which could break in the future.

Doesn't matter how that became to be. It is how I found it. I have to fix it.

Ok. I have no problem with that. I'm just trying to explain what the state of things are :-)

You quoted me talking about targeting .NET 6

Sorry, it wasn't clear to me that this statement was only limited to that aspect of things. It sounded like it was about all the issues you were reporting.

I do hope eventually we might be able to support net6, but it's going to take a ton of work across many teams, so no way to even know if it will happen or when that might be if it does.

@philip-reed
Copy link

philip-reed commented Feb 29, 2024

<TargetFramework>net5.0</TargetFramework>

Source generators must target netstandard2.0.

Just checking if this is still the case in 2024 and with IIncrementalGenerator?
It seems this isn't quite understood yet:

https://github.com/dotnet/roslyn/blob/main/docs/features/incremental-generators.cookbook.md#open-issues

image

Yesterday, I created a source generator in a project which multi-targets net7.0 & net8.0, and it seemed to work against a net7.0 project, but not when that project was updated to net8.0.

@CyrusNajmabadi
Copy link
Member

Yes this is still currently the case.

@ygoe
Copy link

ygoe commented Jul 12, 2024

@sharwell wrote:

Source generators must target netstandard2.0.

So all of this code here is broken?! It's full of language features that won't work with the old .NET Standard 2.0. Can I only use generators that are limited to .NET Framework code even if they support a library that only targets .NET 8? There's even a video from a dotnetconf where these new language features are used. That feature or its limitation doesn't make any sense. What's the use case of code generators after all?

I have the same error message as the original post. Targeting .NET 8.0 for everything. VS 2022.

@jasonmalinowski
Copy link
Member

@ygoe: Don't confuse that there are a few different in play here: you must target netstandard2.0, which means the DLL containing the generator targets netstandard2.0. But that's different than what the end project is targeting, or which language version that application consumes. You can happily target net8.0 for everything except the generator. It can still see newer language constructs in the target application just fine too since you're seeing those as syntax APIs.

But yes, implicit in this is you can't use newer language features in a generator, but that's usually not too much of a hardship. And if it is, you can override the language version in the project file, just understanding warranties are void and you can run into strange corners if you're not careful. But the expectation is that generators are small, fast, and not pulling in many dependencies so it should be fine.

@ygoe
Copy link

ygoe commented Jul 12, 2024

The code from the page I linked to is for the generator implementation, so that's the generator project. In fact the only official documentation I could find is this cookbook and it explicitly recommends using records – a feature that does not exist or work in .netstandard2.0. So still this whole design is pointless in my eyes. It requires a runtime that it cannot run in. How stupid. Also, clearly that cookbook code has never been tested in reality. Besides a missing parenthesis I found there, all of it would never compile.

I know that I can use the generator in any other target project. I'm talking about the generator project itself here.

@jasonmalinowski
Copy link
Member

Thanks for the concrete example. I guess when we wrote the cookbook we had overridden the language version which would make it work. FYI to @jaredpar and @chsienki that we may want to revise the examples there.

@CyrusNajmabadi
Copy link
Member

Records should work fine in netstandard2.0. I recommend polysharp for this

@ygoe
Copy link

ygoe commented Jul 13, 2024

Okay, after a lot of searching and try and error, here's the missing information that everybody needs in order to really write source generators:

  • You must (not should) target .netstandard2.0
  • You should select the latest language version (only possible in the .csproj file, blocked in the project's properties UI editor)
  • When using records, as suggested by the cookbook, you must add a special class to your generator project to make it work. It can be found here: https://stackoverflow.com/a/67687186/143684

The generator's .csproj file looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <LangVersion>latest</LangVersion>
    <Nullable>enable</Nullable>
    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
  </ItemGroup>
</Project>

And creating such a project and setting it up won't work immediately. The generated types cannot be found, no matter how often you recompile. Visual Studio must be restarted, then the generated types are recognised in the application code. It also must be restarted every time these static generated types (with context.RegisterPostInitializationOutput()) are changed.

Any source generation will only happen when explicitly compiling the application project. Modifications to the generator project will at least be picked up immediately. No generation happens while editing or saving application source files or when loading the project. A manual recompilation is needed.

In order to verify the generated code, it is helpful to save it to files on disk. To enable this, the application project consuming the generator needs this setting:

  <PropertyGroup>
    <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
  </PropertyGroup>

The generated files can be opened in Visual Studio, but may not be updated to reflect the latest contents if the compilation failed. An external file editor is needed in that case. The files are stored in obj\Debug\net8.0\generated\ or similar.

@fortimson
Copy link

To use the following versions of the libraries:
<ItemGroup> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.0.1" /> <PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> </ItemGroup>
to ensure it works on .NET 6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests