Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
ParameterSetInfo.cs346 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Collections.ObjectModel;6using System.Globalization;7using System.Linq;8using System.Text.RegularExpressions;9 10using Microsoft.PowerShell;11 12using Dbg = System.Management.Automation.Diagnostics;13 14namespace System.Management.Automation15{16    /// <summary>17    /// The information about a parameter set and its parameters for a cmdlet.18    /// </summary>19    public class CommandParameterSetInfo20    {21        #region ctor22 23        /// <summary>24        /// Constructs the parameter set information using the specified parameter name,25        /// and type metadata.26        /// </summary>27        /// <param name="name">28        /// The formal name of the parameter.29        /// </param>30        /// <param name="isDefaultParameterSet">31        /// True if the parameter set is the default parameter set, or false otherwise.32        /// </param>33        /// <param name="parameterSetFlag">34        /// The bit that specifies the parameter set in the type metadata.35        /// </param>36        /// <param name="parameterMetadata">37        /// The type metadata about the cmdlet.38        /// </param>39        /// <exception cref="ArgumentException">40        /// If <paramref name="name"/> is null or empty.41        /// </exception>42        /// <exception cref="ArgumentNullException">43        /// If <paramref name="parameterMetadata"/> is null.44        /// </exception>45        internal CommandParameterSetInfo(46            string name,47            bool isDefaultParameterSet,48            uint parameterSetFlag,49            MergedCommandParameterMetadata parameterMetadata)50        {51            IsDefault = true;52            Name = string.Empty;53            if (string.IsNullOrEmpty(name))54            {55                throw PSTraceSource.NewArgumentException(nameof(name));56            }57 58            if (parameterMetadata == null)59            {60                throw PSTraceSource.NewArgumentNullException(nameof(parameterMetadata));61            }62 63            this.Name = name;64            this.IsDefault = isDefaultParameterSet;65 66            Initialize(parameterMetadata, parameterSetFlag);67        }68        #endregion ctor69 70        #region public members71 72        /// <summary>73        /// Gets the name of the parameter set.74        /// </summary>75        public string Name { get; }76 77        /// <summary>78        /// Gets whether the parameter set is the default parameter set.79        /// </summary>80        public bool IsDefault { get; }81 82        /// <summary>83        /// Gets the parameter information for the parameters in this parameter set.84        /// </summary>85        public ReadOnlyCollection<CommandParameterInfo> Parameters { get; private set; }86 87        /// <summary>88        /// Gets the synopsis for the cmdlet as a string.89        /// </summary>90        public override string ToString()91        {92            Text.StringBuilder result = new Text.StringBuilder();93 94            GenerateParametersInDisplayOrder(95                parameter => AppendFormatCommandParameterInfo(parameter, result),96                (string str) =>97                {98                    if (result.Length > 0)99                    {100                        result.Append(' ');101                    }102 103                    result.Append('[');104                    result.Append(str);105                    result.Append(']');106                });107 108            return result.ToString();109        }110 111        /// <summary>112        /// GenerateParameters parameters in display order113        /// ie., Positional followed by114        ///      Named Mandatory (in alpha numeric) followed by115        ///      Named (in alpha numeric).116        ///117        /// Callers use <paramref name="parameterAction"/> and118        /// <paramref name="commonParameterAction"/> to handle119        /// syntax generation etc.120        /// </summary>121        /// <param name="parameterAction"></param>122        /// <param name="commonParameterAction"></param>123        /// <returns></returns>124        internal void GenerateParametersInDisplayOrder(125            Action<CommandParameterInfo> parameterAction,126            Action<string> commonParameterAction)127        {128            // First figure out the positions129 130            List<CommandParameterInfo> sortedPositionalParameters = new List<CommandParameterInfo>();131            List<CommandParameterInfo> namedMandatoryParameters = new List<CommandParameterInfo>();132            List<CommandParameterInfo> namedParameters = new List<CommandParameterInfo>();133 134            foreach (CommandParameterInfo parameter in Parameters)135            {136                if (parameter.Position == int.MinValue)137                {138                    // The parameter is a named parameter139                    if (parameter.IsMandatory)140                    {141                        namedMandatoryParameters.Add(parameter);142                    }143                    else144                    {145                        namedParameters.Add(parameter);146                    }147                }148                else149                {150                    // The parameter is positional so add it at the correct151                    // index (note we have to pad the list if the position is152                    // higher than the list count since we don't have any requirements153                    // that positional parameters start at zero and are consecutive.154 155                    if (parameter.Position >= sortedPositionalParameters.Count)156                    {157                        for (int fillerIndex = sortedPositionalParameters.Count;158                             fillerIndex <= parameter.Position;159                             ++fillerIndex)160                        {161                            sortedPositionalParameters.Add(null);162                        }163                    }164 165                    sortedPositionalParameters[parameter.Position] = parameter;166                }167            }168 169            foreach (CommandParameterInfo parameter in sortedPositionalParameters)170            {171                if (parameter == null)172                {173                    continue;174                }175 176                parameterAction(parameter);177            }178 179            // Now convert the named mandatory parameters into a string180            foreach (CommandParameterInfo parameter in namedMandatoryParameters)181            {182                if (parameter == null)183                {184                    continue;185                }186 187                parameterAction(parameter);188            }189 190            List<CommandParameterInfo> commonParameters = new List<CommandParameterInfo>();191 192            // Now convert the named parameters into a string193            foreach (CommandParameterInfo parameter in namedParameters)194            {195                if (parameter == null)196                {197                    continue;198                }199 200                // Hold off common parameters201                bool isCommon = Cmdlet.CommonParameters.Contains(parameter.Name, StringComparer.OrdinalIgnoreCase);202                if (!isCommon)203                {204                    parameterAction(parameter);205                }206                else207                {208                    commonParameters.Add(parameter);209                }210            }211 212            // If all common parameters are present, group them together213            if (commonParameters.Count == Cmdlet.CommonParameters.Count)214            {215                commonParameterAction(HelpDisplayStrings.CommonParameters);216            }217            // Else, convert to string as before218            else219            {220                foreach (CommandParameterInfo parameter in commonParameters)221                {222                    parameterAction(parameter);223                }224            }225        }226 227        #endregion public members228 229        #region private members230 231        private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, Text.StringBuilder result)232        {233            if (result.Length > 0)234            {235                // Add a space between parameters236                result.Append(' ');237            }238 239            if (parameter.ParameterType == typeof(SwitchParameter))240            {241                result.AppendFormat(CultureInfo.InvariantCulture, parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name);242            }243            else244            {245                string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes);246 247                if (parameter.IsMandatory)248                {249                    result.AppendFormat(250                        CultureInfo.InvariantCulture,251                        parameter.Position != int.MinValue ? "[-{0}] <{1}>" : "-{0} <{1}>",252                        parameter.Name,253                        parameterTypeString);254                }255                else256                {257                    result.AppendFormat(258                        CultureInfo.InvariantCulture,259                        parameter.Position != int.MinValue ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]",260                        parameter.Name,261                        parameterTypeString);262                }263            }264        }265 266        internal static string GetParameterTypeString(Type type, IEnumerable<Attribute> attributes)267        {268            string parameterTypeString;269            PSTypeNameAttribute typeName;270            if (attributes != null && (typeName = attributes.OfType<PSTypeNameAttribute>().FirstOrDefault()) != null)271            {272                // If we have a PSTypeName specified on the class, we assume it has a more useful type than the actual273                // parameter type.  This is a reasonable assumption, the parameter binder does honor this attribute.274                //275                // This typename might be long, e.g.:276                //     Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Process277                //     System.Management.ManagementObject#root\cimv2\Win32_Process278                // To shorten this, we will drop the namespaces, both on the .Net side and the CIM/WMI side:279                //     CimInstance#Win32_Process280                // If our regex doesn't match, we'll just use the full name.281                var match = Regex.Match(typeName.PSTypeName, "(.*\\.)?(?<NetTypeName>.*)#(.*[/\\\\])?(?<CimClassName>.*)");282                if (match.Success)283                {284                    parameterTypeString = match.Groups["NetTypeName"].Value + "#" + match.Groups["CimClassName"].Value;285                }286                else287                {288                    parameterTypeString = typeName.PSTypeName;289 290                    // Drop the namespace from the typename, if any.291                    var lastDotIndex = parameterTypeString.LastIndexOf('.');292                    if (lastDotIndex != -1 && lastDotIndex + 1 < parameterTypeString.Length)293                    {294                        parameterTypeString = parameterTypeString.Substring(lastDotIndex + 1);295                    }296                }297 298                // If the type is really an array, but the typename didn't include [], then add it.299                if (type.IsArray && !parameterTypeString.Contains("[]", StringComparison.Ordinal))300                {301                    var t = type;302                    while (t.IsArray)303                    {304                        parameterTypeString += "[]";305                        t = t.GetElementType();306                    }307                }308            }309            else310            {311                Type parameterType = Nullable.GetUnderlyingType(type) ?? type;312                parameterTypeString = ToStringCodeMethods.Type(parameterType, true);313            }314 315            return parameterTypeString;316        }317 318        private void Initialize(MergedCommandParameterMetadata parameterMetadata, uint parameterSetFlag)319        {320            Diagnostics.Assert(321                parameterMetadata != null,322                "The parameterMetadata should never be null");323 324            Collection<CommandParameterInfo> processedParameters =325                new Collection<CommandParameterInfo>();326 327            // Get the parameters in the parameter set328            Collection<MergedCompiledCommandParameter> compiledParameters =329                parameterMetadata.GetParametersInParameterSet(parameterSetFlag);330 331            foreach (MergedCompiledCommandParameter parameter in compiledParameters)332            {333                if (parameter != null)334                {335                    processedParameters.Add(336                        new CommandParameterInfo(parameter.Parameter, parameterSetFlag));337                }338            }339 340            Parameters = new ReadOnlyCollection<CommandParameterInfo>(processedParameters);341        }342 343        #endregion private members344    }345}346