MegaBites-AI/Windows-powershell
0372
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Diagnostics;5using System.Management.Automation.Language;6 7namespace System.Management.Automation8{9 /// <summary>10 /// Represents a parameter to the Command.11 /// </summary>12 [DebuggerDisplay("{ParameterName}")]13 internal sealed class CommandParameterInternal14 {15 private sealed class Parameter16 {17 internal Ast ast;18 internal string parameterName;19 internal string parameterText;20 }21 22 private sealed class Argument23 {24 internal Ast ast;25 internal object value;26 internal bool splatted;27 }28 29 private Parameter _parameter;30 private Argument _argument;31 private bool _spaceAfterParameter;32 private bool _fromHashtableSplatting;33 34 internal bool SpaceAfterParameter => _spaceAfterParameter;35 36 internal bool ParameterNameSpecified => _parameter != null;37 38 internal bool ArgumentSpecified => _argument != null;39 40 internal bool ParameterAndArgumentSpecified => ParameterNameSpecified && ArgumentSpecified;41 42 internal bool FromHashtableSplatting => _fromHashtableSplatting;43 44 /// <summary>45 /// Gets and sets the string that represents parameter name, which does not include the '-' (dash).46 /// </summary>47 internal string ParameterName48 {49 get50 {51 Diagnostics.Assert(ParameterNameSpecified, "Caller must verify parameter name was specified");52 return _parameter.parameterName;53 }54 55 set56 {57 Diagnostics.Assert(ParameterNameSpecified, "Caller must verify parameter name was specified");58 _parameter.parameterName = value;59 }60 }61 62 /// <summary>63 /// The text of the parameter, which typically includes the leading '-' (dash) and, if specified, the trailing ':'.64 /// </summary>65 internal string ParameterText66 {67 get68 {69 Diagnostics.Assert(ParameterNameSpecified, "Caller must verify parameter name was specified");70 return _parameter.parameterText;71 }72 }73 74 /// <summary>75 /// The ast of the parameter, if one was specified.76 /// </summary>77 internal Ast ParameterAst78 {79 get => _parameter?.ast;80 }81 82 /// <summary>83 /// The extent of the parameter, if one was specified.84 /// </summary>85 internal IScriptExtent ParameterExtent86 {87 get => ParameterAst?.Extent ?? PositionUtilities.EmptyExtent;88 }89 90 /// <summary>91 /// The ast of the optional argument, if one was specified.92 /// </summary>93 internal Ast ArgumentAst94 {95 get => _argument?.ast;96 }97 98 /// <summary>99 /// The extent of the optional argument, if one was specified.100 /// </summary>101 internal IScriptExtent ArgumentExtent102 {103 get => ArgumentAst?.Extent ?? PositionUtilities.EmptyExtent;104 }105 106 /// <summary>107 /// The value of the optional argument, if one was specified, otherwise UnboundParameter.Value.108 /// </summary>109 internal object ArgumentValue110 {111 get { return _argument != null ? _argument.value : UnboundParameter.Value; }112 }113 114 /// <summary>115 /// If an argument was specified and is to be splatted, returns true, otherwise false.116 /// </summary>117 internal bool ArgumentToBeSplatted118 {119 get { return _argument != null && _argument.splatted; }120 }121 122 /// <summary>123 /// Set the argument value and ast.124 /// </summary>125 internal void SetArgumentValue(Ast ast, object value)126 {127 _argument ??= new Argument();128 129 _argument.value = value;130 _argument.ast = ast;131 }132 133 /// <summary>134 /// The extent to use when reporting generic errors. The argument extent is used, if it is not empty, otherwise135 /// the parameter extent is used. Some errors may prefer the parameter extent and should not use this method.136 /// </summary>137 internal IScriptExtent ErrorExtent138 {139 get140 {141 var argExtent = ArgumentExtent;142 return argExtent != PositionUtilities.EmptyExtent ? argExtent : ParameterExtent;143 }144 }145 146 #region ctor147 148 /// <summary>149 /// Create a parameter when no argument has been specified.150 /// </summary>151 /// <param name="ast">The ast in script of the parameter.</param>152 /// <param name="parameterName">The parameter name (with no leading dash).</param>153 /// <param name="parameterText">The text of the parameter, as it did, or would, appear in script.</param>154 internal static CommandParameterInternal CreateParameter(155 string parameterName,156 string parameterText,157 Ast ast = null)158 {159 return new CommandParameterInternal160 {161 _parameter =162 new Parameter { ast = ast, parameterName = parameterName, parameterText = parameterText }163 };164 }165 166 /// <summary>167 /// Create a positional argument to a command.168 /// </summary>169 /// <param name="value">The argument value.</param>170 /// <param name="ast">The ast of the argument value in the script.</param>171 /// <param name="splatted">True if the argument value is to be splatted, false otherwise.</param>172 internal static CommandParameterInternal CreateArgument(173 object value,174 Ast ast = null,175 bool splatted = false)176 {177 return new CommandParameterInternal178 {179 _argument = new Argument180 {181 value = value,182 ast = ast,183 splatted = splatted,184 }185 };186 }187 188 /// <summary>189 /// Create an named argument, where the parameter name is known. This can happen when:190 /// * The user uses the ':' syntax, as in191 /// foo -bar:val192 /// * Splatting, as in193 /// $x = @{ bar = val } ; foo @x194 /// * Via an API - when converting a CommandParameter to CommandParameterInternal.195 /// * In the parameter binder when it resolves a positional argument196 /// * Other random places that manually construct command processors and know their arguments.197 /// </summary>198 /// <param name="parameterAst">The ast in script of the parameter.</param>199 /// <param name="parameterName">The parameter name (with no leading dash).</param>200 /// <param name="parameterText">The text of the parameter, as it did, or would, appear in script.</param>201 /// <param name="argumentAst">The ast of the argument value in the script.</param>202 /// <param name="value">The argument value.</param>203 /// <param name="spaceAfterParameter">Used in native commands to correctly handle -foo:bar vs. -foo: bar.</param>204 /// <param name="fromSplatting">Indicate if this parameter-argument pair comes from splatting.</param>205 internal static CommandParameterInternal CreateParameterWithArgument(206 Ast parameterAst,207 string parameterName,208 string parameterText,209 Ast argumentAst,210 object value,211 bool spaceAfterParameter,212 bool fromSplatting = false)213 {214 return new CommandParameterInternal215 {216 _parameter = new Parameter { ast = parameterAst, parameterName = parameterName, parameterText = parameterText },217 _argument = new Argument { ast = argumentAst, value = value },218 _spaceAfterParameter = spaceAfterParameter,219 _fromHashtableSplatting = fromSplatting,220 };221 }222 223 #endregion ctor224 225 internal bool IsDashQuestion()226 {227 return ParameterNameSpecified && (ParameterName.Equals("?", StringComparison.OrdinalIgnoreCase));228 }229 }230}231 