using Bright.Collections; using Luban.Job.Common.Defs; using System; using System.Collections.Generic; using System.Net; namespace Luban.Job.Common.Utils { public class DefUtil { private static readonly char[] s_attrSep = new char[] { '#' }; private static readonly char[] s_attrKeyValueSep = new char[] { '=', ':' }; private static void AddAttr(Dictionary attrs, string rawPair) { var pair = TrimBracePairs(rawPair); int sepIndex = pair.IndexOfAny(s_attrKeyValueSep); string key; string value; if (sepIndex >= 0) { key = pair.Substring(0, sepIndex).Trim(); value = pair.Substring(sepIndex + 1).Trim(); } else { key = value = pair.Trim(); } attrs.Add(key, value); } public static Dictionary ParseAttrs(string tags) { var am = new Dictionary(); if (string.IsNullOrWhiteSpace(tags)) { return am; } int braceDepth = 0; int pairStart = 0; for (int i = 0; i < tags.Length; i++) { var c = tags[i]; if (c == '(' || c == '[' || c == '{') { ++braceDepth; } else if (c == ')' || c == ']' || c == '}') { --braceDepth; } if (braceDepth == 0 && c == '#') { string rawPair = tags.Substring(pairStart, i - pairStart); pairStart = i + 1; AddAttr(am, rawPair); } } if (braceDepth != 0) { throw new Exception($"非法tags:{tags}"); } if (pairStart < tags.Length) { AddAttr(am, tags.Substring(pairStart)); } return am; } public static int IndexOfBaseTypeEnd(string s) { int braceDepth = 0; int firstSharpIndex = -1;// '#' for (int i = 0; i < s.Length; i++) { var c = s[i]; if (c == '(' || c == '[' || c == '{') { ++braceDepth; } else if (c == ')' || c == ')' || c == '}') { --braceDepth; } if (c == '#' && firstSharpIndex == -1) { firstSharpIndex = i; } if (braceDepth == 0 && (c == ',' || c == ';')) { var strContainBaseType = firstSharpIndex > 0 ? s.Substring(0, firstSharpIndex) : s.Substring(0, i); strContainBaseType = strContainBaseType.Replace("(", "").Replace(")", "").Replace("[", "").Replace("]", ""); if (strContainBaseType == "array" || strContainBaseType == "list" || strContainBaseType == "set" || strContainBaseType == "map") { return i; } else { return -1; } } } return -1; } public static int IndexOfElementTypeSep(string s) { int braceDepth = 0; int firstSharpIndex = -1;// '#' for (int i = 0; i < s.Length; i++) { var c = s[i]; if (c == '(' || c == '[' || c == '{') { ++braceDepth; } else if (c == ')' || c == ')' || c == '}') { --braceDepth; } if (c == '#' && firstSharpIndex == -1) { firstSharpIndex = i; } if (braceDepth == 0 && (c == ',' || c == ';')) { return i; } } return -1; } public static string TrimBracePairs(string rawType) { while (rawType.Length > 0 && rawType[0] == '(') { if (rawType[rawType.Length - 1] == ')') { rawType = rawType.Substring(1, rawType.Length - 2); } else { throw new Exception($"type:{rawType} brace not match"); } } return rawType; } public static (string, Dictionary) ParseType(string s) { int sepIndex = s.IndexOfAny(s_attrSep); if (sepIndex < 0) { return (s, new Dictionary()); } else { int braceDepth = 0; for (int i = 0; i < s.Length; i++) { var c = s[i]; if (c == '(' || c == '[' || c == '{') { ++braceDepth; } else if (c == ')' || c == ']' || c == '}') { --braceDepth; } if (braceDepth == 0 && (c == '#')) { return (s.Substring(0, i), ParseAttrs(s.Substring(i + 1))); } } return (s, new Dictionary()); } } public static bool ParseOrientation(string value) { switch (value.Trim()) { case "": case "r": case "row": return true; case "c": case "column": return false; default: { throw new Exception($"orientation 属性值只能为row|r|column|c"); } } } public static bool IsNormalFieldName(string name) { return !name.StartsWith("__") && !name.StartsWith("#"); } public static Dictionary MergeTags(Dictionary tags1, Dictionary tags2) { if (tags2 != null && tags2.Count > 0) { if (tags1 != null) { if (tags1.Count == 0) { return tags2; } else { var result = new Dictionary(tags1); result.AddAll(tags2); return result; } } else { return tags2; } } else { return tags1; } } public static string EscapeCommentByCurrentLanguage(string comment) { var curLan = DefAssemblyBase.LocalAssebmly.CurrentLanguage; switch (curLan) { case ELanguage.INVALID: throw new Exception($"not set current language. can't get recommend naming convention name"); case ELanguage.CS: case ELanguage.JAVA: case ELanguage.GO: case ELanguage.CPP: case ELanguage.LUA: case ELanguage.JAVASCRIPT: case ELanguage.TYPESCRIPT: case ELanguage.PYTHON: case ELanguage.RUST: case ELanguage.PROTOBUF: #if !LUBAN_LITE return System.Web.HttpUtility.HtmlEncode(comment).Replace("\n", "
"); #else throw new NotSupportedException(); #endif default: throw new Exception($"unknown language:{curLan}"); } } public static ELanguage ParseLanguage(string lan) { switch (lan.ToLower()) { case "cs": case "c#": case "csharp": return ELanguage.CS; case "java": return ELanguage.JAVA; case "go": case "golang": return ELanguage.GO; case "cpp": case "c++": return ELanguage.CPP; case "lua": return ELanguage.LUA; case "js": case "javascript": return ELanguage.JAVASCRIPT; case "ts": case "typescript": return ELanguage.TYPESCRIPT; case "python": return ELanguage.PYTHON; case "rust": return ELanguage.RUST; case "pb": case "protobuf": return ELanguage.PROTOBUF; default: throw new ArgumentException($"parse lan:'{lan}' fail"); } } } }