/
githubmirror
/
PowerShell
Обзор
Документация
Войти
/
githubmirror
/
PowerShell
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/System.Management.Automation/engine/ParameterSetInfo.cs
345 строк
13 KB
Dongbo Wang
Revert some of the interpolated string changes (#19018)
25 янв 2023, 20:46
Не верифицирован
25 янв 2023, 20:46
b195088
Код
Авторство
О чём код?
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; using System.Text.RegularExpressions; using Microsoft.PowerShell; using Dbg = System.Management.Automation.Diagnostics; namespace System.Management.Automation { /// <summary> /// The information about a parameter set and its parameters for a cmdlet. /// </summary> public class CommandParameterSetInfo { #region ctor /// <summary> /// Constructs the parameter set information using the specified parameter name, /// and type metadata. /// </summary> /// <param name="name"> /// The formal name of the parameter. /// </param> /// <param name="isDefaultParameterSet"> /// True if the parameter set is the default parameter set, or false otherwise. /// </param> /// <param name="parameterSetFlag"> /// The bit that specifies the parameter set in the type metadata. /// </param> /// <param name="parameterMetadata"> /// The type metadata about the cmdlet. /// </param> /// <exception cref="ArgumentException"> /// If <paramref name="name"/> is null or empty. /// </exception> /// <exception cref="ArgumentNullException"> /// If <paramref name="parameterMetadata"/> is null. /// </exception> internal CommandParameterSetInfo( string name, bool isDefaultParameterSet, uint parameterSetFlag, MergedCommandParameterMetadata parameterMetadata) { IsDefault = true; Name = string.Empty; if (string.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException(nameof(name)); } if (parameterMetadata == null) { throw PSTraceSource.NewArgumentNullException(nameof(parameterMetadata)); } this.Name = name; this.IsDefault = isDefaultParameterSet; Initialize(parameterMetadata, parameterSetFlag); } #endregion ctor #region public members /// <summary> /// Gets the name of the parameter set. /// </summary> public string Name { get; } /// <summary> /// Gets whether the parameter set is the default parameter set. /// </summary> public bool IsDefault { get; } /// <summary> /// Gets the parameter information for the parameters in this parameter set. /// </summary> public ReadOnlyCollection<CommandParameterInfo> Parameters { get; private set; } /// <summary> /// Gets the synopsis for the cmdlet as a string. /// </summary> public override string ToString() { Text.StringBuilder result = new Text.StringBuilder(); GenerateParametersInDisplayOrder( parameter => AppendFormatCommandParameterInfo(parameter, result), (string str) => { if (result.Length > 0) { result.Append(' '); } result.Append('['); result.Append(str); result.Append(']'); }); return result.ToString(); } /// <summary> /// GenerateParameters parameters in display order /// ie., Positional followed by /// Named Mandatory (in alpha numeric) followed by /// Named (in alpha numeric). /// /// Callers use <paramref name="parameterAction"/> and /// <paramref name="commonParameterAction"/> to handle /// syntax generation etc. /// </summary> /// <param name="parameterAction"></param> /// <param name="commonParameterAction"></param> /// <returns></returns> internal void GenerateParametersInDisplayOrder( Action<CommandParameterInfo> parameterAction, Action<string> commonParameterAction) { // First figure out the positions List<CommandParameterInfo> sortedPositionalParameters = new List<CommandParameterInfo>(); List<CommandParameterInfo> namedMandatoryParameters = new List<CommandParameterInfo>(); List<CommandParameterInfo> namedParameters = new List<CommandParameterInfo>(); foreach (CommandParameterInfo parameter in Parameters) { if (parameter.Position == int.MinValue) { // The parameter is a named parameter if (parameter.IsMandatory) { namedMandatoryParameters.Add(parameter); } else { namedParameters.Add(parameter); } } else { // The parameter is positional so add it at the correct // index (note we have to pad the list if the position is // higher than the list count since we don't have any requirements // that positional parameters start at zero and are consecutive. if (parameter.Position >= sortedPositionalParameters.Count) { for (int fillerIndex = sortedPositionalParameters.Count; fillerIndex <= parameter.Position; ++fillerIndex) { sortedPositionalParameters.Add(null); } } sortedPositionalParameters[parameter.Position] = parameter; } } foreach (CommandParameterInfo parameter in sortedPositionalParameters) { if (parameter == null) { continue; } parameterAction(parameter); } // Now convert the named mandatory parameters into a string foreach (CommandParameterInfo parameter in namedMandatoryParameters) { if (parameter == null) { continue; } parameterAction(parameter); } List<CommandParameterInfo> commonParameters = new List<CommandParameterInfo>(); // Now convert the named parameters into a string foreach (CommandParameterInfo parameter in namedParameters) { if (parameter == null) { continue; } // Hold off common parameters bool isCommon = Cmdlet.CommonParameters.Contains(parameter.Name, StringComparer.OrdinalIgnoreCase); if (!isCommon) { parameterAction(parameter); } else { commonParameters.Add(parameter); } } // If all common parameters are present, group them together if (commonParameters.Count == Cmdlet.CommonParameters.Count) { commonParameterAction(HelpDisplayStrings.CommonParameters); } // Else, convert to string as before else { foreach (CommandParameterInfo parameter in commonParameters) { parameterAction(parameter); } } } #endregion public members #region private members private static void AppendFormatCommandParameterInfo(CommandParameterInfo parameter, Text.StringBuilder result) { if (result.Length > 0) { // Add a space between parameters result.Append(' '); } if (parameter.ParameterType == typeof(SwitchParameter)) { result.AppendFormat(CultureInfo.InvariantCulture, parameter.IsMandatory ? "-{0}" : "[-{0}]", parameter.Name); } else { string parameterTypeString = GetParameterTypeString(parameter.ParameterType, parameter.Attributes); if (parameter.IsMandatory) { result.AppendFormat( CultureInfo.InvariantCulture, parameter.Position != int.MinValue ? "[-{0}] <{1}>" : "-{0} <{1}>", parameter.Name, parameterTypeString); } else { result.AppendFormat( CultureInfo.InvariantCulture, parameter.Position != int.MinValue ? "[[-{0}] <{1}>]" : "[-{0} <{1}>]", parameter.Name, parameterTypeString); } } } internal static string GetParameterTypeString(Type type, IEnumerable<Attribute> attributes) { string parameterTypeString; PSTypeNameAttribute typeName; if (attributes != null && (typeName = attributes.OfType<PSTypeNameAttribute>().FirstOrDefault()) != null) { // If we have a PSTypeName specified on the class, we assume it has a more useful type than the actual // parameter type. This is a reasonable assumption, the parameter binder does honor this attribute. // // This typename might be long, e.g.: // Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Process // System.Management.ManagementObject#root\cimv2\Win32_Process // To shorten this, we will drop the namespaces, both on the .Net side and the CIM/WMI side: // CimInstance#Win32_Process // If our regex doesn't match, we'll just use the full name. var match = Regex.Match(typeName.PSTypeName, "(.*\\.)?(?<NetTypeName>.*)#(.*[/\\\\])?(?<CimClassName>.*)"); if (match.Success) { parameterTypeString = match.Groups["NetTypeName"].Value + "#" + match.Groups["CimClassName"].Value; } else { parameterTypeString = typeName.PSTypeName; // Drop the namespace from the typename, if any. var lastDotIndex = parameterTypeString.LastIndexOf('.'); if (lastDotIndex != -1 && lastDotIndex + 1 < parameterTypeString.Length) { parameterTypeString = parameterTypeString.Substring(lastDotIndex + 1); } } // If the type is really an array, but the typename didn't include [], then add it. if (type.IsArray && !parameterTypeString.Contains("[]", StringComparison.Ordinal)) { var t = type; while (t.IsArray) { parameterTypeString += "[]"; t = t.GetElementType(); } } } else { Type parameterType = Nullable.GetUnderlyingType(type) ?? type; parameterTypeString = ToStringCodeMethods.Type(parameterType, true); } return parameterTypeString; } private void Initialize(MergedCommandParameterMetadata parameterMetadata, uint parameterSetFlag) { Diagnostics.Assert( parameterMetadata != null, "The parameterMetadata should never be null"); Collection<CommandParameterInfo> processedParameters = new Collection<CommandParameterInfo>(); // Get the parameters in the parameter set Collection<MergedCompiledCommandParameter> compiledParameters = parameterMetadata.GetParametersInParameterSet(parameterSetFlag); foreach (MergedCompiledCommandParameter parameter in compiledParameters) { if (parameter != null) { processedParameters.Add( new CommandParameterInfo(parameter.Parameter, parameterSetFlag)); } } Parameters = new ReadOnlyCollection<CommandParameterInfo>(processedParameters); } #endregion private members } }