| File: ValueForms\DefaultSafeNamespaceValueFormFactory.cs | Web Access |
| Project: src\sdk\src\TemplateEngine\Microsoft.TemplateEngine.Orchestrator.RunnableProjects\Microsoft.TemplateEngine.Orchestrator.RunnableProjects.csproj (Microsoft.TemplateEngine.Orchestrator.RunnableProjects) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text; using Microsoft.TemplateEngine.Orchestrator.RunnableProjects.Utilities; namespace Microsoft.TemplateEngine.Orchestrator.RunnableProjects.ValueForms { internal class DefaultSafeNamespaceValueFormFactory : ActionableValueFormFactory { internal const string FormIdentifier = "safe_namespace"; internal DefaultSafeNamespaceValueFormFactory() : base(FormIdentifier) { } internal static string ToSafeNamespace(string value) { const char invalidCharacterReplacement = '_'; value = value ?? throw new ArgumentNullException(nameof(value)); value = value.Trim(); StringBuilder safeValueStr = new(value.Length); for (int i = 0; i < value.Length; i++) { if (i < value.Length - 1 && char.IsSurrogatePair(value[i], value[i + 1])) { safeValueStr.Append(invalidCharacterReplacement); // Skip both chars that make up this symbol. i++; continue; } bool isFirstCharacterOfIdentifier = safeValueStr.Length == 0 || safeValueStr[safeValueStr.Length - 1] == '.'; bool isValidFirstCharacter = UnicodeCharacterUtilities.IsIdentifierStartCharacter(value[i]); bool isValidPartCharacter = UnicodeCharacterUtilities.IsIdentifierPartCharacter(value[i]); if (isFirstCharacterOfIdentifier && !isValidFirstCharacter && isValidPartCharacter) { // This character cannot be at the beginning, but is good otherwise. Prefix it with something valid. safeValueStr.Append(invalidCharacterReplacement); safeValueStr.Append(value[i]); } else if ((isFirstCharacterOfIdentifier && isValidFirstCharacter) || (!isFirstCharacterOfIdentifier && isValidPartCharacter) || (safeValueStr.Length > 0 && i < value.Length - 1 && value[i] == '.')) { // This character is allowed to be where it is. safeValueStr.Append(value[i]); } else { safeValueStr.Append(invalidCharacterReplacement); } } return safeValueStr.ToString(); } protected override string Process(string value) => ToSafeNamespace(value); } }