Skip to main content

oak_powershell/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2
3/// Root node of the PowerShell AST.
4#[derive(Debug, Clone, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct PowerShellRoot {
7    /// Top-level items in the script.
8    pub items: Vec<PowerShellItem>,
9}
10
11/// A top-level item in a PowerShell script.
12#[derive(Debug, Clone, PartialEq)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub enum PowerShellItem {
15    /// A statement.
16    Statement(PowerShellStatement),
17    /// A function definition.
18    Function(PowerShellFunction),
19    /// A class definition.
20    Class(PowerShellClass),
21    /// A workflow definition.
22    Workflow(PowerShellWorkflow),
23}
24
25/// A PowerShell statement.
26#[derive(Debug, Clone, PartialEq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub enum PowerShellStatement {
29    /// An expression statement.
30    Expression(Box<PowerShellExpression>),
31    /// An assignment statement.
32    Assignment(PowerShellAssignment),
33    /// An `if` statement.
34    If(PowerShellIf),
35    /// A `while` statement.
36    While(PowerShellWhile),
37    /// A `for` statement.
38    For(PowerShellFor),
39    /// A `foreach` statement.
40    ForEach(PowerShellForEach),
41    /// A `switch` statement.
42    Switch(PowerShellSwitch),
43    /// A `try` statement.
44    Try(PowerShellTry),
45    /// A `return` statement.
46    Return(PowerShellReturn),
47    /// A `break` statement.
48    Break(PowerShellBreak),
49    /// A `continue` statement.
50    Continue(PowerShellContinue),
51    /// An `exit` statement.
52    Exit(PowerShellExit),
53    /// A `throw` statement.
54    Throw(PowerShellThrow),
55    /// A code block.
56    Block(PowerShellBlock),
57}
58
59/// A PowerShell expression.
60#[derive(Debug, Clone, PartialEq)]
61#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
62pub enum PowerShellExpression {
63    /// A literal value.
64    Literal(PowerShellLiteral),
65    /// A variable.
66    Variable(PowerShellVariable),
67    /// A command call.
68    Command(PowerShellCommand),
69    /// A pipeline.
70    Pipeline(PowerShellPipeline),
71    /// A binary operation.
72    Binary(PowerShellBinaryOp),
73    /// A unary operation.
74    Unary(PowerShellUnaryOp),
75    /// A member access.
76    Member(PowerShellMemberAccess),
77    /// An index access.
78    Index(PowerShellIndexAccess),
79    /// A subexpression in parentheses.
80    Subexpression(Box<PowerShellExpression>),
81    /// An array literal.
82    Array(PowerShellArray),
83    /// A hashtable literal.
84    Hashtable(PowerShellHashtable),
85    /// A script block.
86    ScriptBlock(PowerShellScriptBlock),
87}
88
89/// A PowerShell literal value.
90#[derive(Debug, Clone, PartialEq)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92pub enum PowerShellLiteral {
93    /// A string literal.
94    String(String),
95    /// A number literal.
96    Number(String),
97    /// A boolean literal.
98    Boolean(bool),
99    /// A null literal.
100    Null,
101}
102
103/// A PowerShell variable.
104#[derive(Debug, Clone, PartialEq)]
105#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
106pub struct PowerShellVariable {
107    /// Name of the variable.
108    pub name: String,
109    /// Optional scope of the variable.
110    pub scope: Option<String>,
111}
112
113/// A PowerShell command.
114#[derive(Debug, Clone, PartialEq)]
115#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
116pub struct PowerShellCommand {
117    /// Name of the command.
118    pub name: String,
119    /// Arguments passed to the command.
120    pub arguments: Vec<PowerShellArgument>,
121}
122
123/// A PowerShell command argument.
124#[derive(Debug, Clone, PartialEq)]
125#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
126pub enum PowerShellArgument {
127    /// A positional argument.
128    Positional(Box<PowerShellExpression>),
129    /// A named argument.
130    Named(String, Box<PowerShellExpression>),
131    /// A switch parameter.
132    Switch(String),
133}
134
135/// A PowerShell pipeline.
136#[derive(Debug, Clone, PartialEq)]
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138pub struct PowerShellPipeline {
139    /// Commands in the pipeline.
140    pub commands: Vec<PowerShellCommand>,
141}
142
143/// A binary operation in PowerShell.
144#[derive(Debug, Clone, PartialEq)]
145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
146pub struct PowerShellBinaryOp {
147    /// Left operand.
148    pub left: Box<PowerShellExpression>,
149    /// Binary operator.
150    pub operator: PowerShellBinaryOperator,
151    /// Right operand.
152    pub right: Box<PowerShellExpression>,
153}
154
155/// A binary operator in PowerShell.
156#[derive(Debug, Clone, PartialEq)]
157#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
158pub enum PowerShellBinaryOperator {
159    /// Addition `+`.
160    Add,
161    /// Subtraction `-`.
162    Subtract,
163    /// Multiplication `*`.
164    Multiply,
165    /// Division `/`.
166    Divide,
167    /// Modulo `%`.
168    Modulo,
169    /// Equality `-eq`.
170    Equal,
171    /// Inequality `-ne`.
172    NotEqual,
173    /// Less than `-lt`.
174    Less,
175    /// Less than or equal `-le`.
176    LessEqual,
177    /// Greater than `-gt`.
178    Greater,
179    /// Greater than or equal `-ge`.
180    GreaterEqual,
181    /// Pattern match `-like`.
182    Like,
183    /// Pattern non-match `-notlike`.
184    NotLike,
185    /// Regex match `-match`.
186    Match,
187    /// Regex non-match `-notmatch`.
188    NotMatch,
189    /// Collection contains `-contains`.
190    Contains,
191    /// Collection does not contain `-notcontains`.
192    NotContains,
193    /// Item in collection `-in`.
194    In,
195    /// Item not in collection `-notin`.
196    NotIn,
197    /// Logical AND `-and`.
198    And,
199    /// Logical OR `-or`.
200    Or,
201    /// Logical XOR `-xor`.
202    Xor,
203    /// Bitwise AND `-band`.
204    BitwiseAnd,
205    /// Bitwise OR `-bor`.
206    BitwiseOr,
207    /// Bitwise XOR `-bxor`.
208    BitwiseXor,
209}
210
211/// A unary operation in PowerShell.
212#[derive(Debug, Clone, PartialEq)]
213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
214pub struct PowerShellUnaryOp {
215    /// Unary operator.
216    pub operator: PowerShellUnaryOperator,
217    /// Operand.
218    pub operand: Box<PowerShellExpression>,
219}
220
221/// A unary operator in PowerShell.
222#[derive(Debug, Clone, PartialEq)]
223#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
224pub enum PowerShellUnaryOperator {
225    /// Positive `+`.
226    Plus,
227    /// Negative `-`.
228    Minus,
229    /// Logical NOT `-not`.
230    Not,
231    /// Bitwise NOT `-bnot`.
232    BitwiseNot,
233    /// Pre-increment `++$x`.
234    Increment,
235    /// Pre-decrement `--$x`.
236    Decrement,
237}
238
239/// A member access in PowerShell (e.g., `$obj.Prop`).
240#[derive(Debug, Clone, PartialEq)]
241#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
242pub struct PowerShellMemberAccess {
243    /// Object being accessed.
244    pub object: Box<PowerShellExpression>,
245    /// Name of the member.
246    pub member: String,
247}
248
249/// An index access in PowerShell (e.g., `$arr[0]`).
250#[derive(Debug, Clone, PartialEq)]
251#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
252pub struct PowerShellIndexAccess {
253    /// Object being indexed.
254    pub object: Box<PowerShellExpression>,
255    /// Index value.
256    pub index: Box<PowerShellExpression>,
257}
258
259/// An array literal in PowerShell.
260#[derive(Debug, Clone, PartialEq)]
261#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
262pub struct PowerShellArray {
263    /// Elements of the array.
264    pub elements: Vec<PowerShellExpression>,
265}
266
267/// A hashtable literal in PowerShell.
268#[derive(Debug, Clone, PartialEq)]
269#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
270pub struct PowerShellHashtable {
271    /// Entries in the hashtable.
272    pub entries: Vec<PowerShellHashtableEntry>,
273}
274
275/// An entry in a PowerShell hashtable.
276#[derive(Debug, Clone, PartialEq)]
277#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
278pub struct PowerShellHashtableEntry {
279    /// Key of the entry.
280    pub key: Box<PowerShellExpression>,
281    /// Value of the entry.
282    pub value: Box<PowerShellExpression>,
283}
284
285/// A script block in PowerShell.
286#[derive(Debug, Clone, PartialEq)]
287#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
288pub struct PowerShellScriptBlock {
289    /// Statements in the script block.
290    pub statements: Vec<PowerShellStatement>,
291}
292
293/// An assignment operation in PowerShell.
294#[derive(Debug, Clone, PartialEq)]
295#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
296pub struct PowerShellAssignment {
297    /// Target of the assignment.
298    pub target: Box<PowerShellExpression>,
299    /// Assignment operator.
300    pub operator: PowerShellAssignmentOperator,
301    /// Value being assigned.
302    pub value: Box<PowerShellExpression>,
303}
304
305/// An assignment operator in PowerShell.
306#[derive(Debug, Clone, PartialEq)]
307#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
308pub enum PowerShellAssignmentOperator {
309    /// Simple assignment `=`.
310    Assign,
311    /// Addition assignment `+=`.
312    PlusAssign,
313    /// Subtraction assignment `-=`.
314    MinusAssign,
315    /// Multiplication assignment `*=`.
316    MultiplyAssign,
317    /// Division assignment `/=`.
318    DivideAssign,
319    /// Modulo assignment `%=`.
320    ModuloAssign,
321}
322
323/// An `if` statement in PowerShell.
324#[derive(Debug, Clone, PartialEq)]
325#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
326pub struct PowerShellIf {
327    /// Condition to check.
328    pub condition: Box<PowerShellExpression>,
329    /// Block to execute if condition is true.
330    pub then_block: PowerShellScriptBlock,
331    /// Optional `elseif` blocks.
332    pub elseif_blocks: Vec<PowerShellElseIf>,
333    /// Optional `else` block.
334    pub else_block: Option<PowerShellScriptBlock>,
335}
336
337/// An `elseif` clause in a PowerShell `if` statement.
338#[derive(Debug, Clone, PartialEq)]
339#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
340pub struct PowerShellElseIf {
341    /// Condition to check.
342    pub condition: Box<PowerShellExpression>,
343    /// Block to execute if condition is true.
344    pub block: PowerShellScriptBlock,
345}
346
347/// A `while` statement in PowerShell.
348#[derive(Debug, Clone, PartialEq)]
349#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
350pub struct PowerShellWhile {
351    /// Condition to check.
352    pub condition: Box<PowerShellExpression>,
353    /// Block to execute while condition is true.
354    pub block: PowerShellScriptBlock,
355}
356
357/// A `for` statement in PowerShell.
358#[derive(Debug, Clone, PartialEq)]
359#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
360pub struct PowerShellFor {
361    /// Optional initialization expression.
362    pub init: Option<Box<PowerShellExpression>>,
363    /// Optional condition expression.
364    pub condition: Option<Box<PowerShellExpression>>,
365    /// Optional update expression.
366    pub update: Option<Box<PowerShellExpression>>,
367    /// Block to execute in each iteration.
368    pub block: PowerShellScriptBlock,
369}
370
371/// A `foreach` statement in PowerShell.
372#[derive(Debug, Clone, PartialEq)]
373#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
374pub struct PowerShellForEach {
375    /// Loop variable.
376    pub variable: PowerShellVariable,
377    /// Collection to iterate over.
378    pub collection: Box<PowerShellExpression>,
379    /// Block to execute for each element.
380    pub block: PowerShellScriptBlock,
381}
382
383/// A `switch` statement in PowerShell.
384#[derive(Debug, Clone, PartialEq)]
385#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
386pub struct PowerShellSwitch {
387    /// Expression to switch on.
388    pub expression: Box<PowerShellExpression>,
389    /// Cases to check.
390    pub cases: Vec<PowerShellSwitchCase>,
391    /// Optional default block.
392    pub default: Option<PowerShellScriptBlock>,
393}
394
395/// A case clause in a PowerShell `switch` statement.
396#[derive(Debug, Clone, PartialEq)]
397#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
398pub struct PowerShellSwitchCase {
399    /// Pattern to match.
400    pub pattern: Box<PowerShellExpression>,
401    /// Block to execute if pattern matches.
402    pub block: PowerShellScriptBlock,
403}
404
405/// A `try` statement in PowerShell.
406#[derive(Debug, Clone, PartialEq)]
407#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
408pub struct PowerShellTry {
409    /// Block to try executing.
410    pub block: PowerShellScriptBlock,
411    /// Optional `catch` blocks.
412    pub catch_blocks: Vec<PowerShellCatch>,
413    /// Optional `finally` block.
414    pub finally_block: Option<PowerShellScriptBlock>,
415}
416
417/// A `catch` clause in a PowerShell `try` statement.
418#[derive(Debug, Clone, PartialEq)]
419#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
420pub struct PowerShellCatch {
421    /// Optional exception type to catch.
422    pub exception_type: Option<String>,
423    /// Block to execute if exception matches.
424    pub block: PowerShellScriptBlock,
425}
426
427/// A `return` statement in PowerShell.
428#[derive(Debug, Clone, PartialEq)]
429#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
430pub struct PowerShellReturn {
431    /// Optional value to return.
432    pub value: Option<Box<PowerShellExpression>>,
433}
434
435/// A `break` statement in PowerShell.
436#[derive(Debug, Clone, PartialEq)]
437#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
438pub struct PowerShellBreak {
439    /// Optional label to break to.
440    pub label: Option<String>,
441}
442
443/// A `continue` statement in PowerShell.
444#[derive(Debug, Clone, PartialEq)]
445#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
446pub struct PowerShellContinue {
447    /// Optional label to continue to.
448    pub label: Option<String>,
449}
450
451/// An `exit` statement in PowerShell.
452#[derive(Debug, Clone, PartialEq)]
453#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
454pub struct PowerShellExit {
455    /// Optional exit code.
456    pub code: Option<Box<PowerShellExpression>>,
457}
458
459/// A `throw` statement in PowerShell.
460#[derive(Debug, Clone, PartialEq)]
461#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
462pub struct PowerShellThrow {
463    /// Optional exception expression to throw.
464    pub exception: Option<Box<PowerShellExpression>>,
465}
466
467/// A PowerShell code block.
468#[derive(Debug, Clone, PartialEq)]
469#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
470pub struct PowerShellBlock {
471    /// Statements in the block.
472    pub statements: Vec<PowerShellStatement>,
473}
474
475/// A PowerShell function definition.
476#[derive(Debug, Clone, PartialEq)]
477#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
478pub struct PowerShellFunction {
479    /// Name of the function.
480    pub name: String,
481    /// Body of the function.
482    pub body: PowerShellScriptBlock,
483    /// Attributes applied to the function.
484    pub attributes: Vec<PowerShellAttribute>,
485}
486
487/// A PowerShell parameter block (e.g., `param(...)`).
488#[derive(Debug, Clone, PartialEq)]
489#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
490pub struct PowerShellParamBlock {
491    /// Parameters in the block.
492    pub parameters: Vec<PowerShellParameter>,
493}
494
495/// A PowerShell parameter definition.
496#[derive(Debug, Clone, PartialEq)]
497#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
498pub struct PowerShellParameter {
499    /// Name of the parameter.
500    pub name: String,
501    /// Optional type of the parameter.
502    pub param_type: Option<String>,
503    /// Optional default value of the parameter.
504    pub default_value: Option<Box<PowerShellExpression>>,
505    /// Attributes applied to the parameter.
506    pub attributes: Vec<PowerShellAttribute>,
507}
508
509/// A PowerShell attribute (e.g., `[CmdletBinding()]`).
510#[derive(Debug, Clone, PartialEq)]
511#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
512pub struct PowerShellAttribute {
513    /// Name of the attribute.
514    pub name: String,
515    /// Arguments passed to the attribute.
516    pub arguments: Vec<PowerShellExpression>,
517}
518
519/// A PowerShell class definition.
520#[derive(Debug, Clone, PartialEq)]
521#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
522pub struct PowerShellClass {
523    /// Name of the class.
524    pub name: String,
525    /// Optional base class.
526    pub base_class: Option<String>,
527    /// Members of the class.
528    pub members: Vec<PowerShellClassMember>,
529}
530
531/// A member of a PowerShell class.
532#[derive(Debug, Clone, PartialEq)]
533#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
534pub enum PowerShellClassMember {
535    /// A property.
536    Property(PowerShellProperty),
537    /// A method.
538    Method(PowerShellMethod),
539    /// A constructor.
540    Constructor(PowerShellConstructor),
541}
542
543/// A property in a PowerShell class.
544#[derive(Debug, Clone, PartialEq)]
545#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
546pub struct PowerShellProperty {
547    /// Name of the property.
548    pub name: String,
549    /// Optional type of the property.
550    pub property_type: Option<String>,
551    /// Optional default value of the property.
552    pub default_value: Option<Box<PowerShellExpression>>,
553    /// Attributes applied to the property.
554    pub attributes: Vec<PowerShellAttribute>,
555}
556
557/// A method in a PowerShell class.
558#[derive(Debug, Clone, PartialEq)]
559#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
560pub struct PowerShellMethod {
561    /// Name of the method.
562    pub name: String,
563    /// Optional return type of the method.
564    pub return_type: Option<String>,
565    /// Parameters of the method.
566    pub parameters: Vec<PowerShellParameter>,
567    /// Body of the method.
568    pub body: PowerShellScriptBlock,
569    /// Attributes applied to the method.
570    pub attributes: Vec<PowerShellAttribute>,
571}
572
573/// A constructor in a PowerShell class.
574#[derive(Debug, Clone, PartialEq)]
575#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
576pub struct PowerShellConstructor {
577    /// Parameters of the constructor.
578    pub parameters: Vec<PowerShellParameter>,
579    /// Body of the constructor.
580    pub body: PowerShellScriptBlock,
581}
582
583/// A PowerShell workflow definition.
584#[derive(Debug, Clone, PartialEq)]
585#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
586pub struct PowerShellWorkflow {
587    /// Name of the workflow.
588    pub name: String,
589    /// Parameters of the workflow.
590    pub parameters: Vec<PowerShellParameter>,
591    /// Body of the workflow.
592    pub body: PowerShellScriptBlock,
593}