using System; using System.Collections.Generic; using System.Linq; using System.Text; using CodeSmith.Engine; namespace SchemaMapper { public enum CodeLanguage { CSharp, VisualBasic } public static class Extensions { private static readonly HashSet _csharpKeywords; private static readonly HashSet _visualBasicKeywords; private static readonly Dictionary _csharpTypeAlias; static Extensions() { _csharpKeywords = new HashSet(StringComparer.Ordinal) { "as", "do", "if", "in", "is", "for", "int", "new", "out", "ref", "try", "base", "bool", "byte", "case", "char", "else", "enum", "goto", "lock", "long", "null", "this", "true", "uint", "void", "break", "catch", "class", "const", "event", "false", "fixed", "float", "sbyte", "short", "throw", "ulong", "using", "while", "double", "extern", "object", "params", "public", "return", "sealed", "sizeof", "static", "string", "struct", "switch", "typeof", "unsafe", "ushort", "checked", "decimal", "default", "finally", "foreach", "private", "virtual", "abstract", "continue", "delegate", "explicit", "implicit", "internal", "operator", "override", "readonly", "volatile", "__arglist", "__makeref", "__reftype", "interface", "namespace", "protected", "unchecked", "__refvalue", "stackalloc" }; _visualBasicKeywords = new HashSet(StringComparer.OrdinalIgnoreCase) { "as", "do", "if", "in", "is", "me", "of", "on", "or", "to", "and", "dim", "end", "for", "get", "let", "lib", "mod", "new", "not", "rem", "set", "sub", "try", "xor", "ansi", "auto", "byte", "call", "case", "cdbl", "cdec", "char", "cint", "clng", "cobj", "csng", "cstr", "date", "each", "else", "enum", "exit", "goto", "like", "long", "loop", "next", "step", "stop", "then", "true", "wend", "when", "with", "alias", "byref", "byval", "catch", "cbool", "cbyte", "cchar", "cdate", "class", "const", "ctype", "cuint", "culng", "endif", "erase", "error", "event", "false", "gosub", "isnot", "redim", "sbyte", "short", "throw", "ulong", "until", "using", "while", "csbyte", "cshort", "double", "elseif", "friend", "global", "module", "mybase", "object", "option", "orelse", "public", "resume", "return", "select", "shared", "single", "static", "string", "typeof", "ushort", "andalso", "boolean", "cushort", "decimal", "declare", "default", "finally", "gettype", "handles", "imports", "integer", "myclass", "nothing", "partial", "private", "shadows", "trycast", "unicode", "variant", "assembly", "continue", "delegate", "function", "inherits", "operator", "optional", "preserve", "property", "readonly", "synclock", "uinteger", "widening", "addressof", "interface", "namespace", "narrowing", "overloads", "overrides", "protected", "structure", "writeonly", "addhandler", "directcast", "implements", "paramarray", "raiseevent", "withevents", "mustinherit", "overridable", "mustoverride", "removehandler", "class_finalize", "notinheritable", "notoverridable", "class_initialize" }; _csharpTypeAlias = new Dictionary(16) { {"System.Int16", "short"}, {"System.Int32", "int"}, {"System.Int64", "long"}, {"System.String", "string"}, {"System.Object", "object"}, {"System.Boolean", "bool"}, {"System.Void", "void"}, {"System.Char", "char"}, {"System.Byte", "byte"}, {"System.UInt16", "ushort"}, {"System.UInt32", "uint"}, {"System.UInt64", "ulong"}, {"System.SByte", "sbyte"}, {"System.Single", "float"}, {"System.Double", "double"}, {"System.Decimal", "decimal"} }; } public static string ToCamelCase(this string name) { return StringUtil.ToCamelCase(name); } public static string ToPascalCase(this string name) { return StringUtil.ToPascalCase(name); } public static string ToFieldName(this string name) { return "_" + StringUtil.ToCamelCase(name); } public static string MakeUnique(this string name, Func exists) { string uniqueName = name; int count = 1; while (exists(uniqueName)) uniqueName = string.Concat(name, count++); return uniqueName; } public static bool IsKeyword(this string text, CodeLanguage language = CodeLanguage.CSharp) { return language == CodeLanguage.VisualBasic ? _visualBasicKeywords.Contains(text) : _csharpKeywords.Contains(text); } public static string ToSafeName(this string name, CodeLanguage language = CodeLanguage.CSharp) { if (!name.IsKeyword(language)) return name; return language == CodeLanguage.VisualBasic ? string.Format("[{0}]", name) : "@" + name; } public static string ToType(this Type type, CodeLanguage language = CodeLanguage.CSharp) { return ToType(type.FullName, language); } public static string ToType(this string type, CodeLanguage language = CodeLanguage.CSharp) { if (type == "System.Xml.XmlDocument") type = "System.String"; string t; if (language == CodeLanguage.CSharp && _csharpTypeAlias.TryGetValue(type, out t)) return t; return type; } public static string ToNullableType(this Type type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp) { return ToNullableType(type.FullName, isNullable, language); } public static string ToNullableType(this string type, bool isNullable = false, CodeLanguage language = CodeLanguage.CSharp) { bool isValueType = type.IsValueType(); type = type.ToType(language); if (!isValueType || !isNullable) return type; return language == CodeLanguage.VisualBasic ? string.Format("Nullable(Of {0})", type) : type + "?"; } public static bool IsValueType(this string type) { if (!type.StartsWith("System.")) return false; var t = Type.GetType(type, false); return t != null && t.IsValueType; } public static string ToDelimitedString(this IEnumerable values, string delimiter, string format = null) { var sb = new StringBuilder(); foreach (var i in values) { if (sb.Length > 0) sb.Append(delimiter); if (string.IsNullOrEmpty(format)) sb.Append(i); else sb.AppendFormat(format, i); } return sb.ToString(); } } }