/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Management.Automation.Language; #if CORECLR using System.Reflection; #endif namespace System.Management.Automation { /// /// This attribute is used to specify an argument completer for a parameter to a cmdlet or function. /// /// [Parameter()] /// [ArgumentCompleter(typeof(NounArgumentCompleter))] /// public string Noun { get; set; } /// /// [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] public class ArgumentCompleterAttribute : Attribute { /// [SuppressMessage("Microsoft.Naming", "CA1721:PropertyNamesShouldNotMatchGetMethods")] public Type Type { get; private set; } /// public ScriptBlock ScriptBlock { get; private set; } /// The type must implement and have a default constructor. public ArgumentCompleterAttribute(Type type) { if (type == null || (type.GetInterfaces().All(t => t != typeof(IArgumentCompleter)))) { throw PSTraceSource.NewArgumentException("type"); } Type = type; } /// /// This constructor is used primarily via PowerShell scripts. /// /// public ArgumentCompleterAttribute(ScriptBlock scriptBlock) { if (scriptBlock == null) { throw PSTraceSource.NewArgumentNullException("scriptBlock"); } ScriptBlock = scriptBlock; } } /// /// A type specified by the must implement this interface. /// public interface IArgumentCompleter { /// /// Implementations of this function are called by PowerShell to complete arguments. /// /// The name of the command that needs argument completion. /// The name of the parameter that needs argument completion. /// The (possibly empty) word being completed. /// The command ast in case it is needed for completion. /// /// This parameter is similar to $PSBoundParameters, except that sometimes PowerShell cannot or /// will not attempt to evaluate an argument, in which case you may need to use . /// /// /// A collection of completion results, most like with set to /// . /// IEnumerable CompleteArgument( string commandName, string parameterName, string wordToComplete, CommandAst commandAst, IDictionary fakeBoundParameters); } /// /// /// [Cmdlet(VerbsLifecycle.Register, "ArgumentCompleter", HelpUri = "http://go.microsoft.com/fwlink/?LinkId=528576")] public class RegisterArgumentCompleterCommand : PSCmdlet { /// /// /// [Parameter(ParameterSetName = "NativeSet", Mandatory = true)] [Parameter(ParameterSetName = "PowerShellSet")] [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")] public string[] CommandName { get; set; } /// /// /// [Parameter(ParameterSetName = "PowerShellSet", Mandatory = true)] public string ParameterName { get; set; } /// /// /// [Parameter(Mandatory = true)] [AllowNull()] public ScriptBlock ScriptBlock { get; set; } /// /// /// [Parameter(ParameterSetName = "NativeSet")] public SwitchParameter Native { get; set; } /// /// /// protected override void EndProcessing() { Dictionary completerDictionary; if (ParameterName != null) { completerDictionary = Context.CustomArgumentCompleters ?? (Context.CustomArgumentCompleters = new Dictionary(StringComparer.OrdinalIgnoreCase)); } else { completerDictionary = Context.NativeArgumentCompleters ?? (Context.NativeArgumentCompleters = new Dictionary(StringComparer.OrdinalIgnoreCase)); } if (CommandName == null || CommandName.Length == 0) { CommandName = new[] { "" }; } for (int i = 0; i < CommandName.Length; i++) { var key = CommandName[i]; if (!string.IsNullOrWhiteSpace(ParameterName)) { if (!string.IsNullOrWhiteSpace(key)) { key = key + ":" + ParameterName; } else { key = ParameterName; } } completerDictionary[key] = ScriptBlock; } } } }