Describe the bug
ConsumeContextConverterGenerator emits invalid C# when a message type is a C# keyword type (string, object) or an array of one (string[]). The consuming project fails to build with syntax errors in MessageConsumeContext_Converters.g.cs.
GetTypeSyntax, L161–L162 formats the type with SymbolDisplayFormat.FullyQualifiedFormat and then prepends global:: when the name does not already start with it. That format includes UseSpecialTypes, so keyword types come back as string / object with no global:: prefix, and the generator produces global::string, which is not valid C#.
To Reproduce
- Reference a keyword type as a message type anywhere the generator scans, for example:
public static void Handle(IMessageConsumeContext<string> ctx) { }
dotnet build
- The generated converter contains
global::string => new MessageConsumeContext<global::string>(context),
and the build fails with CS1041: Identifier expected; 'string' is a keyword (plus follow-on CS1001 / CS1003).
Verified by running the generator through CSharpGeneratorDriver against dev at 9179885:
| Message type |
Generated arm |
Result |
string |
global::string |
CS1041 |
object |
global::object |
CS1041 |
string[] |
global::string[] |
CS1525, CS8504 and others |
List<string> |
global::System.Collections.Generic.List<string> |
compiles |
So only top-level keyword types and arrays of them are affected; a keyword nested in generic arguments is fine.
Expected behavior
The generated converter compiles for any reference type that satisfies IMessageConsumeContext<T>'s class constraint.
A fix that I checked with the same driver setup: format without UseSpecialTypes, so keyword types are emitted by their metadata names.
static readonly SymbolDisplayFormat TypeFormat = SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions(
SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & ~SymbolDisplayMiscellaneousOptions.UseSpecialTypes
);
With that, the four cases above generate global::System.String, global::System.Object, global::System.String[] and global::System.Collections.Generic.List<global::System.String>, and all compile. The StartsWith("global::") fallback then becomes unnecessary for these types.
Additional context
Found while working on #589 / #592; it predates that change. Keyword message types are unusual, so this is low priority, but the failure is a hard build break with an error pointing at generated code.
Fixing this makes a second, currently masked problem reachable: an object arm can be ordered ahead of an interface arm. That is tracked separately and is best fixed in the same change.
Describe the bug
ConsumeContextConverterGeneratoremits invalid C# when a message type is a C# keyword type (string,object) or an array of one (string[]). The consuming project fails to build with syntax errors inMessageConsumeContext_Converters.g.cs.GetTypeSyntax, L161–L162 formats the type withSymbolDisplayFormat.FullyQualifiedFormatand then prependsglobal::when the name does not already start with it. That format includesUseSpecialTypes, so keyword types come back asstring/objectwith noglobal::prefix, and the generator producesglobal::string, which is not valid C#.To Reproduce
dotnet buildCS1041: Identifier expected; 'string' is a keyword(plus follow-onCS1001/CS1003).Verified by running the generator through
CSharpGeneratorDriveragainstdevat 9179885:stringglobal::stringobjectglobal::objectstring[]global::string[]List<string>global::System.Collections.Generic.List<string>So only top-level keyword types and arrays of them are affected; a keyword nested in generic arguments is fine.
Expected behavior
The generated converter compiles for any reference type that satisfies
IMessageConsumeContext<T>'sclassconstraint.A fix that I checked with the same driver setup: format without
UseSpecialTypes, so keyword types are emitted by their metadata names.With that, the four cases above generate
global::System.String,global::System.Object,global::System.String[]andglobal::System.Collections.Generic.List<global::System.String>, and all compile. TheStartsWith("global::")fallback then becomes unnecessary for these types.Additional context
Found while working on #589 / #592; it predates that change. Keyword message types are unusual, so this is low priority, but the failure is a hard build break with an error pointing at generated code.
Fixing this makes a second, currently masked problem reachable: an
objectarm can be ordered ahead of an interface arm. That is tracked separately and is best fixed in the same change.