Skip to content
Merged
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 @@ -9,10 +9,11 @@ namespace Microsoft.TypeSpec.Generator.Input.Extensions
{
public static class StringExtensions
{
private static bool IsWordSeparator(char c) => !SyntaxFacts.IsIdentifierPartCharacter(c) || c == '_';
private static bool IsWordSeparator(char c, bool preserveUnderscores = false)
=> !SyntaxFacts.IsIdentifierPartCharacter(c) || (!preserveUnderscores && c == '_');

[return: NotNullIfNotNull("name")]
public static string ToIdentifierName(this string name, bool useCamelCase = false)
public static string ToIdentifierName(this string name, bool useCamelCase = false, bool preserveUnderscores = false)
{
if (string.IsNullOrEmpty(name))
{
Expand All @@ -39,7 +40,7 @@ public static string ToIdentifierName(this string name, bool useCamelCase = fals
for (; i < name.Length; i++)
{
var c = name[i];
if (IsWordSeparator(c))
if (IsWordSeparator(c, preserveUnderscores))
{
upperCase = true;
continue;
Expand All @@ -56,7 +57,7 @@ public static string ToIdentifierName(this string name, bool useCamelCase = fals
upperCase = false;
// grow the first word length when this letter follows by two other upper case letters
// this happens in OSProfile, where OS is the first word
if (i + 2 < name.Length && char.IsUpper(name[i + 1]) && (char.IsUpper(name[i + 2]) || IsWordSeparator(name[i + 2])))
if (i + 2 < name.Length && char.IsUpper(name[i + 1]) && (char.IsUpper(name[i + 2]) || IsWordSeparator(name[i + 2], preserveUnderscores)))
firstWordLength++;
// grow the first word length when this letter follows by another upper case letter and an end of the string
// this happens when the string only has one word, like OS, DNS
Expand All @@ -77,6 +78,6 @@ public static string ToIdentifierName(this string name, bool useCamelCase = fals
}

[return: NotNullIfNotNull(nameof(name))]
public static string ToVariableName(this string name) => name.ToIdentifierName(useCamelCase: true);
public static string ToVariableName(this string name, bool preserveUnderscores = false) => name.ToIdentifierName(useCamelCase: true, preserveUnderscores: preserveUnderscores);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using Microsoft.TypeSpec.Generator.Input.Extensions;
using NUnit.Framework;

namespace Microsoft.TypeSpec.Generator.Input.Tests
{
public class StringExtensionsTests
{
// Existing behavior without preserveUnderscores (default)
[TestCase("Tls_1_0", false, "Tls10")]
[TestCase("hello_world", false, "HelloWorld")]
[TestCase("_leading", false, "Leading")]
[TestCase("trailing_", false, "Trailing")]
[TestCase("UPPER_CASE", false, "UPPERCASE")]
[TestCase("simple", false, "Simple")]
[TestCase("", false, "")]
[TestCase(null, false, null)]
// New behavior with preserveUnderscores = true
[TestCase("Tls_1_0", true, "Tls_1_0")]
[TestCase("hello_world", true, "Hello_world")]
[TestCase("_leading", true, "_leading")]
[TestCase("trailing_", true, "Trailing_")]
[TestCase("UPPER_CASE", true, "UPPER_CASE")]
[TestCase("simple", true, "Simple")]
[TestCase("", true, "")]
[TestCase(null, true, null)]
[TestCase("TLS_1_0", true, "TLS_1_0")]
[TestCase("foo__bar", true, "Foo__bar")]
public void TestToIdentifierNamePreserveUnderscores(string name, bool preserveUnderscores, string expected)
{
var result = name.ToIdentifierName(preserveUnderscores: preserveUnderscores);
Assert.AreEqual(expected, result);
}

// Existing behavior of ToVariableName without preserveUnderscores
[TestCase("HelloWorld", false, "helloWorld")]
[TestCase("Tls_1_0", false, "tls10")]
[TestCase("UPPER_CASE", false, "upperCASE")]
// New behavior with preserveUnderscores = true
[TestCase("HelloWorld", true, "helloWorld")]
[TestCase("Tls_1_0", true, "tls_1_0")]
[TestCase("UPPER_CASE", true, "uppeR_CASE")]
public void TestToVariableNamePreserveUnderscores(string name, bool preserveUnderscores, string expected)
{
var result = name.ToVariableName(preserveUnderscores: preserveUnderscores);
Assert.AreEqual(expected, result);
}
}
}
Loading