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 XmlSchema generateSchema(ScriptContext context) { // Ensure that all objects are from one namespace string ns = null; foreach (var type in context.GetKnownTypes()) { var na = (CustomAttributeHelper.First <XsTypeAttribute>(type)); if (na == null) { continue; } if (ns == null && na.Namespace != ScriptActionBase.XSharperNamespace) { ns = na.Namespace; } else if (ns != na.Namespace && na.Namespace != ScriptActionBase.XSharperNamespace) { context.Info.WriteLine("Warning: Object " + na.Name + " has unexpected namespace " + na.Namespace + ". All types must use the same namespace."); } } if (ns == null) { ns = ScriptActionBase.XSharperNamespace; } var xmlSchema = XsXsdGenerator.BuildSchema(ns, context.GetKnownTypes(), typeof(Script), new Type[] { typeof(IScriptAction) }); xmlSchema.Id = ns == ScriptActionBase.XSharperNamespace ? "xsharper" : "custom"; // Compile it, just to make sure it's valid XmlSchemaSet s = new XmlSchemaSet(); s.Add(xmlSchema); s.Compile(); return(xmlSchema); }
public static int Help(ScriptContext context, UsageGenerator usage, CommandLineParameters xsParams) { context.WriteLine(OutputType.Bold, GetLogo(context)); context.WriteLine(); var command = context.GetStr(xs.help, null); if (!string.IsNullOrEmpty(command)) { var tt = new Dictionary <string, Type>(StringComparer.OrdinalIgnoreCase); tt["param"] = typeof(CommandLineParameter); tt["versionInfo"] = typeof(VersionInfo); tt["usage"] = typeof(UsageGenerator); foreach (var s in context.GetKnownTypes()) { foreach (var at in CustomAttributeHelper.All <XsTypeAttribute>(s)) { if (!string.IsNullOrEmpty(at.Name)) { tt[at.Name] = s; } } } Type type; if (tt.TryGetValue(command, out type)) { writeCommandHelp(context, type, usage.CorrectWidth(-1)); return(-2); } if (command == "*") { List <Var> v = new List <Var>(); v.Add(new Var("param", getDescr(typeof(CommandLineParameter)))); v.Add(new Var("versioninfo", getDescr(typeof(VersionInfo)))); v.Add(new Var("usage", getDescr(typeof(UsageGenerator)))); foreach (var s in context.GetKnownTypes()) { var xst = CustomAttributeHelper.First <XsTypeAttribute>(s); if (xst == null || string.IsNullOrEmpty(xst.Name)) { continue; } v.Add(new Var(xst.Name, getDescr(s))); } v.Sort((a, b) => string.Compare(a.Name, b.Name)); v.Insert(0, new Var("Actions:", null)); v.Insert(1, new Var("", null)); Utils.WrapTwoColumns(context.Out, v, 30, usage.CorrectWidth(-1)); return(-2); } if (command.StartsWith(".", StringComparison.Ordinal)) { bool success = false; foreach (var nn in ((IEvaluationContext)context).GetNonameObjects()) { success = writeTypeHelp(context, nn.Type, new StringFilter(command.Substring(1)), usage.CorrectWidth(-1)) || success; } if (!success) { context.Error.WriteLine("Cannot find method '" + command + "'. "); } return(-2); } Type t = context.FindType(command); if (t == null) { t = context.FindType("XS." + command); } if (t != null) { writeTypeHelp(context, t, null, usage.CorrectWidth(-1)); } else if (command.Contains("?") || command.Contains("*")) { var r = Utils.WildcardToRegex(command, RegexOptions.IgnoreCase); foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var ttt in a.GetTypes()) { if (ttt != null && ttt.IsPublic && (r.IsMatch(ttt.Name) || r.IsMatch(Dump.GetFriendlyTypeName(ttt)))) { context.WriteLine(Dump.GetFriendlyTypeName(ttt, true)); } } } } else { context.Error.WriteLine("Cannot find command or type '" + command + "'. Use //help * to display the list of commands"); } } else { context.WriteLine(usage.GetUsage(context, null, null, -1, xsParams)); } return(-2); }
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 + ">"); }