Skip to content

Support source type aliases in generated models #93

Description

@bazer

Summary

Add first-class support for C# source type aliases in DataLinq model declarations and generated implementation/metadata files.

For example:

using Text = System.String;

#nullable disable

[Table("customers")]
public abstract partial class Customer(/* ... */)
{
    [Nullable, Column("name")]
    public abstract Text Name { get; }
}

Current behavior

DataLinq preserves the property type spelling (Text) while parsing the model, but a using alias is scoped to its original compilation unit. The generated implementation lives in another source file and cannot use Text unless the alias is repeated or the type is canonicalized.

The current syntax-only path also cannot prove that Text resolves to the reference type System.String. Consequently, alias-based model types can produce invalid generated code and cannot participate correctly in reference-type/nullability classification.

The using parser currently retains UsingDirectiveSyntax.Name but not the alias relationship, so copying ordinary namespace imports is not sufficient.

Expected behavior

A valid model property expressed through a source alias should generate the same runtime contract as the underlying type:

  • generated files should compile without depending on file-local aliases;
  • emitted property and metadata type names should resolve to the actual CLR type;
  • [Nullable] reference aliases under an explicitly disabled nullable-annotation context should produce CsNullable = true;
  • value-type aliases must remain strict;
  • custom scalar-converter model types expressed through aliases should keep working correctly.

Proposed direction

Use Roslyn semantic type resolution for generator inputs:

  1. Resolve each model property's ITypeSymbol from the current Compilation.
  2. Emit a stable fully qualified type name such as global::System.String rather than copying the alias identifier into generated files.
  3. Derive reference/value-type classification from the resolved symbol.
  4. Keep source spelling/location only for diagnostics and source fidelity where it is safe.
  5. Keep syntax-only metadata parsing conservative when no semantic model is available, or report a focused unsupported-alias diagnostic instead of allowing downstream generated-code failures.
  6. Include relevant alias declarations/targets in incremental generator dependencies so changing only using Text = System.String to another target cannot reuse stale metadata or generated imports.

Blindly copying alias directives into generated files is less robust: aliases are file-local, can collide, and can refer to namespace-, generic-, tuple-, pointer-, or array-shaped types depending on the language version.

Acceptance criteria

  • A generator test using using Text = System.String compiles without diagnostics.
  • The generated implementation uses a resolvable canonical type name rather than an undeclared Text.
  • #nullable disable plus [Nullable] Text emits CsNullable = true and materializes SQL NULL as null.
  • An alias to a non-nullable value type does not become CsNullable.
  • Namespace aliases and custom scalar-converter type aliases have regression coverage.
  • Changing only an alias target in the same incremental generator driver recomputes affected metadata/output.
  • Existing keyword, qualified built-in, enum, and custom type generation remains unchanged.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions