MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.ObjectModel;5using System.Management.Automation.Runspaces;6using System.Text;7 8namespace System.Management.Automation9{10 /// <summary>11 /// Provides information about a function that is stored in session state.12 /// </summary>13 public class FunctionInfo : CommandInfo, IScriptCommandInfo14 {15 #region ctor16 17 /// <summary>18 /// Creates an instance of the FunctionInfo class with the specified name and ScriptBlock.19 /// </summary>20 /// <param name="name">21 /// The name of the function.22 /// </param>23 /// <param name="function">24 /// The ScriptBlock for the function25 /// </param>26 /// <param name="context">27 /// The execution context for the function.28 /// </param>29 /// <exception cref="ArgumentNullException">30 /// If <paramref name="function"/> is null.31 /// </exception>32 internal FunctionInfo(string name, ScriptBlock function, ExecutionContext context) : this(name, function, context, null)33 {34 }35 36 /// <summary>37 /// Creates an instance of the FunctionInfo class with the specified name and ScriptBlock.38 /// </summary>39 /// <param name="name">40 /// The name of the function.41 /// </param>42 /// <param name="function">43 /// The ScriptBlock for the function44 /// </param>45 /// <param name="context">46 /// The execution context for the function.47 /// </param>48 /// <param name="helpFile">49 /// The name of the help file associated with the function.50 /// </param>51 /// <exception cref="ArgumentNullException">52 /// If <paramref name="function"/> is null.53 /// </exception>54 internal FunctionInfo(string name, ScriptBlock function, ExecutionContext context, string helpFile) : base(name, CommandTypes.Function, context)55 {56 if (function == null)57 {58 throw PSTraceSource.NewArgumentNullException(nameof(function));59 }60 61 _scriptBlock = function;62 63 CmdletInfo.SplitCmdletName(name, out _verb, out _noun);64 65 this.Module = function.Module;66 _helpFile = helpFile;67 }68 69 /// <summary>70 /// Creates an instance of the FunctionInfo class with the specified name and ScriptBlock.71 /// </summary>72 /// <param name="name">73 /// The name of the function.74 /// </param>75 /// <param name="function">76 /// The ScriptBlock for the function77 /// </param>78 /// <param name="options">79 /// The options to set on the function. Note, Constant can only be set at creation time.80 /// </param>81 /// <param name="context">82 /// The execution context for the function.83 /// </param>84 /// <exception cref="ArgumentNullException">85 /// If <paramref name="function"/> is null.86 /// </exception>87 internal FunctionInfo(string name, ScriptBlock function, ScopedItemOptions options, ExecutionContext context) : this(name, function, options, context, null)88 {89 }90 91 /// <summary>92 /// Creates an instance of the FunctionInfo class with the specified name and ScriptBlock.93 /// </summary>94 /// <param name="name">95 /// The name of the function.96 /// </param>97 /// <param name="function">98 /// The ScriptBlock for the function99 /// </param>100 /// <param name="options">101 /// The options to set on the function. Note, Constant can only be set at creation time.102 /// </param>103 /// <param name="context">104 /// The execution context for the function.105 /// </param>106 /// <param name="helpFile">107 /// The name of the help file associated with the function.108 /// </param>109 /// <exception cref="ArgumentNullException">110 /// If <paramref name="function"/> is null.111 /// </exception>112 internal FunctionInfo(string name, ScriptBlock function, ScopedItemOptions options, ExecutionContext context, string helpFile)113 : this(name, function, context, helpFile)114 {115 _options = options;116 }117 118 /// <summary>119 /// This is a copy constructor, used primarily for get-command.120 /// </summary>121 internal FunctionInfo(FunctionInfo other)122 : base(other)123 {124 CopyFieldsFromOther(other);125 }126 127 private void CopyFieldsFromOther(FunctionInfo other)128 {129 _verb = other._verb;130 _noun = other._noun;131 _scriptBlock = other._scriptBlock;132 _description = other._description;133 _options = other._options;134 _helpFile = other._helpFile;135 }136 137 /// <summary>138 /// This is a copy constructor, used primarily for get-command.139 /// </summary>140 internal FunctionInfo(string name, FunctionInfo other)141 : base(name, other)142 {143 CopyFieldsFromOther(other);144 145 // Get the verb and noun from the name146 CmdletInfo.SplitCmdletName(name, out _verb, out _noun);147 }148 149 /// <summary>150 /// Create a copy of commandInfo for GetCommandCommand so that we can generate parameter151 /// sets based on an argument list (so we can get the dynamic parameters.)152 /// </summary>153 internal override CommandInfo CreateGetCommandCopy(object[] arguments)154 {155 FunctionInfo copy = new FunctionInfo(this) { IsGetCommandCopy = true, Arguments = arguments };156 return copy;157 }158 159 #endregion ctor160 161 internal override HelpCategory HelpCategory162 {163 get { return HelpCategory.Function; }164 }165 166 /// <summary>167 /// Gets the ScriptBlock which is the implementation of the function.168 /// </summary>169 public ScriptBlock ScriptBlock170 {171 get { return _scriptBlock; }172 }173 174 private ScriptBlock _scriptBlock;175 176 /// <summary>177 /// Updates a function.178 /// </summary>179 /// <param name="newFunction">180 /// The script block that the function should represent.181 /// </param>182 /// <param name="force">183 /// If true, the script block will be applied even if the filter is ReadOnly.184 /// </param>185 /// <param name="options">186 /// Any options to set on the new function, null if none.187 /// </param>188 /// <exception cref="ArgumentNullException">189 /// If <paramref name="newFunction"/> is null.190 /// </exception>191 internal void Update(ScriptBlock newFunction, bool force, ScopedItemOptions options)192 {193 Update(newFunction, force, options, null);194 this.DefiningLanguageMode = newFunction.LanguageMode;195 }196 197 /// <summary/>198 protected internal virtual void Update(FunctionInfo newFunction, bool force, ScopedItemOptions options, string helpFile)199 {200 Update(newFunction.ScriptBlock, force, options, helpFile);201 }202 203 /// <summary>204 /// Updates a function.205 /// </summary>206 /// <param name="newFunction">207 /// The script block that the function should represent.208 /// </param>209 /// <param name="force">210 /// If true, the script block will be applied even if the filter is ReadOnly.211 /// </param>212 /// <param name="options">213 /// Any options to set on the new function, null if none.214 /// </param>215 /// <param name="helpFile">216 /// The helpfile for this function.217 /// </param>218 /// <exception cref="ArgumentNullException">219 /// If <paramref name="newFunction"/> is null.220 /// </exception>221 internal void Update(ScriptBlock newFunction, bool force, ScopedItemOptions options, string helpFile)222 {223 if (newFunction == null)224 {225 throw PSTraceSource.NewArgumentNullException("function");226 }227 228 if ((_options & ScopedItemOptions.Constant) != 0)229 {230 SessionStateUnauthorizedAccessException e =231 new SessionStateUnauthorizedAccessException(232 Name,233 SessionStateCategory.Function,234 "FunctionIsConstant",235 SessionStateStrings.FunctionIsConstant);236 237 throw e;238 }239 240 if (!force && (_options & ScopedItemOptions.ReadOnly) != 0)241 {242 SessionStateUnauthorizedAccessException e =243 new SessionStateUnauthorizedAccessException(244 Name,245 SessionStateCategory.Function,246 "FunctionIsReadOnly",247 SessionStateStrings.FunctionIsReadOnly);248 249 throw e;250 }251 252 _scriptBlock = newFunction;253 254 this.Module = newFunction.Module;255 _commandMetadata = null;256 this._parameterSets = null;257 this.ExternalCommandMetadata = null;258 259 if (options != ScopedItemOptions.Unspecified)260 {261 this.Options = options;262 }263 264 _helpFile = helpFile;265 }266 267 /// <summary>268 /// Returns <see langword="true"/> if this function uses cmdlet binding mode for its parameters; otherwise returns <see langword="false"/>.269 /// </summary>270 public bool CmdletBinding271 {272 get273 {274 return this.ScriptBlock.UsesCmdletBinding;275 }276 }277 278 /// <summary>279 /// Gets the name of the default parameter set.280 /// Returns <see langword="null"/> if this function doesn't use cmdlet parameter binding or if the default parameter set wasn't specified.281 /// </summary>282 public string DefaultParameterSet283 {284 get285 {286 return this.CmdletBinding ? this.CommandMetadata.DefaultParameterSetName : null;287 }288 }289 290 /// <summary>291 /// Gets the definition of the function which is the292 /// ToString() of the ScriptBlock that implements the function.293 /// </summary>294 public override string Definition { get { return _scriptBlock.ToString(); } }295 296 /// <summary>297 /// Gets or sets the scope options for the function.298 /// </summary>299 /// <exception cref="SessionStateUnauthorizedAccessException">300 /// If the trying to set a function that is constant or301 /// if the value trying to be set is ScopedItemOptions.Constant302 /// </exception>303 public ScopedItemOptions Options304 {305 get306 {307 return CopiedCommand == null ? _options : ((FunctionInfo)CopiedCommand).Options;308 }309 310 set311 {312 if (CopiedCommand == null)313 {314 // Check to see if the function is constant, if so315 // throw an exception because the options cannot be changed.316 317 if ((_options & ScopedItemOptions.Constant) != 0)318 {319 SessionStateUnauthorizedAccessException e =320 new SessionStateUnauthorizedAccessException(321 Name,322 SessionStateCategory.Function,323 "FunctionIsConstant",324 SessionStateStrings.FunctionIsConstant);325 326 throw e;327 }328 329 // Now check to see if the caller is trying to set330 // the options to constant. This is only allowed at331 // variable creation332 333 if ((value & ScopedItemOptions.Constant) != 0)334 {335 // user is trying to set the function to constant after336 // creating the function. Do not allow this (as per spec).337 338 SessionStateUnauthorizedAccessException e =339 new SessionStateUnauthorizedAccessException(340 Name,341 SessionStateCategory.Function,342 "FunctionCannotBeMadeConstant",343 SessionStateStrings.FunctionCannotBeMadeConstant);344 345 throw e;346 }347 348 // Ensure we are not trying to remove the AllScope option349 350 if ((value & ScopedItemOptions.AllScope) == 0 &&351 (_options & ScopedItemOptions.AllScope) != 0)352 {353 SessionStateUnauthorizedAccessException e =354 new SessionStateUnauthorizedAccessException(355 this.Name,356 SessionStateCategory.Function,357 "FunctionAllScopeOptionCannotBeRemoved",358 SessionStateStrings.FunctionAllScopeOptionCannotBeRemoved);359 360 throw e;361 }362 363 _options = value;364 }365 else366 {367 ((FunctionInfo)CopiedCommand).Options = value;368 }369 }370 }371 372 private ScopedItemOptions _options = ScopedItemOptions.None;373 374 /// <summary>375 /// Gets or sets the description associated with the function.376 /// </summary>377 public string Description378 {379 get380 {381 return CopiedCommand == null ? _description : ((FunctionInfo)CopiedCommand).Description;382 }383 384 set385 {386 if (CopiedCommand == null)387 {388 _description = value;389 }390 else391 {392 ((FunctionInfo)CopiedCommand).Description = value;393 }394 }395 }396 397 private string _description = null;398 399 /// <summary>400 /// Gets the verb of the function.401 /// </summary>402 public string Verb403 {404 get405 {406 return _verb;407 }408 }409 410 private string _verb = string.Empty;411 412 /// <summary>413 /// Gets the noun of the function.414 /// </summary>415 public string Noun416 {417 get418 {419 return _noun;420 }421 }422 423 private string _noun = string.Empty;424 425 /// <summary>426 /// Gets the help file path for the function.427 /// </summary>428 public string HelpFile429 {430 get431 {432 return _helpFile;433 }434 435 internal set436 {437 _helpFile = value;438 }439 }440 441 private string _helpFile = string.Empty;442 443 /// <summary>444 /// Returns the syntax of a command.445 /// </summary>446 internal override string Syntax447 {448 get449 {450 StringBuilder synopsis = new StringBuilder();451 452 foreach (CommandParameterSetInfo parameterSet in ParameterSets)453 {454 synopsis.AppendLine();455 synopsis.AppendLine(456 string.Format(457 Globalization.CultureInfo.CurrentCulture,458 "{0} {1}",459 Name,460 parameterSet.ToString()));461 }462 463 return synopsis.ToString();464 }465 }466 467 /// <summary>468 /// True if the command has dynamic parameters, false otherwise.469 /// </summary>470 internal override bool ImplementsDynamicParameters471 {472 get { return ScriptBlock.HasDynamicParameters; }473 }474 475 /// <summary>476 /// The command metadata for the function or filter.477 /// </summary>478 internal override CommandMetadata CommandMetadata479 {480 get481 {482 return _commandMetadata ??=483 new CommandMetadata(this.ScriptBlock, this.Name, LocalPipeline.GetExecutionContextFromTLS());484 }485 }486 487 private CommandMetadata _commandMetadata;488 489 /// <summary>490 /// The output type(s) is specified in the script block.491 /// </summary>492 public override ReadOnlyCollection<PSTypeName> OutputType493 {494 get { return ScriptBlock.OutputType; }495 }496 }497}498 