CGC_Codes

C# Autorest CodeNamer

Feb 21st, 2017
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.40 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics.CodeAnalysis;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Text;
  7. using AutoRest.Core.Model;
  8. using AutoRest.Core.Properties;
  9. using AutoRest.Core.Utilities;
  10. using AutoRest.Core.Utilities.Collections;
  11. using AutoRest.Core.Validation;
  12. using static AutoRest.Core.Utilities.DependencyInjection;
  13.  
  14. namespace AutoRest.Core
  15. {
  16.     public class CodeNamer
  17.     {
  18.         private static readonly IDictionary<char, string> basicLaticCharacters = new Dictionary<char, string>
  19.         {
  20.             [(char)32] = "Space",
  21.             [(char)33] = "ExclamationMark",
  22.             [(char)34] = "QuotationMark",
  23.             [(char)35] = "NumberSign",
  24.             [(char)36] = "DollarSign",
  25.             [(char)37] = "PercentSign",
  26.             [(char)38] = "Ampersand",
  27.             [(char)39] = "Apostrophe",
  28.             [(char)40] = "LeftParenthesis",
  29.             [(char)41] = "RightParenthesis",
  30.             [(char)42] = "Asterisk",
  31.             [(char)43] = "PlusSign",
  32.             [(char)44] = "Comma",
  33.             [(char)45] = "HyphenMinus",
  34.             [(char)46] = "FullStop",
  35.             [(char)47] = "Slash",
  36.             [(char)48] = "Zero",
  37.             [(char)49] = "One",
  38.             [(char)50] = "Two",
  39.             [(char)51] = "Three",
  40.             [(char)52] = "Four",
  41.             [(char)53] = "Five",
  42.             [(char)54] = "Six",
  43.             [(char)55] = "Seven",
  44.             [(char)56] = "Eight",
  45.             [(char)57] = "Nine",
  46.             [(char)58] = "Colon",
  47.             [(char)59] = "Semicolon",
  48.             [(char)60] = "LessThanSign",
  49.             [(char)61] = "EqualSign",
  50.             [(char)62] = "GreaterThanSign",
  51.             [(char)63] = "QuestionMark",
  52.             [(char)64] = "AtSign",
  53.             [(char)91] = "LeftSquareBracket",
  54.             [(char)92] = "Backslash",
  55.             [(char)93] = "RightSquareBracket",
  56.             [(char)94] = "CircumflexAccent",
  57.             [(char)96] = "GraveAccent",
  58.             [(char)123] = "LeftCurlyBracket",
  59.             [(char)124] = "VerticalBar",
  60.             [(char)125] = "RightCurlyBracket",
  61.             [(char)126] = "Tilde"
  62.         };
  63.  
  64.         public CodeNamer()
  65.         {
  66.         }
  67.  
  68.        
  69.         public static CodeNamer Instance
  70.             =>
  71.             Singleton<CodeNamer>.HasInstance
  72.                 ? Singleton<CodeNamer>.Instance
  73.                 : (Singleton<CodeNamer>.Instance = new CodeNamer());
  74.  
  75.        
  76.         public HashSet<string> ReservedWords { get; } = new HashSet<string>();
  77.  
  78.        
  79.         public virtual string CamelCase(string name)
  80.         {
  81.             if (string.IsNullOrWhiteSpace(name))
  82.             {
  83.                 return name;
  84.             }
  85.  
  86.             if (name[0] == '_')
  87.            
  88.             {
  89.                 return '_' + CamelCase(name.Substring(1));
  90.             }
  91.  
  92.             return
  93.                 name.Split('_', '-', ' ')
  94.                     .Where(s => !string.IsNullOrEmpty(s))
  95.                     .Select((s, i) => FormatCase(s, i == 0))
  96.                     .DefaultIfEmpty("")
  97.                     .Aggregate(string.Concat);
  98.         }
  99.  
  100.        
  101.         public virtual string PascalCase(string name)
  102.         {
  103.             if (string.IsNullOrWhiteSpace(name))
  104.             {
  105.                 return name;
  106.             }
  107.  
  108.             if (name[0] == '_')
  109.            
  110.             {
  111.                 return '_' + CamelCase(name.Substring(1));
  112.             }
  113.  
  114.             return
  115.                 name.Split('_', '-', ' ')
  116.                     .Where(s => !string.IsNullOrEmpty(s))
  117.                     .Select(s => FormatCase(s, false))
  118.                     .DefaultIfEmpty("")
  119.                     .Aggregate(string.Concat);
  120.         }
  121.  
  122.        
  123.         [SuppressMessage("Microsoft.Design", "CA1026:DefaultParametersShouldNotBeUsed")]
  124.         public virtual string QuoteValue(string value, string quoteChar = "\"", string escapeChar = "\\")
  125.         {
  126.             if (quoteChar == null)
  127.             {
  128.                 throw new ArgumentNullException(nameof(quoteChar));
  129.             }
  130.             if (escapeChar == null)
  131.             {
  132.                 throw new ArgumentNullException(nameof(escapeChar));
  133.             }
  134.             if (string.IsNullOrWhiteSpace(value))
  135.             {
  136.                 value = string.Empty;
  137.             }
  138.             return quoteChar + value.Replace(quoteChar, escapeChar + quoteChar) + quoteChar;
  139.         }
  140.  
  141.        
  142.         public virtual string EscapeDefaultValue(string defaultValue, IModelType type)
  143.         {
  144.             return defaultValue;
  145.         }
  146.  
  147.        
  148.         public virtual string GetEnumMemberName(string name)
  149.         {
  150.             if (string.IsNullOrWhiteSpace(name))
  151.             {
  152.                 return name;
  153.             }
  154.             return PascalCase(RemoveInvalidCharacters(name));
  155.         }
  156.  
  157.        
  158.         public virtual string GetFieldName(string name)
  159.         {
  160.             if (string.IsNullOrWhiteSpace(name))
  161.             {
  162.                 return name;
  163.             }
  164.             return '_' + GetVariableName(name);
  165.         }
  166.  
  167.        
  168.         public virtual string GetInterfaceName(string name)
  169.         {
  170.             if (string.IsNullOrWhiteSpace(name))
  171.             {
  172.                 return name;
  173.             }
  174.             return $"I{PascalCase(RemoveInvalidCharacters(name))}";
  175.         }
  176.  
  177.        
  178.         public virtual string GetMethodName(string name)
  179.         {
  180.             if (string.IsNullOrWhiteSpace(name))
  181.             {
  182.                 return name;
  183.             }
  184.             return PascalCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Operation")));
  185.         }
  186.  
  187.        
  188.         public virtual string GetNamespaceName(string name)
  189.         {
  190.             if (string.IsNullOrWhiteSpace(name))
  191.             {
  192.                 return name;
  193.             }
  194.             return PascalCase(RemoveInvalidCharactersNamespace(name));
  195.         }
  196.  
  197.        
  198.         public virtual string GetParameterName(string name)
  199.         {
  200.             if (string.IsNullOrWhiteSpace(name))
  201.             {
  202.                 return name;
  203.             }
  204.             return GetVariableName(GetEscapedReservedName(name, "Parameter"));
  205.         }
  206.  
  207.        
  208.         public virtual string GetPropertyName(string name)
  209.         {
  210.             if (string.IsNullOrWhiteSpace(name))
  211.             {
  212.                 return name;
  213.             }
  214.             return PascalCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Property")));
  215.         }
  216.  
  217.        
  218.         public virtual string GetTypeName(string name)
  219.         {
  220.             if (string.IsNullOrWhiteSpace(name))
  221.             {
  222.                 return name;
  223.             }
  224.             return PascalCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Model")));
  225.         }
  226.  
  227.        
  228.         public virtual string GetMethodGroupName(string name)
  229.         {
  230.             if (string.IsNullOrWhiteSpace(name))
  231.             {
  232.                 return name;
  233.             }
  234.             return PascalCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Model")));
  235.         }
  236.  
  237.         public virtual string GetClientName(string name)
  238.         {
  239.             if (string.IsNullOrWhiteSpace(name))
  240.             {
  241.                 return name;
  242.             }
  243.             return PascalCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Model")));
  244.         }
  245.  
  246.        
  247.         public virtual string GetVariableName(string name)
  248.         {
  249.             if (string.IsNullOrWhiteSpace(name))
  250.             {
  251.                 return name;
  252.             }
  253.             return CamelCase(RemoveInvalidCharacters(GetEscapedReservedName(name, "Variable")));
  254.         }
  255.  
  256.        
  257.         private string FormatCase(string name, bool toLower)
  258.         {
  259.             if (!string.IsNullOrEmpty(name))
  260.             {
  261.                 if ((name.Length < 2) || ((name.Length == 2) && char.IsUpper(name[0]) && char.IsUpper(name[1])))
  262.                 {
  263.                     name = toLower ? name.ToLowerInvariant() : name.ToUpperInvariant();
  264.                 }
  265.                 else
  266.                 {
  267.                     name =
  268.                     (toLower
  269.                         ? char.ToLowerInvariant(name[0])
  270.                         : char.ToUpperInvariant(name[0])) + name.Substring(1, name.Length - 1);
  271.                 }
  272.             }
  273.             return name;
  274.         }
  275.  
  276.        
  277.         public virtual string RemoveInvalidCharacters(string name)
  278.         {
  279.             return GetValidName(name, '_', '-');
  280.         }
  281.  
  282.        
  283.         protected virtual string RemoveInvalidCharactersNamespace(string name)
  284.         {
  285.             return GetValidName(name, '_', '-', '.');
  286.         }
  287.  
  288.        
  289.         public virtual string GetValidName(string name, params char[] allowedCharacters)
  290.         {
  291.             var correctName = RemoveInvalidCharacters(name, allowedCharacters);
  292.  
  293.            
  294.             if (string.IsNullOrEmpty(correctName) ||
  295.                 basicLaticCharacters.ContainsKey(correctName[0]))
  296.             {
  297.                 var sb = new StringBuilder();
  298.                 foreach (var symbol in name)
  299.                 {
  300.                     if (basicLaticCharacters.ContainsKey(symbol))
  301.                     {
  302.                         sb.Append(basicLaticCharacters[symbol]);
  303.                     }
  304.                     else
  305.                     {
  306.                         sb.Append(symbol);
  307.                     }
  308.                 }
  309.                 correctName = RemoveInvalidCharacters(sb.ToString(), allowedCharacters);
  310.             }
  311.  
  312.            
  313.             if (correctName.IsNullOrEmpty())
  314.             {
  315.                 throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidIdentifierName,
  316.                     name));
  317.             }
  318.  
  319.             return correctName;
  320.         }
  321.  
  322.        
  323.         private string RemoveInvalidCharacters(string name, params char[] allowerCharacters)
  324.         {
  325.             return new string(name.Replace("[]", "Sequence")
  326.                 .Where(c => char.IsLetterOrDigit(c) || allowerCharacters.Contains(c))
  327.                 .ToArray());
  328.         }
  329.  
  330.        
  331.         protected virtual string GetEscapedReservedName(string name, string appendValue)
  332.         {
  333.             if (name == null)
  334.             {
  335.                 throw new ArgumentNullException("name");
  336.             }
  337.  
  338.             if (appendValue == null)
  339.             {
  340.                 throw new ArgumentNullException("appendValue");
  341.             }
  342.  
  343.             if (ReservedWords.Contains(name, StringComparer.OrdinalIgnoreCase))
  344.             {
  345.                 name += appendValue;
  346.             }
  347.  
  348.             return name;
  349.         }
  350.  
  351.         public virtual string IsNameLegal(string desiredName, IIdentifier whoIsAsking)
  352.         {
  353.             if (string.IsNullOrWhiteSpace(desiredName))
  354.             {
  355.                
  356.                 throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidIdentifierName,
  357.                     desiredName));
  358.             }
  359.  
  360.             if (ReservedWords.Contains(desiredName))
  361.             {
  362.                 return desiredName;
  363.             }
  364.  
  365.             return null;
  366.         }
  367.  
  368.         public virtual IIdentifier IsNameAvailable(string desiredName, HashSet<IIdentifier> reservedNames)
  369.         {
  370.            
  371.             return
  372.                 reservedNames.FirstOrDefault(
  373.                     each => each.MyReservedNames.WhereNotNull().Any(name => name.Equals(desiredName)));
  374.         }
  375.  
  376.        
  377.         public virtual bool IsSpecialCase(IIdentifier whoIsAsking, IIdentifier reservedName)
  378.         {
  379.            
  380.             if (whoIsAsking is Property && reservedName is CompositeType)
  381.             {
  382.                 return true;
  383.             }
  384.  
  385.              
  386.             if (whoIsAsking is Parameter && reservedName is Method)
  387.             {
  388.                 return true;
  389.             }
  390.  
  391.              
  392.             if (whoIsAsking is MethodGroup)
  393.             {
  394.                 return true;
  395.             }
  396.  
  397.             return false;
  398.         }
  399.  
  400.         public virtual string GetUnique(string desiredName, IIdentifier whoIsAsking,
  401.             IEnumerable<IIdentifier> reservedNames, IEnumerable<IIdentifier> siblingNames,
  402.             HashSet<string> locallyReservedNames = null)
  403.         {
  404.            
  405.             if (string.IsNullOrEmpty(desiredName))
  406.             {
  407.                 return desiredName;
  408.             }
  409.  
  410. #if refactoring_out
  411.             // special case: properties can actually have the same name as a composite type
  412.             // as long as that type is not the parent class of the property itself.
  413.             if (whoIsAsking is Property)
  414.             {
  415.                 reservedNames = reservedNames.Where(each => !(each is CompositeType));
  416.  
  417.                 var parent = (whoIsAsking as IChild)?.Parent as IIdentifier;
  418.                 if (parent != null)
  419.                 {
  420.                     reservedNames = reservedNames.ConcatSingleItem(parent);
  421.                 }
  422.             }
  423. #endif
  424.  
  425.             var names = new HashSet<IIdentifier>(reservedNames.Where(each => !IsSpecialCase(whoIsAsking, each)));
  426.  
  427.            
  428.             string conflict;
  429.             while ((conflict = IsNameLegal(desiredName, whoIsAsking)) != null)
  430.             {
  431.                 desiredName += whoIsAsking.Qualifier;
  432.                
  433.  
  434.             }
  435.  
  436.            
  437.  
  438.             IIdentifier confl;
  439.             while (null != (confl = IsNameAvailable(desiredName, names)))
  440.             {
  441.                 desiredName += whoIsAsking.Qualifier;
  442.                
  443.             }
  444.  
  445.  
  446.              
  447.             if (whoIsAsking is CompositeType)
  448.             {
  449.                 siblingNames = siblingNames.Where(each => !(each is Property));
  450.             }
  451.             if (whoIsAsking is Property)
  452.             {
  453.                 siblingNames = siblingNames.Where(each => !(each is CompositeType));
  454.             }
  455.  
  456.            
  457.             names = new HashSet<IIdentifier>(siblingNames);
  458.             var baseName = desiredName;
  459.             var suffix = 0;
  460.             while (IsNameAvailable(desiredName, names) != null)
  461.             {
  462.                 desiredName = baseName + ++suffix;
  463.             }
  464.  
  465.            
  466.             while (true == locallyReservedNames?.Contains(desiredName))
  467.             {
  468.                 desiredName = baseName + ++suffix;
  469.             }
  470.  
  471.             return desiredName;
  472.         }
  473.     }
  474. }
Advertisement
Add Comment
Please, Sign In to add comment