// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System.Collections.Generic; using Dbg = System.Management.Automation; namespace System.Management.Automation { /// /// Holds the state of a Monad Shell session. /// internal sealed partial class SessionStateInternal { #region cmdlets /// /// Gets the value of the specified cmdlet from the cmdlet table. /// /// /// The name of the cmdlet value to retrieve. /// /// /// The CmdletInfo representing the cmdlet. /// internal CmdletInfo GetCmdlet(string cmdletName) { return GetCmdlet(cmdletName, CommandOrigin.Internal); } /// /// Gets the value of the specified cmdlet from the cmdlet table. /// /// /// The name of the cmdlet value to retrieve. /// /// /// The origin of hte command trying to retrieve this cmdlet. /// /// /// The CmdletInfo representing the cmdlet. /// internal CmdletInfo GetCmdlet(string cmdletName, CommandOrigin origin) { CmdletInfo result = null; if (string.IsNullOrEmpty(cmdletName)) { return null; } // Use the scope enumerator to find the alias using the // appropriate scoping rules SessionStateScopeEnumerator scopeEnumerator = new SessionStateScopeEnumerator(_currentScope); foreach (SessionStateScope scope in scopeEnumerator) { result = scope.GetCmdlet(cmdletName); if (result != null) { // Now check the visibility of the cmdlet... SessionState.ThrowIfNotVisible(origin, result); // Make sure the cmdlet isn't private or if it is that the current // scope is the same scope the cmdlet was retrieved from. if ((result.Options & ScopedItemOptions.Private) != 0 && scope != _currentScope) { result = null; } else { break; } } } return result; } /// /// Gets the value of the specified cmdlet from the cmdlet table. /// /// /// The name of the cmdlet value to retrieve. /// /// /// A scope identifier that is either one of the "special" scopes like /// "global", "script", "local", or "private, or a numeric ID of a relative scope /// to the current scope. /// /// /// The CmdletInfo representing the cmdlet. /// /// /// If is less than zero, or not /// a number and not "script", "global", "local", or "private" /// /// /// If is less than zero or greater than the number of currently /// active scopes. /// internal CmdletInfo GetCmdletAtScope(string cmdletName, string scopeID) { CmdletInfo result = null; if (string.IsNullOrEmpty(cmdletName)) { return null; } SessionStateScope scope = GetScopeByID(scopeID); result = scope.GetCmdlet(cmdletName); // Make sure the alias isn't private or if it is that the current // scope is the same scope the alias was retrieved from. if (result != null && (result.Options & ScopedItemOptions.Private) != 0 && scope != _currentScope) { result = null; } return result; } /// /// Gets an IEnumerable for the cmdlet table. /// internal IDictionary> GetCmdletTable() { Dictionary> result = new Dictionary>(StringComparer.OrdinalIgnoreCase); SessionStateScopeEnumerator scopeEnumerator = new SessionStateScopeEnumerator(_currentScope); foreach (SessionStateScope scope in scopeEnumerator) { foreach (KeyValuePair> entry in scope.CmdletTable) { if (!result.ContainsKey(entry.Key)) { // Make sure the cmdlet isn't private or if it is that the current // scope is the same scope the alias was retrieved from. List toBeAdded = new List(); foreach (CmdletInfo cmdletInfo in entry.Value) { if ((cmdletInfo.Options & ScopedItemOptions.Private) == 0 || scope == _currentScope) { toBeAdded.Add(cmdletInfo); } } result.Add(entry.Key, toBeAdded); } } } return result; } /// /// Gets an IEnumerable for the cmdlet table for a given scope. /// /// /// A scope identifier that is either one of the "special" scopes like /// "global", "script", "local", or "private, or a numeric ID of a relative scope /// to the current scope. /// /// /// If is less than zero, or not /// a number and not "script", "global", "local", or "private" /// /// /// If is less than zero or greater than the number of currently /// active scopes. /// internal IDictionary> GetCmdletTableAtScope(string scopeID) { Dictionary> result = new Dictionary>(StringComparer.OrdinalIgnoreCase); SessionStateScope scope = GetScopeByID(scopeID); foreach (KeyValuePair> entry in scope.CmdletTable) { // Make sure the alias isn't private or if it is that the current // scope is the same scope the alias was retrieved from. List toBeAdded = new List(); foreach (CmdletInfo cmdletInfo in entry.Value) { if ((cmdletInfo.Options & ScopedItemOptions.Private) == 0 || scope == _currentScope) { toBeAdded.Add(cmdletInfo); } } result.Add(entry.Key, toBeAdded); } return result; } internal void RemoveCmdlet(string name, int index, bool force) { RemoveCmdlet(name, index, force, CommandOrigin.Internal); } /// /// Removes a cmdlet from the function table. /// /// /// The name of the cmdlet to remove. /// /// /// The name of the cmdlet to remove. /// /// /// THe origin of the caller of this API /// /// /// If true, the cmdlet is removed even if it is ReadOnly. /// /// /// If is null or empty. /// /// /// If the function is constant. /// internal void RemoveCmdlet(string name, int index, bool force, CommandOrigin origin) { if (string.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException(nameof(name)); } // Use the scope enumerator to find an existing function SessionStateScopeEnumerator scopeEnumerator = new SessionStateScopeEnumerator(_currentScope); foreach (SessionStateScope scope in scopeEnumerator) { CmdletInfo cmdletInfo = scope.GetCmdlet(name); if (cmdletInfo != null) { // Make sure the cmdlet isn't private or if it is that the current // scope is the same scope the cmdlet was retrieved from. if ((cmdletInfo.Options & ScopedItemOptions.Private) != 0 && scope != _currentScope) { cmdletInfo = null; } else { scope.RemoveCmdlet(name, index, force); break; } } } } /// /// Removes a cmdlet entry from the cmdlet table. /// /// /// The name of the cmdlet entry to remove. /// /// /// If true, the cmdlet is removed even if it is ReadOnly. /// /// /// If is null or empty. /// /// /// If the function is constant. /// internal void RemoveCmdletEntry(string name, bool force) { if (string.IsNullOrEmpty(name)) { throw PSTraceSource.NewArgumentException(nameof(name)); } // Use the scope enumerator to find an existing function SessionStateScopeEnumerator scopeEnumerator = new SessionStateScopeEnumerator(_currentScope); foreach (SessionStateScope scope in scopeEnumerator) { CmdletInfo cmdletInfo = scope.GetCmdlet(name); if (cmdletInfo != null) { // Make sure the cmdlet isn't private or if it is that the current // scope is the same scope the cmdlet was retrieved from. if ((cmdletInfo.Options & ScopedItemOptions.Private) != 0 && scope != _currentScope) { cmdletInfo = null; } else { scope.RemoveCmdletEntry(name, force); break; } } } } #endregion cmdlets } }