Skip to content

Commit

Permalink
fix: Fixed Discriminator property name for some cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
HavenDV committed Dec 3, 2024
1 parent f4299e4 commit 095bf0a
Show file tree
Hide file tree
Showing 14 changed files with 130 additions and 335 deletions.
17 changes: 2 additions & 15 deletions src/libs/AutoSDK/Extensions/OpenApiExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Microsoft.OpenApi.Models;
using Microsoft.OpenApi.Readers;
using AutoSDK.Models;
using AutoSDK.Naming.Properties;
using AutoSDK.Serialization.Form;
using Microsoft.OpenApi.Validations;

Expand Down Expand Up @@ -571,20 +572,6 @@ public static string ClearForXml(this string text)
};
}

internal static string ToCSharpName(this string text, Settings settings, SchemaContext? parent)
{
var name = text.ToPropertyName();

name = PropertyData.HandleWordSeparators(name);

if (parent != null)
{
name = name.FixPropertyName(parent.Id);
}

return PropertyData.SanitizeName(name, settings.ClsCompliantEnumPrefix, true);
}

public static T ResolveIfRequired<T>(this T referenceable) where T : class, IOpenApiReferenceable
{
referenceable = referenceable ?? throw new ArgumentNullException(nameof(referenceable));
Expand Down Expand Up @@ -693,7 +680,7 @@ public static PropertyData ToEnumValue(
return PropertyData.Default with
{
Id = id,
Name = PropertyData.SanitizeName(name, settings.ClsCompliantEnumPrefix),
Name = CSharpPropertyNameGenerator.SanitizeName(name, settings.ClsCompliantEnumPrefix),
Summary = ClearForXml(ExtractEnumSummaryFromDescription(id, description)),
};
}
Expand Down
4 changes: 3 additions & 1 deletion src/libs/AutoSDK/Models/AnyOfData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Immutable;
using AutoSDK.Extensions;
using AutoSDK.Naming.AnyOfs;
using AutoSDK.Naming.Properties;
using AutoSDK.Serialization.Json;

namespace AutoSDK.Models;
Expand Down Expand Up @@ -39,7 +40,8 @@ public static AnyOfData FromSchemaContext(SchemaContext context)
context.Schema.Discriminator.Mapping.Count != 0)
{
discriminatorType = context.Children.FirstOrDefault(x => x.Hint == Hint.Discriminator)?.TypeData;
discriminatorPropertyName = context.Schema.Discriminator.PropertyName.ToPropertyName();
discriminatorPropertyName = context.Schema.Discriminator.PropertyName.ToPropertyName()
.ToCSharpName(context.Settings, context.Parent);
}

var count = context.IsAnyOf
Expand Down
3 changes: 2 additions & 1 deletion src/libs/AutoSDK/Models/MethodParameter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Immutable;
using Microsoft.OpenApi.Models;
using AutoSDK.Extensions;
using AutoSDK.Naming.Properties;
using AutoSDK.Serialization.Json;

namespace AutoSDK.Models;
Expand Down Expand Up @@ -66,7 +67,7 @@ public static MethodParameter FromSchemaContext(SchemaContext context)
name = name.FixPropertyName(context.Parent.Id);
}

name = PropertyData.SanitizeName(name, context.Settings.ClsCompliantEnumPrefix, true);
name = CSharpPropertyNameGenerator.SanitizeName(name, context.Settings.ClsCompliantEnumPrefix, true);

var isRequired =
parameter.Required ||
Expand Down
80 changes: 3 additions & 77 deletions src/libs/AutoSDK/Models/PropertyData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AutoSDK.Extensions;
using AutoSDK.Naming.Properties;

namespace AutoSDK.Models;

Expand Down Expand Up @@ -37,7 +38,6 @@ public readonly record struct PropertyData(
public static PropertyData FromSchemaContext(SchemaContext context)
{
context = context ?? throw new ArgumentNullException(nameof(context));
var propertyName = context.PropertyName ?? throw new InvalidOperationException("Property name or parameter name is required.");
var type = context.TypeData;

// OpenAPI doesn't allow metadata for references so sometimes allOf with single item is used to add metadata.
Expand All @@ -50,21 +50,11 @@ public static PropertyData FromSchemaContext(SchemaContext context)
};
}

var name = propertyName.ToPropertyName();

name = HandleWordSeparators(name);

if (context.Parent != null)
{
name = name.FixPropertyName(context.Parent.Id);
}

name = SanitizeName(name, context.Settings.ClsCompliantEnumPrefix, true);

var requiredProperties = context.Parent != null
? new HashSet<string>(context.Parent.Schema.Required)
: [];

var propertyName = context.PropertyName ?? throw new InvalidOperationException("Property name or parameter name is required.");
var isRequired =
requiredProperties.Contains(propertyName) &&
context.Schema is { WriteOnly: false };
Expand All @@ -76,7 +66,7 @@ public static PropertyData FromSchemaContext(SchemaContext context)

return new PropertyData(
Id: propertyName,
Name: name,
Name: CSharpPropertyNameGenerator.ComputePropertyName(context),
Type: type with
{
CSharpTypeNullability = type.CSharpTypeNullability || context.Schema is { WriteOnly: true },
Expand All @@ -99,70 +89,6 @@ public static PropertyData FromSchemaContext(SchemaContext context)
DiscriminatorValue: string.Empty);
}

internal static string SanitizeName(string? name, string clsCompliantEnumPrefix, bool skipHandlingWordSeparators = false)
{
static bool InvalidFirstChar(char ch)
=> ch is not ('_' or >= 'A' and <= 'Z' or >= 'a' and <= 'z');

static bool InvalidSubsequentChar(char ch)
=> ch is not (
'_'
or >= 'A' and <= 'Z'
or >= 'a' and <= 'z'
or >= '0' and <= '9'
);

if (name is null || name.Length == 0)
{
return "";
}

if (!skipHandlingWordSeparators)
{
name = HandleWordSeparators(name);
}

if (name.Length == 0)
{
return string.IsNullOrWhiteSpace(clsCompliantEnumPrefix)
? "_"
: clsCompliantEnumPrefix;
}

if (InvalidFirstChar(name[0]))
{
name = (string.IsNullOrWhiteSpace(clsCompliantEnumPrefix)
? "_"
: clsCompliantEnumPrefix) + name;
}

if (!name.Skip(1).Any(InvalidSubsequentChar))
{
return name;
}

Span<char> buf = stackalloc char[name.Length];
name.AsSpan().CopyTo(buf);

for (var i = 1; i < buf.Length; i++)
{
if (InvalidSubsequentChar(buf[i]))
{
buf[i] = '_';
}
}

// Span<char>.ToString implementation checks for char type, new string(&buf[0], buf.length)
return buf.ToString();
}

internal static string HandleWordSeparators(string name)
{
return name
.ReplacePlusAndMinusOnStart()
.UseWordSeparator('_', '+', '-', '.', '/', '(', '[', ']', ')');
}

public string ParameterName => Name
.Replace(".", string.Empty)
.ToParameterName()
Expand Down
1 change: 1 addition & 0 deletions src/libs/AutoSDK/Models/SchemaContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.OpenApi.Models;
using AutoSDK.Extensions;
using AutoSDK.Naming.Models;
using AutoSDK.Naming.Properties;
using Microsoft.OpenApi.Any;

namespace AutoSDK.Models;
Expand Down
3 changes: 2 additions & 1 deletion src/libs/AutoSDK/Naming/Clients/ClientNameGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.OpenApi.Models;
using AutoSDK.Extensions;
using AutoSDK.Models;
using AutoSDK.Naming.Properties;

namespace AutoSDK.Naming.Clients;

Expand All @@ -25,6 +26,6 @@ public static string GeneratePropertyName(
.SkipWhile(c => !char.IsDigit(c) && !char.IsLetter(c))
.ToArray());

return PropertyData.SanitizeName(name.ToClassName(), settings.ClsCompliantEnumPrefix);
return CSharpPropertyNameGenerator.SanitizeName(name.ToClassName(), settings.ClsCompliantEnumPrefix);
}
}
3 changes: 2 additions & 1 deletion src/libs/AutoSDK/Naming/Models/ModelNameGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.OpenApi.Models;
using AutoSDK.Extensions;
using AutoSDK.Models;
using AutoSDK.Naming.Properties;

namespace AutoSDK.Naming.Models;

Expand Down Expand Up @@ -112,7 +113,7 @@ public static string ComputeId(SchemaContext context)
{
context = context ?? throw new ArgumentNullException(nameof(context));

context.ClassName = PropertyData.SanitizeName(context.ComputeClassName(), context.Settings.ClsCompliantEnumPrefix);
context.ClassName = CSharpPropertyNameGenerator.SanitizeName(context.ComputeClassName(), context.Settings.ClsCompliantEnumPrefix);
context.Id = context.ClassName;

return context.Id;
Expand Down
105 changes: 105 additions & 0 deletions src/libs/AutoSDK/Naming/Properties/PropertyNameGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using AutoSDK.Extensions;
using AutoSDK.Models;

namespace AutoSDK.Naming.Properties;

public static class CSharpPropertyNameGenerator
{
public static string ComputePropertyName(
SchemaContext context)
{
context = context ?? throw new ArgumentNullException(nameof(context));
var propertyName = context.PropertyName ?? throw new InvalidOperationException("Property name or parameter name is required.");

var name = propertyName.ToPropertyName();

name = HandleWordSeparators(name);

if (context.Parent != null)
{
name = name.FixPropertyName(context.Parent.Id);
}

name = SanitizeName(name, context.Settings.ClsCompliantEnumPrefix, true);

return name;
}

internal static string SanitizeName(string? name, string clsCompliantEnumPrefix, bool skipHandlingWordSeparators = false)
{
static bool InvalidFirstChar(char ch)
=> ch is not ('_' or >= 'A' and <= 'Z' or >= 'a' and <= 'z');

static bool InvalidSubsequentChar(char ch)
=> ch is not (
'_'
or >= 'A' and <= 'Z'
or >= 'a' and <= 'z'
or >= '0' and <= '9'
);

if (name is null || name.Length == 0)
{
return "";
}

if (!skipHandlingWordSeparators)
{
name = HandleWordSeparators(name);
}

if (name.Length == 0)
{
return string.IsNullOrWhiteSpace(clsCompliantEnumPrefix)
? "_"
: clsCompliantEnumPrefix;
}

if (InvalidFirstChar(name[0]))
{
name = (string.IsNullOrWhiteSpace(clsCompliantEnumPrefix)
? "_"
: clsCompliantEnumPrefix) + name;
}

if (!name.Skip(1).Any(InvalidSubsequentChar))
{
return name;
}

Span<char> buf = stackalloc char[name.Length];
name.AsSpan().CopyTo(buf);

for (var i = 1; i < buf.Length; i++)
{
if (InvalidSubsequentChar(buf[i]))
{
buf[i] = '_';
}
}

// Span<char>.ToString implementation checks for char type, new string(&buf[0], buf.length)
return buf.ToString();
}

internal static string HandleWordSeparators(string name)
{
return name
.ReplacePlusAndMinusOnStart()
.UseWordSeparator('_', '+', '-', '.', '/', '(', '[', ']', ')');
}

internal static string ToCSharpName(this string text, Settings settings, SchemaContext? parent)
{
var name = text.ToPropertyName();

name = HandleWordSeparators(name);

if (parent != null)
{
name = name.FixPropertyName(parent.Id);
}

return SanitizeName(name, settings.ClsCompliantEnumPrefix, true);
}
}

This file was deleted.

Loading

0 comments on commit 095bf0a

Please sign in to comment.