Search code examples
c#roslynroslyn-code-analysissourcegenerators

Intellisense not seeing source generated from a local C# source generator


I have a solution which contains 4 projects. One of them is a Roslyn source generator, one is a class library which uses the source generator, one is a testing project which also uses the source generator, and the other is for unit tests which doesn't use it. The project builds and runs perfectly, but I get error squiggles in my IDE for the generated code. I've tried both Visual Studio and VS Code (even on a completely different computer), however on VS Code there is a small time window while the project is opening back up where I can hover over the generated method and see its signature. The source generator targets .NET Standard 2.0. I've restarted my editors, cleaned and rebuilt everything, cleaned and only rebuilt the source generator before opening the IDE, cleared all the caches, and restarted my computer.

Here is the .csproj. Some of this I copied over from some project on the internet in an attempt to get it to work, but it didn't help.

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
      <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
      <IncludeBuildOutput>false</IncludeBuildOutput>
      <LangVersion>12</LangVersion>
      <IsRoslynComponent>true</IsRoslynComponent>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="SourceGeneratorsKit" Version="0.0.1" GeneratePathProperty="true" PrivateAssets="all" />
  </ItemGroup>
    
    <PropertyGroup>
        <GetTargetPathDependsOn>$(GetTargetPathDependsOn);GetDependencyTargetPaths</GetTargetPathDependsOn>
    </PropertyGroup>
    
    <Target Name="GetDependencyTargetPaths">
        <ItemGroup>
            <TargetPathWithTargetPlatformMoniker Include="$(PKGSourceGeneratorsKit)\lib\netstandard2.0\SourceGeneratorsKit.dll" IncludeRuntimeDependency="false" />
        </ItemGroup>
    </Target>

</Project>

This is how it looks like without the other stuff I copied in. It doesn't work in this form either.

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

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

  <ItemGroup>
    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
    <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="SourceGeneratorsKit" Version="0.0.1" GeneratePathProperty="true" PrivateAssets="all" />
  </ItemGroup>

</Project>

This is how I reference the source generator in the projects that need it:

<ItemGroup>
    <ProjectReference Include="..\Datapack.Net.SourceGenerator\Datapack.Net.SourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

The source generator code:

    [Generator]
    public class ProjectGenerator : ISourceGenerator
    {
        private readonly SyntaxReceiver Projects = new DerivedClassesReceiver("Project");

        public void Execute(GeneratorExecutionContext context)
        {
            if (!(context.SyntaxContextReceiver is SyntaxReceiver)) return;

            foreach (var i in Projects.Classes)
            {
                ProcessClass(context, i);
            }
        }

        public void ProcessClass(GeneratorExecutionContext context, INamedTypeSymbol symbol)
        {
            // Unimportant
        }

        public void Initialize(GeneratorInitializationContext context)
        {
            context.RegisterForSyntaxNotifications(() => Projects);
        }
    }

Here's the full source code if you want to look at it.


Solution

  • It turns out that changing the source generator into an incremental generator fixed the issue, at least for VS Code. Once I can verify that this will continue to work I'll accept this answer.

    If anyone reading this has the same problem I did, then this article may be useful for converting a source generator to an incremental generator.