2024-10-10

Using Roslyn inside Rider

 Recently I was struggling with actually getting the 'roslyn source code generator' to generate things available to my other project inside Rider.

Storing this as a memo for the exact things that made this work so I have a good baseline to branch out from in the future. Might help someone.

Setup the project

- New Solution
-- Generator (class library, netstandard2.0)
-- MyConsoleApp (console app, netstandard2.0)

ManageNuGetPackages

- Microsoft.CodeAnalysis.Analyzers
- Microsoft.CodeAnalysisCSharp.Workspaces
- Microsoft.Compilers.Toolset
- NetStandard.Library 2.x.x

MyConsoleApp-project

Add a dependency to Generator, and then modify the .csproj file like this

<!-- Add this as a new ItemGroup, replacing paths and names appropriately -->
<ItemGroup>
<ProjectReference Include="..\Generator\Generator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Net.Compilers.Toolset" Version="4.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

Generator-project

Adding launchsettings.json

Create a file at ./Properties/launchSettings.json and paste the following code inside it (I had to create the Properties-Directory inside Rider)

{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"Generators": {
"commandName": "DebugRoslynComponent",
"targetProject": "../MyConsoleApp/MyConsoleApp.csproj"
}
} } 

Create the Generator-file

Create a file called HelloWorldGenerator.cs and paste this content inside it
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;

namespace Generator;

[Generator]
public class HelloWorldGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{

}

public void Execute(GeneratorExecutionContext context)
{
// begin creating the source we'll inject into the users compilation
var sourceBuilder = new StringBuilder(@"
using System;
namespace HelloWorldGenerated
{
public static class HelloWorld
{
public static void SayHello()
{
Console.WriteLine(""Hello from generated code!"");
Console.WriteLine(""The following syntax trees existed in the compilation that created this program:"");
");

// using the context, get a list of syntax trees in the users compilation
var syntaxTrees = context.Compilation.SyntaxTrees;

// add the filepath of each tree to the class we're building
foreach (SyntaxTree tree in syntaxTrees)
{
sourceBuilder.AppendLine($@"Console.WriteLine(@"" - {tree.FilePath}"");");
}

// finish creating the source to inject
sourceBuilder.Append(@"
}
}
}");

// inject the created source into the users compilation
context.AddSource("helloWorldGenerator", SourceText.From(sourceBuilder.ToString(), Encoding.UTF8));
}
}
End result 
after doing a couple of attempts at
- Reload project
- Restart Rider
- Rebuild Solution
Inside the console app it should now be possible to write
HelloWorldGenerated.HelloWorld.SayHello();
And inside the 'solution view' you should be able to see the following by expanding
/MyConsoleApp/Dependencies/.NetStandard2.0/Source Generators/Generator.HelloWorldGenerator




Inga kommentarer:

Skicka en kommentar