Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/AutomationUtils/HelpUtils.cs
Ben Marsh bc47b15e06 Merge utility library changes from GitSync.
[CL 16135807 by Ben Marsh in ue5-main branch]
2021-04-27 22:41:48 -04:00

218 lines
5.9 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Reflection;
using EpicGames.Core;
using System.Linq;
namespace AutomationTool
{
/// <summary>
/// Help Attribute.
/// </summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class HelpAttribute : DescriptionAttribute
{
private bool IsParamHelp;
/// <summary>
/// Basic constructor for class descriptions.
/// </summary>
/// <param name="Description">Class description</param>
public HelpAttribute(string Description)
: base(Description)
{
IsParamHelp = false;
}
/// <summary>
/// Constructor for parameter descriptions.
/// </summary>
/// <param name="ParamName">Paramter name</param>
/// <param name="Description">Paramter description</param>
public HelpAttribute(string ParamName, string Description)
: base(FormatDescription(ParamName, Description))
{
IsParamHelp = true;
}
/// <summary>
/// Additional type to display help for.
/// </summary>
/// <param name="AdditionalType"></param>
public HelpAttribute(Type AdditionalType)
{
IsParamHelp = false;
AdditionalHelp = AdditionalType;
}
private static string FormatDescription(string Name, string Description)
{
return String.Format("-{0} {1}", Name, Description);
}
public bool IsParam
{
get { return IsParamHelp; }
}
public Type AdditionalHelp
{
get;
private set;
}
}
/// <summary>
/// Base utility function for script commands.
/// </summary>
public partial class CommandUtils
{
/// <summary>
/// Displays help for the specified command.
/// <param name="Command">Command type.</param>
/// </summary>
public static void Help(Type Command)
{
string Description;
List<string> Params;
GetTypeHelp(Command, out Description, out Params);
LogHelp(Command, Description, Params);
}
/// <summary>
/// Displays help for the specified Type.
/// </summary>
/// <param name="Command">Type to display help for.</param>
public static void LogHelp(Type Command)
{
string Description;
List<string> Params;
GetTypeHelp(Command, out Description, out Params);
LogHelp(Command, Description, Params);
}
/// <summary>
/// Displays a formatted help for the specified Command type.
/// </summary>
/// <param name="Command">Command Type</param>
/// <param name="Description">Command Desscription</param>
/// <param name="Params">Command Parameters</param>
public static void LogHelp(Type Command, string Description, List<string> Params)
{
Dictionary<string, string> ParamDict = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
// Extract Params/Descriptions into Key/Value pairs
foreach (var Param in Params)
{
// Find the first space (should be following the param name)
if (!String.IsNullOrWhiteSpace(Param))
{
var ParamName = String.Empty;
var ParamDesc = String.Empty;
var SplitPoint = Param.IndexOf(' ');
if (SplitPoint > 0)
{
// Extract the name and description seperately
ParamName = Param.Substring(0, SplitPoint);
ParamDesc = Param.Substring(SplitPoint + 1, Param.Length - (SplitPoint + 1));
}
else
{
ParamName = Param;
}
// build dictionary using Name and Desc as Key and Value
if (!ParamDict.ContainsKey(ParamName))
{
ParamDict.Add(ParamName, ParamDesc);
}
else
{
LogWarning("Duplicated help parameter \"{0}\"", ParamName);
}
}
}
Log.TraceInformation("");
HelpUtils.PrintHelp(String.Format("{0} Help:", Command.Name), Description, ParamDict.ToList(), HelpUtils.WindowWidth, Log.Logger);
}
/// <summary>
/// Gets the description and a list of parameters for the specified type.
/// </summary>
/// <param name="ObjType">Type to get help for.</param>
/// <param name="ObjectDescription">Description</param>
/// <param name="Params">List of paramters</param>
public static void GetTypeHelp(Type ObjType, out string ObjectDescription, out List<string> Params)
{
ObjectDescription = String.Empty;
Params = new List<string>();
var AllAttributes = ObjType.GetCustomAttributes(false);
foreach (var CustomAttribute in AllAttributes)
{
var HelpAttribute = CustomAttribute as HelpAttribute;
if (HelpAttribute != null)
{
if (HelpAttribute.IsParam)
{
Params.Add(HelpAttribute.Description);
}
else if (HelpAttribute.AdditionalHelp != null)
{
string DummyDescription;
List<string> AdditionalParams;
GetTypeHelp(HelpAttribute.AdditionalHelp, out DummyDescription, out AdditionalParams);
Params.AddRange(AdditionalParams);
}
else
{
if (!String.IsNullOrEmpty(ObjectDescription))
{
ObjectDescription += Environment.NewLine;
}
ObjectDescription += HelpAttribute.Description;
}
}
}
var AllMembers = GetAllMemebers(ObjType);
foreach (var Member in AllMembers)
{
var AllMemeberAtributes = Member.GetCustomAttributes(false);
foreach (var CustomAttribute in AllMemeberAtributes)
{
var HelpAttribute = CustomAttribute as HelpAttribute;
if (HelpAttribute != null && HelpAttribute.IsParam)
{
Params.Add(HelpAttribute.Description);
}
}
}
}
private static List<MemberInfo> GetAllMemebers(Type ObjType)
{
var Members = new List<MemberInfo>();
for (; ObjType != null; ObjType = ObjType.BaseType)
{
var ObjMembers = ObjType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
Members.AddRange(ObjMembers);
}
return Members;
}
}
}