• x01.CodeBuilder: 生成代码框架


    根据 Assembly 生成代码框架。

    这是学习 AvalonEdit 的一个副产品。学习时,照着源代码新建文件夹,新建文件,添加方法与属性,虽然只是个框架,也要花费大量时间。为什么不让它自动生成呢?于是,新建了个控制台程序,一步步添加,一步步显示,一步步调整。虽然还有许多不完善的地方,但它基本能用了。将 Main 方法略作改动,便成了 Build 方法。为操作方便,加了个 WPF 界面。OK!下一步可参照 ILSpy 来进行改写,当也是一款不错的工具吧。限于时间与能力,暂且作罢。

    主要代码如下:

      1 /**
      2  * Program.cs (c) 2015 by x01
      3  */
      4 using System;
      5 using System.Collections.Generic;
      6 using System.Diagnostics;
      7 using System.IO;
      8 using System.Linq;
      9 using System.Reflection;
     10 using System.Text;
     11 using System.Text.RegularExpressions;
     12 using System.Windows;
     13 
     14 namespace x01.CodeBuilder
     15 {
     16     public class Test<THllo>
     17     {
     18         
     19     }
     20     /// <summary>
     21     /// Description of Program.
     22     /// </summary>
     23     public static  class BuildHelper
     24     {
     25         static readonly StringBuilder sb = new StringBuilder();
     26         static readonly List<string> usings = new List<string>();
     27         static string headerFormat = "/**
     * {0}.cs (c) 2015 by x01
     */
    ";
     28         
     29         /// <summary>
     30         /// 根据 Assebmly 生成代码框架。
     31         /// </summary>
     32         /// <param name="path">程序集路径名</param>
     33         /// <param name="outputDirectory">输出目录</param>
     34         public static void Build(string path, string outputDirectory)
     35         {
     36             if (!File.Exists(path)) {
     37                 throw new Exception("Assembly file not found.");
     38             }
     39             if (!Directory.Exists(outputDirectory)) {
     40                 Directory.CreateDirectory(outputDirectory);
     41             }
     42             
     43             Assembly assembly = Assembly.LoadFile(path);
     44             string assemblyName = assembly.FullName.Split(',')[0];
     45             
     46             string assemblyPath = Path.GetDirectoryName(assembly.Location);
     47             foreach (var type in assembly.GetTypes()) {
     48                 usings.Clear();
     49                 
     50                 if (!(type.IsEnum || type.IsClass || type.IsInterface || type.IsGenericType)) {
     51                     continue;
     52                 }
     53                 
     54                 string typeName = type.FullName.Replace(assemblyName + ".","");
     55                 
     56                 string[] typeNameSplits = typeName.Split('.');
     57                 string fileDirectory = outputDirectory;
     58                 if (typeNameSplits.Length > 1) {
     59                     for (int i = 0; i < typeNameSplits.Length - 1; i++) {
     60                         fileDirectory += "\" + typeNameSplits[i];
     61                         if (!Directory.Exists(fileDirectory)) {
     62                             Directory.CreateDirectory(fileDirectory);
     63                         }
     64                     }
     65                 }
     66                 
     67                 sb.Clear();
     68                 int lastDotIndex = type.FullName.LastIndexOf('.');
     69                 string namespaceName = lastDotIndex > 0 ? type.FullName.Substring(0,lastDotIndex) : type.FullName;
     70                 
     71                 sb.Append("namespace " + namespaceName + "
    {
    ");
     72                 
     73                 string convertName = ConvertType(type.Name); 
     74                 sb.Append("	//TODO: " + convertName + "
    ");
     75             
     76                 if (type.IsPublic) {
     77                     sb.Append("	public ");
     78                 } else {
     79                     sb.Append("	");
     80                 }
     81                 
     82                 if (type.IsAbstract && !type.IsInterface) {
     83                     sb.Append("abstract ");
     84                 } else if (type.IsSealed && !type.IsEnum) {
     85                     sb.Append("sealed ");
     86                 }
     87                 
     88                 if (type.IsEnum) {
     89                     sb.Append("enum ");
     90                 } else if (type.IsClass) {
     91                     sb.Append("class ");
     92                 } else if (type.IsInterface) {
     93                     sb.Append("interface ");
     94                 }
     95                 
     96                 sb.Append(convertName); 
     97                 if (type.BaseType != null && !string.IsNullOrEmpty(type.BaseType.Name)) {
     98                     sb.Append(" : " + ConvertType(type.BaseType.Name));
     99                 }
    100                 sb.Append("
    	{
    ");
    101                 
    102                 var baseProperties = type.BaseType != null ? type.BaseType.GetProperties() : new PropertyInfo[1];
    103                 foreach (var property in type.GetProperties()) {
    104                     if (type.IsEnum) continue;
    105                     
    106                     var propertyString = property.ToString();
    107                     bool skip = false;
    108                     foreach (var bp in baseProperties) {
    109                         if (bp == null) continue;
    110                         if (propertyString == bp.ToString()) {
    111                             skip = true;
    112                             break;
    113                         }
    114                     }
    115                     if (skip) continue;
    116                     
    117                     int lastIndex = propertyString.LastIndexOf('.');
    118                     string propu = string.Empty;
    119                     if (lastIndex >= 0)
    120                         propu = propertyString.Substring(0,lastIndex);
    121                     propu = ConvertType(propu);
    122                     if (!usings.Contains(propu) && !string.IsNullOrEmpty(propu)) {
    123                         usings.Add(propu);
    124                     }
    125                     string p = propertyString.Substring(lastIndex+1);
    126                     string[] ps = p.Split(' ');
    127                     ps[0] = ConvertType(ps[0]) + " ";
    128                     p = string.Empty;
    129                     for (int i = 0; i < ps.Length; i++) {
    130                         p += ps[i];
    131                     }
    132                     sb.Append("		public " + p + " { get; set; }
    ");
    133                 }
    134     
    135                 sb.Append("
    ");
    136                 
    137                 var baseMethods =  type.BaseType != null ? type.BaseType.GetMethods() : new MethodInfo[1];
    138                 foreach (var method in type.GetMethods()) {
    139                     if (type.IsEnum) continue;
    140                     
    141                     bool skip = false;
    142                     foreach (var bm in baseMethods) {
    143                         if (bm == null) break;
    144                         if (bm.ToString() == method.ToString()) {
    145                             skip = true;
    146                             break;
    147                         }
    148                     }
    149                     if (skip) continue;
    150                     
    151                     var typeString = method.ReturnType.ToString();
    152                     if (method.Name.Contains("get_") || method.Name.Contains("set_") 
    153                         || method.Name.Contains("add_") || method.Name.Contains("remove_")) {
    154                         continue;
    155                     }
    156                     int lastIndex = typeString.LastIndexOf('.');
    157                     string r = string.Empty;
    158                     if (lastIndex > 0) {
    159                         string u = typeString.Substring(0,lastIndex);
    160                         u = ConvertType(u);
    161                         if (!usings.Contains(u) && !string.IsNullOrEmpty(u)) {
    162                             usings.Add(u);
    163                         }
    164                         r = typeString.Substring(lastIndex+1);
    165                     } else {
    166                         r = typeString;
    167                     }
    168                     r = ConvertType(r);
    169                     sb.Append("		public " + r + " " + method.Name + "(");
    170                     int pcount = method.GetParameters().Length;
    171                     int count = 0;
    172                     foreach (var parameter in method.GetParameters()) {
    173                         var paramString = parameter.ParameterType.ToString();
    174                         int plast = paramString.LastIndexOf('.');
    175                         string ptype = string.Empty;
    176                         if (plast > 0) {
    177                             string pu = paramString.Substring(0, plast);
    178                             pu = ConvertType(pu);
    179                             if (!usings.Contains(pu)) {
    180                                 usings.Add(pu);
    181                             }
    182                             ptype = paramString.Substring(plast+1);
    183                         } else {
    184                             ptype = paramString;
    185                         }
    186                         ptype = ConvertType(ptype);
    187                         count ++;
    188                         if (pcount == 1 || pcount == count)
    189                             sb.Append(ptype + " " + parameter.Name);
    190                         else 
    191                             sb.Append(ptype + " " + parameter.Name + ", ");
    192                     }
    193                     sb.Append(")
    ");
    194                     sb.Append("		{
    			throw new NotImplementedException();
    		}
    ");
    195                 }
    196                 
    197                 sb.Append("	}
    "); // end type
    198                 
    199                 sb.Append("}"); //end namespace
    200                 
    201                 string header = string.Format(headerFormat, convertName);
    202                 string ustring = header;
    203                 foreach (var us in usings) {
    204                     ustring += "using " + us + ";
    ";
    205                 }
    206                 ustring += "
    " + sb.ToString();
    207 
    208                 if (!string.IsNullOrEmpty(convertName)) {
    209                     string filename = Path.Combine(fileDirectory, convertName) + ".cs";
    210                     File.WriteAllText(filename, ustring);
    211                 }
    212             }
    213         }
    214         
    215         static string ConvertType(string typeName)
    216         {
    217             int index = typeName.IndexOf('`');
    218             if (index >= 0)
    219                 typeName = typeName.Substring(0,index);
    220             index = typeName.IndexOf('+');
    221             if (index >= 0) 
    222                 typeName = typeName.Substring(0,index);
    223             index = typeName.IndexOf('<');
    224             if (index >= 0)
    225                 typeName = typeName.Substring(0,index);
    226             index = typeName.IndexOf(']');
    227             if (index >= 0)
    228                 typeName = typeName.Substring(0, index);
    229             
    230             switch (typeName) {
    231                 case "Boolean":
    232                     return "bool";
    233                 case "Void":
    234                     return "void";
    235                 case "Int32":
    236                     return "int";
    237                 case "Object":
    238                     return "object";
    239                 case "Double":
    240                     return "double";
    241                 case "String":
    242                     return "string";
    243                 case "Long":
    244                     return "long";
    245                 default:
    246                     break;
    247             }
    248             
    249             return typeName;
    250         }
    251         
    252         // 测试用的。
    253 //        static void Main(string[] args)
    254 //        {
    255 //            string path = @"E:TempLabx01x01.CodeBuilderinDebugx01.MelonEdit.exe";
    256 //            string target = @"E:TempLabx01Output";
    257 //            Build(path,target);
    258 //            
    259 //            Console.ReadKey(true);
    260 //        }
    261     }
    262 }
    View Code

    看一看,真是惨不忍睹。这大概就是所谓的意大利面条吧。

    源代码下载:https://github.com/chinax01/x01.CodeBuilder

  • 相关阅读:
    C#中设置窗口在最前显示而其他窗口不能使用
    C#中关闭子窗口而不释放子窗口对象的方法
    C#窗体越界时鼠标还能回到初始坐标位置
    C#程序实现软件开机自动启动的两种常用方法
    C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面
    图标库网址收藏
    C# Winform打包部署时添加注册表信息实现开机自启动
    C# winform程序怎么打包成安装项目(VS2010图解)
    数据库的三级范式,涉及范式的问题
    基数排序
  • 原文地址:https://www.cnblogs.com/china_x01/p/5026429.html
Copyright © 2020-2023  润新知