|
1 | | -# This is used only to parse the parameters to New|Set|Remove-Alias |
2 | | -class AliasParameterVisitor : System.Management.Automation.Language.AstVisitor { |
3 | | - [string]$Parameter = $null |
4 | | - [string]$Command = $null |
5 | | - [string]$Name = $null |
6 | | - [string]$Value = $null |
7 | | - [string]$Scope = $null |
8 | | - |
9 | | - # Parameter Names |
10 | | - [System.Management.Automation.Language.AstVisitAction] VisitCommandParameter([System.Management.Automation.Language.CommandParameterAst]$ast) { |
11 | | - $this.Parameter = $ast.ParameterName |
12 | | - return [System.Management.Automation.Language.AstVisitAction]::Continue |
13 | | - } |
14 | | - |
15 | | - # Parameter Values |
16 | | - [System.Management.Automation.Language.AstVisitAction] VisitStringConstantExpression([System.Management.Automation.Language.StringConstantExpressionAst]$ast) { |
17 | | - # The FIRST command element is always the command name |
18 | | - if (!$this.Command) { |
19 | | - $this.Command = $ast.Value |
20 | | - return [System.Management.Automation.Language.AstVisitAction]::Continue |
21 | | - } else { |
22 | | - switch ($this.Parameter) { |
23 | | - "Scope" { |
24 | | - $this.Scope = $ast.Value |
25 | | - } |
26 | | - "Name" { |
27 | | - $this.Name = $ast.Value |
28 | | - } |
29 | | - "Value" { |
30 | | - $this.Value = $ast.Value |
31 | | - } |
32 | | - "Force" { |
33 | | - if ($ast.Value) { |
34 | | - # Force parameter was passed as named parameter with a positional parameter after it which is alias name |
35 | | - $this.Name = $ast.Value |
36 | | - } |
37 | | - } |
38 | | - default { |
39 | | - if (!$this.Parameter) { |
40 | | - # For bare arguments, the order is Name, Value: |
41 | | - if (!$this.Name) { |
42 | | - $this.Name = $ast.Value |
43 | | - } else { |
44 | | - $this.Value = $ast.Value |
45 | | - } |
46 | | - } |
47 | | - } |
48 | | - } |
49 | | - |
50 | | - $this.Parameter = $null |
51 | | - |
52 | | - # If we have enough information, stop the visit |
53 | | - # For -Scope global or Remove-Alias, we don't want to export these |
54 | | - if ($this.Name -and $this.Command -eq "Remove-Alias") { |
55 | | - $this.Command = "Remove-Alias" |
56 | | - return [System.Management.Automation.Language.AstVisitAction]::StopVisit |
57 | | - } elseif ($this.Name -and $this.Scope -eq "Global") { |
58 | | - return [System.Management.Automation.Language.AstVisitAction]::StopVisit |
59 | | - } |
60 | | - return [System.Management.Automation.Language.AstVisitAction]::Continue |
61 | | - } |
62 | | - } |
63 | | - |
64 | | - [AliasParameterVisitor] Clear() { |
65 | | - $this.Command = $null |
66 | | - $this.Parameter = $null |
67 | | - $this.Name = $null |
68 | | - $this.Value = $null |
69 | | - $this.Scope = $null |
70 | | - return $this |
71 | | - } |
72 | | -} |
73 | | - |
74 | | -# This visits everything at the top level of the script |
75 | | -class AliasVisitor : System.Management.Automation.Language.AstVisitor { |
76 | | - [System.Collections.Hashtable]$Aliases = @{} |
77 | | - [AliasParameterVisitor]$Parameters = @{} |
78 | | - |
79 | | - # The [Alias(...)] attribute on functions matters, but we can't export aliases that are defined inside a function |
80 | | - [System.Management.Automation.Language.AstVisitAction] VisitFunctionDefinition([System.Management.Automation.Language.FunctionDefinitionAst]$ast) { |
81 | | - $this.Aliases[$ast.Name] = @($ast.Body.ParamBlock.Attributes.Where{ $_.TypeName.Name -eq "Alias" }.PositionalArguments.Value) |
82 | | - return [System.Management.Automation.Language.AstVisitAction]::SkipChildren |
83 | | - } |
84 | | - |
85 | | - # Top-level commands matter, but only if they're alias commands |
86 | | - [System.Management.Automation.Language.AstVisitAction] VisitCommand([System.Management.Automation.Language.CommandAst]$ast) { |
87 | | - if ($ast.CommandElements[0].Value -imatch "(New|Set|Remove)-Alias") { |
88 | | - $ast.Visit($this.Parameters.Clear()) |
89 | | - if ($this.Parameters.Command -ieq "Remove-Alias") { |
90 | | - Write-Warning -Message "Found an alias '$($this.Parameters.Name)' that is removed using $($this.Parameters.Command), assuming the alias should not be exported." |
91 | | - |
92 | | - $this.Aliases.Remove($this.Parameters.Name) |
93 | | - } elseif ($this.Parameters.Scope -ine 'Global') { |
94 | | - if ($this.Parameters.Name -notin $this.Aliases.Keys) |
95 | | - { |
96 | | - $this.Aliases[$this.Parameters.Name] = $this.Parameters.Name |
97 | | - } |
98 | | - } |
99 | | - } |
100 | | - return [System.Management.Automation.Language.AstVisitAction]::SkipChildren |
101 | | - } |
102 | | -} |
103 | 1 |
|
104 | 2 | function GetCommandAlias { |
105 | 3 | <# |
106 | 4 | .SYNOPSIS |
107 | 5 | Parses one or more files for aliases and returns a list of alias names. |
108 | 6 | #> |
109 | 7 | [CmdletBinding()] |
110 | | - [OutputType([System.Collections.Hashtable])] |
| 8 | + [OutputType([System.Collections.Generic.Hashset[string]])] |
111 | 9 | param( |
112 | 10 | # The AST to find aliases in |
113 | 11 | [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)] |
|
0 commit comments