MegaBites-AI/Windows-powershell
0308
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Generic;5using System.Management.Automation.Runspaces;6 7using Dbg = System.Management.Automation;8 9namespace System.Management.Automation10{11 /// <summary>12 /// Holds the state of a Monad Shell session.13 /// </summary>14 internal sealed partial class SessionStateInternal15 {16 #region aliases17 18 /// <summary>19 /// Add a new alias entry to this session state object...20 /// </summary>21 /// <param name="entry">The entry to add.</param>22 /// <param name="scopeID">23 /// A scope identifier that is either one of the "special" scopes like24 /// "global", "script", "local", or "private, or a numeric ID of a relative scope25 /// to the current scope.26 /// </param>27 internal void AddSessionStateEntry(SessionStateAliasEntry entry, string scopeID)28 {29 AliasInfo alias = new AliasInfo(entry.Name, entry.Definition, this.ExecutionContext, entry.Options)30 {31 Visibility = entry.Visibility,32 Module = entry.Module,33 Description = entry.Description34 };35 36 // Create alias in the global scope...37 this.SetAliasItemAtScope(alias, scopeID, true, CommandOrigin.Internal);38 }39 40 /// <summary>41 /// Gets an IEnumerable for the alias table.42 /// </summary>43 internal IDictionary<string, AliasInfo> GetAliasTable()44 {45 // On 7.0 version we have 132 aliases so we set a larger number to reduce re-allocations.46 const int InitialAliasCount = 150;47 Dictionary<string, AliasInfo> result =48 new Dictionary<string, AliasInfo>(InitialAliasCount, StringComparer.OrdinalIgnoreCase);49 50 SessionStateScopeEnumerator scopeEnumerator =51 new SessionStateScopeEnumerator(_currentScope);52 53 foreach (SessionStateScope scope in scopeEnumerator)54 {55 foreach (AliasInfo entry in scope.AliasTable)56 {57 if (!result.ContainsKey(entry.Name))58 {59 // Make sure the alias isn't private or if it is that the current60 // scope is the same scope the alias was retrieved from.61 62 if ((entry.Options & ScopedItemOptions.Private) == 0 ||63 scope == _currentScope)64 {65 result.Add(entry.Name, entry);66 }67 }68 }69 }70 71 return result;72 }73 74 /// <summary>75 /// Gets an IEnumerable for the alias table for a given scope.76 /// </summary>77 /// <param name="scopeID">78 /// A scope identifier that is either one of the "special" scopes like79 /// "global", "script", "local", or "private, or a numeric ID of a relative scope80 /// to the current scope.81 /// </param>82 /// <exception cref="ArgumentException">83 /// If <paramref name="scopeID"/> is less than zero, or not84 /// a number and not "script", "global", "local", or "private"85 /// </exception>86 /// <exception cref="ArgumentOutOfRangeException">87 /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently88 /// active scopes.89 /// </exception>90 internal IDictionary<string, AliasInfo> GetAliasTableAtScope(string scopeID)91 {92 Dictionary<string, AliasInfo> result =93 new Dictionary<string, AliasInfo>(StringComparer.OrdinalIgnoreCase);94 95 SessionStateScope scope = GetScopeByID(scopeID);96 97 foreach (AliasInfo entry in scope.AliasTable)98 {99 // Make sure the alias isn't private or if it is that the current100 // scope is the same scope the alias was retrieved from.101 102 if ((entry.Options & ScopedItemOptions.Private) == 0 ||103 scope == _currentScope)104 {105 result.Add(entry.Name, entry);106 }107 }108 109 return result;110 }111 112 /// <summary>113 /// List of aliases to export from this session state object...114 /// </summary>115 internal List<AliasInfo> ExportedAliases { get; } = new List<AliasInfo>();116 117 /// <summary>118 /// Gets the value of the specified alias from the alias table.119 /// </summary>120 /// <param name="aliasName">121 /// The name of the alias value to retrieve.122 /// </param>123 /// <param name="origin">124 /// The origin of the command calling this API.125 /// </param>126 /// <returns>127 /// The AliasInfo representing the alias.128 /// </returns>129 internal AliasInfo GetAlias(string aliasName, CommandOrigin origin)130 {131 AliasInfo result = null;132 if (string.IsNullOrEmpty(aliasName))133 {134 return null;135 }136 137 // Use the scope enumerator to find the alias using the138 // appropriate scoping rules139 140 SessionStateScopeEnumerator scopeEnumerator =141 new SessionStateScopeEnumerator(_currentScope);142 143 foreach (SessionStateScope scope in scopeEnumerator)144 {145 result = scope.GetAlias(aliasName);146 147 if (result != null)148 {149 // Now check the visibility of the variable...150 SessionState.ThrowIfNotVisible(origin, result);151 152 // Make sure the alias isn't private or if it is that the current153 // scope is the same scope the alias was retrieved from.154 155 if ((result.Options & ScopedItemOptions.Private) != 0 &&156 scope != _currentScope)157 {158 result = null;159 }160 else161 {162 break;163 }164 }165 }166 167 return result;168 }169 170 /// <summary>171 /// Gets the value of the specified alias from the alias table.172 /// </summary>173 /// <param name="aliasName">174 /// The name of the alias value to retrieve.175 /// </param>176 /// <returns>177 /// The AliasInfo representing the alias.178 /// </returns>179 internal AliasInfo GetAlias(string aliasName)180 {181 return GetAlias(aliasName, CommandOrigin.Internal);182 }183 184 /// <summary>185 /// Gets the value of the specified alias from the alias table.186 /// </summary>187 /// <param name="aliasName">188 /// The name of the alias value to retrieve.189 /// </param>190 /// <param name="scopeID">191 /// A scope identifier that is either one of the "special" scopes like192 /// "global", "script", "local", or "private, or a numeric ID of a relative scope193 /// to the current scope.194 /// </param>195 /// <returns>196 /// The AliasInfo representing the alias.197 /// </returns>198 /// <exception cref="ArgumentException">199 /// If <paramref name="scopeID"/> is less than zero, or not200 /// a number and not "script", "global", "local", or "private"201 /// </exception>202 /// <exception cref="ArgumentOutOfRangeException">203 /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently204 /// active scopes.205 /// </exception>206 internal AliasInfo GetAliasAtScope(string aliasName, string scopeID)207 {208 AliasInfo result = null;209 if (string.IsNullOrEmpty(aliasName))210 {211 return null;212 }213 214 SessionStateScope scope = GetScopeByID(scopeID);215 result = scope.GetAlias(aliasName);216 217 // Make sure the alias isn't private or if it is that the current218 // scope is the same scope the alias was retrieved from.219 220 if (result != null &&221 (result.Options & ScopedItemOptions.Private) != 0 &&222 scope != _currentScope)223 {224 result = null;225 }226 227 return result;228 }229 230 /// <summary>231 /// Sets the alias with specified name to the specified value in the current scope.232 /// </summary>233 /// <param name="aliasName">234 /// The name of the alias to set.235 /// </param>236 /// <param name="value">237 /// The value to set the alias to.238 /// </param>239 /// <param name="force">240 /// If true, the value will be set even if the alias is ReadOnly.241 /// </param>242 /// <param name="origin">243 /// THe origin of the caller of this API244 /// </param>245 /// <returns>246 /// The resulting AliasInfo for the alias that was set.247 /// </returns>248 /// <exception cref="ArgumentException">249 /// If <paramref name="aliasName"/> or <paramref name="value"/> is null or empty.250 /// </exception>251 /// <exception cref="SessionStateUnauthorizedAccessException">252 /// If the alias is read-only or constant.253 /// </exception>254 internal AliasInfo SetAliasValue(string aliasName, string value, bool force, CommandOrigin origin)255 {256 if (string.IsNullOrEmpty(aliasName))257 {258 throw PSTraceSource.NewArgumentException(nameof(aliasName));259 }260 261 if (string.IsNullOrEmpty(value))262 {263 throw PSTraceSource.NewArgumentException(nameof(value));264 }265 266 AliasInfo info = _currentScope.SetAliasValue(aliasName, value, this.ExecutionContext, force, origin);267 268 return info;269 }270 271 /// <summary>272 /// Sets the alias with specified name to the specified value in the current scope.273 /// BUGBUG: this overload only exists for the test suites. They should be cleaned up274 /// and this overload removed.275 /// </summary>276 /// <param name="aliasName">277 /// The name of the alias to set.278 /// </param>279 /// <param name="value">280 /// The value to set the alias to.281 /// </param>282 /// <param name="force">283 /// If true, the value will be set even if the alias is ReadOnly.284 /// </param>285 /// <returns>286 /// The resulting AliasInfo for the alias that was set.287 /// </returns>288 /// <exception cref="ArgumentException">289 /// If <paramref name="aliasName"/> or <paramref name="value"/> is null or empty.290 /// </exception>291 /// <exception cref="SessionStateUnauthorizedAccessException">292 /// If the alias is read-only or constant.293 /// </exception>294 internal AliasInfo SetAliasValue(string aliasName, string value, bool force)295 {296 return SetAliasValue(aliasName, value, force, CommandOrigin.Internal);297 }298 299 /// <summary>300 /// Sets the alias with specified name to the specified value in the current scope.301 /// </summary>302 /// <param name="aliasName">303 /// The name of the alias to set.304 /// </param>305 /// <param name="value">306 /// The value to set the alias to.307 /// </param>308 /// <param name="options">309 /// The options to set on the alias.310 /// </param>311 /// <param name="force">312 /// If true, the value will be set even if the alias is ReadOnly.313 /// </param>314 /// <param name="origin">315 /// The origin of the caller of this API316 /// </param>317 /// <returns>318 /// The resulting AliasInfo for the alias that was set.319 /// </returns>320 /// <exception cref="ArgumentException">321 /// If <paramref name="aliasName"/> or <paramref name="value"/> is null or empty.322 /// </exception>323 /// <exception cref="SessionStateUnauthorizedAccessException">324 /// If the alias is read-only or constant.325 /// </exception>326 internal AliasInfo SetAliasValue(327 string aliasName,328 string value,329 ScopedItemOptions options,330 bool force,331 CommandOrigin origin)332 {333 if (string.IsNullOrEmpty(aliasName))334 {335 throw PSTraceSource.NewArgumentException(nameof(aliasName));336 }337 338 if (string.IsNullOrEmpty(value))339 {340 throw PSTraceSource.NewArgumentException(nameof(value));341 }342 343 AliasInfo info = _currentScope.SetAliasValue(aliasName, value, options, this.ExecutionContext, force, origin);344 345 return info;346 }347 348 /// <summary>349 /// Sets the alias with specified name to the specified value in the current scope.350 /// BUGBUG: this api only exists for the test suites. They should be fixed and it should be removed.351 /// </summary>352 /// <param name="aliasName">353 /// The name of the alias to set.354 /// </param>355 /// <param name="value">356 /// The value to set the alias to.357 /// </param>358 /// <param name="options">359 /// The options to set on the alias.360 /// </param>361 /// <param name="force">362 /// If true, the value will be set even if the alias is ReadOnly.363 /// </param>364 /// <returns>365 /// The resulting AliasInfo for the alias that was set.366 /// </returns>367 /// <exception cref="ArgumentException">368 /// If <paramref name="aliasName"/> or <paramref name="value"/> is null or empty.369 /// </exception>370 /// <exception cref="SessionStateUnauthorizedAccessException">371 /// If the alias is read-only or constant.372 /// </exception>373 internal AliasInfo SetAliasValue(374 string aliasName,375 string value,376 ScopedItemOptions options,377 bool force)378 {379 return SetAliasValue(aliasName, value, options, force, CommandOrigin.Internal);380 }381 382 /// <summary>383 /// Sets the alias with specified name to the specified value in the current scope.384 /// </summary>385 /// <param name="alias">386 /// The AliasInfo representing the alias.387 /// </param>388 /// <param name="force">389 /// If true, the alias will be set even if there is an existing ReadOnly390 /// alias.391 /// </param>392 /// <param name="origin">393 /// Specifies the origin of the command setting the alias.394 /// </param>395 /// <returns>396 /// The resulting AliasInfo for the alias that was set.397 /// </returns>398 /// <exception cref="ArgumentNullException">399 /// If <paramref name="alias"/> is null.400 /// </exception>401 /// <exception cref="SessionStateUnauthorizedAccessException">402 /// If the alias is read-only or constant.403 /// </exception>404 internal AliasInfo SetAliasItem(AliasInfo alias, bool force, CommandOrigin origin)405 {406 if (alias == null)407 {408 throw PSTraceSource.NewArgumentNullException(nameof(alias));409 }410 411 AliasInfo info = _currentScope.SetAliasItem(alias, force, origin);412 413 return info;414 }415 416 /// <summary>417 /// Sets the alias with specified name to the specified value in the current scope.418 /// </summary>419 /// <param name="alias">420 /// The AliasInfo representing the alias.421 /// </param>422 /// <param name="scopeID">423 /// A scope identifier that is either one of the "special" scopes like424 /// "global", "script", "local", or "private, or a numeric ID of a relative scope425 /// to the current scope.426 /// </param>427 /// <param name="force">428 /// If true, the alias will be set even if there is an existing ReadOnly429 /// alias.430 /// </param>431 /// <param name="origin">432 /// Specifies the command origin of the calling command.433 /// </param>434 /// <returns>435 /// The resulting AliasInfo for the alias that was set.436 /// </returns>437 /// <exception cref="ArgumentException">438 /// If <paramref name="scopeID"/> is less than zero, or not439 /// a number and not "script", "global", "local", or "private"440 /// </exception>441 /// <exception cref="ArgumentOutOfRangeException">442 /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently443 /// active scopes.444 /// </exception>445 /// <exception cref="ArgumentNullException">446 /// If <paramref name="alias"/> is null.447 /// </exception>448 /// <exception cref="SessionStateUnauthorizedAccessException">449 /// If the alias is read-only or constant.450 /// </exception>451 internal AliasInfo SetAliasItemAtScope(AliasInfo alias, string scopeID, bool force, CommandOrigin origin)452 {453 if (alias == null)454 {455 throw PSTraceSource.NewArgumentNullException(nameof(alias));456 }457 458 // If the "private" scope was specified, make sure the options contain459 // the Private flag460 461 if (string.Equals(scopeID, StringLiterals.Private, StringComparison.OrdinalIgnoreCase))462 {463 alias.Options |= ScopedItemOptions.Private;464 }465 466 SessionStateScope scope = GetScopeByID(scopeID);467 468 AliasInfo info = scope.SetAliasItem(alias, force, origin);469 470 return info;471 }472 473 /// <summary>474 /// Sets the alias with specified name to the specified value in the current scope.475 /// </summary>476 /// <param name="alias">477 /// The AliasInfo representing the alias.478 /// </param>479 /// <param name="scopeID">480 /// A scope identifier that is either one of the "special" scopes like481 /// "global", "script", "local", or "private, or a numeric ID of a relative scope482 /// to the current scope.483 /// </param>484 /// <param name="force">485 /// If true, the alias will be set even if there is an existing ReadOnly486 /// alias.487 /// </param>488 /// <returns>489 /// The resulting AliasInfo for the alias that was set.490 /// </returns>491 /// <exception cref="ArgumentException">492 /// If <paramref name="scopeID"/> is less than zero, or not493 /// a number and not "script", "global", "local", or "private"494 /// </exception>495 /// <exception cref="ArgumentOutOfRangeException">496 /// If <paramref name="scopeID"/> is less than zero or greater than the number of currently497 /// active scopes.498 /// </exception>499 /// <exception cref="ArgumentNullException">500 /// If <paramref name="alias"/> is null.501 /// </exception>502 /// <exception cref="SessionStateUnauthorizedAccessException">503 /// If the alias is read-only or constant.504 /// </exception>505 internal AliasInfo SetAliasItemAtScope(AliasInfo alias, string scopeID, bool force)506 {507 return SetAliasItemAtScope(alias, scopeID, force, CommandOrigin.Internal);508 }509 510 /// <summary>511 /// Removes the specified alias.512 /// </summary>513 /// <param name="aliasName">514 /// The name of the alias to remove.515 /// </param>516 /// <param name="force">517 /// If true the alias will be removed even if its ReadOnly.518 /// </param>519 /// <exception cref="ArgumentException">520 /// If <paramref name="aliasName"/> is null or empty.521 /// </exception>522 /// <exception cref="SessionStateUnauthorizedAccessException">523 /// If the alias is constant.524 /// </exception>525 internal void RemoveAlias(string aliasName, bool force)526 {527 if (string.IsNullOrEmpty(aliasName))528 {529 throw PSTraceSource.NewArgumentException(nameof(aliasName));530 }531 532 // Use the scope enumerator to find an existing function533 534 SessionStateScopeEnumerator scopeEnumerator =535 new SessionStateScopeEnumerator(_currentScope);536 537 foreach (SessionStateScope scope in scopeEnumerator)538 {539 AliasInfo alias =540 scope.GetAlias(aliasName);541 542 if (alias != null)543 {544 // Make sure the alias isn't private or if it is that the current545 // scope is the same scope the alias was retrieved from.546 547 if ((alias.Options & ScopedItemOptions.Private) != 0 &&548 scope != _currentScope)549 {550 alias = null;551 }552 else553 {554 scope.RemoveAlias(aliasName, force);555 556 break;557 }558 }559 }560 }561 562 /// <summary>563 /// Gets the aliases by command name (used by metadata-driven help)564 /// </summary>565 /// <param name="command"></param>566 /// <returns></returns>567 internal IEnumerable<string> GetAliasesByCommandName(string command)568 {569 SessionStateScopeEnumerator scopeEnumerator =570 new SessionStateScopeEnumerator(_currentScope);571 572 foreach (SessionStateScope scope in scopeEnumerator)573 {574 foreach (string alias in scope.GetAliasesByCommandName(command))575 {576 yield return alias;577 }578 }579 580 yield break;581 }582 583 #endregion aliases584 }585}586 