Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,11 @@ private void AppendType(CSharpType type, bool isDeclaration, bool writeTypeNameO
UseNamespace(type.Namespace);

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

{
AppendRaw(type.Namespace);
AppendRaw(".");
}
if (type.DeclaringType is not null)
AppendRaw($"{type.DeclaringType.Name}.");
AppendRaw(type.Name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -727,5 +727,54 @@ public void CodeWriter_WriteMethod_AbstractMethodWithoutBody()
var result = codeWriter.ToString(false);
Assert.AreEqual(expected, result);
}

// Regression test for https://github.com/microsoft/typespec/issues/9880
// When a CSharpType has an empty namespace (can happen when Roslyn cannot resolve the type),
// the CodeWriter should not output "global::." (global prefix followed by empty namespace and dot).
[Test]
public void TypeWithEmptyNamespaceDoesNotOutputGlobalDot()
{
// Create a CSharpType with an empty namespace (simulating an unresolved error type)
var typeWithEmptyNamespace = new CSharpType(
"UnresolvedType",
"", // empty namespace
isValueType: false,
isNullable: false,
declaringType: null,
args: [],
isPublic: true,
isStruct: false);

using var writer = new CodeWriter();
writer.Append($"{typeWithEmptyNamespace}");
var result = writer.ToString(false);

// Should contain "global::UnresolvedType" (without extra dot after global::)
Assert.That(result, Does.Contain("global::UnresolvedType"),
"Type with empty namespace should be prefixed with 'global::' directly followed by the type name");
}

// Verifies that types with proper namespaces still work correctly
[Test]
public void TypeWithNamespaceOutputsCorrectly()
{
var typeWithNamespace = new CSharpType(
"ResolvedType",
"Sample.Models",
isValueType: false,
isNullable: false,
declaringType: null,
args: [],
isPublic: true,
isStruct: false);

using var writer = new CodeWriter();
writer.Append($"{typeWithNamespace}");
var result = writer.ToString(false);

// Should contain the full qualified name
Assert.That(result, Does.Contain("global::Sample.Models.ResolvedType"),
"Type with namespace should include the full namespace in output");
}
}
}
Loading