| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- //------------------------------------------------------------------------------
- // <copyright file="CodeIdentifier.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">Microsoft</owner>
- //------------------------------------------------------------------------------
- namespace System.Xml.Serialization {
-
- using System;
- using System.Text;
- using System.Collections;
- using System.IO;
- using System.Globalization;
- using System.Diagnostics;
- using System.CodeDom;
- using System.CodeDom.Compiler;
- using Microsoft.CSharp;
-
- /// <include file='doc\CodeIdentifier.uex' path='docs/doc[@for="CodeIdentifier"]/*' />
- ///<internalonly/>
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public class CodeIdentifier {
- internal static CodeDomProvider csharp = new CSharpCodeProvider();
- internal const int MaxIdentifierLength = 511;
- [Obsolete("This class should never get constructed as it contains only static methods.")]
- public CodeIdentifier() {
- }
- /// <include file='doc\CodeIdentifier.uex' path='docs/doc[@for="CodeIdentifier.MakePascal"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public static string MakePascal(string identifier) {
- identifier = MakeValid(identifier);
- if (identifier.Length <= 2)
- return identifier.ToUpper(CultureInfo.InvariantCulture);
- else if (char.IsLower(identifier[0]))
- return char.ToUpper(identifier[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture) + identifier.Substring(1);
- else
- return identifier;
- }
-
- /// <include file='doc\CodeIdentifier.uex' path='docs/doc[@for="CodeIdentifier.MakeCamel"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public static string MakeCamel(string identifier) {
- identifier = MakeValid(identifier);
- if (identifier.Length <= 2)
- return identifier.ToLower(CultureInfo.InvariantCulture);
- else if (char.IsUpper(identifier[0]))
- return char.ToLower(identifier[0], CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture) + identifier.Substring(1);
- else
- return identifier;
- }
-
- /// <include file='doc\CodeIdentifier.uex' path='docs/doc[@for="CodeIdentifier.MakeValid"]/*' />
- /// <devdoc>
- /// <para>[To be supplied.]</para>
- /// </devdoc>
- public static string MakeValid(string identifier) {
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < identifier.Length && builder.Length < MaxIdentifierLength; i++) {
- char c = identifier[i];
- if (IsValid(c)) {
- if (builder.Length == 0 && !IsValidStart(c)) {
- builder.Append("Item");
- }
- builder.Append(c);
- }
- }
- if (builder.Length == 0) return "Item";
- return builder.ToString();
- }
- internal static string MakeValidInternal(string identifier) {
- if (identifier.Length > 30) {
- return "Item";
- }
- return MakeValid(identifier);
- }
- static bool IsValidStart(char c) {
- // the given char is already a valid name character
- #if DEBUG
- // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
- if (!IsValid(c)) throw new ArgumentException(Res.GetString(Res.XmlInternalErrorDetails, "Invalid identifier character " + ((Int16)c).ToString(CultureInfo.InvariantCulture)), "c");
- #endif
- // First char cannot be a number
- if (Char.GetUnicodeCategory(c) == UnicodeCategory.DecimalDigitNumber)
- return false;
- return true;
- }
- static bool IsValid(char c) {
- UnicodeCategory uc = Char.GetUnicodeCategory(c);
- // each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc
- //
- switch (uc) {
- case UnicodeCategory.UppercaseLetter: // Lu
- case UnicodeCategory.LowercaseLetter: // Ll
- case UnicodeCategory.TitlecaseLetter: // Lt
- case UnicodeCategory.ModifierLetter: // Lm
- case UnicodeCategory.OtherLetter: // Lo
- case UnicodeCategory.DecimalDigitNumber: // Nd
- case UnicodeCategory.NonSpacingMark: // Mn
- case UnicodeCategory.SpacingCombiningMark: // Mc
- case UnicodeCategory.ConnectorPunctuation: // Pc
- break;
- case UnicodeCategory.LetterNumber:
- case UnicodeCategory.OtherNumber:
- case UnicodeCategory.EnclosingMark:
- case UnicodeCategory.SpaceSeparator:
- case UnicodeCategory.LineSeparator:
- case UnicodeCategory.ParagraphSeparator:
- case UnicodeCategory.Control:
- case UnicodeCategory.Format:
- case UnicodeCategory.Surrogate:
- case UnicodeCategory.PrivateUse:
- case UnicodeCategory.DashPunctuation:
- case UnicodeCategory.OpenPunctuation:
- case UnicodeCategory.ClosePunctuation:
- case UnicodeCategory.InitialQuotePunctuation:
- case UnicodeCategory.FinalQuotePunctuation:
- case UnicodeCategory.OtherPunctuation:
- case UnicodeCategory.MathSymbol:
- case UnicodeCategory.CurrencySymbol:
- case UnicodeCategory.ModifierSymbol:
- case UnicodeCategory.OtherSymbol:
- case UnicodeCategory.OtherNotAssigned:
- return false;
- default:
- #if DEBUG
- // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe
- throw new ArgumentException(Res.GetString(Res.XmlInternalErrorDetails, "Unhandled category " + uc), "c");
- #else
- return false;
- #endif
- }
- return true;
- }
- internal static void CheckValidIdentifier(string ident) {
- if (!CodeGenerator.IsValidLanguageIndependentIdentifier(ident))
- throw new ArgumentException(Res.GetString(Res.XmlInvalidIdentifier, ident), "ident");
- }
- internal static string GetCSharpName(string name) {
- //
- return EscapeKeywords(name.Replace('+', '.'), csharp);
- }
- static int GetCSharpName(Type t, Type[] parameters, int index, StringBuilder sb) {
- if (t.DeclaringType != null && t.DeclaringType != t) {
- index = GetCSharpName(t.DeclaringType, parameters, index, sb);
- sb.Append(".");
- }
- string name = t.Name;
- int nameEnd = name.IndexOf('`');
- if (nameEnd < 0) {
- nameEnd = name.IndexOf('!');
- }
- if (nameEnd > 0) {
- EscapeKeywords(name.Substring(0, nameEnd), csharp, sb);
- sb.Append("<");
- int arguments = Int32.Parse(name.Substring(nameEnd+1), CultureInfo.InvariantCulture) + index;
- for (; index < arguments; index++) {
- sb.Append(GetCSharpName(parameters[index]));
- if (index < arguments -1) {
- sb.Append(",");
- }
- }
- sb.Append(">");
- }
- else {
- EscapeKeywords(name, csharp, sb);
- }
- return index;
- }
- internal static string GetCSharpName(Type t) {
- int rank = 0;
- while (t.IsArray) {
- t = t.GetElementType();
- rank++;
- }
- StringBuilder sb = new StringBuilder();
- sb.Append("global::");
- string ns = t.Namespace;
- if (ns != null && ns.Length > 0) {
- string[] parts = ns.Split(new char[] {'.'});
- for (int i = 0; i < parts.Length; i++) {
- EscapeKeywords(parts[i], csharp, sb);
- sb.Append(".");
- }
- }
- Type[] arguments = t.IsGenericType || t.ContainsGenericParameters ? t.GetGenericArguments() : new Type[0];
- GetCSharpName(t, arguments, 0, sb);
- for (int i = 0; i < rank; i++) {
- sb.Append("[]");
- }
- return sb.ToString();
- }
- //
- /*
- internal static string GetTypeName(string name, CodeDomProvider codeProvider) {
- return codeProvider.GetTypeOutput(new CodeTypeReference(name));
- }
- */
- static void EscapeKeywords(string identifier, CodeDomProvider codeProvider, StringBuilder sb) {
- if (identifier == null || identifier.Length == 0)
- return;
- string originalIdentifier = identifier;
- int arrayCount = 0;
- while (identifier.EndsWith("[]", StringComparison.Ordinal)) {
- arrayCount++;
- identifier = identifier.Substring(0, identifier.Length - 2);
- }
- if (identifier.Length > 0) {
- CheckValidIdentifier(identifier);
- identifier = codeProvider.CreateEscapedIdentifier(identifier);
- sb.Append(identifier);
- }
- for (int i = 0; i < arrayCount; i++) {
- sb.Append("[]");
- }
- }
- static string EscapeKeywords(string identifier, CodeDomProvider codeProvider) {
- if (identifier == null || identifier.Length == 0) return identifier;
- string originalIdentifier = identifier;
- string[] names = identifier.Split(new char[] {'.', ',', '<', '>'});
- StringBuilder sb = new StringBuilder();
- int separator = -1;
- for (int i = 0; i < names.Length; i++) {
- if (separator >= 0) {
- sb.Append(originalIdentifier.Substring(separator, 1));
- }
- separator++;
- separator += names[i].Length;
- string escapedName = names[i].Trim();
- EscapeKeywords(escapedName, codeProvider, sb);
- }
- if (sb.Length != originalIdentifier.Length)
- return sb.ToString();
- return originalIdentifier;
- }
- }
- }
|