2016-03-30 14:20:52 -07:00
/********************************************************************++
Copyright (c) Microsoft Corporation. All rights reserved.
--********************************************************************/
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
using System.Collections ;
using System.Collections.Generic ;
using System.Management.Automation.Language ;
using System.Management.Automation.Runspaces ;
2016-07-29 13:02:49 -07:00
using Dbg = System . Management . Automation . Diagnostics ;
2016-03-30 14:20:52 -07:00
namespace System.Management.Automation
{
/// <summary>
/// Holds the state of a Monad Shell session
/// </summary>
internal sealed partial class SessionStateInternal
{
#region Functions
/// <summary>
/// Add an new SessionState function entry to this session state object...
/// </summary>
/// <param name="entry">The entry to add</param>
internal void AddSessionStateEntry ( SessionStateFunctionEntry entry )
{
ScriptBlock sb = entry . ScriptBlock . Clone ();
FunctionInfo fn = this . SetFunction ( entry . Name , sb , null , entry . Options , false , CommandOrigin . Internal , this . ExecutionContext , entry . HelpFile , true );
fn . Visibility = entry . Visibility ;
fn . Module = entry . Module ;
fn . ScriptBlock . LanguageMode = PSLanguageMode . FullLanguage ;
}
#if ! CORECLR // Workflow Not Supported On CSS
internal void AddSessionStateEntry ( InitialSessionState initialSessionState , SessionStateWorkflowEntry entry )
{
var converterInstance = Utils . GetAstToWorkflowConverterAndEnsureWorkflowModuleLoaded ( null );
var workflowInfo = entry . WorkflowInfo ;
if ( workflowInfo == null )
{
workflowInfo = converterInstance . CompileWorkflow ( entry . Name , entry . Definition , initialSessionState );
}
WorkflowInfo wf = new WorkflowInfo ( workflowInfo );
wf = this . SetWorkflowRaw ( wf , CommandOrigin . Internal );
wf . Visibility = entry . Visibility ;
wf . Module = entry . Module ;
}
#endif
/// <summary>
/// Gets a flattened view of the functions that are visible using
/// the current scope as a reference and filtering the functions in
/// the other scopes based on the scoping rules.
/// </summary>
///
/// <returns>
/// An IDictionary representing the visible functions.
/// </returns>
///
internal IDictionary GetFunctionTable ()
2016-07-29 13:02:49 -07:00
{
2016-03-30 14:20:52 -07:00
SessionStateScopeEnumerator scopeEnumerator =
2016-07-29 13:02:49 -07:00
new SessionStateScopeEnumerator ( _currentScope );
2016-03-30 14:20:52 -07:00
Dictionary < string , FunctionInfo > result =
new Dictionary < string , FunctionInfo >( StringComparer . OrdinalIgnoreCase );
foreach ( SessionStateScope scope in scopeEnumerator )
{
foreach ( FunctionInfo entry in scope . FunctionTable . Values )
{
if (! result . ContainsKey ( entry . Name ))
{
result . Add ( entry . Name , entry );
}
}
}
return result ;
} // GetFunctionTable
/// <summary>
/// Gets an IEnumerable for the function table for a given scope
/// </summary>
///
/// <param name="scopeID">
/// 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.
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="scopeID"/> is less than zero, or not
/// a number and not "script", "global", "local", or "private"
/// </exception>
///
/// <exception cref="ArgumentOutOfRangeException">
/// If <paramref name="scopeID"/> is less than zero or greater than the number of currently
/// active scopes.
/// </exception>
///
internal IDictionary < string , FunctionInfo > GetFunctionTableAtScope ( string scopeID )
{
Dictionary < string , FunctionInfo > result =
new Dictionary < string , FunctionInfo >( StringComparer . OrdinalIgnoreCase );
SessionStateScope scope = GetScopeByID ( scopeID );
foreach ( FunctionInfo entry in scope . FunctionTable . Values )
{
// Make sure the function/filter isn't private or if it is that the current
// scope is the same scope the alias was retrieved from.
if (( entry . Options & ScopedItemOptions . Private ) == 0 ||
2016-07-29 13:02:49 -07:00
scope == _currentScope )
2016-03-30 14:20:52 -07:00
{
result . Add ( entry . Name , entry );
}
}
return result ;
} // GetFunctionTableAtScope
/// <summary>
/// List of functions/filters to export from this session state object...
/// </summary>
internal List < FunctionInfo > ExportedFunctions
{
get
{
return _exportedFunctions ;
}
}
private List < FunctionInfo > _exportedFunctions = new List < FunctionInfo >();
/// <summary>
/// List of workflows to export from this session state object...
/// </summary>
internal List < WorkflowInfo > ExportedWorkflows
{
get
{
return _exportedWorkflows ;
}
}
private List < WorkflowInfo > _exportedWorkflows = new List < WorkflowInfo >();
internal bool UseExportList
{
get { return _useExportList ; }
set { _useExportList = value ; }
}
private bool _useExportList = false ;
/// <summary>
/// Get a functions out of session state.
/// </summary>
///
/// <param name="name">
/// name of function to look up
/// </param>
///
/// <param name="origin">
/// Origin of the command that called this API...
/// </param>
///
/// <returns>
/// The value of the specified function.
/// </returns>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
internal FunctionInfo GetFunction ( string name , CommandOrigin origin )
{
if ( String . IsNullOrEmpty ( name ))
{
throw PSTraceSource . NewArgumentException ( "name" );
}
FunctionInfo result = null ;
FunctionLookupPath lookupPath = new FunctionLookupPath ( name );
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher ( this , lookupPath , origin );
if ( searcher . MoveNext ())
{
result = (( IEnumerator < FunctionInfo >) searcher ). Current ;
}
return result ;
} // GetFunction
/// <summary>
/// Get a functions out of session state.
/// </summary>
///
/// <param name="name">
/// name of function to look up
/// </param>
///
/// <returns>
/// The value of the specified function.
/// </returns>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
internal FunctionInfo GetFunction ( string name )
{
return GetFunction ( name , CommandOrigin . Internal );
} // GetFunction
2016-07-29 13:02:49 -07:00
private IEnumerable < string > GetFunctionAliases ( IParameterMetadataProvider ipmp )
2016-03-30 14:20:52 -07:00
{
if ( ipmp == null || ipmp . Body . ParamBlock == null )
yield break ;
var attributes = ipmp . Body . ParamBlock . Attributes ;
foreach ( var attributeAst in attributes )
{
var attributeType = attributeAst . TypeName . GetReflectionAttributeType ();
if ( attributeType == typeof ( AliasAttribute ))
{
2016-07-29 13:02:49 -07:00
var cvv = new ConstantValueVisitor { AttributeArgument = true };
2016-03-30 14:20:52 -07:00
for ( int i = 0 ; i < attributeAst . PositionalArguments . Count ; i ++)
{
yield return Compiler . _attrArgToStringConverter . Target ( Compiler . _attrArgToStringConverter ,
attributeAst . PositionalArguments [ i ]. Accept ( cvv ));
}
}
}
}
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="origin">
/// Origin of the caller of this API
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunctionRaw (
string name ,
ScriptBlock function ,
CommandOrigin origin )
{
if ( String . IsNullOrEmpty ( name ))
{
throw PSTraceSource . NewArgumentException ( "name" );
}
if ( function == null )
{
throw PSTraceSource . NewArgumentNullException ( "function" );
}
string originalName = name ;
FunctionLookupPath path = new FunctionLookupPath ( name );
name = path . UnqualifiedPath ;
if ( String . IsNullOrEmpty ( name ))
{
SessionStateException exception =
new SessionStateException (
originalName ,
SessionStateCategory . Function ,
"ScopedFunctionMustHaveName" ,
SessionStateStrings . ScopedFunctionMustHaveName ,
ErrorCategory . InvalidArgument );
throw exception ;
}
ScopedItemOptions options = ScopedItemOptions . None ;
if ( path . IsPrivate )
{
options |= ScopedItemOptions . Private ;
}
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher (
this ,
path ,
origin );
var functionInfo = searcher . InitialScope . SetFunction ( name , function , null , options , false , origin , ExecutionContext );
foreach ( var aliasName in GetFunctionAliases ( function . Ast as IParameterMetadataProvider ))
{
searcher . InitialScope . SetAliasValue ( aliasName , name , ExecutionContext , false , origin );
}
return functionInfo ;
} // SetFunctionRaw
internal WorkflowInfo SetWorkflowRaw (
WorkflowInfo workflowInfo ,
CommandOrigin origin )
{
string originalName = workflowInfo . Name ;
string name = originalName ;
FunctionLookupPath path = new FunctionLookupPath ( name );
name = path . UnqualifiedPath ;
if ( String . IsNullOrEmpty ( name ))
{
SessionStateException exception =
new SessionStateException (
originalName ,
SessionStateCategory . Function ,
"ScopedFunctionMustHaveName" ,
SessionStateStrings . ScopedFunctionMustHaveName ,
ErrorCategory . InvalidArgument );
throw exception ;
}
ScopedItemOptions options = ScopedItemOptions . None ;
if ( path . IsPrivate )
{
options |= ScopedItemOptions . Private ;
}
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher (
this ,
path ,
origin );
// The script that defines a workflowInfo wrapper is fully trusted
workflowInfo . ScriptBlock . LanguageMode = PSLanguageMode . FullLanguage ;
if ( workflowInfo . Module == null && this . Module != null )
{
workflowInfo . Module = this . Module ;
}
var wfInfo = ( WorkflowInfo )
searcher . InitialScope . SetFunction ( name , workflowInfo . ScriptBlock , null , options , false , origin , ExecutionContext , null ,
( arg1 , arg2 , arg3 , arg4 , arg5 , arg6 ) => workflowInfo );
foreach ( var aliasName in GetFunctionAliases ( workflowInfo . ScriptBlock . Ast as IParameterMetadataProvider ))
{
searcher . InitialScope . SetAliasValue ( aliasName , name , ExecutionContext , false , origin );
}
return wfInfo ;
} // SetWorkflowRaw
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="originalFunction">
/// The original function (if any) from which the ScriptBlock is derived.
/// </param>
///
/// <param name="options">
/// The options to set on the function.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <param name="origin">
/// Origin of the caller of this API
/// </param>
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction (
2016-07-29 13:02:49 -07:00
string name ,
2016-03-30 14:20:52 -07:00
ScriptBlock function ,
FunctionInfo originalFunction ,
ScopedItemOptions options ,
bool force ,
CommandOrigin origin )
{
return SetFunction ( name , function , originalFunction , options , force , origin , ExecutionContext , null );
} // SetFunction
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="originalFunction">
/// The original function (if any) from which the ScriptBlock is derived.
/// </param>
///
/// <param name="options">
/// The options to set on the function.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <param name="origin">
/// Origin of the caller of this API
/// </param>
///
/// <param name="helpFile">
/// The name of the help file associated with the function.
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction (
string name ,
ScriptBlock function ,
FunctionInfo originalFunction ,
ScopedItemOptions options ,
bool force ,
CommandOrigin origin ,
string helpFile )
{
return SetFunction ( name , function , originalFunction , options , force , origin , ExecutionContext , helpFile , false );
} // SetFunction
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="originalFunction">
/// The original function (if any) from which the ScriptBlock is derived.
/// </param>
///
/// <param name="options">
/// The options to set on the function.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <param name="origin">
/// Origin of the caller of this API
/// </param>
///
/// <param name="context">
/// The execution context for the function.
/// </param>
///
/// <param name="helpFile">
/// The name of the help file associated with the function.
/// </param>
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction (
string name ,
ScriptBlock function ,
FunctionInfo originalFunction ,
ScopedItemOptions options ,
bool force ,
CommandOrigin origin ,
ExecutionContext context ,
string helpFile )
{
return SetFunction ( name , function , originalFunction , options , force , origin , context , helpFile , false );
} // SetFunction
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="originalFunction">
/// The original function (if any) from which the ScriptBlock is derived.
/// </param>
///
/// <param name="options">
/// The options to set on the function.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <param name="origin">
/// Origin of the caller of this API
/// </param>
///
/// <param name="context">
/// The execution context for the function.
/// </param>
///
/// <param name="helpFile">
/// The name of the help file associated with the function.
/// </param>
///
/// <param name="isPreValidated">
/// Set to true if it is a regular function (meaning, we do not need to check this is a workflow or if the script contains JobDefinition Attribute and then process it)
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction (
string name ,
ScriptBlock function ,
FunctionInfo originalFunction ,
ScopedItemOptions options ,
bool force ,
CommandOrigin origin ,
ExecutionContext context ,
string helpFile ,
bool isPreValidated )
{
if ( String . IsNullOrEmpty ( name ))
{
throw PSTraceSource . NewArgumentException ( "name" );
}
if ( function == null )
{
throw PSTraceSource . NewArgumentNullException ( "function" );
}
string originalName = name ;
FunctionLookupPath path = new FunctionLookupPath ( name );
name = path . UnqualifiedPath ;
if ( String . IsNullOrEmpty ( name ))
{
SessionStateException exception =
new SessionStateException (
originalName ,
SessionStateCategory . Function ,
"ScopedFunctionMustHaveName" ,
SessionStateStrings . ScopedFunctionMustHaveName ,
ErrorCategory . InvalidArgument );
throw exception ;
}
if ( path . IsPrivate )
{
options |= ScopedItemOptions . Private ;
}
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher (
this ,
path ,
origin );
return searcher . InitialScope . SetFunction ( name , function , originalFunction , options , force , origin , context , helpFile );
} // SetFunction
/// <summary>
/// Set a function in the current scope of session state.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="originalFunction">
/// The original function (if any) from which the ScriptBlock is derived.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <param name="origin">
/// The origin of the caller
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// or
/// If <paramref name="function"/> is not a <see cref="FilterInfo">FilterInfo</see>
/// or <see cref="FunctionInfo">FunctionInfo</see>
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction (
string name ,
ScriptBlock function ,
FunctionInfo originalFunction ,
bool force ,
CommandOrigin origin )
{
if ( String . IsNullOrEmpty ( name ))
{
throw PSTraceSource . NewArgumentException ( "name" );
}
if ( function == null )
{
throw PSTraceSource . NewArgumentNullException ( "function" );
}
string originalName = name ;
FunctionLookupPath path = new FunctionLookupPath ( name );
name = path . UnqualifiedPath ;
if ( String . IsNullOrEmpty ( name ))
{
SessionStateException exception =
new SessionStateException (
originalName ,
SessionStateCategory . Function ,
"ScopedFunctionMustHaveName" ,
SessionStateStrings . ScopedFunctionMustHaveName ,
ErrorCategory . InvalidArgument );
throw exception ;
}
ScopedItemOptions options = ScopedItemOptions . None ;
if ( path . IsPrivate )
{
options |= ScopedItemOptions . Private ;
}
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher (
this ,
path ,
origin );
FunctionInfo result = null ;
SessionStateScope scope = searcher . InitialScope ;
2016-07-29 13:02:49 -07:00
2016-03-30 14:20:52 -07:00
if ( searcher . MoveNext ())
{
scope = searcher . CurrentLookupScope ;
name = searcher . Name ;
if ( path . IsPrivate )
{
// Need to add the Private flag
FunctionInfo existingFunction = scope . GetFunction ( name );
options |= existingFunction . Options ;
result = scope . SetFunction ( name , function , originalFunction , options , force , origin , ExecutionContext );
}
else
{
result = scope . SetFunction ( name , function , force , origin , ExecutionContext );
}
}
else
{
if ( path . IsPrivate )
{
result = scope . SetFunction ( name , function , originalFunction , options , force , origin , ExecutionContext );
}
else
{
result = scope . SetFunction ( name , function , force , origin , ExecutionContext );
}
}
return result ;
}
/// <summary>
/// Set a function in the current scope of session state.
///
/// BUGBUG: this overload is preserved because a lot of tests use reflection to
/// call it. The tests should be fixed and this API eventually removed.
/// </summary>
///
/// <param name="name">
/// The name of the function to set.
/// </param>
///
/// <param name="function">
/// The new value of the function being set.
/// </param>
///
/// <param name="force">
/// If true, the function will be set even if its ReadOnly.
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// or
/// If <paramref name="function"/> is not a <see cref="FilterInfo">FilterInfo</see>
/// or <see cref="FunctionInfo">FunctionInfo</see>
/// </exception>
///
/// <exception cref="ArgumentNullException">
/// If <paramref name="function"/> is null.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is read-only or constant.
/// </exception>
///
/// <exception cref="SessionStateOverflowException">
/// If the maximum number of functions have been reached for this scope.
/// </exception>
///
internal FunctionInfo SetFunction ( string name , ScriptBlock function , bool force )
{
return SetFunction ( name , function , null , force , CommandOrigin . Internal );
}
/// <summary>
/// Removes a function from the function table.
/// </summary>
///
/// <param name="name">
/// The name of the function to remove.
/// </param>
///
/// <param name="origin">
/// THe origin of the caller of this API
/// </param>
///
/// <param name="force">
/// If true, the function is removed even if it is ReadOnly.
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is constant.
/// </exception>
///
2016-07-29 13:02:49 -07:00
internal void RemoveFunction ( string name , bool force , CommandOrigin origin )
2016-03-30 14:20:52 -07:00
{
if ( String . IsNullOrEmpty ( name ))
{
throw PSTraceSource . NewArgumentException ( "name" );
}
// Use the scope enumerator to find an existing function
2016-07-29 13:02:49 -07:00
SessionStateScope scope = _currentScope ;
2016-03-30 14:20:52 -07:00
FunctionLookupPath path = new FunctionLookupPath ( name );
FunctionScopeItemSearcher searcher =
new FunctionScopeItemSearcher (
this ,
path ,
origin );
if ( searcher . MoveNext ())
{
scope = searcher . CurrentLookupScope ;
}
scope . RemoveFunction ( name , force );
} // RemoveFunction
/// <summary>
/// Removes a function from the function table.
/// </summary>
///
/// <param name="name">
/// The name of the function to remove.
/// </param>
///
/// <param name="force">
/// If true, the function is removed even if it is ReadOnly.
/// </param>
///
/// <exception cref="ArgumentException">
/// If <paramref name="name"/> is null or empty.
/// </exception>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is constant.
/// </exception>
///
internal void RemoveFunction ( string name , bool force )
{
RemoveFunction ( name , force , CommandOrigin . Internal );
}
/// <summary>
/// Removes a function from the function table
/// if the function was imported from the given module.
///
/// BUGBUG: This is only used by the implict remoting functions...
/// </summary>
///
/// <param name="name">
/// The name of the function to remove.
/// </param>
///
/// <param name="module">
/// Module the function might be imported from.
/// </param>
///
/// <exception cref="SessionStateUnauthorizedAccessException">
/// If the function is constant.
/// </exception>
///
internal void RemoveFunction ( string name , PSModuleInfo module )
{
Dbg . Assert ( module != null , "Caller should verify that module parameter is not null" );
FunctionInfo func = GetFunction ( name ) as FunctionInfo ;
if ( func != null && func . ScriptBlock != null
&& func . ScriptBlock . File != null
&& func . ScriptBlock . File . Equals ( module . Path , StringComparison . OrdinalIgnoreCase ))
{
RemoveFunction ( name , true );
}
}
#endregion Functions
} // SessionStateInternal class
}