Skip to content

Below C# 10, WriteSourceFile silently drops the template's assembly:/module: attributes and file comments #77

Open

Description

@matt-edmondson

What's wrong

The block-scoped namespace path added for consumers below C# 10 (#72, fixing #71) rebuilds the template as withoutNamespace but copies only FileName, Usings and Classes:

https://github.com/ktsu-dev/SourceGeneratorToolkit/blob/effd00a/SourceGeneratorToolkit/GeneratorBase.cs#L324-L344

SourceFileTemplate also carries Attributes and Comments (inherited from CodeBlocker's TemplateBase), and AddSourceFile writes both — global assembly:/module: attributes after the usings and before the namespace. On the C# 10+ path the template is passed through whole, so those are kept; on the block path they vanish with no diagnostic.

Repro

Template: Namespace = "Gen", Usings = { "System" }, Attributes = { "assembly: CLSCompliant(true)" }, one class A, rendered through GeneratorHarness:

  • LanguageVersion = Latest: using System; / [assembly: CLSCompliant(true)] / namespace Gen; / class A {} — correct
  • LanguageVersion = CSharp7_3: namespace Gen { using System; class A {} } — the attribute is gone, 0 diagnostics

Reproduced by running the harness at both language versions. File-level Comments are lost the same way.

Why it matters

A generator's output means something different depending on the consumer's LangVersion: an InternalsVisibleTo, CLSCompliant or other assembly attribute the generator emits simply isn't applied in C# 7.3–9 projects, and nothing tells either the generator author or the consumer.

Suggested fix

In the block path, write what has to live outside the namespace first — comments, then usings and attributes (attributes must follow usings and precede the namespace; an assembly: attribute inside a namespace block doesn't compile) — then open the namespace block around a classes-only copy. E.g. render a copy with only Usings/Attributes/Comments and no namespace or classes, then the block around a copy with only Classes. (Usings can stay outside the block too; that's equivalent.)

Acceptance criteria

  • A C# 7.3 harness test with Attributes set emits the attribute before namespace Gen { and the output compiles
  • A C# 7.3 test with Comments set keeps the comments
  • Latest-version output unchanged

Activity

  1. matt-edmondson commented on Nov 12, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

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

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions