Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
AliasHelpProvider.cs323 linesDownload Raw Back to help
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections;5using System.Collections.Generic;6using System.Management.Automation.Internal;7 8namespace System.Management.Automation9{10    /// <summary>11    /// Implements the help provider for alias help.12    /// </summary>13    /// <remarks>14    /// Unlike other help providers, AliasHelpProvider directly inherits from HelpProvider15    /// instead of HelpProviderWithCache. This is because alias can be created/removed/updated16    /// in a Microsoft Command Shell session. And thus caching may result in old alias being cached.17    ///18    /// The real information for alias is stored in command help. To retrieve the real19    /// help information, help forwarding is needed.20    /// </remarks>21    internal class AliasHelpProvider : HelpProvider22    {23        /// <summary>24        /// Initializes a new instance of AliasHelpProvider class.25        /// </summary>26        internal AliasHelpProvider(HelpSystem helpSystem) : base(helpSystem)27        {28            _sessionState = helpSystem.ExecutionContext.SessionState;29            _commandDiscovery = helpSystem.ExecutionContext.CommandDiscovery;30            _context = helpSystem.ExecutionContext;31        }32 33        private readonly ExecutionContext _context;34 35        /// <summary>36        /// Session state for current Microsoft Command Shell session.37        /// </summary>38        /// <remarks>39        /// _sessionState is mainly used for alias help search in the case40        /// of wildcard search patterns. This is currently not achievable41        /// through _commandDiscovery.42        /// </remarks>43        private readonly SessionState _sessionState;44 45        /// <summary>46        /// Command Discovery object for current session.47        /// </summary>48        /// <remarks>49        /// _commandDiscovery is mainly used for exact match help for alias.50        /// The AliasInfo object returned from _commandDiscovery is essential51        /// in creating AliasHelpInfo.52        /// </remarks>53        private readonly CommandDiscovery _commandDiscovery;54 55        #region Common Properties56 57        /// <summary>58        /// Name of alias help provider.59        /// </summary>60        /// <value>Name of alias help provider</value>61        internal override string Name62        {63            get64            {65                return "Alias Help Provider";66            }67        }68 69        /// <summary>70        /// Help category of alias help provider, which is a constant: HelpCategory.Alias.71        /// </summary>72        /// <value>Help category of alias help provider.</value>73        internal override HelpCategory HelpCategory74        {75            get76            {77                return HelpCategory.Alias;78            }79        }80 81        #endregion82 83        #region Help Provider Interface84 85        /// <summary>86        /// Exact match an alias help target.87        /// </summary>88        /// <remarks>89        /// This will90        ///     a. use _commandDiscovery object to retrieve AliasInfo object.91        ///     b. Create AliasHelpInfo object based on AliasInfo object92        /// </remarks>93        /// <param name="helpRequest">Help request object.</param>94        /// <returns>Help info found.</returns>95        internal override IEnumerable<HelpInfo> ExactMatchHelp(HelpRequest helpRequest)96        {97            CommandInfo commandInfo = null;98 99            try100            {101                commandInfo = _commandDiscovery.LookupCommandInfo(helpRequest.Target);102            }103            catch (CommandNotFoundException)104            {105                // CommandNotFoundException is expected here if target doesn't match any106                // commandlet. Just ignore this exception and bail out.107            }108 109            if ((commandInfo != null) && (commandInfo.CommandType == CommandTypes.Alias))110            {111                AliasInfo aliasInfo = (AliasInfo)commandInfo;112 113                HelpInfo helpInfo = AliasHelpInfo.GetHelpInfo(aliasInfo);114                if (helpInfo != null)115                {116                    yield return helpInfo;117                }118            }119        }120 121        /// <summary>122        /// Search an alias help target.123        /// </summary>124        /// <remarks>125        /// This will,126        ///     a. use _sessionState object to get a list of alias that match the target.127        ///     b. for each alias, retrieve help info as in ExactMatchHelp.128        /// </remarks>129        /// <param name="helpRequest">Help request object.</param>130        /// <param name="searchOnlyContent">131        /// If true, searches for pattern in the help content. Individual132        /// provider can decide which content to search in.133        ///134        /// If false, searches for pattern in the command names.135        /// </param>136        /// <returns>A IEnumerable of helpinfo object.</returns>137        internal override IEnumerable<HelpInfo> SearchHelp(HelpRequest helpRequest, bool searchOnlyContent)138        {139            // aliases do not have help content...so doing nothing in that case140            if (!searchOnlyContent)141            {142                string target = helpRequest.Target;143                string pattern = target;144                var allAliases = new HashSet<string>(StringComparer.OrdinalIgnoreCase);145 146                if (!WildcardPattern.ContainsWildcardCharacters(target))147                {148                    pattern += "*";149                }150 151                WildcardPattern matcher = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);152                IDictionary<string, AliasInfo> aliasTable = _sessionState.Internal.GetAliasTable();153 154                foreach (string name in aliasTable.Keys)155                {156                    if (matcher.IsMatch(name))157                    {158                        HelpRequest exactMatchHelpRequest = helpRequest.Clone();159                        exactMatchHelpRequest.Target = name;160                        // Duplicates??161                        foreach (HelpInfo helpInfo in ExactMatchHelp(exactMatchHelpRequest))162                        {163                            // Component/Role/Functionality match is done only for SearchHelp164                            // as "get-help * -category alias" should not forward help to165                            // CommandHelpProvider..(ExactMatchHelp does forward help to166                            // CommandHelpProvider)167                            if (!Match(helpInfo, helpRequest))168                            {169                                continue;170                            }171 172                            if (allAliases.Contains(name))173                            {174                                continue;175                            }176 177                            allAliases.Add(name);178 179                            yield return helpInfo;180                        }181                    }182                }183 184                CommandSearcher searcher =185                        new CommandSearcher(186                            pattern,187                            SearchResolutionOptions.ResolveAliasPatterns, CommandTypes.Alias,188                            _context);189 190                while (searcher.MoveNext())191                {192                    CommandInfo current = ((IEnumerator<CommandInfo>)searcher).Current;193 194                    if (_context.CurrentPipelineStopping)195                    {196                        yield break;197                    }198 199                    AliasInfo alias = current as AliasInfo;200 201                    if (alias != null)202                    {203                        string name = alias.Name;204                        HelpRequest exactMatchHelpRequest = helpRequest.Clone();205                        exactMatchHelpRequest.Target = name;206 207                        // Duplicates??208                        foreach (HelpInfo helpInfo in ExactMatchHelp(exactMatchHelpRequest))209                        {210                            // Component/Role/Functionality match is done only for SearchHelp211                            // as "get-help * -category alias" should not forward help to212                            // CommandHelpProvider..(ExactMatchHelp does forward help to213                            // CommandHelpProvider)214                            if (!Match(helpInfo, helpRequest))215                            {216                                continue;217                            }218 219                            if (allAliases.Contains(name))220                            {221                                continue;222                            }223 224                            allAliases.Add(name);225 226                            yield return helpInfo;227                        }228                    }229                }230 231                foreach (CommandInfo current in ModuleUtils.GetMatchingCommands(pattern, _context, helpRequest.CommandOrigin))232                {233                    if (_context.CurrentPipelineStopping)234                    {235                        yield break;236                    }237 238                    AliasInfo alias = current as AliasInfo;239 240                    if (alias != null)241                    {242                        string name = alias.Name;243 244                        HelpInfo helpInfo = AliasHelpInfo.GetHelpInfo(alias);245 246                        if (allAliases.Contains(name))247                        {248                            continue;249                        }250 251                        allAliases.Add(name);252 253                        yield return helpInfo;254                    }255                }256            }257        }258 259        private static bool Match(HelpInfo helpInfo, HelpRequest helpRequest)260        {261            if (helpRequest == null)262                return true;263 264            if ((helpRequest.HelpCategory & helpInfo.HelpCategory) == 0)265            {266                return false;267            }268 269            if (!Match(helpInfo.Component, helpRequest.Component))270            {271                return false;272            }273 274            if (!Match(helpInfo.Role, helpRequest.Role))275            {276                return false;277            }278 279            if (!Match(helpInfo.Functionality, helpRequest.Functionality))280            {281                return false;282            }283 284            return true;285        }286 287        private static bool Match(string target, string[] patterns)288        {289            // patterns should never be null as shell never accepts290            // empty inputs. Keeping this check as a safe measure.291            if (patterns == null || patterns.Length == 0)292                return true;293 294            foreach (string pattern in patterns)295            {296                if (Match(target, pattern))297                {298                    // we have a match so return true299                    return true;300                }301            }302 303            // We dont have a match so far..so return false304            return false;305        }306 307        private static bool Match(string target, string pattern)308        {309            if (string.IsNullOrEmpty(pattern))310                return true;311 312            if (string.IsNullOrEmpty(target))313                target = string.Empty;314 315            WildcardPattern matcher = WildcardPattern.Get(pattern, WildcardOptions.IgnoreCase);316 317            return matcher.IsMatch(target);318        }319 320        #endregion321    }322}323