Skip to content

Fix: Handle empty namespace in CodeWriter to prevent 'global::.' output#9882

Closed
live1206 wants to merge 1 commit intomicrosoft:mainfrom
live1206:fix/csharp-custom-type-alias-namespace
Closed

Fix: Handle empty namespace in CodeWriter to prevent 'global::.' output#9882
live1206 wants to merge 1 commit intomicrosoft:mainfrom
live1206:fix/csharp-custom-type-alias-namespace

Conversation

@live1206
Copy link
Contributor

@live1206 live1206 commented Mar 3, 2026

Summary

When a CSharpType has an empty namespace (which can occur when Roslyn cannot resolve a type reference, such as in Custom code that inherits from generated types), the CodeWriter was outputting global::. followed by the type name, resulting in invalid C# syntax.

Before:

public partial class PublisherResource : global::.HciClusterPublisherResource, IJsonModel<PublisherData>

After:

public partial class PublisherResource : global::HciClusterPublisherResource, IJsonModel<PublisherData>

Root Cause

The issue occurs when:

  1. Custom code has a type alias class (e.g., PublisherResource : HciClusterPublisherResource)
  2. The base type HciClusterPublisherResource is a generated type that exists in the Generated/ folder
  3. When compiling the Custom code folder, Roslyn cannot resolve HciClusterPublisherResource because generated files are excluded from the compilation
  4. This causes Roslyn to mark the base type as an error type with no namespace
  5. When the CodeWriter writes the base type, it outputs global::{empty_namespace}.{name} which becomes global::.{name}

Fix

Added a check in CodeWriter.AppendType to only append the namespace and dot separator when the namespace is not empty.

Tests

Added two unit tests:

  • TypeWithEmptyNamespaceDoesNotOutputGlobalDot: Verifies the fix
  • TypeWithNamespaceOutputsCorrectly: Regression test for normal case

All existing tests pass (1263 generator tests + 1171 ClientModel tests).

Fixes #9880

@microsoft-github-policy-service microsoft-github-policy-service bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Mar 3, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 3, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@9882

commit: 40989df

@github-actions
Copy link
Contributor

github-actions bot commented Mar 3, 2026

No changes needing a change description found.

When a CSharpType has an empty namespace (which can occur when Roslyn
cannot resolve a type reference, such as in Custom code that inherits
from generated types), the CodeWriter was outputting 'global::.'
followed by the type name, resulting in invalid C# syntax.

This fix adds a check to only append the namespace and dot separator
when the namespace is not empty.

Fixes microsoft#9880

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@live1206 live1206 force-pushed the fix/csharp-custom-type-alias-namespace branch from a86d4a0 to 6df22b1 Compare March 3, 2026 07:32
AppendRaw("global::");
AppendRaw(type.Namespace);
AppendRaw(".");
if (!string.IsNullOrEmpty(type.Namespace))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right approach. If the actual namespace is not included in the global reference, we may not end up adding the correct using as part of Roslyn reduce. The actual issue would be somewhere in here -
https://github.com/microsoft/typespec/blob/main/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Providers/ModelProvider.cs#L294

We already have handling for this so we would need to debug to figure out why it isn't working.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My guess is that we are not properly handling when the generated base type is renamed somehow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The root cause is fixed in #9885

@live1206 live1206 closed this Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] C# generator emits broken base type namespace (global::.ClassName) for Custom code type aliases

2 participants