RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.72k stars 1.29k forks source link

Generated class names cause compiler warning. #4849

Open KutanaDev opened 5 months ago

KutanaDev commented 5 months ago

I'm using this yaml file: https://github.com/legalesign/Legalesign-V1-OpenAPI3/blob/master/legalesign-api-v1.yaml

When I process that using nswag 13.8.2 it creates C# classes named Objects2 and Objects3 and this compiles without warnings.

However, when I use nswag 14.0.7 instead (the latest release), the created C# classes now have names objects and objects2.

Whilst that compiles, there's a warning that wasn't there with the older nswag release:

1>T:\Development\FB19960 - nuget\LegalEsignApi\obj\legalesign-api-v1Client.cs(8982,26,8982,33): warning CS8981: The type name 'objects' only contains lower-cased ascii characters. Such names may become reserved for the language.

KutanaDev commented 5 months ago

Same as issue #4837 ?

WolfgangHG commented 3 months ago

Just to add a few search keywords: this warning was introduced in .NET7 (C# 11) and thus also appears in .NET8 projects. We are hit by it after updating a .NET6 application to .NET8.

WolfgangHG commented 3 months ago

Workaround: add a file ".editorconfig" in the affected project and switch off the warning for those generated files:

[MyApiClient.cs]
dotnet_diagnostic.CS8981.severity = none
WolfgangHG commented 3 months ago

After digging through the code I think this could be fixed by modifying https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema/DefaultTypeNameGenerator.cs#L91, because "GenerateAnonymousTypeName" does not call "ConversionUtilities.ConvertToUpperCamelCase" when it builds types from the hint. It could be modified like this (adding a call three times):

    private string GenerateAnonymousTypeName(string typeNameHint, IEnumerable<string> reservedTypeNames)
    {
      if (!string.IsNullOrEmpty(typeNameHint))
      {
        if (this.TypeNameMappings.TryGetValue(typeNameHint, out var mapping))
        {
          typeNameHint = mapping;
        }

        typeNameHint = GetLastSegment(typeNameHint)!;
        typeNameHint = ConversionUtilities.ConvertToUpperCamelCase(typeNameHint, true);

        if (typeNameHint != null &&
            !reservedTypeNames.Contains(typeNameHint) &&
            Array.IndexOf(reservedTypeNames.ToArray(), typeNameHint) == -1)
        {
          return typeNameHint;
        }

        var count = 1;
        do
        {
          count++;
        } while (reservedTypeNames.Contains(ConversionUtilities.ConvertToUpperCamelCase(typeNameHint + count, true)));

        return ConversionUtilities.ConvertToUpperCamelCase(typeNameHint + count, true);
      }

      return GenerateAnonymousTypeName("Anonymous", reservedTypeNames);
    }

At least this fixes the generating of lower case class names for me. And I compared the code usages of my own generated client from NSwag 13 with the NSwag 14 version, and I see that my code that uses lower case type names now would use the the same type names with numbers ("Data3") that were created by NSwag 13.

@RicoSuter What do you think? Shall I send a pull request?