private/Add-DynamicFunctionDynamicParamBlock.ps1
function Add-DynamicFunctionDynamicParamBlock { [CmdletBinding()] param ( # StringBuilder in which to add the param block placeholder [Parameter(Mandatory)] [System.Text.StringBuilder]$StringBuilder, # Dynamic parameter ParameterAst object(s) [Parameter(Mandatory, ValueFromPipeline)] [System.Management.Automation.Language.ParameterAst[]]$ParameterAst, # Default values for the [Dynamic()] parameters, if any [Parameter()] [hashtable]$DefaultValueTable = @{} ) begin { try { $commonParameters = @( 'Verbose', 'Debug', 'ErrorAction', 'WarningAction', 'InformationAction', 'ErrorVariable', 'WarningVariable', 'InformationVariable', 'OutVariable', 'OutBuffer', 'PipelineVariable' ) $null = $StringBuilder.AppendLine(' dynamicparam {') $null = $StringBuilder.AppendLine(' # create container for all dynamically created parameters:') $null = $StringBuilder.AppendLine(' $paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()') } catch { $PSCmdlet.ThrowTerminatingError($_) } } process { try { $ParameterAst | ForEach-Object { $parameter = $_ $dynamicAttribute = Get-DynamicFunctionParameterDynamicAttribute -ParameterAst $parameter $condition = Get-DynamicFunctionParameterDynamicAttributeCondition -AttributeAst $dynamicAttribute $parameterName = $parameter.Name.VariablePath.UserPath $null = $StringBuilder.AppendLine() $null = $StringBuilder.AppendLine(' <#') $null = $StringBuilder.AppendLine(" region Start Parameter -$parameterName ####") $null = $StringBuilder.AppendLine(' created programmatically via Resolve-DynamicFunctionDefinition') $null = $StringBuilder.AppendLine(' #>') $null = $StringBuilder.AppendLine() if ($condition) { $null = $StringBuilder.AppendLine(" if ($condition) {") $padLeft = ' ' } else { $padLeft = $null } $null = $StringBuilder.AppendLine("$padLeft # create container storing all attributes for parameter -$parameterName") $null = $StringBuilder.AppendLine("$padLeft `$attributeCollection = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()") $null = $StringBuilder.AppendLine() $conflicts = $commonParameters -like "$parameterName*" if ($conflicts.Count -gt 0) { throw ('Parameter -{0} conflicts with built-in parameters {1}. Rename -{0}.' -f $parameterName, ('-' + ($conflicts -join ', -'))) } $defaultValue = $parameter.DefaultValue.Extent.Text # Set the default type to Object, in case there is no type defined $theType = 'Object' $hasParameterAttribute = $false $parameter.Attributes | ForEach-Object { $attribute = $_ switch ($attribute.GetType().FullName) { 'System.Management.Automation.Language.TypeConstraintAst' { $theType = $attribute.TypeName.FullName } 'System.Management.Automation.Language.AttributeAst' { $typeName = $attribute.TypeName.FullName if ($typename -ne 'Dynamic') { if (!$hasParameterAttribute -and $typename -eq 'Parameter') { $hasParameterAttribute = $true } [string]$positionals = $attribute.PositionalArguments.Extent.Text -join ', ' $null = $StringBuilder.AppendLine(("$padLeft # Define attribute [{0}()]:" -f $attribute.TypeName.FullName)) $null = $StringBuilder.AppendLine(("$padLeft `$attrib = [{0}]::new({1})" -f $attribute.TypeName.FullName, $positionals)) $attribute.NamedArguments | ForEach-Object { $namedAttributeExpression = $_.ToString() if ($_.ExpressionOmitted) { $namedAttributeExpression += ' = $true' } $null = $StringBuilder.AppendLine(("$padLeft `$attrib.{0}" -f $namedAttributeExpression)) } $null = $StringBuilder.AppendLine("$padLeft `$attributeCollection.Add(`$attrib)") $null = $StringBuilder.AppendLine() } } default { Write-Warning "Unexpected Type: $attribute" } } } if (!$hasParameterAttribute) { $null = $StringBuilder.AppendLine("$padLeft # Define attribute [Parameter()]") $null = $StringBuilder.AppendLine("$padLeft `$attrib = [Parameter]::new()") $null = $StringBuilder.AppendLine("$padLeft `$attributeCollection.Add(`$attrib)") $null = $StringBuilder.AppendLine() } $null = $StringBuilder.AppendLine("$padLeft # compose dynamic parameter:") $null = $StringBuilder.AppendLine("$padLeft `$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new('$parameterName', [$theType], `$attributeCollection)") # store parameter default value: if ($null -ne $defaultValue) { $DefaultValueTable[$parameterName] = $defaultValue } $null = $StringBuilder.AppendLine() $null = $StringBuilder.AppendLine("$padLeft # add parameter to parameter collection:") $null = $StringBuilder.AppendLine("$padLeft `$paramDictionary.Add('$parameterName', `$dynParam)") if ($condition) { $null = $StringBuilder.AppendLine(' }') } $null = $StringBuilder.AppendLine() $null = $StringBuilder.AppendLine(' <#') $null = $StringBuilder.AppendLine(" endregion End Parameter -$($parameterName) ####") $null = $StringBuilder.AppendLine(' created programmatically via Resolve-DynamicFunctionDefinition') $null = $StringBuilder.AppendLine(' #>') $null = $StringBuilder.AppendLine() } } catch { $PSCmdlet.ThrowTerminatingError($_) } } end { try { $null = $StringBuilder.AppendLine(" # return dynamic parameter collection:") $null = $StringBuilder.AppendLine(" `$paramDictionary") $null = $StringBuilder.AppendLine(" }") $null = $StringBuilder.AppendLine() } catch { $PSCmdlet.ThrowTerminatingError($_) } } } |