Module refinery.lib.scripts.ps1.synth
AST-to-source synthesizer for PowerShell.
Expand source code Browse git
"""
AST-to-source synthesizer for PowerShell.
"""
from __future__ import annotations
import io
from refinery.lib.scripts import Block, Node, Synthesizer
from refinery.lib.scripts.ps1.deobfuscation.helpers import BACKTICK_ENCODE
from refinery.lib.scripts.ps1.model import (
Expression,
Ps1ArrayExpression,
Ps1ArrayLiteral,
Ps1AssignmentExpression,
Ps1Attribute,
Ps1BinaryExpression,
Ps1BreakStatement,
Ps1CastExpression,
Ps1ClassDefinition,
Ps1Code,
Ps1CommandArgument,
Ps1CommandArgumentKind,
Ps1CommandInvocation,
Ps1ContinueStatement,
Ps1DataSection,
Ps1DoLoop,
Ps1EnumDefinition,
Ps1EnumMember,
Ps1ErrorNode,
Ps1Exit,
Ps1ExitStatement,
Ps1ExpandableHereString,
Ps1ExpandableString,
Ps1ExpressionStatement,
Ps1FileRedirection,
Ps1ForEachLoop,
Ps1ForLoop,
Ps1FunctionDefinition,
Ps1HashLiteral,
Ps1HereString,
Ps1IfStatement,
Ps1IndexExpression,
Ps1IntegerLiteral,
Ps1InvokeMember,
Ps1Jump,
Ps1MemberAccess,
Ps1MemberModifier,
Ps1MergingRedirection,
Ps1MethodMember,
Ps1ParamBlock,
Ps1ParameterDeclaration,
Ps1ParenExpression,
Ps1Pipeline,
Ps1PipelineElement,
Ps1PropertyMember,
Ps1RangeExpression,
Ps1RealLiteral,
Ps1RedirectionStream,
Ps1ReturnStatement,
Ps1ScopeModifier,
Ps1Script,
Ps1ScriptBlock,
Ps1StringLiteral,
Ps1SubExpression,
Ps1SwitchStatement,
Ps1ThrowStatement,
Ps1TrapStatement,
Ps1TryCatchFinally,
Ps1TypeExpression,
Ps1UnaryExpression,
Ps1Variable,
Ps1WhileLoop,
)
from refinery.lib.scripts.ps1.token import KEYWORD_SPELLING
class Ps1Synthesizer(Synthesizer):
def _emit_block(self, block: Block):
self._write('{')
self._depth += 1
for stmt in block.body:
self._newline()
self.visit(stmt)
self._depth -= 1
if block.body:
self._newline()
self._write('}')
def _emit_statement_list(self, stmts: list):
for i, stmt in enumerate(stmts):
if i > 0:
self._newline()
self.visit(stmt)
def visit_Ps1Variable(self, node: Ps1Variable):
prefix = '@' if node.splatted else '$'
scope_str = ''
if node.scope != Ps1ScopeModifier.NONE:
scope_str = F'{node.scope.value}:'
name = F'{{{node.name}}}' if node.braced else node.name
self._write(F'{prefix}{scope_str}{name}')
def visit_Ps1IntegerLiteral(self, node: Ps1IntegerLiteral):
self._write(node.raw)
def visit_Ps1RealLiteral(self, node: Ps1RealLiteral):
self._write(node.raw)
def visit_Ps1StringLiteral(self, node: Ps1StringLiteral):
if '\n' in node.raw:
self._write(F'"{self._escape_for_dq(node.value)}"')
else:
self._write(node.raw)
def visit_Ps1ExpandableString(self, node: Ps1ExpandableString):
self._write('"')
for part in node.parts:
if isinstance(part, Ps1StringLiteral):
self._write(self._escape_for_dq(part.value))
elif isinstance(part, Ps1Variable):
self._emit_variable_in_dq(part)
else:
self.visit(part)
self._write('"')
def _emit_variable_in_dq(self, node: Ps1Variable):
prefix = '@' if node.splatted else '$'
scope_str = ''
if node.scope != Ps1ScopeModifier.NONE:
scope_str = F'{node.scope.value}:'
self._write(F'{prefix}{{{scope_str}{node.name}}}')
@staticmethod
def _escape_for_dq(value: str) -> str:
for c in '`"$':
value = value.replace(c, F'`{c}')
for ch, esc in BACKTICK_ENCODE.items():
value = value.replace(ch, esc)
return value
def visit_Ps1HereString(self, node: Ps1HereString):
if '\n' in node.value:
self._write(F'"{self._escape_for_dq(node.value)}"')
else:
self._write(node.raw)
def visit_Ps1ExpandableHereString(self, node: Ps1ExpandableHereString):
self._write(node.raw)
def visit_Ps1BinaryExpression(self, node: Ps1BinaryExpression):
spine: list[tuple[str, Expression | None]] = []
current: Expression | None = node
while isinstance(current, Ps1BinaryExpression):
spine.append((current.operator, current.right))
current = current.left
if current:
self.visit(current)
for operator, right in reversed(spine):
self._write(F' {operator} ')
if right:
self.visit(right)
def visit_Ps1UnaryExpression(self, node: Ps1UnaryExpression):
if node.prefix:
self._write(node.operator)
if node.operator.startswith('-') and len(node.operator) > 1:
self._write(' ')
if node.operand:
self.visit(node.operand)
else:
if node.operand:
self.visit(node.operand)
self._write(node.operator)
def visit_Ps1TypeExpression(self, node: Ps1TypeExpression):
self._write(F'[{node.name}]')
def visit_Ps1CastExpression(self, node: Ps1CastExpression):
self._write(F'[{node.type_name}]')
if node.operand:
self.visit(node.operand)
def _emit_member_prefix(self, node: Ps1MemberAccess | Ps1InvokeMember):
if node.object:
self.visit(node.object)
self._write(node.access.value)
if isinstance(node.member, Expression):
self.visit(node.member)
else:
self._write(str(node.member))
def visit_Ps1MemberAccess(self, node: Ps1MemberAccess):
self._emit_member_prefix(node)
def visit_Ps1IndexExpression(self, node: Ps1IndexExpression):
if node.object:
self.visit(node.object)
self._write('[')
if node.index:
self.visit(node.index)
self._write(']')
def visit_Ps1InvokeMember(self, node: Ps1InvokeMember):
self._emit_member_prefix(node)
self._write('(')
for i, arg in enumerate(node.arguments):
if i > 0:
self._write(', ')
self.visit(arg)
self._write(')')
def visit_Ps1CommandInvocation(self, node: Ps1CommandInvocation):
if node.invocation_operator:
self._write(node.invocation_operator)
self._write(' ')
if node.name:
self.visit(node.name)
for arg in node.arguments:
self._write(' ')
self.visit(arg)
for redir in node.redirections:
self._write(' ')
self.visit(redir)
def visit_Ps1CommandArgument(self, node: Ps1CommandArgument):
if node.kind == Ps1CommandArgumentKind.SWITCH:
self._write(node.name)
elif node.kind == Ps1CommandArgumentKind.NAMED:
self._write(F'{node.name}:')
if node.value:
self._emit_argument_value(node.value)
elif node.kind == Ps1CommandArgumentKind.POSITIONAL:
if node.value:
self._emit_argument_value(node.value)
def _emit_argument_value(self, value: Expression):
if isinstance(value, Ps1BinaryExpression):
self._write('(')
self.visit(value)
self._write(')')
else:
self.visit(value)
def visit_Ps1AssignmentExpression(self, node: Ps1AssignmentExpression):
if node.target:
self.visit(node.target)
self._write(F' {node.operator} ')
if node.value:
self.visit(node.value)
def visit_Ps1ArrayLiteral(self, node: Ps1ArrayLiteral):
for i, elem in enumerate(node.elements):
if i > 0:
self._write(', ')
self.visit(elem)
def visit_Ps1ArrayExpression(self, node: Ps1ArrayExpression):
self._write('@(')
self._emit_statement_list(node.body)
self._write(')')
def visit_Ps1HashLiteral(self, node: Ps1HashLiteral):
self._write('@{')
if node.pairs:
self._depth += 1
for key, value in node.pairs:
self._newline()
self.visit(key)
self._write(' = ')
self.visit(value)
self._depth -= 1
self._newline()
self._write('}')
def visit_Ps1SubExpression(self, node: Ps1SubExpression):
self._write('$(')
self._emit_statement_list(node.body)
self._write(')')
def visit_Ps1ParenExpression(self, node: Ps1ParenExpression):
self._write('(')
if node.expression:
self.visit(node.expression)
self._write(')')
def _emit_script_body(self, node: Ps1Code, *, newline_after: bool):
has_named = (
node.begin_block or node.process_block
or node.end_block or node.dynamicparam_block
)
if has_named:
for keyword, block in (
('begin', node.begin_block),
('process', node.process_block),
('end', node.end_block),
('dynamicparam', node.dynamicparam_block),
):
if block:
if not newline_after:
self._newline()
self._write(F'{keyword} ')
self._emit_block(block)
if newline_after:
self._newline()
else:
if newline_after:
self._emit_statement_list(node.body)
else:
for stmt in node.body:
self._newline()
self.visit(stmt)
def visit_Ps1ScriptBlock(self, node: Ps1ScriptBlock):
self._write('{')
self._depth += 1
if node.param_block:
self._newline()
self.visit(node.param_block)
self._emit_script_body(node, newline_after=False)
self._depth -= 1
has_content = (
node.body or node.param_block
or node.begin_block or node.process_block
or node.end_block or node.dynamicparam_block
)
if has_content:
self._newline()
self._write('}')
def visit_Ps1RangeExpression(self, node: Ps1RangeExpression):
if node.start:
self.visit(node.start)
self._write('..')
if node.end:
self.visit(node.end)
def _render_to_string(self, node: Node) -> str:
saved = self._parts
self._parts = io.StringIO()
try:
self.visit(node)
return self._parts.getvalue()
finally:
self._parts = saved
def visit_Ps1Attribute(self, node: Ps1Attribute):
self._write(F'[{node.name}')
if node.positional_args or node.named_args:
self._write('(')
items: list[str] = []
for arg in node.positional_args:
items.append(self._render_to_string(arg))
for key, val in node.named_args:
items.append(F'{key}={self._render_to_string(val)}')
self._write(', '.join(items))
self._write(')')
self._write(']')
def visit_Ps1ParameterDeclaration(self, node: Ps1ParameterDeclaration):
for attr in node.attributes:
self.visit(attr)
if node.variable:
self.visit(node.variable)
if node.default_value:
self._write(' = ')
self.visit(node.default_value)
def visit_Ps1ParamBlock(self, node: Ps1ParamBlock):
for attr in node.attributes:
self.visit(attr)
self._newline()
self._write(KEYWORD_SPELLING.get('param', 'param'))
self._write('(')
for i, param in enumerate(node.parameters):
if i > 0:
self._write(', ')
self.visit(param)
self._write(')')
def _emit_redirection_stream(self, stream: Ps1RedirectionStream) -> str:
if stream == Ps1RedirectionStream.OUTPUT:
return ''
if stream == Ps1RedirectionStream.ALL:
return '*'
return str(stream.value)
def visit_Ps1FileRedirection(self, node: Ps1FileRedirection):
prefix = self._emit_redirection_stream(node.stream)
op = '>>' if node.append else '>'
self._write(F'{prefix}{op}')
if node.target:
self._write(' ')
self.visit(node.target)
def visit_Ps1MergingRedirection(self, node: Ps1MergingRedirection):
prefix = self._emit_redirection_stream(node.from_stream)
self._write(F'{prefix}>&{node.to_stream.value}')
def visit_Ps1PipelineElement(self, node: Ps1PipelineElement):
if node.expression:
self.visit(node.expression)
for redir in node.redirections:
self._write(' ')
self.visit(redir)
def visit_Ps1Pipeline(self, node: Ps1Pipeline):
for i, elem in enumerate(node.elements):
if i > 0:
self._write(' | ')
self.visit(elem)
def visit_Ps1ExpressionStatement(self, node: Ps1ExpressionStatement):
if node.expression:
self.visit(node.expression)
def visit_Ps1IfStatement(self, node: Ps1IfStatement):
for i, (cond, body) in enumerate(node.clauses):
if i == 0:
self._write('if (')
else:
self._write(' elseif (')
if cond:
self.visit(cond)
self._write(') ')
self._emit_block(body)
if node.else_block:
self._write(' else ')
self._emit_block(node.else_block)
def visit_Ps1WhileLoop(self, node: Ps1WhileLoop):
if node.label:
self._write(F'{node.label} ')
self._write('while (')
if node.condition:
self.visit(node.condition)
self._write(') ')
if node.body:
self._emit_block(node.body)
def visit_Ps1DoLoop(self, node: Ps1DoLoop):
if node.label:
self._write(F'{node.label} ')
self._write('do ')
if node.body:
self._emit_block(node.body)
keyword = 'until' if node.is_until else 'while'
self._write(F' {keyword} (')
if node.condition:
self.visit(node.condition)
self._write(')')
def visit_Ps1ForLoop(self, node: Ps1ForLoop):
if node.label:
self._write(F'{node.label} ')
self._write('for (')
if node.initializer:
self.visit(node.initializer)
self._write('; ')
if node.condition:
self.visit(node.condition)
self._write('; ')
if node.iterator:
self.visit(node.iterator)
self._write(') ')
if node.body:
self._emit_block(node.body)
def visit_Ps1ForEachLoop(self, node: Ps1ForEachLoop):
if node.label:
self._write(F'{node.label} ')
self._write('foreach ')
if node.parallel:
self._write('-Parallel ')
self._write('(')
if node.variable:
self.visit(node.variable)
self._write(' in ')
if node.iterable:
self.visit(node.iterable)
self._write(') ')
if node.body:
self._emit_block(node.body)
def visit_Ps1SwitchStatement(self, node: Ps1SwitchStatement):
if node.label:
self._write(F'{node.label} ')
self._write('switch ')
if node.regex:
self._write('-Regex ')
if node.wildcard:
self._write('-Wildcard ')
if node.exact:
self._write('-Exact ')
if node.case_sensitive:
self._write('-CaseSensitive ')
if node.file:
self._write('-File ')
if node.value:
self.visit(node.value)
self._write(' {')
else:
self._write('(')
if node.value:
self.visit(node.value)
self._write(') {')
self._depth += 1
for cond, body in node.clauses:
self._newline()
if cond is None:
self._write('default ')
else:
self.visit(cond)
self._write(' ')
self._emit_block(body)
self._depth -= 1
self._newline()
self._write('}')
def visit_Ps1TryCatchFinally(self, node: Ps1TryCatchFinally):
self._write('try ')
if node.try_block:
self._emit_block(node.try_block)
for clause in node.catch_clauses:
self._write(' catch')
if clause.types:
self._write(' ')
self._write(' '.join(F'[{t}]' for t in clause.types))
self._write(' ')
if clause.body:
self._emit_block(clause.body)
if node.finally_block:
self._write(' finally ')
self._emit_block(node.finally_block)
def visit_Ps1TrapStatement(self, node: Ps1TrapStatement):
self._write('trap ')
if node.type_name:
self._write(F'[{node.type_name}] ')
if node.body:
self._emit_block(node.body)
def visit_Ps1FunctionDefinition(self, node: Ps1FunctionDefinition):
kw = 'filter' if node.is_filter else 'function'
self._write(F'{kw} {node.name} ')
if node.body:
self.visit(node.body)
def _emit_member_modifiers(self, modifiers: Ps1MemberModifier):
if Ps1MemberModifier.STATIC in modifiers:
self._write('static ')
if Ps1MemberModifier.HIDDEN in modifiers:
self._write('hidden ')
def visit_Ps1PropertyMember(self, node: Ps1PropertyMember):
for attr in node.attributes:
self.visit(attr)
self._emit_member_modifiers(node.modifiers)
if node.type_constraint:
self.visit(node.type_constraint)
if node.variable:
self.visit(node.variable)
if node.initial_value:
self._write(' = ')
self.visit(node.initial_value)
def visit_Ps1MethodMember(self, node: Ps1MethodMember):
for attr in node.attributes:
self.visit(attr)
self._emit_member_modifiers(node.modifiers)
if node.return_type:
self.visit(node.return_type)
self._write(' ')
if node.definition:
funcdef = node.definition
self._write(F'{funcdef.name}(')
if funcdef.body and funcdef.body.param_block:
for i, param in enumerate(funcdef.body.param_block.parameters):
if i > 0:
self._write(', ')
self.visit(param)
self._write(') {')
self._depth += 1
if funcdef.body:
self._emit_script_body(funcdef.body, newline_after=False)
self._depth -= 1
has_content = funcdef.body and (
funcdef.body.body
or funcdef.body.begin_block
or funcdef.body.process_block
or funcdef.body.end_block
or funcdef.body.dynamicparam_block
)
if has_content:
self._newline()
self._write('}')
def visit_Ps1ClassDefinition(self, node: Ps1ClassDefinition):
self._write(F'class {node.name}')
if node.base_types:
self._write(' : ')
self._write(', '.join(node.base_types))
self._write(' {')
self._depth += 1
for member in node.members:
self._newline()
self.visit(member)
self._depth -= 1
if node.members:
self._newline()
self._write('}')
def visit_Ps1EnumMember(self, node: Ps1EnumMember):
self._write(node.name)
if node.value is not None:
self._write(' = ')
self.visit(node.value)
def visit_Ps1EnumDefinition(self, node: Ps1EnumDefinition):
self._write(F'enum {node.name}')
if node.base_type:
self._write(F' : {node.base_type}')
self._write(' {')
self._depth += 1
for member in node.members:
self._newline()
self.visit(member)
self._depth -= 1
if node.members:
self._newline()
self._write('}')
def _visit_jump(self, node: Ps1Jump, name: str):
self._write(name)
if suffix := node.label:
self._write(' ')
self.visit(suffix)
def _visit_exit(self, node: Ps1Exit, name: str):
self._write(name)
if suffix := node.pipeline:
self._write(' ')
self.visit(suffix)
def visit_Ps1ReturnStatement(self, node: Ps1ReturnStatement):
self._visit_exit(node, 'return')
def visit_Ps1ExitStatement(self, node: Ps1ExitStatement):
self._visit_exit(node, 'exit')
def visit_Ps1ThrowStatement(self, node: Ps1ThrowStatement):
self._visit_exit(node, 'throw')
def visit_Ps1BreakStatement(self, node: Ps1BreakStatement):
self._visit_jump(node, 'break')
def visit_Ps1ContinueStatement(self, node: Ps1ContinueStatement):
self._visit_jump(node, 'continue')
def visit_Ps1DataSection(self, node: Ps1DataSection):
self._write('data ')
if node.name:
self._write(F'{node.name} ')
if node.commands:
self._write('-SupportedCommand ')
for i, cmd in enumerate(node.commands):
if i > 0:
self._write(', ')
self.visit(cmd)
self._write(' ')
if node.body:
self._emit_block(node.body)
def visit_Ps1ErrorNode(self, node: Ps1ErrorNode):
self._write(node.text)
def visit_Ps1Script(self, node: Ps1Script):
if node.param_block:
self.visit(node.param_block)
self._newline()
self._emit_script_body(node, newline_after=True)
def visit_Block(self, node: Block):
self._emit_block(node)
Classes
class Ps1Synthesizer (indent=' ')-
Base class for AST-to-source synthesizers. Provides indentation-aware output buffering shared by all language-specific synthesizers.
Expand source code Browse git
class Ps1Synthesizer(Synthesizer): def _emit_block(self, block: Block): self._write('{') self._depth += 1 for stmt in block.body: self._newline() self.visit(stmt) self._depth -= 1 if block.body: self._newline() self._write('}') def _emit_statement_list(self, stmts: list): for i, stmt in enumerate(stmts): if i > 0: self._newline() self.visit(stmt) def visit_Ps1Variable(self, node: Ps1Variable): prefix = '@' if node.splatted else '$' scope_str = '' if node.scope != Ps1ScopeModifier.NONE: scope_str = F'{node.scope.value}:' name = F'{{{node.name}}}' if node.braced else node.name self._write(F'{prefix}{scope_str}{name}') def visit_Ps1IntegerLiteral(self, node: Ps1IntegerLiteral): self._write(node.raw) def visit_Ps1RealLiteral(self, node: Ps1RealLiteral): self._write(node.raw) def visit_Ps1StringLiteral(self, node: Ps1StringLiteral): if '\n' in node.raw: self._write(F'"{self._escape_for_dq(node.value)}"') else: self._write(node.raw) def visit_Ps1ExpandableString(self, node: Ps1ExpandableString): self._write('"') for part in node.parts: if isinstance(part, Ps1StringLiteral): self._write(self._escape_for_dq(part.value)) elif isinstance(part, Ps1Variable): self._emit_variable_in_dq(part) else: self.visit(part) self._write('"') def _emit_variable_in_dq(self, node: Ps1Variable): prefix = '@' if node.splatted else '$' scope_str = '' if node.scope != Ps1ScopeModifier.NONE: scope_str = F'{node.scope.value}:' self._write(F'{prefix}{{{scope_str}{node.name}}}') @staticmethod def _escape_for_dq(value: str) -> str: for c in '`"$': value = value.replace(c, F'`{c}') for ch, esc in BACKTICK_ENCODE.items(): value = value.replace(ch, esc) return value def visit_Ps1HereString(self, node: Ps1HereString): if '\n' in node.value: self._write(F'"{self._escape_for_dq(node.value)}"') else: self._write(node.raw) def visit_Ps1ExpandableHereString(self, node: Ps1ExpandableHereString): self._write(node.raw) def visit_Ps1BinaryExpression(self, node: Ps1BinaryExpression): spine: list[tuple[str, Expression | None]] = [] current: Expression | None = node while isinstance(current, Ps1BinaryExpression): spine.append((current.operator, current.right)) current = current.left if current: self.visit(current) for operator, right in reversed(spine): self._write(F' {operator} ') if right: self.visit(right) def visit_Ps1UnaryExpression(self, node: Ps1UnaryExpression): if node.prefix: self._write(node.operator) if node.operator.startswith('-') and len(node.operator) > 1: self._write(' ') if node.operand: self.visit(node.operand) else: if node.operand: self.visit(node.operand) self._write(node.operator) def visit_Ps1TypeExpression(self, node: Ps1TypeExpression): self._write(F'[{node.name}]') def visit_Ps1CastExpression(self, node: Ps1CastExpression): self._write(F'[{node.type_name}]') if node.operand: self.visit(node.operand) def _emit_member_prefix(self, node: Ps1MemberAccess | Ps1InvokeMember): if node.object: self.visit(node.object) self._write(node.access.value) if isinstance(node.member, Expression): self.visit(node.member) else: self._write(str(node.member)) def visit_Ps1MemberAccess(self, node: Ps1MemberAccess): self._emit_member_prefix(node) def visit_Ps1IndexExpression(self, node: Ps1IndexExpression): if node.object: self.visit(node.object) self._write('[') if node.index: self.visit(node.index) self._write(']') def visit_Ps1InvokeMember(self, node: Ps1InvokeMember): self._emit_member_prefix(node) self._write('(') for i, arg in enumerate(node.arguments): if i > 0: self._write(', ') self.visit(arg) self._write(')') def visit_Ps1CommandInvocation(self, node: Ps1CommandInvocation): if node.invocation_operator: self._write(node.invocation_operator) self._write(' ') if node.name: self.visit(node.name) for arg in node.arguments: self._write(' ') self.visit(arg) for redir in node.redirections: self._write(' ') self.visit(redir) def visit_Ps1CommandArgument(self, node: Ps1CommandArgument): if node.kind == Ps1CommandArgumentKind.SWITCH: self._write(node.name) elif node.kind == Ps1CommandArgumentKind.NAMED: self._write(F'{node.name}:') if node.value: self._emit_argument_value(node.value) elif node.kind == Ps1CommandArgumentKind.POSITIONAL: if node.value: self._emit_argument_value(node.value) def _emit_argument_value(self, value: Expression): if isinstance(value, Ps1BinaryExpression): self._write('(') self.visit(value) self._write(')') else: self.visit(value) def visit_Ps1AssignmentExpression(self, node: Ps1AssignmentExpression): if node.target: self.visit(node.target) self._write(F' {node.operator} ') if node.value: self.visit(node.value) def visit_Ps1ArrayLiteral(self, node: Ps1ArrayLiteral): for i, elem in enumerate(node.elements): if i > 0: self._write(', ') self.visit(elem) def visit_Ps1ArrayExpression(self, node: Ps1ArrayExpression): self._write('@(') self._emit_statement_list(node.body) self._write(')') def visit_Ps1HashLiteral(self, node: Ps1HashLiteral): self._write('@{') if node.pairs: self._depth += 1 for key, value in node.pairs: self._newline() self.visit(key) self._write(' = ') self.visit(value) self._depth -= 1 self._newline() self._write('}') def visit_Ps1SubExpression(self, node: Ps1SubExpression): self._write('$(') self._emit_statement_list(node.body) self._write(')') def visit_Ps1ParenExpression(self, node: Ps1ParenExpression): self._write('(') if node.expression: self.visit(node.expression) self._write(')') def _emit_script_body(self, node: Ps1Code, *, newline_after: bool): has_named = ( node.begin_block or node.process_block or node.end_block or node.dynamicparam_block ) if has_named: for keyword, block in ( ('begin', node.begin_block), ('process', node.process_block), ('end', node.end_block), ('dynamicparam', node.dynamicparam_block), ): if block: if not newline_after: self._newline() self._write(F'{keyword} ') self._emit_block(block) if newline_after: self._newline() else: if newline_after: self._emit_statement_list(node.body) else: for stmt in node.body: self._newline() self.visit(stmt) def visit_Ps1ScriptBlock(self, node: Ps1ScriptBlock): self._write('{') self._depth += 1 if node.param_block: self._newline() self.visit(node.param_block) self._emit_script_body(node, newline_after=False) self._depth -= 1 has_content = ( node.body or node.param_block or node.begin_block or node.process_block or node.end_block or node.dynamicparam_block ) if has_content: self._newline() self._write('}') def visit_Ps1RangeExpression(self, node: Ps1RangeExpression): if node.start: self.visit(node.start) self._write('..') if node.end: self.visit(node.end) def _render_to_string(self, node: Node) -> str: saved = self._parts self._parts = io.StringIO() try: self.visit(node) return self._parts.getvalue() finally: self._parts = saved def visit_Ps1Attribute(self, node: Ps1Attribute): self._write(F'[{node.name}') if node.positional_args or node.named_args: self._write('(') items: list[str] = [] for arg in node.positional_args: items.append(self._render_to_string(arg)) for key, val in node.named_args: items.append(F'{key}={self._render_to_string(val)}') self._write(', '.join(items)) self._write(')') self._write(']') def visit_Ps1ParameterDeclaration(self, node: Ps1ParameterDeclaration): for attr in node.attributes: self.visit(attr) if node.variable: self.visit(node.variable) if node.default_value: self._write(' = ') self.visit(node.default_value) def visit_Ps1ParamBlock(self, node: Ps1ParamBlock): for attr in node.attributes: self.visit(attr) self._newline() self._write(KEYWORD_SPELLING.get('param', 'param')) self._write('(') for i, param in enumerate(node.parameters): if i > 0: self._write(', ') self.visit(param) self._write(')') def _emit_redirection_stream(self, stream: Ps1RedirectionStream) -> str: if stream == Ps1RedirectionStream.OUTPUT: return '' if stream == Ps1RedirectionStream.ALL: return '*' return str(stream.value) def visit_Ps1FileRedirection(self, node: Ps1FileRedirection): prefix = self._emit_redirection_stream(node.stream) op = '>>' if node.append else '>' self._write(F'{prefix}{op}') if node.target: self._write(' ') self.visit(node.target) def visit_Ps1MergingRedirection(self, node: Ps1MergingRedirection): prefix = self._emit_redirection_stream(node.from_stream) self._write(F'{prefix}>&{node.to_stream.value}') def visit_Ps1PipelineElement(self, node: Ps1PipelineElement): if node.expression: self.visit(node.expression) for redir in node.redirections: self._write(' ') self.visit(redir) def visit_Ps1Pipeline(self, node: Ps1Pipeline): for i, elem in enumerate(node.elements): if i > 0: self._write(' | ') self.visit(elem) def visit_Ps1ExpressionStatement(self, node: Ps1ExpressionStatement): if node.expression: self.visit(node.expression) def visit_Ps1IfStatement(self, node: Ps1IfStatement): for i, (cond, body) in enumerate(node.clauses): if i == 0: self._write('if (') else: self._write(' elseif (') if cond: self.visit(cond) self._write(') ') self._emit_block(body) if node.else_block: self._write(' else ') self._emit_block(node.else_block) def visit_Ps1WhileLoop(self, node: Ps1WhileLoop): if node.label: self._write(F'{node.label} ') self._write('while (') if node.condition: self.visit(node.condition) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1DoLoop(self, node: Ps1DoLoop): if node.label: self._write(F'{node.label} ') self._write('do ') if node.body: self._emit_block(node.body) keyword = 'until' if node.is_until else 'while' self._write(F' {keyword} (') if node.condition: self.visit(node.condition) self._write(')') def visit_Ps1ForLoop(self, node: Ps1ForLoop): if node.label: self._write(F'{node.label} ') self._write('for (') if node.initializer: self.visit(node.initializer) self._write('; ') if node.condition: self.visit(node.condition) self._write('; ') if node.iterator: self.visit(node.iterator) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1ForEachLoop(self, node: Ps1ForEachLoop): if node.label: self._write(F'{node.label} ') self._write('foreach ') if node.parallel: self._write('-Parallel ') self._write('(') if node.variable: self.visit(node.variable) self._write(' in ') if node.iterable: self.visit(node.iterable) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1SwitchStatement(self, node: Ps1SwitchStatement): if node.label: self._write(F'{node.label} ') self._write('switch ') if node.regex: self._write('-Regex ') if node.wildcard: self._write('-Wildcard ') if node.exact: self._write('-Exact ') if node.case_sensitive: self._write('-CaseSensitive ') if node.file: self._write('-File ') if node.value: self.visit(node.value) self._write(' {') else: self._write('(') if node.value: self.visit(node.value) self._write(') {') self._depth += 1 for cond, body in node.clauses: self._newline() if cond is None: self._write('default ') else: self.visit(cond) self._write(' ') self._emit_block(body) self._depth -= 1 self._newline() self._write('}') def visit_Ps1TryCatchFinally(self, node: Ps1TryCatchFinally): self._write('try ') if node.try_block: self._emit_block(node.try_block) for clause in node.catch_clauses: self._write(' catch') if clause.types: self._write(' ') self._write(' '.join(F'[{t}]' for t in clause.types)) self._write(' ') if clause.body: self._emit_block(clause.body) if node.finally_block: self._write(' finally ') self._emit_block(node.finally_block) def visit_Ps1TrapStatement(self, node: Ps1TrapStatement): self._write('trap ') if node.type_name: self._write(F'[{node.type_name}] ') if node.body: self._emit_block(node.body) def visit_Ps1FunctionDefinition(self, node: Ps1FunctionDefinition): kw = 'filter' if node.is_filter else 'function' self._write(F'{kw} {node.name} ') if node.body: self.visit(node.body) def _emit_member_modifiers(self, modifiers: Ps1MemberModifier): if Ps1MemberModifier.STATIC in modifiers: self._write('static ') if Ps1MemberModifier.HIDDEN in modifiers: self._write('hidden ') def visit_Ps1PropertyMember(self, node: Ps1PropertyMember): for attr in node.attributes: self.visit(attr) self._emit_member_modifiers(node.modifiers) if node.type_constraint: self.visit(node.type_constraint) if node.variable: self.visit(node.variable) if node.initial_value: self._write(' = ') self.visit(node.initial_value) def visit_Ps1MethodMember(self, node: Ps1MethodMember): for attr in node.attributes: self.visit(attr) self._emit_member_modifiers(node.modifiers) if node.return_type: self.visit(node.return_type) self._write(' ') if node.definition: funcdef = node.definition self._write(F'{funcdef.name}(') if funcdef.body and funcdef.body.param_block: for i, param in enumerate(funcdef.body.param_block.parameters): if i > 0: self._write(', ') self.visit(param) self._write(') {') self._depth += 1 if funcdef.body: self._emit_script_body(funcdef.body, newline_after=False) self._depth -= 1 has_content = funcdef.body and ( funcdef.body.body or funcdef.body.begin_block or funcdef.body.process_block or funcdef.body.end_block or funcdef.body.dynamicparam_block ) if has_content: self._newline() self._write('}') def visit_Ps1ClassDefinition(self, node: Ps1ClassDefinition): self._write(F'class {node.name}') if node.base_types: self._write(' : ') self._write(', '.join(node.base_types)) self._write(' {') self._depth += 1 for member in node.members: self._newline() self.visit(member) self._depth -= 1 if node.members: self._newline() self._write('}') def visit_Ps1EnumMember(self, node: Ps1EnumMember): self._write(node.name) if node.value is not None: self._write(' = ') self.visit(node.value) def visit_Ps1EnumDefinition(self, node: Ps1EnumDefinition): self._write(F'enum {node.name}') if node.base_type: self._write(F' : {node.base_type}') self._write(' {') self._depth += 1 for member in node.members: self._newline() self.visit(member) self._depth -= 1 if node.members: self._newline() self._write('}') def _visit_jump(self, node: Ps1Jump, name: str): self._write(name) if suffix := node.label: self._write(' ') self.visit(suffix) def _visit_exit(self, node: Ps1Exit, name: str): self._write(name) if suffix := node.pipeline: self._write(' ') self.visit(suffix) def visit_Ps1ReturnStatement(self, node: Ps1ReturnStatement): self._visit_exit(node, 'return') def visit_Ps1ExitStatement(self, node: Ps1ExitStatement): self._visit_exit(node, 'exit') def visit_Ps1ThrowStatement(self, node: Ps1ThrowStatement): self._visit_exit(node, 'throw') def visit_Ps1BreakStatement(self, node: Ps1BreakStatement): self._visit_jump(node, 'break') def visit_Ps1ContinueStatement(self, node: Ps1ContinueStatement): self._visit_jump(node, 'continue') def visit_Ps1DataSection(self, node: Ps1DataSection): self._write('data ') if node.name: self._write(F'{node.name} ') if node.commands: self._write('-SupportedCommand ') for i, cmd in enumerate(node.commands): if i > 0: self._write(', ') self.visit(cmd) self._write(' ') if node.body: self._emit_block(node.body) def visit_Ps1ErrorNode(self, node: Ps1ErrorNode): self._write(node.text) def visit_Ps1Script(self, node: Ps1Script): if node.param_block: self.visit(node.param_block) self._newline() self._emit_script_body(node, newline_after=True) def visit_Block(self, node: Block): self._emit_block(node)Ancestors
Methods
def visit_Ps1Variable(self, node)-
Expand source code Browse git
def visit_Ps1Variable(self, node: Ps1Variable): prefix = '@' if node.splatted else '$' scope_str = '' if node.scope != Ps1ScopeModifier.NONE: scope_str = F'{node.scope.value}:' name = F'{{{node.name}}}' if node.braced else node.name self._write(F'{prefix}{scope_str}{name}') def visit_Ps1IntegerLiteral(self, node)-
Expand source code Browse git
def visit_Ps1IntegerLiteral(self, node: Ps1IntegerLiteral): self._write(node.raw) def visit_Ps1RealLiteral(self, node)-
Expand source code Browse git
def visit_Ps1RealLiteral(self, node: Ps1RealLiteral): self._write(node.raw) def visit_Ps1StringLiteral(self, node)-
Expand source code Browse git
def visit_Ps1StringLiteral(self, node: Ps1StringLiteral): if '\n' in node.raw: self._write(F'"{self._escape_for_dq(node.value)}"') else: self._write(node.raw) def visit_Ps1ExpandableString(self, node)-
Expand source code Browse git
def visit_Ps1ExpandableString(self, node: Ps1ExpandableString): self._write('"') for part in node.parts: if isinstance(part, Ps1StringLiteral): self._write(self._escape_for_dq(part.value)) elif isinstance(part, Ps1Variable): self._emit_variable_in_dq(part) else: self.visit(part) self._write('"') def visit_Ps1HereString(self, node)-
Expand source code Browse git
def visit_Ps1HereString(self, node: Ps1HereString): if '\n' in node.value: self._write(F'"{self._escape_for_dq(node.value)}"') else: self._write(node.raw) def visit_Ps1ExpandableHereString(self, node)-
Expand source code Browse git
def visit_Ps1ExpandableHereString(self, node: Ps1ExpandableHereString): self._write(node.raw) def visit_Ps1BinaryExpression(self, node)-
Expand source code Browse git
def visit_Ps1BinaryExpression(self, node: Ps1BinaryExpression): spine: list[tuple[str, Expression | None]] = [] current: Expression | None = node while isinstance(current, Ps1BinaryExpression): spine.append((current.operator, current.right)) current = current.left if current: self.visit(current) for operator, right in reversed(spine): self._write(F' {operator} ') if right: self.visit(right) def visit_Ps1UnaryExpression(self, node)-
Expand source code Browse git
def visit_Ps1UnaryExpression(self, node: Ps1UnaryExpression): if node.prefix: self._write(node.operator) if node.operator.startswith('-') and len(node.operator) > 1: self._write(' ') if node.operand: self.visit(node.operand) else: if node.operand: self.visit(node.operand) self._write(node.operator) def visit_Ps1TypeExpression(self, node)-
Expand source code Browse git
def visit_Ps1TypeExpression(self, node: Ps1TypeExpression): self._write(F'[{node.name}]') def visit_Ps1CastExpression(self, node)-
Expand source code Browse git
def visit_Ps1CastExpression(self, node: Ps1CastExpression): self._write(F'[{node.type_name}]') if node.operand: self.visit(node.operand) def visit_Ps1MemberAccess(self, node)-
Expand source code Browse git
def visit_Ps1MemberAccess(self, node: Ps1MemberAccess): self._emit_member_prefix(node) def visit_Ps1IndexExpression(self, node)-
Expand source code Browse git
def visit_Ps1IndexExpression(self, node: Ps1IndexExpression): if node.object: self.visit(node.object) self._write('[') if node.index: self.visit(node.index) self._write(']') def visit_Ps1InvokeMember(self, node)-
Expand source code Browse git
def visit_Ps1InvokeMember(self, node: Ps1InvokeMember): self._emit_member_prefix(node) self._write('(') for i, arg in enumerate(node.arguments): if i > 0: self._write(', ') self.visit(arg) self._write(')') def visit_Ps1CommandInvocation(self, node)-
Expand source code Browse git
def visit_Ps1CommandInvocation(self, node: Ps1CommandInvocation): if node.invocation_operator: self._write(node.invocation_operator) self._write(' ') if node.name: self.visit(node.name) for arg in node.arguments: self._write(' ') self.visit(arg) for redir in node.redirections: self._write(' ') self.visit(redir) def visit_Ps1CommandArgument(self, node)-
Expand source code Browse git
def visit_Ps1CommandArgument(self, node: Ps1CommandArgument): if node.kind == Ps1CommandArgumentKind.SWITCH: self._write(node.name) elif node.kind == Ps1CommandArgumentKind.NAMED: self._write(F'{node.name}:') if node.value: self._emit_argument_value(node.value) elif node.kind == Ps1CommandArgumentKind.POSITIONAL: if node.value: self._emit_argument_value(node.value) def visit_Ps1AssignmentExpression(self, node)-
Expand source code Browse git
def visit_Ps1AssignmentExpression(self, node: Ps1AssignmentExpression): if node.target: self.visit(node.target) self._write(F' {node.operator} ') if node.value: self.visit(node.value) def visit_Ps1ArrayLiteral(self, node)-
Expand source code Browse git
def visit_Ps1ArrayLiteral(self, node: Ps1ArrayLiteral): for i, elem in enumerate(node.elements): if i > 0: self._write(', ') self.visit(elem) def visit_Ps1ArrayExpression(self, node)-
Expand source code Browse git
def visit_Ps1ArrayExpression(self, node: Ps1ArrayExpression): self._write('@(') self._emit_statement_list(node.body) self._write(')') def visit_Ps1HashLiteral(self, node)-
Expand source code Browse git
def visit_Ps1HashLiteral(self, node: Ps1HashLiteral): self._write('@{') if node.pairs: self._depth += 1 for key, value in node.pairs: self._newline() self.visit(key) self._write(' = ') self.visit(value) self._depth -= 1 self._newline() self._write('}') def visit_Ps1SubExpression(self, node)-
Expand source code Browse git
def visit_Ps1SubExpression(self, node: Ps1SubExpression): self._write('$(') self._emit_statement_list(node.body) self._write(')') def visit_Ps1ParenExpression(self, node)-
Expand source code Browse git
def visit_Ps1ParenExpression(self, node: Ps1ParenExpression): self._write('(') if node.expression: self.visit(node.expression) self._write(')') def visit_Ps1ScriptBlock(self, node)-
Expand source code Browse git
def visit_Ps1ScriptBlock(self, node: Ps1ScriptBlock): self._write('{') self._depth += 1 if node.param_block: self._newline() self.visit(node.param_block) self._emit_script_body(node, newline_after=False) self._depth -= 1 has_content = ( node.body or node.param_block or node.begin_block or node.process_block or node.end_block or node.dynamicparam_block ) if has_content: self._newline() self._write('}') def visit_Ps1RangeExpression(self, node)-
Expand source code Browse git
def visit_Ps1RangeExpression(self, node: Ps1RangeExpression): if node.start: self.visit(node.start) self._write('..') if node.end: self.visit(node.end) def visit_Ps1Attribute(self, node)-
Expand source code Browse git
def visit_Ps1Attribute(self, node: Ps1Attribute): self._write(F'[{node.name}') if node.positional_args or node.named_args: self._write('(') items: list[str] = [] for arg in node.positional_args: items.append(self._render_to_string(arg)) for key, val in node.named_args: items.append(F'{key}={self._render_to_string(val)}') self._write(', '.join(items)) self._write(')') self._write(']') def visit_Ps1ParameterDeclaration(self, node)-
Expand source code Browse git
def visit_Ps1ParameterDeclaration(self, node: Ps1ParameterDeclaration): for attr in node.attributes: self.visit(attr) if node.variable: self.visit(node.variable) if node.default_value: self._write(' = ') self.visit(node.default_value) def visit_Ps1ParamBlock(self, node)-
Expand source code Browse git
def visit_Ps1ParamBlock(self, node: Ps1ParamBlock): for attr in node.attributes: self.visit(attr) self._newline() self._write(KEYWORD_SPELLING.get('param', 'param')) self._write('(') for i, param in enumerate(node.parameters): if i > 0: self._write(', ') self.visit(param) self._write(')') def visit_Ps1FileRedirection(self, node)-
Expand source code Browse git
def visit_Ps1FileRedirection(self, node: Ps1FileRedirection): prefix = self._emit_redirection_stream(node.stream) op = '>>' if node.append else '>' self._write(F'{prefix}{op}') if node.target: self._write(' ') self.visit(node.target) def visit_Ps1MergingRedirection(self, node)-
Expand source code Browse git
def visit_Ps1MergingRedirection(self, node: Ps1MergingRedirection): prefix = self._emit_redirection_stream(node.from_stream) self._write(F'{prefix}>&{node.to_stream.value}') def visit_Ps1PipelineElement(self, node)-
Expand source code Browse git
def visit_Ps1PipelineElement(self, node: Ps1PipelineElement): if node.expression: self.visit(node.expression) for redir in node.redirections: self._write(' ') self.visit(redir) def visit_Ps1Pipeline(self, node)-
Expand source code Browse git
def visit_Ps1Pipeline(self, node: Ps1Pipeline): for i, elem in enumerate(node.elements): if i > 0: self._write(' | ') self.visit(elem) def visit_Ps1ExpressionStatement(self, node)-
Expand source code Browse git
def visit_Ps1ExpressionStatement(self, node: Ps1ExpressionStatement): if node.expression: self.visit(node.expression) def visit_Ps1IfStatement(self, node)-
Expand source code Browse git
def visit_Ps1IfStatement(self, node: Ps1IfStatement): for i, (cond, body) in enumerate(node.clauses): if i == 0: self._write('if (') else: self._write(' elseif (') if cond: self.visit(cond) self._write(') ') self._emit_block(body) if node.else_block: self._write(' else ') self._emit_block(node.else_block) def visit_Ps1WhileLoop(self, node)-
Expand source code Browse git
def visit_Ps1WhileLoop(self, node: Ps1WhileLoop): if node.label: self._write(F'{node.label} ') self._write('while (') if node.condition: self.visit(node.condition) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1DoLoop(self, node)-
Expand source code Browse git
def visit_Ps1DoLoop(self, node: Ps1DoLoop): if node.label: self._write(F'{node.label} ') self._write('do ') if node.body: self._emit_block(node.body) keyword = 'until' if node.is_until else 'while' self._write(F' {keyword} (') if node.condition: self.visit(node.condition) self._write(')') def visit_Ps1ForLoop(self, node)-
Expand source code Browse git
def visit_Ps1ForLoop(self, node: Ps1ForLoop): if node.label: self._write(F'{node.label} ') self._write('for (') if node.initializer: self.visit(node.initializer) self._write('; ') if node.condition: self.visit(node.condition) self._write('; ') if node.iterator: self.visit(node.iterator) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1ForEachLoop(self, node)-
Expand source code Browse git
def visit_Ps1ForEachLoop(self, node: Ps1ForEachLoop): if node.label: self._write(F'{node.label} ') self._write('foreach ') if node.parallel: self._write('-Parallel ') self._write('(') if node.variable: self.visit(node.variable) self._write(' in ') if node.iterable: self.visit(node.iterable) self._write(') ') if node.body: self._emit_block(node.body) def visit_Ps1SwitchStatement(self, node)-
Expand source code Browse git
def visit_Ps1SwitchStatement(self, node: Ps1SwitchStatement): if node.label: self._write(F'{node.label} ') self._write('switch ') if node.regex: self._write('-Regex ') if node.wildcard: self._write('-Wildcard ') if node.exact: self._write('-Exact ') if node.case_sensitive: self._write('-CaseSensitive ') if node.file: self._write('-File ') if node.value: self.visit(node.value) self._write(' {') else: self._write('(') if node.value: self.visit(node.value) self._write(') {') self._depth += 1 for cond, body in node.clauses: self._newline() if cond is None: self._write('default ') else: self.visit(cond) self._write(' ') self._emit_block(body) self._depth -= 1 self._newline() self._write('}') def visit_Ps1TryCatchFinally(self, node)-
Expand source code Browse git
def visit_Ps1TryCatchFinally(self, node: Ps1TryCatchFinally): self._write('try ') if node.try_block: self._emit_block(node.try_block) for clause in node.catch_clauses: self._write(' catch') if clause.types: self._write(' ') self._write(' '.join(F'[{t}]' for t in clause.types)) self._write(' ') if clause.body: self._emit_block(clause.body) if node.finally_block: self._write(' finally ') self._emit_block(node.finally_block) def visit_Ps1TrapStatement(self, node)-
Expand source code Browse git
def visit_Ps1TrapStatement(self, node: Ps1TrapStatement): self._write('trap ') if node.type_name: self._write(F'[{node.type_name}] ') if node.body: self._emit_block(node.body) def visit_Ps1FunctionDefinition(self, node)-
Expand source code Browse git
def visit_Ps1FunctionDefinition(self, node: Ps1FunctionDefinition): kw = 'filter' if node.is_filter else 'function' self._write(F'{kw} {node.name} ') if node.body: self.visit(node.body) def visit_Ps1PropertyMember(self, node)-
Expand source code Browse git
def visit_Ps1PropertyMember(self, node: Ps1PropertyMember): for attr in node.attributes: self.visit(attr) self._emit_member_modifiers(node.modifiers) if node.type_constraint: self.visit(node.type_constraint) if node.variable: self.visit(node.variable) if node.initial_value: self._write(' = ') self.visit(node.initial_value) def visit_Ps1MethodMember(self, node)-
Expand source code Browse git
def visit_Ps1MethodMember(self, node: Ps1MethodMember): for attr in node.attributes: self.visit(attr) self._emit_member_modifiers(node.modifiers) if node.return_type: self.visit(node.return_type) self._write(' ') if node.definition: funcdef = node.definition self._write(F'{funcdef.name}(') if funcdef.body and funcdef.body.param_block: for i, param in enumerate(funcdef.body.param_block.parameters): if i > 0: self._write(', ') self.visit(param) self._write(') {') self._depth += 1 if funcdef.body: self._emit_script_body(funcdef.body, newline_after=False) self._depth -= 1 has_content = funcdef.body and ( funcdef.body.body or funcdef.body.begin_block or funcdef.body.process_block or funcdef.body.end_block or funcdef.body.dynamicparam_block ) if has_content: self._newline() self._write('}') def visit_Ps1ClassDefinition(self, node)-
Expand source code Browse git
def visit_Ps1ClassDefinition(self, node: Ps1ClassDefinition): self._write(F'class {node.name}') if node.base_types: self._write(' : ') self._write(', '.join(node.base_types)) self._write(' {') self._depth += 1 for member in node.members: self._newline() self.visit(member) self._depth -= 1 if node.members: self._newline() self._write('}') def visit_Ps1EnumMember(self, node)-
Expand source code Browse git
def visit_Ps1EnumMember(self, node: Ps1EnumMember): self._write(node.name) if node.value is not None: self._write(' = ') self.visit(node.value) def visit_Ps1EnumDefinition(self, node)-
Expand source code Browse git
def visit_Ps1EnumDefinition(self, node: Ps1EnumDefinition): self._write(F'enum {node.name}') if node.base_type: self._write(F' : {node.base_type}') self._write(' {') self._depth += 1 for member in node.members: self._newline() self.visit(member) self._depth -= 1 if node.members: self._newline() self._write('}') def visit_Ps1ReturnStatement(self, node)-
Expand source code Browse git
def visit_Ps1ReturnStatement(self, node: Ps1ReturnStatement): self._visit_exit(node, 'return') def visit_Ps1ExitStatement(self, node)-
Expand source code Browse git
def visit_Ps1ExitStatement(self, node: Ps1ExitStatement): self._visit_exit(node, 'exit') def visit_Ps1ThrowStatement(self, node)-
Expand source code Browse git
def visit_Ps1ThrowStatement(self, node: Ps1ThrowStatement): self._visit_exit(node, 'throw') def visit_Ps1BreakStatement(self, node)-
Expand source code Browse git
def visit_Ps1BreakStatement(self, node: Ps1BreakStatement): self._visit_jump(node, 'break') def visit_Ps1ContinueStatement(self, node)-
Expand source code Browse git
def visit_Ps1ContinueStatement(self, node: Ps1ContinueStatement): self._visit_jump(node, 'continue') def visit_Ps1DataSection(self, node)-
Expand source code Browse git
def visit_Ps1DataSection(self, node: Ps1DataSection): self._write('data ') if node.name: self._write(F'{node.name} ') if node.commands: self._write('-SupportedCommand ') for i, cmd in enumerate(node.commands): if i > 0: self._write(', ') self.visit(cmd) self._write(' ') if node.body: self._emit_block(node.body) def visit_Ps1ErrorNode(self, node)-
Expand source code Browse git
def visit_Ps1ErrorNode(self, node: Ps1ErrorNode): self._write(node.text) def visit_Ps1Script(self, node)-
Expand source code Browse git
def visit_Ps1Script(self, node: Ps1Script): if node.param_block: self.visit(node.param_block) self._newline() self._emit_script_body(node, newline_after=True) def visit_Block(self, node)-
Expand source code Browse git
def visit_Block(self, node: Block): self._emit_block(node)