/// <summary> /// Builds the command tree. /// </summary> /// <param name="source">The source.</param> /// <param name="includeParentTypes">if set to <c>true</c> it will include only this type.</param> /// <returns></returns> public static commandTree BuildCommandTree(IAceOperationSetExecutor source, Boolean includeParentTypes = true) { commandTree rootDesc = new commandTree(); rootDesc.name = "commands"; rootDesc.nodeLevel = commandTreeNodeLevel.root; rootDesc.description = $"Reference of console commands available at {source.consoleTitle} command line interface."; rootDesc.helpLines.Add(source.consoleHelp); rootDesc.helpLines.AddRange(source.helpHeader); commandTree output = rootDesc; List <Type> types = new List <Type>(); if (includeParentTypes) { types = source.GetType().GetBaseTypeList(true, true, typeof(aceOperationSetExecutorBase)); } else { types.Add(source.GetType()); } types.Reverse(); foreach (Type t in types) { if (t.IsInterface) { continue; } if (t.IsClass) { output.Add(BuildTreeNodeForType(t, source, output), t.Name); } } return(output); }
/// <summary> /// Reports the command tree. /// </summary> /// <param name="tree">The tree.</param> /// <param name="output">The output.</param> public static void ReportCommandTree(this commandTree tree, ITextRender output, Boolean paginate, Int32 lastPageLine = 0, aceCommandConsoleHelpOptions option = aceCommandConsoleHelpOptions.full) { output.AppendHeading(tree.name.ToUpper(), 1); output.AppendParagraph(tree.description); if (tree.helpLines.Any()) { output.AppendHeading("Description", 2); foreach (String ln in tree.helpLines) { output.AppendLine(ln); } } if (option.HasFlag(aceCommandConsoleHelpOptions.parameters)) { output.AppendHeading("Properties", 2); foreach (var pair in tree.properties) { output.AppendPair(pair.Value.Name, pair.Value.PropertyType.Name, true, ":"); } output.AppendHorizontalLine(); } if (option.HasFlag(aceCommandConsoleHelpOptions.plugins)) { output.AppendHeading("Plugins", 2); foreach (var pair in tree.plugins) { output.AppendPair(pair.Key.Trim('.'), pair.Value.GetType().Name, true, ":"); var methods = pair.Value.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public); if (Enumerable.Any <MethodInfo>(methods)) { List <String> lst = new List <string>(); foreach (MemberInfo mInfo in Enumerable.Where <MethodInfo>(methods, x => x.Name.StartsWith(aceMenuItemMeta.METHOD_PREFIX))) { lst.Add(pair.Key.add(mInfo.Name.removeStartsWith(aceMenuItemMeta.METHOD_PREFIX), ".").Trim('.')); } output.AppendList(lst); } } output.AppendHorizontalLine(); } if (option.HasFlag(aceCommandConsoleHelpOptions.modules)) { output.AppendHeading("Modules", 2); foreach (var pair in tree.modules) { output.AppendPair(pair.Value.Name, pair.Value.PropertyType.Name, true, ":"); } output.AppendHorizontalLine(); } //if (option.HasFlag(aceCommandConsoleHelpOptions.brief)) //{ // output.AppendHeading("Overview", 2); // foreach (var pair in tree.flatAccess) // { // output.AppendPair(pair.Value.path.Trim('.'), pair.Value.menuMeta.cmdParams.ToString(false, true, true), true, " "); // } // output.AppendHorizontalLine(); //} if (option.HasFlag(aceCommandConsoleHelpOptions.commands)) { foreach (commandTreeDescription node in tree) { node.ReportCommandNode(output, paginate, lastPageLine); } } }
/// <summary> /// Builds the type of the tree node for. /// </summary> /// <param name="type">The type.</param> /// <param name="source">The source.</param> /// <param name="host">The host.</param> /// <returns></returns> internal static commandTreeDescription BuildTreeNodeForType(Type type, IAceOperationSetExecutor source, commandTreeDescription parent, String nameOverride = "", commandTreeNodeLevel level = commandTreeNodeLevel.type) { settingsMemberInfoEntry typeInfo = new settingsMemberInfoEntry(type); commandTreeDescription output = parent.Add(nameOverride.or(typeInfo.name, typeInfo.displayName, type.Name)); commandTree host = parent.root as commandTree; output.description = typeInfo.description; output.nodeLevel = level; output.helpLines.Add(typeInfo.info_helpTitle); output.helpLines.Add(typeInfo.info_helpTips); output.helpLines.AddRange(typeInfo.additionalInfo); var methods = type.GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly); aceDictionarySet <String, commandTreeDescription> groups = new aceDictionarySet <string, commandTreeDescription>(); aceDictionarySet <String, commandTreeDescription> group_nodes = new aceDictionarySet <string, commandTreeDescription>(); foreach (MemberInfo __m in methods) { if (__m.Name.StartsWith(aceMenuItemMeta.METHOD_PREFIX)) { commandTreeDescription desc = new commandTreeDescription(); desc.setByMemberInfo(__m); desc.nodeLevel = commandTreeNodeLevel.group; groups.Add(desc.category, desc); } } foreach (String group in groups.Keys.OrderBy(x => x)) { var ordered = groups[group].OrderBy(x => x.name); commandTreeDescription gdesc = parent.Add(group); gdesc.nodeLevel = commandTreeNodeLevel.group; foreach (var cdesc in ordered) { cdesc.nodeLevel = commandTreeNodeLevel.command; gdesc.Add(cdesc, cdesc.name); host.flatAccess.Add(cdesc.path, cdesc); } } var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly); foreach (PropertyInfo pi in properties) { if (pi.DeclaringType.Name == "aceCommandConsole") { continue; } if (pi.DeclaringType.Name == "aceAdvancedConsole") { continue; } if (pi.PropertyType.GetInterfaces().Contains(typeof(IAceOperationSetExecutor))) { var plugin_instance = source.imbGetPropertySafe(pi) as IAceOperationSetExecutor; var plugin_node = BuildTreeNodeForType(pi.PropertyType, source, parent, pi.Name, commandTreeNodeLevel.plugin); plugin_node.setByMemberInfo(pi); host.plugins.Add(plugin_node.path, plugin_instance); } else if (pi.PropertyType.IsValueType || pi.PropertyType.isTextOrNumber() || pi.GetCustomAttributes(false).Any()) { if (pi.CanWrite) { var prop = parent.Add(pi.Name); prop.setByMemberInfo(pi); prop.nodeLevel = commandTreeNodeLevel.parameter; host.properties.Add(prop.path, pi); } } else if (pi.PropertyType.IsClass || pi.GetCustomAttributes(false).Any()) { if (!pi.PropertyType.IsGenericType) { var prop = parent.Add(pi.Name); prop.setByMemberInfo(pi); prop.nodeLevel = commandTreeNodeLevel.module; host.modules.Add(prop.path, pi); } } } return(output); }