/// <summary> /// 生成代码 /// </summary> /// <param name="fileName">模板文件名</param> /// <returns>代码</returns> private static LeftArray <string> code(string fileName) { string code = File.ReadAllText(fileName); int index = code.IndexOf(@"*/ ", StringComparison.Ordinal); if (index != -1) { int startIndex = index += 4, count = 0; Dictionary <SubString, Replace> keys = DictionaryCreator.CreateSubString <Replace>(); Replace replace; foreach (string keyValue in code.Substring(0, index).Split(new string[] { "/*" }, StringSplitOptions.None)) { if (count == 0) { count = 1; continue; } if ((index = keyValue.IndexOf(':')) != -1 && keyValue.EndsWith(@"*/ ", StringComparison.Ordinal)) { keys[new SubString { String = keyValue, StartIndex = 0, Length = index }] = replace = new Replace { values = new SubString { String = keyValue, StartIndex = ++index, Length = keyValue.Length - index - 4 }.Split(';').GetArray(value => value.Split(',')) }; replace.indexs = new LeftArray <int> [replace.values[0].Length]; } else { Messages.Add("自定义数据错误 : " + keyValue); } } LeftArray <string> codeList = new LeftArray <string>(); for (code = code.Substring(startIndex), startIndex = 0, index = code.IndexOf("/*", StringComparison.Ordinal); index != -1; index = code.IndexOf("/*", startIndex)) { codeList.Add(code.Substring(startIndex, index - startIndex)); if ((startIndex = code.IndexOf("*/", index, StringComparison.Ordinal) + 2) != 1 && startIndex != index + 4) { string name = code.Substring(index, startIndex - index); if ((index = code.IndexOf(name, startIndex, StringComparison.Ordinal)) != -1) { startIndex = index + name.Length; name = name.Substring(2, name.Length - 4); if (name[name.Length - 1] == ']') { int arrayIndex = name.LastIndexOf('[') + 1; if (arrayIndex == 0 || !int.TryParse(name.Substring(arrayIndex, name.Length - arrayIndex - 1), out index)) { Messages.Add("自定义名称索引错误 : " + name); index = 0; } else { name = name.Substring(0, arrayIndex - 1); } } else { index = 0; } if (keys.TryGetValue(name, out replace)) { replace.indexs[index].Add(codeList.Length); codeList.Add(string.Empty); } else { Messages.Add("自定义名称不匹配 : " + name); } } else { Messages.Add("自定义名称不匹配 : " + name); } } else { Messages.Add("自定义名称错误 : " + code.Substring(index)); startIndex = code.Length; } } codeList.Add(code.Substring(startIndex)); string[] codes = codeList.ToArray(); LeftArray <string> values = default(LeftArray <string>); Replace[] replaces = keys.Values.getArray(); do { index = replaces.Length; while (--index >= 0 && ++replaces[index].index == replaces[index].values.Length) { ; } if (index == -1) { break; } while (++index != replaces.Length) { replaces[index].index = 0; } for (index = replaces.Length; --index >= 0;) { replace = replaces[index]; LeftArray <SubString> replaceCode = replace.values[replace.index]; for (startIndex = replace.indexs.Length; --startIndex >= 0;) { foreach (int codeIndex in replace.indexs[startIndex]) { codes[codeIndex] = replaceCode[startIndex]; } } } values.Add(string.Concat(codes)); }while (true); return(values); } else { Messages.Add("自定义文件错误 : " + fileName); } return(default(LeftArray <string>)); }
/// <summary> /// 启动代码生成 /// </summary> public void Start() { if (string.IsNullOrEmpty(ProjectPath) || !Directory.Exists(ProjectPath)) { Messages.Add("项目路径不存在 : " + ProjectPath); } else { try { if (IsAutoCSerCodeGenerator || IsCustomCodeGenerator) { run(new CSharper()); //if (IsCombinationTemplate) // run(new CombinationTemplate()); } else { KeyValue <Type, GeneratorAttribute>[] generators = (CustomConfig.Default.IsAutoCSer ? CurrentAssembly.GetTypes() : NullValue <Type> .Array) .concat(CustomConfig.Assembly == null ? null : CustomConfig.Assembly.GetTypes()) .getFind(type => !type.IsInterface && !type.IsAbstract && typeof(IGenerator).IsAssignableFrom(type)) .GetArray(type => new KeyValue <Type, GeneratorAttribute>(type, type.customAttribute <GeneratorAttribute>())) .getFind(value => value.Value != null && value.Value.IsAuto).ToArray(); if (generators.Length != 0) { generators = generators.sort((left, right) => string.CompareOrdinal(left.Key.FullName, right.Key.FullName)); HashSet <Type> types = generators.getHash(value => value.Key); KeyValue <Type, Type>[] depends = generators .getFind(value => value.Value.DependType != null && types.Contains(value.Value.DependType)) .GetArray(value => new KeyValue <Type, Type>(value.Key, value.Value.DependType)); foreach (Type type in AutoCSer.Algorithm.TopologySort.Sort(depends, types, true)) { run(type.Assembly.CreateInstance(type.FullName) as IGenerator); } } if (CustomConfig.Default.IsAutoCSer) { foreach (Type type in Types) { if (!type.IsGenericType && !type.IsInterface && !type.IsEnum) { foreach (Metadata.MethodIndex methodInfo in Metadata.MethodIndex.GetMethods <TestMethodAttribute>(type, MemberFilters.Static, false, true, false)) { MethodInfo method = methodInfo.Method; if (method.IsGenericMethod) { //isTest = false; Messages.Message("测试用例不能是泛型函数 " + method.fullName()); } else { Type returnType = method.ReturnType; if ((returnType == typeof(bool) || returnType == typeof(void)) && method.GetParameters().Length == 0) { try { object returnValue = method.Invoke(null, null); if (method.ReturnType == typeof(bool) && !(bool)returnValue) { //isTest = false; Messages.Message("测试用例调用失败 " + method.fullName()); } } catch (Exception error) { Messages.Message(error.ToString()); } } } } } } } } } catch (Exception error) { Messages.Add(error); } finally { Coder.Output(this); } } }
///// <summary> ///// 添加没有依赖的记忆代码 ///// </summary> ///// <param name="code">没有依赖的记忆代码</param> //[MethodImpl(AutoCSer.MethodImpl.AggressiveInlining)] //public static void AddRemember(string code) //{ // rememberCodes.Add(code); //} /// <summary> /// 输出代码 /// </summary> public static void Output(ProjectParameter parameter) { StringArray[] builders = new StringArray[codes.Length]; for (int index = codes.Length; index != 0;) { StringArray builder = codes[--index]; if (builder.Length != 0) { builders[index] = builder; codes[index] = new StringArray(); } CodeLanguage language = (CodeLanguage)(byte)index; switch (language) { case CodeLanguage.JavaScript: case CodeLanguage.TypeScript: if (builders[index] != null) { Messages.Add("生成了未知的 " + language + " 代码。"); } break; } } //StringArray rememberCodeBuilder = null; //if (rememberCodes.Length != 0) //{ // rememberCodeBuilder = rememberCodes; // rememberCodes = new StringArray(); //} codeTypes.Clear(); if (Messages.IsError) { return; } //string message = string.Empty; for (int index = builders.Length; index != 0;) { StringArray builder = builders[--index]; if (builder != null) { switch (index) { case (int)CodeLanguage.CSharp: string code = builder.ToString(), AutoCSerFileName = null; #if !DotNetStandard bool isAutoCSer = false; #endif if (!string.IsNullOrEmpty(code)) { string fileName = parameter.ProjectPath + (AutoCSerFileName = "{" + parameter.DefaultNamespace + "}.AutoCSer.cs"); if (WriteFile(fileName, WarningCode + code + FileEndCode)) { #if !DotNetStandard isAutoCSer = true; #endif Messages.Message(fileName + " 被修改"); //message = fileName + " 被修改"; } } #if !DotNetStandard if (parameter.IsProjectFile && isAutoCSer) { string projectFile = parameter.AssemblyPath + parameter.ProjectName + ".csproj"; if (File.Exists(projectFile)) { string projectXml = File.ReadAllText(projectFile, System.Text.Encoding.UTF8); if (isAutoCSer) { AutoCSerFileName = @"<Compile Include=""" + AutoCSerFileName + @""" />"; } int fileIndex; if (isAutoCSer && (fileIndex = projectXml.IndexOf(AutoCSerFileName)) != -1) { break; } string csFileName = @".cs"" /> "; if ((fileIndex = projectXml.IndexOf(csFileName)) != -1) { if (isAutoCSer) { AutoCSerFileName += @" "; } projectXml = projectXml.Insert(fileIndex + csFileName.Length, AutoCSerFileName); MoveFile(projectFile, projectXml); } } } #endif break; } } } //if (message.Length != 0) AutoCSer.Log.Pub.Log.waitThrow(AutoCSer.Log.LogType.All, message); }