functions/Get-ReSplat.ps1
function Get-ReSplat { <# .SYNOPSIS Resolves all splats in the offered Ast. .DESCRIPTION Resolves all splats in the offered Ast. This will look up any hashtable definitions and property-assignments to that hashtable, whether through property notation, index assignment or add method. It will then attempt to define an authorative list of properties assigned to that hashtable. If the result is unclear, that will be indicated accordingly. Return Objects include properties: + Splat : The original Ast where the hashtable is used for splatting + Parameters : A hashtable containing all properties clearly identified + ParametersKnown : Whether we are confident of having identified all properties passed through as parameters .PARAMETER Ast The Ast object to search. Use "Read-ReAst" to parse a scriptfile into an AST object. .EXAMPLE PS C:\> Get-ReSplat -Ast $ast Returns all splats used in the Abstract Syntax Tree object specified #> [OutputType([Refactor.Splat])] [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [System.Management.Automation.Language.Ast] $Ast ) $splats = Search-ReAst -Ast $Ast -Filter { if ($args[0] -isnot [System.Management.Automation.Language.VariableExpressionAst]) { return $false } $args[0].Splatted } if (-not $splats) { return } foreach ($splat in $splats) { # Select the last variable declaration _before_ the splat is being used $assignments = Search-ReAst -Ast $Ast -Filter { if ($args[0] -isnot [System.Management.Automation.Language.AssignmentStatementAst]) { return $false } if ($args[0].Left -isnot [System.Management.Automation.Language.VariableExpressionAst]) { return $false } $args[0].Left.VariablePath.UserPath -eq $splat.Data.VariablePath.UserPath } $declaration = $assignments | Where-Object { $_.Start -lt $splat.Start } | Sort-Object { $_.Start } -Descending | Select-Object -First 1 $result = [Refactor.Splat]@{ Ast = $splat.Data } if (-not $declaration) { $result.ParametersKnown = $false $result continue } $propertyAssignments = Search-ReAst -Ast $Ast -Filter { if ($args[0].Extent.StartLineNumber -le $declaration.Start) { return $false } if ($args[0].Extent.StartLineNumber -ge $splat.Start) { return $false } $isAssignment = $( ($args[0] -is [System.Management.Automation.Language.AssignmentStatementAst]) -and ( ($args[0].Left.VariablePath.UserPath -eq $splat.Data.VariablePath.UserPath) -or ($args[0].Left.Expression.VariablePath.UserPath -eq $splat.Data.VariablePath.UserPath) -or ($args[0].Left.Target.VariablePath.UserPath -eq $splat.Data.VariablePath.UserPath) ) ) $isAddition = $( ($args[0] -is [System.Management.Automation.Language.InvokeMemberExpressionAst]) -and ($args[0].Expression.VariablePath.UserPath -eq $splat.Data.VariablePath.UserPath) -and ($args[0].Member.Value -eq 'Add') ) $isAddition -or $isAssignment } if ($declaration.Data.Right.Expression -isnot [System.Management.Automation.Language.HashtableAst]) { $result.ParametersKnown = $false } foreach ($pair in $declaration.Data.Right.Expression.KeyValuePairs) { if ($pair.Item1 -is [System.Management.Automation.Language.StringConstantExpressionAst]) { $result.Parameters[$pair.Item1.Value] = $pair.Item1.Value } else { $result.ParametersKnown = $false } } foreach ($assignment in $propertyAssignments) { switch ($assignment.Type) { 'AssignmentStatementAst' { if ($assignment.Data.Left.Member -is [System.Management.Automation.Language.StringConstantExpressionAst]) { $result.Parameters[$assignment.Data.Left.Member.Value] = $assignment.Data.Left.Member.Value continue } if ($assignment.Data.Left.Index -is [System.Management.Automation.Language.StringConstantExpressionAst]) { $result.Parameters[$assignment.Data.Left.Index.Value] = $assignment.Data.Left.Index.Value continue } $result.ParametersKnown = $false } 'InvokeMemberExpressionAst' { if ($assignment.Data.Arguments[0] -is [System.Management.Automation.Language.StringConstantExpressionAst]) { $result.Parameters[$assignment.Data.Arguments[0].Value] = $assignment.Data.Arguments[0].Value continue } $result.ParametersKnown = $false } } } # Include all relevant Ast objects $result.Assignments = @($declaration.Data) + @($propertyAssignments.Data) | Remove-PSFNull -Enumerate $result } } |