"Fossies" - the Fresh Open Source Software Archive

Member "PowerShell-7.2.6/src/System.Management.Automation/help/AliasHelpProvider.cs" (11 Aug 2022, 11394 Bytes) of package /linux/misc/PowerShell-7.2.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C# source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "AliasHelpProvider.cs" see the Fossies "Dox" file reference documentation.

    1 // Copyright (c) Microsoft Corporation.
    2 // Licensed under the MIT License.
    3 
    4 using System.Collections;
    5 using System.Collections.Generic;
    6 using System.Management.Automation.Internal;
    7 
    8 namespace System.Management.Automation
    9 {
   10     /// <summary>
   11     /// Implements the help provider for alias help.
   12     /// </summary>
   13     /// <remarks>
   14     /// Unlike other help providers, AliasHelpProvider directly inherits from HelpProvider
   15     /// instead of HelpProviderWithCache. This is because alias can be created/removed/updated
   16     /// 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 real
   19     /// help information, help forwarding is needed.
   20     /// </remarks>
   21     internal class AliasHelpProvider : HelpProvider
   22     {
   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 case
   40         /// of wildcard search patterns. This is currently not achievable
   41         /// 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 essential
   51         /// in creating AliasHelpInfo.
   52         /// </remarks>
   53         private readonly CommandDiscovery _commandDiscovery;
   54 
   55         #region Common Properties
   56 
   57         /// <summary>
   58         /// Name of alias help provider.
   59         /// </summary>
   60         /// <value>Name of alias help provider</value>
   61         internal override string Name
   62         {
   63             get
   64             {
   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 HelpCategory
   74         {
   75             get
   76             {
   77                 return HelpCategory.Alias;
   78             }
   79         }
   80 
   81         #endregion
   82 
   83         #region Help Provider Interface
   84 
   85         /// <summary>
   86         /// Exact match an alias help target.
   87         /// </summary>
   88         /// <remarks>
   89         /// This will
   90         ///     a. use _commandDiscovery object to retrieve AliasInfo object.
   91         ///     b. Create AliasHelpInfo object based on AliasInfo object
   92         /// </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             try
  100             {
  101                 commandInfo = _commandDiscovery.LookupCommandInfo(helpRequest.Target);
  102             }
  103             catch (CommandNotFoundException)
  104             {
  105                 // CommandNotFoundException is expected here if target doesn't match any
  106                 // 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. Individual
  132         /// 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 case
  140             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 SearchHelp
  164                             // as "get-help * -category alias" should not forwad help to
  165                             // CommandHelpProvider..(ExactMatchHelp does forward help to
  166                             // 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 SearchHelp
  211                             // as "get-help * -category alias" should not forwad help to
  212                             // CommandHelpProvider..(ExactMatchHelp does forward help to
  213                             // 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 accepts
  290             // 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 true
  299                     return true;
  300                 }
  301             }
  302 
  303             // We dont have a match so far..so return false
  304             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         #endregion
  321     }
  322 }