private static PropertyInfo[] getPropertiesToSave(object o) { List <PropertyInfo> ret = new List <PropertyInfo>(); Type t = o.GetType(); var def = Utils.CreateInstance(t); foreach (var pi in t.GetProperties(BindingFlags.Public | BindingFlags.Default | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) { if (pi.PropertyType != typeof(ExecutableScriptBase)) { if (!CustomAttributeHelper.Has <XsElementAttribute>(pi) && XsAttributeAttribute.GetNames(pi, false) == null) { continue; } object propValue = pi.GetValue(o, null); var ea = CustomAttributeHelper.First <XsElementAttribute>(pi); if (ea != null && ea.SkipIfEmpty && ea.IsEmpty(propValue)) { continue; } // References are supposed to be resolved during initialization, they're not included into executable if (pi.Name == "From" && o is Reference && !((Reference)o).Dynamic) { continue; } if (propValue == null || propValue.Equals(pi.GetValue(def, null))) { if (pi.PropertyType != typeof(ExecutableScriptBase)) { continue; } } } ret.Add(pi); } return(ret.ToArray()); }
private static void writeCommandHelp(ScriptContext context, Type commandType, int width) { var desc = (DescriptionAttribute[])commandType.GetCustomAttributes(typeof(DescriptionAttribute), false); XsTypeAttribute xst = ((XsTypeAttribute[])commandType.GetCustomAttributes(typeof(XsTypeAttribute), false))[0]; string desct = (desc.Length == 0) ? commandType.FullName : desc[0].Description; context.Bold.WriteLine(xst.Name + " (" + commandType.FullName + ")"); context.WriteLine(Utils.Wrap(desct, width, string.Empty)); context.WriteLine(); bool hasValue = false; string hasValueName = null; var def = Utils.CreateInstance(commandType); for (int required = 1; required >= 0; required--) { List <Var> v = new List <Var>(); foreach (var p in commandType.GetProperties(BindingFlags.Public | BindingFlags.SetProperty | BindingFlags.Instance)) { var aa = XsAttributeAttribute.GetNames(p, false); if (aa == null) { continue; } // If more than 1 are returned, choose the preferred one string ba = null; var hs = false; foreach (var attribute in aa) { if (attribute.Length > 0 && ba == null) { ba = attribute; } if (attribute.Length == 0) { hasValue = true; hs = true; } } if (ba == null) { ba = aa[0]; } if (hasValue && hs) { hasValueName = ba; } if (CustomAttributeHelper.Has <XsRequiredAttribute>(p) != (required == 1)) { continue; } var type = p.PropertyType; string dv = null; string typeName; StringBuilder d = new StringBuilder(); var dd = CustomAttributeHelper.First <DescriptionAttribute>(p); if (dd != null) { d.Append(dd.Description); } if (type == typeof(bool)) { typeName = "bool"; dv = "false"; } else if (type == typeof(int)) { typeName = "int"; dv = "0"; } else if (type == typeof(object)) { typeName = CustomAttributeHelper.Has <XsNotTransformed>(p)?"object":"object*"; dv = "null"; } else if (type == typeof(string)) { typeName = CustomAttributeHelper.Has <XsNotTransformed>(p) ? "string" : "string*"; dv = "null"; } else if (type.IsEnum) { typeName = Dump.GetFriendlyTypeName(type); bool f = true; if (d.Length > 0) { d.Append(". "); } d.Append("Values: "); foreach (var s1 in Enum.GetNames(type)) { if (!f) { d.Append(CustomAttributeHelper.Has <FlagsAttribute>(type) ? " | " : " / "); } f = false; d.Append(Utils.LowercaseFirstLetter(s1)); } } else { typeName = Dump.GetFriendlyTypeName(type); } string vn = ba.PadRight(20, ' '); vn += typeName.PadRight(10, ' '); if (required == 0) { if (d.Length > 0) { d.Append(" "); } d.Append("(default: "); var ddd = p.GetValue(def, null); if (type == typeof(string) && (ddd != null || dv != "null")) { d.Append("'" + (ddd ?? dv) + "'"); } else if (type.IsEnum) { d.Append(Utils.LowercaseFirstLetter((ddd ?? dv).ToString())); } else { d.Append(ddd ?? dv); } d.Append(")"); } v.Add(new Var(" " + vn, d.ToString())); } v.Sort((a, b) => string.Compare(a.Name, b.Name)); if (v.Count == 0) { continue; } context.Bold.WriteLine((required == 1) ? "Required attributes:" : "Optional attributes:"); Utils.WrapTwoColumns(context.Out, v, 35, width); context.Out.WriteLine(); } //z1.Sort((a, b) => string.Compare(a.Name, b.Name)); //UsageGenerator ug = new UsageGenerator(); //ug.Options = UsageOptions.AutoSuffix; //context.WriteLine(ug.GetUsage(context, null, null, -1, z1)); context.Bold.WriteLine("Syntax:"); context.Bold.Write(" <" + xst.Name); context.Write(" ... attributes ... "); context.Bold.WriteLine(" >"); List <EleInfo> att = new List <EleInfo>(); foreach (var p in commandType.GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.SetProperty | BindingFlags.Instance)) { var aa = CustomAttributeHelper.First <XsElementAttribute>(p); if (aa == null) { continue; } var d = CustomAttributeHelper.First <DescriptionAttribute>(p); att.Add(new EleInfo() { Attr = aa, Description = (d == null) ? null : d.Description, Property = p }); } att.Sort((a, b) => (a.Attr.Ordering - b.Attr.Ordering) * 10000 + a.Attr.Name.CompareTo(b.Attr.Name)); foreach (var aa in att) { string pref = string.Empty; if (!string.IsNullOrEmpty(aa.Attr.Name)) { if (aa.Attr.SkipIfEmpty) { context.Bold.WriteLine(" [<" + aa.Attr.Name + ">"); } else { context.Bold.WriteLine(" <" + aa.Attr.Name + ">"); } pref = " "; if (aa.Description != null) { context.Info.Write(Utils.Wrap(pref + " " + aa.Description, width, pref + " ")); } } if (!string.IsNullOrEmpty(aa.Attr.CollectionItemElementName)) { for (int i = 0; i < 2; ++i) { context.Bold.Write(pref + " "); if (aa.Attr.SkipIfEmpty) { context.Bold.Write("["); } context.Bold.Write("<" + aa.Attr.CollectionItemElementName + " "); var xs = CustomAttributeHelper.First <XsTypeAttribute>(aa.Attr.CollectionItemType); var hv = false; if (xs != null && string.IsNullOrEmpty(xs.Name)) { // Write attributes here foreach (var pp in aa.Attr.CollectionItemType.GetProperties(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.SetProperty | BindingFlags.Instance)) { var tt = XsAttributeAttribute.GetNames(pp, false); if (tt == null) { continue; } var bba = tt[0]; foreach (var attribute in tt) { if (attribute == tt[0] && attribute.Length > 0) { bba = attribute; } if (attribute.Length == 0) { hv = true; } } if (bba.Length > 0) { context.Write(bba + "=\"...\" "); } } } if (hv) { context.Bold.Write(">"); context.Write("..value.."); context.Bold.Write("</" + aa.Attr.CollectionItemElementName + ">"); } else { context.Bold.Write(" />"); } if (aa.Attr.SkipIfEmpty) { context.Bold.Write("]"); } context.Bold.WriteLine(); } } else if (aa.Attr.CollectionItemType != null) { var name = "action"; if (aa.Attr.CollectionItemType != typeof(IScriptAction)) { name = "<" + aa.Attr.CollectionItemType.Name + " />"; } context.WriteLine(pref + " " + name); context.WriteLine(pref + " " + name); context.WriteLine(pref + " ..."); } if (!string.IsNullOrEmpty(aa.Attr.Name)) { if (aa.Attr.SkipIfEmpty) { context.Bold.WriteLine(" </" + aa.Attr.Name + ">]"); } else { context.Bold.WriteLine(" </" + aa.Attr.Name + ">"); } } } if (hasValue) { context.WriteLine(" value (see " + hasValueName + " attribute)"); } context.Bold.WriteLine(" </" + xst.Name + ">"); }