MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.ObjectModel;5 6using Dbg = System.Management.Automation;7 8namespace System.Management.Automation9{10 /// <summary>11 /// A collection of the attributes on the PSVariable object.12 /// </summary>13 internal class PSVariableAttributeCollection : Collection<Attribute>14 {15 #region constructor16 17 /// <summary>18 /// Constructs a variable attribute collection attached to19 /// the specified variable. Whenever the attributes change20 /// the variable value is verified against the attribute.21 /// </summary>22 /// <param name="variable">23 /// The variable that needs to be verified anytime an attribute24 /// changes.25 /// </param>26 /// <exception cref="ArgumentNullException">27 /// If <paramref name="variable"/> is null.28 /// </exception>29 internal PSVariableAttributeCollection(PSVariable variable)30 {31 if (variable == null)32 {33 throw PSTraceSource.NewArgumentNullException(nameof(variable));34 }35 36 _variable = variable;37 }38 #endregion constructor39 40 #region Collection overrides41 42 /// <summary>43 /// Ensures that the variable that the attribute is being added to is still44 /// valid after the attribute is added.45 /// </summary>46 /// <param name="index">47 /// The zero-based index at which <paramref name="item"/> should be inserted.48 /// </param>49 /// <param name="item">50 /// The attribute being added to the collection.51 /// </param>52 /// <exception cref="ValidationMetadataException">53 /// If the new attribute causes the variable to be in an invalid state.54 /// </exception>55 /// <exception cref="ArgumentTransformationMetadataException">56 /// If the new attribute is an ArgumentTransformationAttribute and the transformation57 /// fails.58 /// </exception>59 protected override void InsertItem(int index, Attribute item)60 {61 object variableValue = VerifyNewAttribute(item);62 63 base.InsertItem(index, item);64 65 _variable.SetValueRaw(variableValue, true);66 }67 68 /// <summary>69 /// Ensures that the variable that the attribute is being set to is still70 /// valid after the attribute is set.71 /// </summary>72 /// <param name="index">73 /// The zero-based index at which <paramref name="item"/> should be set.74 /// </param>75 /// <param name="item">76 /// The attribute being set in the collection.77 /// </param>78 /// <exception cref="ValidationMetadataException">79 /// If the new attribute causes the variable to be in an invalid state.80 /// </exception>81 protected override void SetItem(int index, Attribute item)82 {83 object variableValue = VerifyNewAttribute(item);84 85 base.SetItem(index, item);86 87 _variable.SetValueRaw(variableValue, true);88 }89 #endregion Collection overrides90 91 #region private data92 93 /// <summary>94 /// Ordinarily, the collection checks/converts the value (by applying the attribute)95 /// when an attribute is added. This is both slow and wrong when the attributes96 /// have already been checked/applied during parameter binding. So if checking97 /// has already been done, this function will add the attribute without checking98 /// and possibly updating the value.99 /// </summary>100 /// <param name="item">The attribute to add.</param>101 internal void AddAttributeNoCheck(Attribute item)102 {103 base.InsertItem(this.Count, item);104 }105 106 /// <summary>107 /// Validates and performs any transformations that the new attribute108 /// implements.109 /// </summary>110 /// <param name="item">111 /// The new attribute to be added to the collection.112 /// </param>113 /// <returns>114 /// The new variable value. This may change from the original value if the115 /// new attribute is an ArgumentTransformationAttribute.116 /// </returns>117 private object VerifyNewAttribute(Attribute item)118 {119 object variableValue = _variable.Value;120 121 // Perform transformation before validating122 ArgumentTransformationAttribute argumentTransformation = item as ArgumentTransformationAttribute;123 if (argumentTransformation != null)124 {125 // Get an EngineIntrinsics instance using the context of the thread.126 127 ExecutionContext context = Runspaces.LocalPipeline.GetExecutionContextFromTLS();128 EngineIntrinsics engine = null;129 130 if (context != null)131 {132 engine = context.EngineIntrinsics;133 }134 135 variableValue = argumentTransformation.TransformInternal(engine, variableValue);136 }137 138 if (!PSVariable.IsValidValue(variableValue, item))139 {140 ValidationMetadataException e = new ValidationMetadataException(141 "ValidateSetFailure",142 null,143 Metadata.InvalidMetadataForCurrentValue,144 _variable.Name,145 ((_variable.Value != null) ? _variable.Value.ToString() : string.Empty));146 147 throw e;148 }149 150 return variableValue;151 }152 153 /// <summary>154 /// The variable whose value needs to be verified anytime155 /// the attributes change.156 /// </summary>157 private readonly PSVariable _variable;158 #endregion private data159 }160}161 