Last active
April 4, 2024 14:29
-
-
Save romero126/99b20dffb3cf66b9fdb4e44bb3896f86 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ConstrainedVariableInterpolation : System.Management.Automation.Language.AstVisitor { | |
hidden [Hashtable] $Property | |
[System.Collections.Generic.List[PSCustomObject]] $Result | |
hidden [System.Management.Automation.Language.Ast] $Ast | |
[System.Management.Automation.Language.AstVisitAction] CheckForPostAction([System.Management.Automation.Language.Ast] $ast, [System.Management.Automation.Language.AstVisitAction] $action) | |
{ | |
throw 'CheckForPostAction not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitErrorStatement([System.Management.Automation.Language.ErrorStatementAst] $errorStatementAst) | |
{ | |
throw 'VisitErrorStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitErrorExpression([System.Management.Automation.Language.ErrorExpressionAst] $errorExpressionAst) | |
{ | |
throw 'VisitErrorExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitScriptBlock([System.Management.Automation.Language.ScriptBlockAst] $scriptBlockAst) | |
{ | |
#throw 'VisitScriptBlock not supported' | |
if ( | |
($scriptBlockAst.ParamBlock) -or | |
($scriptBlockAst.BeginBlock) -or | |
($scriptBlockAst.ProcessBlock) -or | |
($scriptBlockAst.DynamicParamBlock) | |
) | |
{ | |
throw "VisitScriptBlock not supported" | |
} | |
return $this.ExpandExpressionList($scriptBlockAst.EndBlock) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitParamBlock([System.Management.Automation.Language.ParamBlockAst] $paramBlockAst) | |
{ | |
throw 'VisitParamBlock not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitNamedBlock([System.Management.Automation.Language.NamedBlockAst] $namedBlockAst) | |
{ | |
return $this.ExpandExpressionObjects($namedBlockAst.Statements) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitTypeConstraint([System.Management.Automation.Language.TypeConstraintAst] $typeConstraintAst) | |
{ | |
throw 'VisitTypeConstraint not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitAttribute([System.Management.Automation.Language.AttributeAst] $attributeAst) | |
{ | |
throw 'VisitAttribute not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitParameter([System.Management.Automation.Language.ParameterAst] $parameterAst) | |
{ | |
throw 'VisitParameter not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitTypeExpression([System.Management.Automation.Language.TypeExpressionAst] $typeExpressionAst) | |
{ | |
throw 'VisitTypeExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitFunctionDefinition([System.Management.Automation.Language.FunctionDefinitionAst] $functionDefinitionAst) | |
{ | |
throw 'VisitFunctionDefinition not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitStatementBlock([System.Management.Automation.Language.StatementBlockAst] $statementBlockAst) | |
{ | |
return $this.ExpandExpressionObjects($statementBlockAst.Statements) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitIfStatement([System.Management.Automation.Language.IfStatementAst] $ifStmtAst) | |
{ | |
throw 'VisitIfStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitTrap([System.Management.Automation.Language.TrapStatementAst] $trapStatementAst) | |
{ | |
throw 'VisitTrap not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitSwitchStatement([System.Management.Automation.Language.SwitchStatementAst] $switchStatementAst) | |
{ | |
throw 'VisitSwitchStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitDataStatement([System.Management.Automation.Language.DataStatementAst] $dataStatementAst) | |
{ | |
throw 'VisitDataStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitForEachStatement([System.Management.Automation.Language.ForEachStatementAst] $forEachStatementAst) | |
{ | |
throw 'VisitForEachStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitDoWhileStatement([System.Management.Automation.Language.DoWhileStatementAst] $doWhileStatementAst) | |
{ | |
throw 'VisitDoWhileStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitForStatement([System.Management.Automation.Language.ForStatementAst] $forStatementAst) | |
{ | |
throw 'VisitForStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitWhileStatement([System.Management.Automation.Language.WhileStatementAst] $whileStatementAst) | |
{ | |
throw 'VisitWhileStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitCatchClause([System.Management.Automation.Language.CatchClauseAst] $catchClauseAst) | |
{ | |
throw 'VisitCatchClause not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitTryStatement([System.Management.Automation.Language.TryStatementAst] $tryStatementAst) | |
{ | |
throw 'VisitTryStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitBreakStatement([System.Management.Automation.Language.BreakStatementAst] $breakStatementAst) | |
{ | |
throw 'VisitBreakStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitContinueStatement([System.Management.Automation.Language.ContinueStatementAst] $continueStatementAst) | |
{ | |
throw 'VisitContinueStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitReturnStatement([System.Management.Automation.Language.ReturnStatementAst] $returnStatementAst) | |
{ | |
throw 'VisitReturnStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitExitStatement([System.Management.Automation.Language.ExitStatementAst] $exitStatementAst) | |
{ | |
throw 'VisitExitStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitThrowStatement([System.Management.Automation.Language.ThrowStatementAst] $throwStatementAst) | |
{ | |
throw 'VisitThrowStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitDoUntilStatement([System.Management.Automation.Language.DoUntilStatementAst] $doUntilStatementAst) | |
{ | |
throw 'VisitDoUntilStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitAssignmentStatement([System.Management.Automation.Language.AssignmentStatementAst] $assignmentStatementAst) | |
{ | |
throw 'VisitAssignmentStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitPipeline([System.Management.Automation.Language.PipelineAst] $pipelineAst) | |
{ | |
return $this.ExpandExpressionObjects($pipelineAst.PipelineElements) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitCommand([System.Management.Automation.Language.CommandAst] $commandAst) | |
{ | |
throw 'VisitCommand not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitCommandExpression([System.Management.Automation.Language.CommandExpressionAst] $commandExpressionAst) | |
{ | |
return $this.ExpandExpression($commandExpressionAst.Expression) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitCommandParameter([System.Management.Automation.Language.CommandParameterAst] $commandParameterAst) | |
{ | |
throw 'VisitCommandParameter not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitMergingRedirection([System.Management.Automation.Language.MergingRedirectionAst] $redirectionAst) | |
{ | |
throw 'VisitMergingRedirection not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitFileRedirection([System.Management.Automation.Language.FileRedirectionAst] $redirectionAst) | |
{ | |
throw 'VisitFileRedirection not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitBinaryExpression([System.Management.Automation.Language.BinaryExpressionAst] $binaryExpressionAst) | |
{ | |
$left = [ConstrainedVariableInterpolation]::Parse($binaryExpressionAst.Left, $this.Property).Value | |
$right = [ConstrainedVariableInterpolation]::Parse($binaryExpressionAst.Right, $this.Property).Value | |
$r = switch ($binaryExpressionAst.Operator) | |
{ | |
<# AndAnd, VisitBinaryExpression PWSH && #># "AndAnd" { $left && $right } | |
<# OrOr, VisitBinaryExpression PWSH || #># "OrOr" { $left -OrOr $right } | |
<# Ampersand & #># "Ampersand" { $left -Ampersand $right } | |
<# Pipe | #># "Pipe" { $left -Pipe $right } | |
<# Comma , #># "Comma" { $left -Comma $right } | |
<# MinusMinus -- #># "MinusMinus" { $left -MinusMinus $right } | |
<# PlusPlus ++ #># "PlusPlus" { $left -PlusPlus $right } | |
<# DotDot, VisitBinaryExpression .. #> "DotDot" { $left .. $right } | |
<# ColonColon :: #># "ColonColon" { $left -ColonColon $right } | |
<# Dot . #># "Dot" { $left -Dot $right } | |
<# Exclaim ! #># "Exclaim" { $left -Exclaim $right } | |
<# Multiply, VisitBinaryExpression * #> "Multiply" { $left * $right } | |
<# Divide, VisitBinaryExpression / #> "Divide" { $left / $right } | |
<# Rem % #># "Rem" { $left -Rem $right } | |
<# Plus, VisitBinaryExpression + #> "Plus" { $left + $right } | |
<# Minus, VisitBinaryExpression - #> "Minus" { $left - $right } | |
<# Equals = #># "Equals" { $left -Equals $right } | |
<# PlusEquals += #># "PlusEquals" { $left -PlusEquals $right } | |
<# MinusEquals -= #># "MinusEquals" { $left -MinusEquals $right } | |
<# MultiplyEquals *= #># "MultiplyEquals" { $left -MultiplyEquals $right } | |
<# DivideEquals /= #># "DivideEquals" { $left -DivideEquals $right } | |
<# RemainderEquals %= #># "RemainderEquals" { $left -RemainderEquals $right } | |
<# Redirection > or >> #># "Redirection" { $left -Redirection $right } | |
<# RedirectInStd < #># "RedirectInStd" { $left -RedirectInStd $right } | |
<# Format, VisitBinaryExpression -f #> "Format" { $left -f $right } | |
<# Not, VisitUnaryExpression -not #># "Not" { $left -Not $right } | |
<# Bnot, PS7? -bnot #># "Bnot" { $left -Bnot $right } | |
<# And, VisitBinaryExpression -And #> "And" { $left -And $right } | |
<# Or, VisitBinaryExpression -Or #> "Or" { $left -Or $right } | |
<# Xor, VisitBinaryExpression -Xor #> "Xor" { $left -Xor $right } | |
<# Band, VisitBinaryExpression -Band #> "Band" { $left -Band $right } | |
<# Bor, VisitBinaryExpression -Bor #> "Bor" { $left -Bor $right } | |
<# Bxor, VisitBinaryExpression -Bxor #> "Bxor" { $left -Bxor $right } | |
<# Join, VisitBinaryExpression -Join #> "Join" { $left -Join $right } | |
<# Ieq, VisitBinaryExpression -Ieq #> "Ieq" { $left -Ieq $right } | |
<# Ine, VisitBinaryExpression -Ine #> "Ine" { $left -Ine $right } | |
<# Ige, VisitBinaryExpression -Ige #> "Ige" { $left -Ige $right } | |
<# Igt, VisitBinaryExpression -Igt #> "Igt" { $left -Igt $right } | |
<# Ilt, VisitBinaryExpression -Ilt #> "Ilt" { $left -Ilt $right } | |
<# Ile, VisitBinaryExpression -Ile #> "Ile" { $left -Ile $right } | |
<# Ilike, VisitBinaryExpression -Ilike #> "Ilike" { $left -Ilike $right } | |
<# Inotlike, VisitBinaryExpression -Inotlike #> "Inotlike" { $left -Inotlike $right } | |
<# Imatch, VisitBinaryExpression -Imatch #> "Imatch" { $left -Imatch $right } | |
<# Inotmatch, VisitBinaryExpression -Inotmatch #> "Inotmatch" { $left -Inotmatch $right } | |
<# Ireplace, VisitBinaryExpression -Ireplace #> "Ireplace" { $left -Ireplace $right } | |
<# Icontains, VisitBinaryExpression -Icontains #> "Icontains" { $left -Icontains $right } | |
<# Inotcontains, VisitBinaryExpression -Inotcontains #> "Inotcontains" { $left -Inotcontains $right } | |
<# Iin, VisitBinaryExpression -Iin #> "Iin" { $left -Iin $right } | |
<# Inotin, VisitBinaryExpression -Inotin #> "Inotin" { $left -Inotin $right } | |
<# Isplit, VisitBinaryExpression -Isplit #> "Isplit" { $left -Isplit $right } | |
<# Ceq, VisitBinaryExpression -Ceq #> "Ceq" { $left -Ceq $right } | |
<# Cne, VisitBinaryExpression -Cne #> "Cne" { $left -Cne $right } | |
<# Cge, VisitBinaryExpression -Cge #> "Cge" { $left -Cge $right } | |
<# Cgt, VisitBinaryExpression -Cgt #> "Cgt" { $left -Cgt $right } | |
<# Clt, VisitBinaryExpression -Clt #> "Clt" { $left -Clt $right } | |
<# Cle, VisitBinaryExpression -Cle #> "Cle" { $left -Cle $right } | |
<# Clike, VisitBinaryExpression -Clike #> "Clike" { $left -Clike $right } | |
<# Cnotlike, VisitBinaryExpression -Cnotlike #> "Cnotlike" { $left -Cnotlike $right } | |
<# Cmatch, VisitBinaryExpression -Cmatch #> "Cmatch" { $left -Cmatch $right } | |
<# Cnotmatch, VisitBinaryExpression -Cnotmatch #> "Cnotmatch" { $left -Cnotmatch $right } | |
<# Creplace, VisitBinaryExpression -Creplace #> "Creplace" { $left -Creplace $right } | |
<# Ccontains, VisitBinaryExpression -Ccontains #> "Ccontains" { $left -Ccontains $right } | |
<# Cnotcontains, VisitBinaryExpression -Cnotcontains #> "Cnotcontains" { $left -Cnotcontains $right } | |
<# Cin, VisitBinaryExpression -Cin #> "Cin" { $left -Cin $right } | |
<# Cnotin, VisitBinaryExpression -Cnotin #> "Cnotin" { $left -Cnotin $right } | |
<# Csplit, VisitBinaryExpression -Csplit #> "Csplit" { $left -Csplit $right } | |
<# Is, VisitBinaryExpression -Is #> "Is" { $left -Is $right } | |
<# IsNot, VisitBinaryExpression -IsNot #> "IsNot" { $left -IsNot $right } | |
<# As, VisitBinaryExpression -As #> "As" { $left -As $right } | |
<# PostFixPlusPlus, VisitUnaryExpression $v++ #># "PostFixPlusPlus" { $left -PostFixPlusPlus $right } # $v++ ; VisitUnaryExpression | |
<# PostFixMinusMinus, VisitUnaryExpression $v++ #># "PostFixMinusMinus" { $left -PostFixMinusMinus $right } # $v-- ; VisitUnaryExpression | |
<# Shl, VisitBinaryExpression -Shl #> "Shl" { $left -Shl $right } | |
<# Shr, VisitBinaryExpression -Shr #> "Shr" { $left -Shr $right } | |
default { | |
$binaryExpressionAst | fl * -force | Out-Host | |
$binaryExpressionAst | Out-String | Write-Host | |
start-sleep 5 | |
throw "NotImplementedException" | |
} | |
} | |
#Write-Host $left, $binaryExpressionAst.Operator, $right, "=", "$r" | |
return $this.ExpandExpression($binaryExpressionAst, $r) | |
#throw 'VisitBinaryExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitUnaryExpression([System.Management.Automation.Language.UnaryExpressionAst] $unaryExpressionAst) | |
{ | |
throw 'VisitUnaryExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitConvertExpression([System.Management.Automation.Language.ConvertExpressionAst] $convertExpressionAst) | |
{ | |
$child = [ConstrainedVariableInterpolation]::Parse($convertExpressionAst.Child, $this.Property) | |
return $this.ExpandExpression($convertExpressionAst, ($child.Value -as $convertExpressionAst.StaticType)) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitConstantExpression([System.Management.Automation.Language.ConstantExpressionAst] $constantExpressionAst) | |
{ | |
return $this.ExpandExpression($constantExpressionAst, $constantExpressionAst.Value) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitStringConstantExpression([System.Management.Automation.Language.StringConstantExpressionAst] $stringConstantExpressionAst) | |
{ | |
return $this.ExpandExpression($stringConstantExpressionAst, $stringConstantExpressionAst.Value) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitSubExpression([System.Management.Automation.Language.SubExpressionAst] $subExpressionAst) | |
{ | |
return $this.ExpandExpression($subExpressionAst.SubExpression) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitUsingExpression([System.Management.Automation.Language.UsingExpressionAst] $usingExpressionAst) | |
{ | |
throw 'VisitUsingExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitVariableExpression([System.Management.Automation.Language.VariableExpressionAst] $variableExpressionAst) | |
{ | |
return $this.ExpandExpression($variableExpressionAst, $this.Property.$($variableExpressionAst.VariablePath.UserPath)) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitMemberExpression([System.Management.Automation.Language.MemberExpressionAst] $memberExpressionAst) | |
{ | |
# Expand both expressions here | |
$value = [ConstrainedVariableInterpolation]::Parse($memberExpressionAst.Expression, $this.Property) | |
$member = [ConstrainedVariableInterpolation]::Parse($memberExpressionAst.Member, $this.Property) | |
return $this.ExpandExpression($memberExpressionAst, $($value.Value).$($member.Value)) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitInvokeMemberExpression([System.Management.Automation.Language.InvokeMemberExpressionAst] $methodCallAst) | |
{ | |
throw 'VisitInvokeMemberExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitArrayExpression([System.Management.Automation.Language.ArrayExpressionAst] $arrayExpressionAst) | |
{ | |
throw 'VisitArrayExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitArrayLiteral([System.Management.Automation.Language.ArrayLiteralAst] $arrayLiteralAst) | |
{ | |
return $this.ExpandExpressionObjects($arrayLiteralAst.Elements) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitHashtable([System.Management.Automation.Language.HashtableAst] $hashtableAst) | |
{ | |
throw 'VisitHashtable not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitScriptBlockExpression([System.Management.Automation.Language.ScriptBlockExpressionAst] $scriptBlockExpressionAst) | |
{ | |
return $this.ExpandExpressionObjects($scriptBlockExpressionAst.ScriptBlock) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitParenExpression([System.Management.Automation.Language.ParenExpressionAst] $parenExpressionAst) | |
{ | |
return $this.ExpandExpressionObjects($parenExpressionAst.Pipeline) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitExpandableStringExpression([System.Management.Automation.Language.ExpandableStringExpressionAst] $expandableStringExpressionAst) | |
{ | |
return $this.ExpandExpressionList($expandableStringExpressionAst.NestedExpressions) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitIndexExpression([System.Management.Automation.Language.IndexExpressionAst] $indexExpressionAst) | |
{ | |
$target = [ConstrainedVariableInterpolation]::Parse($indexExpressionAst.Target, $this.Property) | |
$index = [ConstrainedVariableInterpolation]::Parse($indexExpressionAst.Index, $this.Property) | |
return $this.ExpandExpression($indexExpressionAst, $($target.Value)[$index.Value]) | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitAttributedExpression([System.Management.Automation.Language.AttributedExpressionAst] $attributedExpressionAst) | |
{ | |
throw 'VisitAttributedExpression not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitBlockStatement([System.Management.Automation.Language.BlockStatementAst] $blockStatementAst) | |
{ | |
throw 'VisitBlockStatement not supported' | |
} | |
[System.Management.Automation.Language.AstVisitAction] VisitNamedAttributeArgument([System.Management.Automation.Language.NamedAttributeArgumentAst] $namedAttributeArgumentAst) | |
{ | |
throw 'VisitNamedAttributeArgument not supported' | |
} | |
hidden [System.Management.Automation.Language.AstVisitAction] ExpandExpressionObjects([Object] $Elements) | |
{ | |
#return $this.ExpandExpressionList($Elements) | |
$r = foreach ($expression in $elements) { | |
$resolvedExpression = [ConstrainedVariableInterpolation]::Parse($expression, $this.Property) | |
if ($null -eq $resolvedExpression.Value) { | |
return $this.ExpandExpression( $this.Ast, $this.Ast.Extent.Text ) | |
} | |
$resolvedExpression.Value | |
} | |
return $this.ExpandExpression( $this.Ast, $r) | |
} | |
hidden [System.Management.Automation.Language.AstVisitAction] ExpandExpressionList([Object] $Elements) | |
{ | |
# Sets the value to a string | |
$string = $this.Ast.Extent.Text | |
$r = for ($i = @($elements).Count - 1; $i -ge 0; $i--) | |
{ | |
$expression = $elements[$i] | |
$resolvedExpression = [ConstrainedVariableInterpolation]::Parse($expression, $this.Property) | |
# If there is no resolved value we Failback to No-ResolvedValue | |
if ($null -eq $resolvedExpression.Value) { | |
return $this.ExpandExpression( $this.Ast, $this.Ast.Extent.Text ) | |
} | |
$resolvedString = "{0}" -f ($resolvedExpression.Value -join " ") | |
$resolvedString | |
# Remove and insert expression | |
$string = $string.Remove( | |
$expression.Extent.StartOffset - $this.Ast.Extent.StartOffset, | |
$expression.Extent.EndOffset - $expression.Extent.StartOffset | |
) | |
$string = $string.Insert( | |
$expression.Extent.StartOffset - $this.Ast.Extent.StartOffset, | |
$resolvedString | |
) | |
} | |
return $this.ExpandExpression( $this.Ast, $string) | |
} | |
hidden [System.Management.Automation.Language.AstVisitAction] ExpandExpression([System.Management.Automation.Language.Ast] $Ast) | |
{ | |
return $this.ExpandExpression($Ast, [ConstrainedVariableInterpolation]::Parse($Ast, $this.Property).Value) | |
} | |
hidden [System.Management.Automation.Language.AstVisitAction] ExpandExpression([System.Management.Automation.Language.Ast] $Ast, [object] $Value) | |
{ | |
$this.Result.Add( | |
@{ | |
StartOffset = $Ast.Extent.StartOffset | |
EndOffset = $Ast.Extent.EndOffset | |
Value = $Value | |
} | |
) | |
return [System.Management.Automation.Language.AstVisitAction]::StopVisit | |
} | |
ConstrainedVariableInterpolation([System.Management.Automation.Language.Ast] $Ast, [Hashtable] $Property) | |
{ | |
$this.Result = New-Object System.Collections.Generic.List[PSCustomObject] | |
$this.Ast = $Ast; | |
$this.Property = $Property; | |
} | |
static [Object] Parse([System.Management.Automation.Language.Ast] $Ast, [Hashtable]$Property) | |
{ | |
# We use this parse to expand | |
$visitor = [ConstrainedVariableInterpolation]::new($Ast, $Property) | |
$Ast.Visit($visitor) | |
return $visitor.Result | |
} | |
static [Object] Parse([string] $String, [Hashtable]$Property) | |
{ | |
# Add Properties | |
$Property['True'] = $true | |
$Property['False'] = $false | |
$Property['Null'] = $null | |
# Double Escape Strings because FUN | |
# Turn into ScriptBlock | |
$parseString = $string.Replace("""", """""") | |
$parseString = "{""$parseString""}" | |
[System.Management.Automation.Language.Token[]] $astTokens = $null; | |
[System.Management.Automation.Language.ParseError[]] $astErrors = $null | |
$astVisitor = [System.Management.Automation.Language.Parser]::ParseInput($parseString, [ref] $astTokens, [ref] $astErrors) | |
# Check if Visitor has a valid Expandable syntax | |
$hasValidVisitor = $astVisitor.FindAll( | |
{ | |
$args[0].GetType().Name -in "IndexExpressionAst", "MemberExpressionAst", "VariableExpressionAst", "BinaryExpressionAst", "ConvertExpressionAst" | |
}, | |
$true | |
) | |
if (-not $hasValidVisitor) { | |
return $string | |
} | |
try { | |
$_resultObjects = [string][ConstrainedVariableInterpolation]::Parse($astVisitor, $Property).Value | |
$_resultObjects = $_resultObjects.Replace("""""", """") | |
return $_resultObjects.SubString(2, $_resultObjects.Length -4) | |
} | |
catch { | |
throw $_ | |
} | |
return $String | |
} | |
} | |
function Expand-String | |
{ | |
[CmdletBinding()] | |
[Alias("Expand-StringVariables")] | |
param( | |
[Parameter(Mandatory, ValueFromPipeline)] | |
[string] $String, | |
[Parameter(Mandatory)] | |
[hashtable] $Property | |
) | |
begin { | |
} | |
process { | |
return [ConstrainedVariableInterpolation]::Parse($String, $Property) | |
} | |
end { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment