2

I can't generate a readonly record struct using Roslyn.

My code:

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

var tree = SyntaxFactory.CompilationUnit()
    .AddMembers(
            SyntaxFactory.RecordDeclaration(
                SyntaxFactory.Token(SyntaxKind.RecordKeyword),
                SyntaxFactory.Identifier("A"))
            .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken))
            .AddModifiers(
                        SyntaxFactory.Token(SyntaxKind.PublicKeyword),
                        SyntaxFactory.Token(SyntaxKind.ReadOnlyKeyword))
            .WithClassOrStructKeyword(
                SyntaxFactory.Token(SyntaxKind.StructKeyword))
            .WithParameterList(
                SyntaxFactory.ParameterList()))
    .NormalizeWhitespace();

Console.WriteLine(tree.ToFullString());

var refApis = AppDomain.CurrentDomain.GetAssemblies()
    .Where(a => !a.IsDynamic)
    .Select(a => MetadataReference.CreateFromFile(a.Location));

var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);

var compilation = CSharpCompilation.Create("something", new SyntaxTree[] { tree.SyntaxTree }, refApis, options);
var diag = compilation.GetDiagnostics().Where(e => e.Severity == DiagnosticSeverity.Error).ToList();

foreach (var d in diag)
{
    Console.WriteLine(d);
}

Console.ReadLine();

I get such a result "public readonly record struct A();" and such an error "(1,31): error CS0106: The "readonly" modifier is invalid for this element."

1
  • This is strange. I've tried with the same syntax tree and I get the exact same compile error. However, you can also create a syntax tree using CSharpSyntaxTree.ParseText("public readonly record struct A();") and this compiles without the error. Inspecting both syntax trees they look the same but there must be some minor difference not immediately visible that triggers the compile error. Commented Sep 13, 2023 at 12:12

1 Answer 1

4

The problem is that the record declaration you're creating has SyntaxKind.RecordDeclaration instead of SyntaxKind.RecordStructDeclaration. Even if you are adding the struct keyword, it doesn't change the SyntaxKind that was originally created. To fix this, you'll need to do it as follows:

            SyntaxFactory.RecordDeclaration(
                SyntaxKind.RecordStructDeclaration,
                SyntaxFactory.Token(SyntaxKind.RecordKeyword),
                SyntaxFactory.Identifier("A"))

instead of

            SyntaxFactory.RecordDeclaration(
                SyntaxFactory.Token(SyntaxKind.RecordKeyword),
                SyntaxFactory.Identifier("A"))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.