1pub mod macros;
2pub mod utils;
3
4#[cfg(feature = "walker")]
5pub mod walker;
6
7#[cfg(feature = "builder")]
8pub mod builder;
9
10#[cfg(feature = "printer")]
11pub mod printer;
12
13use std::{ collections::VecDeque, fmt::{ self, Display, Formatter } };
14
15use bstr::BString;
16use bumpalo::Bump;
17use serde::Serialize;
18
19use crate::utils::CloneIn;
20
21#[cfg(feature = "builder")]
22use crate::builder::{ Blueprint, BlueprintBuildable, BlueprintWrapper, Builder };
23
24#[cfg(feature = "walker")]
25use crate::walker::{ Walkable, WalkerItem };
26
27#[cfg(feature = "printer")]
28use crate::printer::{ PrintBuilder, Printable, PrintType, PrintConfig };
29
30#[derive(Debug, PartialEq, Clone, Serialize)]
31pub enum BodyType {
32 Basic,
33 Short,
34 Empty,
35}
36
37#[derive(Debug, Clone, PartialEq, Serialize)]
38pub struct RangeLocation {
39 pub start: Location,
40 pub end: Location,
41}
42
43#[derive(Debug, Clone, PartialEq, Serialize)]
44pub struct Location {
45 pub line: u32,
46 pub column: u32,
47 pub offset: u32,
48}
49
50#[derive(Debug, PartialEq, Serialize)]
51pub struct Node<'a> {
52 pub node_type: NodeType,
53 #[serde(flatten)]
54 pub wrapper: NodeWrapper<'a>,
55 pub loc: Option<RangeLocation>,
56 pub leadings: Option<bumpalo::collections::Vec<'a, Node<'a>>>,
57 pub trailings: Option<bumpalo::collections::Vec<'a, Node<'a>>>,
58}
59
60impl<'a> Node<'a> {
61 pub fn new(node_type: NodeType, wrapper: NodeWrapper<'a>, loc: Option<RangeLocation>) -> Self {
62 Self { node_type, wrapper, loc, leadings: None, trailings: None }
63 }
64
65 pub fn leadings_shift(&mut self, arena: &'a Bump, node: Node<'a>) {
66 if let Some(leadings) = &mut self.leadings {
67 leadings.insert(0, node);
68 } else {
69 self.leadings = Some(bumpalo::vec![in arena; node]);
70 }
71 }
72
73 pub fn leadings_push(&mut self, arena: &'a Bump, node: Node<'a>) {
74 if let Some(leadings) = &mut self.leadings {
75 leadings.push(node);
76 } else {
77 self.leadings = Some(bumpalo::vec![in arena; node]);
78 }
79 }
80
81 pub fn trailings_push(&mut self, arena: &'a Bump, node: Node<'a>) {
82 if let Some(trailings) = &mut self.trailings {
83 trailings.push(node);
84 } else {
85 self.trailings = Some(bumpalo::vec![in arena; node]);
86 }
87 }
88}
89
90#[derive(Debug, PartialEq, Serialize)]
91#[serde(untagged)]
92pub enum NodeWrapper<'a> {
93 AnonymousClass(AnonymousClassNode<'a>),
94 AnonymousFunction(AnonymousFunctionNode<'a>),
95 CallArgument(CallArgumentNode<'a>),
96 Array(ArrayNode<'a>),
97 ArrayItem(ArrayItemNode<'a>),
98 ArrayLookup(ArrayLookupNode<'a>),
99 ArrowFunction(ArrowFunctionNode<'a>),
100 Assignment(AssignmentNode<'a>),
101 Attribute(AttributeNode<'a>),
102 AttributeItem(AttributeItemNode<'a>),
103 Bin(BinNode<'a>),
104 Block(BlockNode<'a>),
105 Boolean(BooleanNode),
106 Break(BreakNode<'a>),
107 Call(CallNode<'a>),
108 Case(CaseNode<'a>),
109 Cast(CastNode<'a>),
110 Catch(CatchNode<'a>),
111 Class(ClassNode<'a>),
112 ClassKeyword(ClassKeywordNode),
113 Clone(CloneNode<'a>),
114 CommentBlock(CommentBlockNode),
115 CommentDoc(CommentDocNode),
116 CommentLine(CommentLineNode),
117 Const(ConstNode<'a>),
118 ConstProperty(ConstPropertyNode<'a>),
119 ConstructorParameter(ConstructorParameterNode<'a>),
120 Continue(ContinueNode<'a>),
121 Declare(DeclareNode<'a>),
122 DeclareArgument(DeclareArgumentNode<'a>),
123 DoWhile(DoWhileNode<'a>),
124 DoWhileCondition(DoWhileConditionNode<'a>),
125 Echo(EchoNode<'a>),
126 Else(ElseNode<'a>),
127 Encapsed(EncapsedNode<'a>),
128 EncapsedPart(EncapsedPartNode<'a>),
129 Enum(EnumNode<'a>),
130 EnumItem(EnumItemNode<'a>),
131 Eval(EvalNode<'a>),
132 Exit(ExitNode<'a>),
133 Finally(FinallyNode<'a>),
134 For(ForNode<'a>),
135 Foreach(ForeachNode<'a>),
136 Function(FunctionNode<'a>),
137 Global(GlobalNode<'a>),
138 Goto(GotoNode<'a>),
139 HereDoc(HereDocNode<'a>),
140 Identifier(IdentifierNode),
141 If(IfNode<'a>),
142 Include(IncludeNode<'a>),
143 Inline(InlineNode),
144 Interface(InterfaceNode<'a>),
145 IntersectionType(IntersectionTypeNode<'a>),
146 Label(LabelNode<'a>),
147 List(ListNode<'a>),
148 Magic(MagicNode),
149 MagicMethod(MagicMethodNode),
150 Match(MatchNode<'a>),
151 MatchArm(MatchArmNode<'a>),
152 Method(MethodNode<'a>),
153 Namespace(NamespaceNode<'a>),
154 Negate(NegateNode<'a>),
155 New(NewNode<'a>),
156 NowDoc(NowDocNode),
157 Null(NullNode),
158 Number(NumberNode),
159 ObjectAccess(ObjectAccessNode<'a>),
160 Parameter(ParameterNode<'a>),
161 Parent(ParentNode),
162 Parenthesis(ParenthesisNode<'a>),
163 Post(PostNode<'a>),
164 Pre(PreNode<'a>),
165 Print(PrintNode<'a>),
166 Program(ProgramNode<'a>),
167 Property(PropertyNode<'a>),
168 PropertyHook(PropertyHookNode<'a>),
169 PropertyItem(PropertyItemNode<'a>),
170 Reference(ReferenceNode<'a>),
171 Return(ReturnNode<'a>),
172 SelfKeyword(SelfNode),
173 Silent(SilentNode<'a>),
174 Static(StaticNode<'a>),
175 StaticKeyword(StaticKeywordNode),
176 StaticLookup(StaticLookupNode<'a>),
177 String(StringNode),
178 Switch(SwitchNode<'a>),
179 Ternary(TernaryNode<'a>),
180 This(ThisNode),
181 Trait(TraitNode<'a>),
182 TraitUse(TraitUseNode<'a>),
183 TraitUseAlias(TraitUseAliasNode<'a>),
184 TraitUsePrecedence(TraitUsePrecedenceNode<'a>),
185 Throw(ThrowNode<'a>),
186 Try(TryNode<'a>),
187 Type(TypeNode),
188 UnionType(UnionTypeNode<'a>),
189 Use(UseNode<'a>),
190 UseItem(UseItemNode<'a>),
191 Variable(VariableNode<'a>),
192 Variadic(VariadicNode<'a>),
193 While(WhileNode<'a>),
194 Yield(YieldNode<'a>),
195 YieldFrom(YieldFromNode<'a>),
196}
197
198#[derive(Debug, Clone, PartialEq, Serialize)]
199#[serde(rename_all = "snake_case")]
200pub enum NodeType {
201 AnonymousClass,
202 AnonymousFunction,
203 CallArgument,
204 Array,
205 ArrayItem,
206 ArrayLookup,
207 ArrowFunction,
208 Assignment,
209 Attribute,
210 AttributeItem,
211 Bin,
212 Block,
213 Boolean,
214 Break,
215 Call,
216 Case,
217 Cast,
218 Catch,
219 Class,
220 ClassKeyword,
221 Clone,
222 CommentBlock,
223 CommentDoc,
224 CommentLine,
225 Const,
226 ConstProperty,
227 ConstructorParameter,
228 Continue,
229 Declare,
230 DeclareArgument,
231 DoWhile,
232 DoWhileCondition,
233 Echo,
234 Else,
235 Encapsed,
236 EncapsedPart,
237 Enum,
238 EnumItem,
239 Eval,
240 Exit,
241 Finally,
242 For,
243 Foreach,
244 Function,
245 Global,
246 Goto,
247 HereDoc,
248 Identifier,
249 If,
250 Include,
251 Inline,
252 Interface,
253 IntersectionType,
254 Label,
255 List,
256 Magic,
257 MagicMethod,
258 Match,
259 MatchArm,
260 Method,
261 Namespace,
262 Negate,
263 New,
264 NowDoc,
265 Null,
266 Number,
267 ObjectAccess,
268 Parameter,
269 Parent,
270 Parenthesis,
271 Post,
272 Pre,
273 Print,
274 Program,
275 Property,
276 PropertyHook,
277 PropertyItem,
278 Reference,
279 Return,
280 SelfKeyword,
281 Silent,
282 Static,
283 StaticKeyword,
284 StaticLookup,
285 String,
286 Switch,
287 Ternary,
288 This,
289 Trait,
290 TraitUse,
291 TraitUseAlias,
292 TraitUsePrecedence,
293 Throw,
294 Try,
295 Type,
296 UnionType,
297 Use,
298 UseItem,
299 Variable,
300 Variadic,
301 While,
302 Yield,
303 YieldFrom,
304}
305
306macro_rules! new_node {
307 (
308 $node_type:ident,
309 $struct_name:ident < $lt:lifetime > { $($field_name:ident: $field_type:ty),* $(,)? },
310 $blueprint_name:ident < $blt:lifetime > {
311 $($blueprint_field_name:ident: $blueprint_field_type:ty),* $(,)?
312 }
313 ) => {
314 #[derive(Debug, PartialEq, Serialize)]
315 pub struct $struct_name<$lt> {
316 $(pub $field_name: $field_type),*
317 }
318
319 impl<$lt> $struct_name<$lt> {
320 pub fn loc($($field_name: $field_type,)* loc: Option<RangeLocation>) -> Node<$lt> {
321 Node {
322 leadings: None,
323 trailings: None,
324 node_type: NodeType::$node_type,
325 wrapper: NodeWrapper::$node_type(
326 Self { $($field_name),* }
327 ),
328 loc
329 }
330 }
331 }
332
333 impl<'arena> CloneIn<'arena> for $struct_name<'_> {
334 type Cloned = $struct_name<'arena>;
335
336 #[inline]
337 fn clone_in(&self, arena: &'arena Bump) -> Self::Cloned {
338 $struct_name {
339 $($field_name: self.$field_name.clone_in(arena)),*
340 }
341 }
342 }
343
344 #[cfg(feature = "walker")]
345 impl<'arena> Walkable<'arena> for $struct_name<'arena> {
346 fn populate_walks<'a>(&'a self, stack: &mut VecDeque<WalkerItem<'arena, 'a>>, level: u16) {
347 let next_level = level + 1;
348 let mut scoped_stack = VecDeque::new();
349 $(self.$field_name.populate_walks(&mut scoped_stack, next_level);)*
350 scoped_stack.into_iter().rev().for_each(|x| stack.push_back(x))
351 }
352 }
353
354 #[cfg(feature = "builder")]
355 #[derive(Debug)]
356 pub struct $blueprint_name<$blt> {
357 $(pub $blueprint_field_name: $blueprint_field_type),*
358 }
359
360 #[cfg(feature = "builder")]
361 impl Builder {
362 #[allow(non_snake_case)]
363 pub fn $node_type<$blt>(&self, $($blueprint_field_name: $blueprint_field_type,)*) -> std::boxed::Box<Blueprint<$blt>> {
364 std::boxed::Box::new(
365 Blueprint {
366 leadings: vec![],
367 trailings: vec![],
368 node_type: NodeType::$node_type,
369 wrapper: BlueprintWrapper::$node_type(
370 $blueprint_name {
371 $($blueprint_field_name: $blueprint_field_name),*
372 }
373 )
374 }
375 )
376 }
377 }
378
379 #[cfg(feature = "builder")]
380 impl<'arena, $blt> BlueprintBuildable<'arena> for $blueprint_name<$blt> {
381 type Result = Node<'arena>;
382
383 fn build(&self, arena: &'arena Bump) -> Self::Result {
384 $struct_name::loc(
385 $(self.$field_name.build(arena),)*
386 None
387 )
388 }
389 }
390
391 #[cfg(feature = "printer")]
392 impl<$lt> Printable for $struct_name<$lt> {
393 fn build_print(&self, config: &PrintConfig) -> PrintBuilder {
394 let mut builder = PrintBuilder::new(PrintType::Object);
395 builder.push_props(!(config.with_leading_trailing || config.with_location), &mut [
396 $((stringify!($field_name), self.$field_name.build_print(config)),)*
397 ]);
398 builder.shift_new_line(stringify!($struct_name));
399 builder
400 }
401 }
402 };
403
404 (
405 $node_type:ident,
406 $struct_name:ident { $($field_name:ident: $field_type:ty),* $(,)? },
407 $blueprint_name:ident < $blt:lifetime > {
408 $($blueprint_field_name:ident: $blueprint_field_type:ty),* $(,)?
409 }
410 ) => {
411 #[derive(Debug, PartialEq, Serialize)]
412 pub struct $struct_name {
413 $(pub $field_name: $field_type),*
414 }
415
416 impl $struct_name {
417 pub fn loc<'a>($($field_name: $field_type,)* loc: Option<RangeLocation>) -> Node<'a> {
418 Node::new(
419 NodeType::$node_type,
420 NodeWrapper::$node_type(
421 Self { $($field_name),* }
422 ),
423 loc
424 )
425 }
426 }
427
428 impl<'arena> CloneIn<'arena> for $struct_name {
429 type Cloned = $struct_name;
430
431 #[inline]
432 fn clone_in(&self, _: &'arena Bump) -> Self::Cloned {
433 $struct_name {
434 $($field_name: self.$field_name.clone()),*
435 }
436 }
437 }
438
439 #[cfg(feature = "walker")]
440 impl<'arena> Walkable<'arena> for $struct_name {
441 fn populate_walks<'a>(&'a self, stack: &mut VecDeque<WalkerItem<'arena, 'a>>, level: u16) {
442 let next_level = level + 1;
443 let mut scoped_stack = VecDeque::new();
444 $(self.$field_name.populate_walks(&mut scoped_stack, next_level);)*
445 scoped_stack.into_iter().rev().for_each(|x| stack.push_back(x))
446 }
447 }
448
449 #[cfg(feature = "builder")]
450 #[derive(Debug)]
451 pub struct $blueprint_name<$blt> {
452 $(pub $blueprint_field_name: $blueprint_field_type),*
453 }
454
455 #[cfg(feature = "builder")]
456 impl Builder {
457 #[allow(non_snake_case)]
458 pub fn $node_type<$blt>(&self, $($blueprint_field_name: $blueprint_field_type,)*) -> std::boxed::Box<Blueprint<$blt>> {
459 std::boxed::Box::new(
460 Blueprint {
461 leadings: vec![],
462 trailings: vec![],
463 node_type: NodeType::$node_type,
464 wrapper: BlueprintWrapper::$node_type(
465 $blueprint_name {
466 $($blueprint_field_name: $blueprint_field_name),*
467 }
468 )
469 }
470 )
471 }
472 }
473
474 #[cfg(feature = "builder")]
475 impl<'arena, $blt> BlueprintBuildable<'arena> for $blueprint_name<$blt> {
476 type Result = Node<'arena>;
477
478 fn build(&self, arena: &'arena Bump) -> Self::Result {
479 $struct_name::loc(
480 $(self.$field_name.build(arena),)*
481 None
482 )
483 }
484 }
485
486 #[cfg(feature = "printer")]
487 impl Printable for $struct_name {
488 fn build_print(&self, config: &PrintConfig) -> PrintBuilder {
489 let mut builder = PrintBuilder::new(PrintType::Object);
490 builder.push_props(!(config.with_leading_trailing || config.with_location), &mut [
491 $((stringify!($field_name), self.$field_name.build_print(config)),)*
492 ]);
493 builder.shift_new_line(stringify!($struct_name));
494 builder
495 }
496 }
497 };
498
499 (
500 $node_type:ident,
501 $struct_name:ident { $($field_name:ident: $field_type:ty),* $(,)? },
502 $blueprint_name:ident { $($blueprint_field_name:ident: $blueprint_field_type:ty),* $(,)? }
503 ) => {
504 #[derive(Debug, PartialEq, Serialize)]
505 pub struct $struct_name {
506 $(pub $field_name: $field_type),*
507 }
508
509 impl $struct_name {
510 pub fn loc<'a>($($field_name: $field_type,)* loc: Option<RangeLocation>) -> Node<'a> {
511 Node::new(
512 NodeType::$node_type,
513 NodeWrapper::$node_type(
514 Self { $($field_name),* }
515 ),
516 loc
517 )
518 }
519 }
520
521 impl<'arena> CloneIn<'arena> for $struct_name {
522 type Cloned = $struct_name;
523
524 #[inline]
525 fn clone_in(&self, _: &'arena Bump) -> Self::Cloned {
526 $struct_name {
527 $($field_name: self.$field_name.clone()),*
528 }
529 }
530 }
531
532 #[cfg(feature = "walker")]
533 impl<'arena> Walkable<'arena> for $struct_name {
534
535 #[allow(unused_variables, unused_mut)]
536 fn populate_walks<'a>(&'a self, stack: &mut VecDeque<WalkerItem<'arena, 'a>>, level: u16) {
537 let next_level = level + 1;
538 let mut scoped_stack = VecDeque::new();
539 $(self.$field_name.populate_walks(&mut scoped_stack, next_level);)*
540 scoped_stack.into_iter().rev().for_each(|x| stack.push_back(x))
541 }
542 }
543
544 #[cfg(feature = "builder")]
545 #[derive(Debug)]
546 pub struct $blueprint_name {
547 $(pub $blueprint_field_name: $blueprint_field_type),*
548 }
549
550 #[cfg(feature = "builder")]
551 impl Builder {
552 #[allow(non_snake_case)]
553 pub fn $node_type<'a>(&self, $($blueprint_field_name: $blueprint_field_type,)*) -> std::boxed::Box<Blueprint<'a>> {
554 std::boxed::Box::new(
555 Blueprint {
556 leadings: vec![],
557 trailings: vec![],
558 node_type: NodeType::$node_type,
559 wrapper: BlueprintWrapper::$node_type(
560 $blueprint_name {
561 $($blueprint_field_name: $blueprint_field_name),*
562 }
563 )
564 }
565 )
566 }
567 }
568
569 #[cfg(feature = "builder")]
570 impl<'arena> BlueprintBuildable<'arena> for $blueprint_name {
571 type Result = Node<'arena>;
572
573 #[allow(unused_variables)]
574 fn build(&self, arena: &'arena Bump) -> Self::Result {
575 $struct_name::loc(
576 $(self.$field_name.build(arena),)*
577 None
578 )
579 }
580 }
581
582 #[cfg(feature = "printer")]
583 impl Printable for $struct_name {
584
585 #[allow(unused_variables)]
586 fn build_print(&self, config: &PrintConfig) -> PrintBuilder {
587 let mut builder = PrintBuilder::new(PrintType::Object);
588 builder.push_props(!(config.with_leading_trailing || config.with_location), &mut [
589 $((stringify!($field_name), self.$field_name.build_print(config)),)*
590 ]);
591 builder.shift_new_line(stringify!($struct_name));
592 builder
593 }
594 }
595 };
596}
597
598new_node!(AnonymousClass, AnonymousClassNode<'a> { parameters: bumpalo::collections::Vec<'a, Node<'a>>, extends: Option<bumpalo::boxed::Box<'a, Node<'a>>>, implements: bumpalo::collections::Vec<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, AnonymousClassBlueprint<'b> { parameters: &'b [Box<Blueprint<'b>>], extends: Option<Box<Blueprint<'b>>>, implements: &'b [Box<Blueprint<'b>>], body: Box<Blueprint<'b>>, });
599new_node!(AnonymousFunction, AnonymousFunctionNode<'a> { is_ref: bool, parameters: bumpalo::collections::Vec<'a, Node<'a>>, uses: bumpalo::collections::Vec<'a, Node<'a>>, return_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, AnonymousFunctionBlueprint<'b> { is_ref: bool, parameters: &'b [Box<Blueprint<'b>>], uses: &'b [Box<Blueprint<'b>>], return_type: Option<Box<Blueprint<'b>>>, body: Box<Blueprint<'b>>, });
600new_node!(CallArgument, CallArgumentNode<'a> { name: Option<bumpalo::boxed::Box<'a, Node<'a>>>, value: bumpalo::boxed::Box<'a, Node<'a>>, }, CallArgumentBlueprint<'b> { name: Option<Box<Blueprint<'b>>>, value: Box<Blueprint<'b>>, });
601new_node!(Array, ArrayNode<'a> { is_short: bool, items: bumpalo::collections::Vec<'a, Node<'a>>, }, ArrayBlueprint<'b> { is_short: bool, items: &'b [Box<Blueprint<'b>>], });
602new_node!(ArrayItem, ArrayItemNode<'a> { key: Option<bumpalo::boxed::Box<'a, Node<'a>>>, value: bumpalo::boxed::Box<'a, Node<'a>>, }, ArrayItemBlueprint<'b> { key: Option<Box<Blueprint<'b>>>, value: Box<Blueprint<'b>>, });
603new_node!(ArrayLookup, ArrayLookupNode<'a> { left: bumpalo::boxed::Box<'a, Node<'a>>, right: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, ArrayLookupBlueprint<'b> { left: Box<Blueprint<'b>>, right: Option<Box<Blueprint<'b>>>, });
604new_node!(ArrowFunction, ArrowFunctionNode<'a> { is_ref: bool, parameters: bumpalo::collections::Vec<'a, Node<'a>>, return_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, ArrowFunctionBlueprint<'b> { is_ref: bool, parameters: &'b [Box<Blueprint<'b>>], return_type: Option<Box<Blueprint<'b>>>, body: Box<Blueprint<'b>>, });
605new_node!(Assignment, AssignmentNode<'a> { left: bumpalo::boxed::Box<'a, Node<'a>>, operator: AssignmentType, right: bumpalo::boxed::Box<'a, Node<'a>>, }, AssignmentBlueprint<'b> { left: Box<Blueprint<'b>>, operator: AssignmentType, right: Box<Blueprint<'b>>, });
606new_node!(Attribute, AttributeNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, AttributeBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
607new_node!(AttributeItem, AttributeItemNode<'a> { name: BString, arguments: bumpalo::collections::Vec<'a, Node<'a>>, }, AttributeItemBlueprint<'b> { name: &'b str, arguments: &'b [Box<Blueprint<'b>>], });
608new_node!(Bin, BinNode<'a> { left: bumpalo::boxed::Box<'a, Node<'a>>, operator: BinaryType, right: bumpalo::boxed::Box<'a, Node<'a>>, }, BinBlueprint<'b> { left: Box<Blueprint<'b>>, operator: BinaryType, right: Box<Blueprint<'b>>, });
609new_node!(Block, BlockNode<'a> { statements: bumpalo::collections::Vec<'a, Node<'a>>, }, BlockBlueprint<'b> { statements: &'b [Box<Blueprint<'b>>], });
610new_node!(Boolean, BooleanNode { is_true: bool }, BooleanBlueprint { is_true: bool });
611new_node!(Break, BreakNode<'a> { statement: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, BreakBlueprint<'b> { statement: Option<Box<Blueprint<'b>>>, });
612new_node!(Call, CallNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, arguments: bumpalo::collections::Vec<'a, Node<'a>>, }, CallBlueprint<'b> { name: Box<Blueprint<'b>>, arguments: &'b [Box<Blueprint<'b>>], });
613new_node!(Case, CaseNode<'a> { condition: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, CaseBlueprint<'b> { condition: Option<Box<Blueprint<'b>>>, body: Box<Blueprint<'b>>, });
614new_node!(Cast, CastNode<'a> { cast_type: CastType, expression: bumpalo::boxed::Box<'a, Node<'a>>, }, CastBlueprint<'b> { cast_type: CastType, expression: Box<Blueprint<'b>>, });
615new_node!(Catch, CatchNode<'a> { types: bumpalo::collections::Vec<'a, Node<'a>>, variable: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, CatchBlueprint<'b> { types: &'b [Box<Blueprint<'b>>], variable: Option<Box<Blueprint<'b>>>, body: Box<Blueprint<'b>>, });
616new_node!(Class, ClassNode<'a> { inheritance: Option<Inheritance>, name: Option<bumpalo::boxed::Box<'a, Node<'a>>>, extends: Option<bumpalo::boxed::Box<'a, Node<'a>>>, implements: bumpalo::collections::Vec<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, is_readonly: bool, }, ClassBlueprint<'b> { inheritance: Option<Inheritance>, name: Option<Box<Blueprint<'b>>>, extends: Option<Box<Blueprint<'b>>>, implements: &'b [Box<Blueprint<'b>>], body: Box<Blueprint<'b>>, is_readonly: bool, });
617new_node!(ClassKeyword, ClassKeywordNode {}, ClassKeywordBlueprint {});
618new_node!(Clone, CloneNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, CloneBlueprint<'b> { statement: Box<Blueprint<'b>>, });
619new_node!(CommentBlock, CommentBlockNode { comment: BString, }, CommentBlockBlueprint<'b> { comment: &'b str, });
620new_node!(CommentDoc, CommentDocNode { comment: BString, }, CommentDocBlueprint<'b> { comment: &'b str, });
621new_node!(CommentLine, CommentLineNode { comment: BString, }, CommentLineBlueprint<'b> { comment: &'b str, });
622new_node!(Const, ConstNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, ConstBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
623new_node!(ConstProperty, ConstPropertyNode<'a> { const_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, visibilities: Vec<Visibility>, items: bumpalo::collections::Vec<'a, Node<'a>>, }, ConstPropertyBlueprint<'b> { const_type: Option<Box<Blueprint<'b>>>, visibilities: Vec<Visibility>, items: &'b [Box<Blueprint<'b>>], });
624new_node!(ConstructorParameter, ConstructorParameterNode<'a> { visibilities: Vec<Visibility>, modifier: Option<Modifier>, parameter: bumpalo::boxed::Box<'a, Node<'a>>, }, ConstructorParameterBlueprint<'b> { visibilities: Vec<Visibility>, modifier: Option<Modifier>, parameter: Box<Blueprint<'b>>, });
625new_node!(Continue, ContinueNode<'a> { statement: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, ContinueBlueprint<'b> { statement: Option<Box<Blueprint<'b>>>, });
626new_node!(Declare, DeclareNode<'a> { arguments: bumpalo::collections::Vec<'a, Node<'a>>, body: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body_type: BodyType, }, DeclareBlueprint<'b> { arguments: &'b [Box<Blueprint<'b>>], body: Option<Box<Blueprint<'b>>>, body_type: BodyType, });
627new_node!(DeclareArgument, DeclareArgumentNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, value: bumpalo::boxed::Box<'a, Node<'a>>, }, DeclareArgumentBlueprint<'b> { name: Box<Blueprint<'b>>, value: Box<Blueprint<'b>>, });
628new_node!(DoWhile, DoWhileNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, DoWhileBlueprint<'b> { condition: Box<Blueprint<'b>>, body: Box<Blueprint<'b>>, });
629new_node!(DoWhileCondition, DoWhileConditionNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, }, DoWhileConditionBlueprint<'b> { condition: Box<Blueprint<'b>>, });
630new_node!(Echo, EchoNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, EchoBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
631new_node!(Else, ElseNode<'a> { body: bumpalo::boxed::Box<'a, Node<'a>>, is_short: bool, }, ElseBlueprint<'b> { body: Box<Blueprint<'b>>, is_short: bool, });
632new_node!(Encapsed, EncapsedNode<'a> { quote: Quote, values: bumpalo::collections::Vec<'a, Node<'a>>, }, EncapsedBlueprint<'b> { quote: Quote, values: &'b [Box<Blueprint<'b>>], });
633new_node!(EncapsedPart, EncapsedPartNode<'a> { is_advanced: bool, value: bumpalo::boxed::Box<'a, Node<'a>>, }, EncapsedPartBlueprint<'b> { is_advanced: bool, value: Box<Blueprint<'b>>, });
634new_node!(Enum, EnumNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, enum_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, implements: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: bumpalo::collections::Vec<'a, Node<'a>>, }, EnumBlueprint<'b> { name: Box<Blueprint<'b>>, enum_type: Option<Box<Blueprint<'b>>>, implements: Option<Box<Blueprint<'b>>>, body: &'b [Box<Blueprint<'b>>], });
635new_node!(EnumItem, EnumItemNode<'a> { value: bumpalo::boxed::Box<'a, Node<'a>>, }, EnumItemBlueprint<'b> { value: Box<Blueprint<'b>>, });
636new_node!(Eval, EvalNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, EvalBlueprint<'b> { statement: Box<Blueprint<'b>>, });
637new_node!(Exit, ExitNode<'a> { statement: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, ExitBlueprint<'b> { statement: Option<Box<Blueprint<'b>>>, });
638new_node!(Finally, FinallyNode<'a> { body: bumpalo::boxed::Box<'a, Node<'a>>, }, FinallyBlueprint<'b> { body: Box<Blueprint<'b>>, });
639new_node!(For, ForNode<'a> { inits: bumpalo::collections::Vec<'a, Node<'a>>, tests: bumpalo::collections::Vec<'a, Node<'a>>, increments: bumpalo::collections::Vec<'a, Node<'a>>, body: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body_type: BodyType, }, ForBlueprint<'b> { inits: &'b [Box<Blueprint<'b>>], tests: &'b [Box<Blueprint<'b>>], increments: &'b [Box<Blueprint<'b>>], body: Option<Box<Blueprint<'b>>>, body_type: BodyType, });
640new_node!(Foreach, ForeachNode<'a> { source: bumpalo::boxed::Box<'a, Node<'a>>, key: Option<bumpalo::boxed::Box<'a, Node<'a>>>, value: bumpalo::boxed::Box<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, is_short: bool, }, ForeachBlueprint<'b> { source: Box<Blueprint<'b>>, key: Option<Box<Blueprint<'b>>>, value: Box<Blueprint<'b>>, body: Box<Blueprint<'b>>, is_short: bool, });
641new_node!(Function, FunctionNode<'a> { is_ref: bool, name: bumpalo::boxed::Box<'a, Node<'a>>, parameters: bumpalo::collections::Vec<'a, Node<'a>>, return_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, body: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, FunctionBlueprint<'b> { is_ref: bool, name: Box<Blueprint<'b>>, parameters: &'b [Box<Blueprint<'b>>], return_type: Option<Box<Blueprint<'b>>>, body: Option<Box<Blueprint<'b>>>, });
642new_node!(Global, GlobalNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, GlobalBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
643new_node!(Goto, GotoNode<'a> { label: bumpalo::boxed::Box<'a, Node<'a>>, }, GotoBlueprint<'b> { label: Box<Blueprint<'b>>, });
644new_node!(HereDoc, HereDocNode<'a> { label: BString, values: bumpalo::collections::Vec<'a, Node<'a>>, }, HereDocBlueprint<'b> { label: &'b str, values: &'b [Box<Blueprint<'b>>], });
645new_node!(Identifier, IdentifierNode { name: BString, }, IdentifierBlueprint<'b> { name: &'b str, });
646new_node!(If, IfNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, valid: bumpalo::boxed::Box<'a, Node<'a>>, invalid: Option<bumpalo::boxed::Box<'a, Node<'a>>>, is_short: bool, }, IfBlueprint<'b> { condition: Box<Blueprint<'b>>, valid: Box<Blueprint<'b>>, invalid: Option<Box<Blueprint<'b>>>, is_short: bool, });
647new_node!(Include, IncludeNode<'a> { use_parenthesis: bool, is_require: bool, is_once: bool, argument: bumpalo::boxed::Box<'a, Node<'a>>, }, IncludeBlueprint<'b> { use_parenthesis: bool, is_require: bool, is_once: bool, argument: Box<Blueprint<'b>>, });
648new_node!(Inline, InlineNode { text: BString, }, InlineBlueprint<'b> { text: &'b str, });
649new_node!(Interface, InterfaceNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, extends: bumpalo::collections::Vec<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, InterfaceBlueprint<'b> { name: Box<Blueprint<'b>>, extends: &'b [Box<Blueprint<'b>>], body: Box<Blueprint<'b>>, });
650new_node!(IntersectionType, IntersectionTypeNode<'a> { types: bumpalo::collections::Vec<'a, Node<'a>>, }, IntersectionTypeBlueprint<'b> { types: &'b [Box<Blueprint<'b>>], });
651new_node!(Label, LabelNode<'a> { label: bumpalo::boxed::Box<'a, Node<'a>>, }, LabelBlueprint<'b> { label: Box<Blueprint<'b>>, });
652new_node!(List, ListNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, ListBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
653new_node!(Magic, MagicNode { name: MagicName }, MagicBlueprint { name: MagicName });
654new_node!(
655 MagicMethod,
656 MagicMethodNode { name: MagicMethodName },
657 MagicMethodBlueprint { name: MagicMethodName }
658);
659new_node!(Match, MatchNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, arms: bumpalo::collections::Vec<'a, Node<'a>>, }, MatchBlueprint<'b> { condition: Box<Blueprint<'b>>, arms: &'b [Box<Blueprint<'b>>], });
660new_node!(MatchArm, MatchArmNode<'a> { conditions: bumpalo::collections::Vec<'a, Node<'a>>, expr: bumpalo::boxed::Box<'a, Node<'a>>, }, MatchArmBlueprint<'b> { conditions: &'b [Box<Blueprint<'b>>], expr: Box<Blueprint<'b>>, });
661new_node!(Method, MethodNode<'a> { visibility: Option<Visibility>, inheritance: Option<Inheritance>, is_static: bool, function: bumpalo::boxed::Box<'a, Node<'a>>, }, MethodBlueprint<'b> { visibility: Option<Visibility>, inheritance: Option<Inheritance>, is_static: bool, function: Box<Blueprint<'b>>, });
662new_node!(Namespace, NamespaceNode<'a> { name: BString, body: bumpalo::boxed::Box<'a, Node<'a>>, is_bracket: bool, }, NamespaceBlueprint<'b> { name: &'b str, body: Box<Blueprint<'b>>, is_bracket: bool, });
663new_node!(Negate, NegateNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, NegateBlueprint<'b> { statement: Box<Blueprint<'b>>, });
664new_node!(New, NewNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, NewBlueprint<'b> { statement: Box<Blueprint<'b>>, });
665new_node!(NowDoc, NowDocNode { label: BString, value: BString, }, NowDocBlueprint<'b> { label: &'b str, value: &'b str, });
666new_node!(Null, NullNode {}, NullBlueprint {});
667new_node!(Number, NumberNode { value: BString, }, NumberBlueprint<'b> { value: &'b str, });
668new_node!(ObjectAccess, ObjectAccessNode<'a> { object: bumpalo::boxed::Box<'a, Node<'a>>, property: bumpalo::boxed::Box<'a, Node<'a>>, use_bracket: bool, is_nullsafe: bool, }, ObjectAccessBlueprint<'b> { object: Box<Blueprint<'b>>, property: Box<Blueprint<'b>>, use_bracket: bool, is_nullsafe: bool, });
669new_node!(Parameter, ParameterNode<'a> { variable_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, is_ref: bool, is_ellipsis: bool, name: bumpalo::boxed::Box<'a, Node<'a>>, value: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, ParameterBlueprint<'b> { variable_type: Option<Box<Blueprint<'b>>>, is_ref: bool, is_ellipsis: bool, name: Box<Blueprint<'b>>, value: Option<Box<Blueprint<'b>>>, });
670new_node!(Parent, ParentNode {}, ParentBlueprint {});
671new_node!(Parenthesis, ParenthesisNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, ParenthesisBlueprint<'b> { statement: Box<Blueprint<'b>>, });
672new_node!(Post, PostNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, operator: PostType, }, PostBlueprint<'b> { statement: Box<Blueprint<'b>>, operator: PostType, });
673new_node!(Pre, PreNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, operator: PreType, }, PreBlueprint<'b> { statement: Box<Blueprint<'b>>, operator: PreType, });
674new_node!(Print, PrintNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, PrintBlueprint<'b> { statement: Box<Blueprint<'b>>, });
675new_node!(Program, ProgramNode<'a> { children: bumpalo::collections::Vec<'a, Node<'a>>, }, ProgramBlueprint<'b> { children: &'b [Box<Blueprint<'b>>], });
676new_node!(Property, PropertyNode<'a> { visibilities: Vec<Visibility>, modifier: Option<Modifier>, hooks: bumpalo::collections::Vec<'a, Node<'a>>, items: bumpalo::collections::Vec<'a, Node<'a>>, }, PropertyBlueprint<'b> { visibilities: Vec<Visibility>, modifier: Option<Modifier>, hooks: &'b [Box<Blueprint<'b>>], items: &'b [Box<Blueprint<'b>>], });
677new_node!(PropertyHook, PropertyHookNode<'a> { is_get: bool, is_ref: bool, parameters: bumpalo::collections::Vec<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, PropertyHookBlueprint<'b> { is_get: bool, is_ref: bool, parameters: &'b [Box<Blueprint<'b>>], body: Box<Blueprint<'b>>, });
678new_node!(PropertyItem, PropertyItemNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, variable_type: Option<bumpalo::boxed::Box<'a, Node<'a>>>, value: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, PropertyItemBlueprint<'b> { name: Box<Blueprint<'b>>, variable_type: Option<Box<Blueprint<'b>>>, value: Option<Box<Blueprint<'b>>>, });
679new_node!(Reference, ReferenceNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, ReferenceBlueprint<'b> { statement: Box<Blueprint<'b>>, });
680new_node!(Return, ReturnNode<'a> { statement: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, ReturnBlueprint<'b> { statement: Option<Box<Blueprint<'b>>>, });
681new_node!(SelfKeyword, SelfNode {}, SelfBlueprint {});
682new_node!(Silent, SilentNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, SilentBlueprint<'b> { statement: Box<Blueprint<'b>>, });
683new_node!(Static, StaticNode<'a> { items: bumpalo::collections::Vec<'a, Node<'a>>, }, StaticBlueprint<'b> { items: &'b [Box<Blueprint<'b>>], });
684new_node!(StaticKeyword, StaticKeywordNode {}, StaticKeywordBlueprint {});
685new_node!(StaticLookup, StaticLookupNode<'a> { left: bumpalo::boxed::Box<'a, Node<'a>>, right: bumpalo::boxed::Box<'a, Node<'a>>, use_bracket: bool, }, StaticLookupBlueprint<'b> { left: Box<Blueprint<'b>>, right: Box<Blueprint<'b>>, use_bracket: bool, });
686new_node!(String, StringNode { quote: Quote, value: BString, }, StringBlueprint<'b> { quote: Quote, value: &'b str, });
687new_node!(Switch, SwitchNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, is_short: bool, }, SwitchBlueprint<'b> { condition: Box<Blueprint<'b>>, body: Box<Blueprint<'b>>, is_short: bool, });
688new_node!(Ternary, TernaryNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, valid: bumpalo::boxed::Box<'a, Node<'a>>, invalid: bumpalo::boxed::Box<'a, Node<'a>>, }, TernaryBlueprint<'b> { condition: Box<Blueprint<'b>>, valid: Box<Blueprint<'b>>, invalid: Box<Blueprint<'b>>, });
689new_node!(This, ThisNode {}, ThisBlueprint {});
690new_node!(Throw, ThrowNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, ThrowBlueprint<'b> { statement: Box<Blueprint<'b>>, });
691new_node!(Trait, TraitNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, }, TraitBlueprint<'b> { name: Box<Blueprint<'b>>, body: Box<Blueprint<'b>>, });
692new_node!(TraitUse, TraitUseNode<'a> { traits: bumpalo::collections::Vec<'a, Node<'a>>, adaptations: bumpalo::collections::Vec<'a, Node<'a>>, }, TraitUseBlueprint<'b> { traits: &'b [Box<Blueprint<'b>>], adaptations: &'b [Box<Blueprint<'b>>], });
693new_node!(TraitUseAlias, TraitUseAliasNode<'a> { trait_name: Option<bumpalo::boxed::Box<'a, Node<'a>>>, method: bumpalo::boxed::Box<'a, Node<'a>>, alias: Option<bumpalo::boxed::Box<'a, Node<'a>>>, visibility: Option<Visibility>, }, TraitUseAliasBlueprint<'b> { trait_name: Option<Box<Blueprint<'b>>>, method: Box<Blueprint<'b>>, alias: Option<Box<Blueprint<'b>>>, visibility: Option<Visibility>, });
694new_node!(TraitUsePrecedence, TraitUsePrecedenceNode<'a> { trait_name: Option<bumpalo::boxed::Box<'a, Node<'a>>>, method: bumpalo::boxed::Box<'a, Node<'a>>, instead: bumpalo::boxed::Box<'a, Node<'a>>, }, TraitUsePrecedenceBlueprint<'b> { trait_name: Option<Box<Blueprint<'b>>>, method: Box<Blueprint<'b>>, instead: Box<Blueprint<'b>>, });
695new_node!(Try, TryNode<'a> { body: bumpalo::boxed::Box<'a, Node<'a>>, catches: bumpalo::collections::Vec<'a, Node<'a>>, }, TryBlueprint<'b> { body: Box<Blueprint<'b>>, catches: &'b [Box<Blueprint<'b>>], });
696new_node!(Type, TypeNode { is_nullable: bool, name: BString, }, TypeBlueprint<'b> { is_nullable: bool, name: &'b str, });
697new_node!(UnionType, UnionTypeNode<'a> { types: bumpalo::collections::Vec<'a, Node<'a>>, }, UnionTypeBlueprint<'b> { types: &'b [Box<Blueprint<'b>>], });
698new_node!(Use, UseNode<'a> { name: Option<BString>, items: bumpalo::collections::Vec<'a, Node<'a>>, }, UseBlueprint<'b> { name: Option<&'b str>, items: &'b [Box<Blueprint<'b>>], });
699new_node!(UseItem, UseItemNode<'a> { modifier: Option<UseItemModifier>, name: BString, alias: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, UseItemBlueprint<'b> { modifier: Option<UseItemModifier>, name: &'b str, alias: Option<Box<Blueprint<'b>>>, });
700new_node!(Variable, VariableNode<'a> { name: bumpalo::boxed::Box<'a, Node<'a>>, }, VariableBlueprint<'b> { name: Box<Blueprint<'b>>, });
701new_node!(Variadic, VariadicNode<'a> { statement: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, VariadicBlueprint<'b> { statement: Option<Box<Blueprint<'b>>>, });
702new_node!(While, WhileNode<'a> { condition: bumpalo::boxed::Box<'a, Node<'a>>, body: bumpalo::boxed::Box<'a, Node<'a>>, is_short: bool, }, WhileBlueprint<'b> { condition: Box<Blueprint<'b>>, body: Box<Blueprint<'b>>, is_short: bool, });
703new_node!(Yield, YieldNode<'a> { key: Option<bumpalo::boxed::Box<'a, Node<'a>>>, value: Option<bumpalo::boxed::Box<'a, Node<'a>>>, }, YieldBlueprint<'b> { key: Option<Box<Blueprint<'b>>>, value: Option<Box<Blueprint<'b>>>, });
704new_node!(YieldFrom, YieldFromNode<'a> { statement: bumpalo::boxed::Box<'a, Node<'a>>, }, YieldFromBlueprint<'b> { statement: Box<Blueprint<'b>>, });
705
706#[derive(Debug, PartialEq, Clone, Serialize)]
707pub enum MagicMethodName {
708 Construct,
709 Destruct,
710 Call,
711 CallStatic,
712 Get,
713 Set,
714 Isset,
715 Unset,
716 Sleep,
717 Wakeup,
718 Serialize,
719 Unserialize,
720 ToString,
721 Invoke,
722 SetState,
723 Clone,
724 DebugInfo,
725}
726
727impl TryFrom<&BString> for MagicMethodName {
728 type Error = String;
729
730 fn try_from(value: &BString) -> Result<Self, Self::Error> {
731 match value.as_slice() {
732 b"__construct" => Ok(MagicMethodName::Construct),
733 b"__destruct" => Ok(MagicMethodName::Destruct),
734 b"__call" => Ok(MagicMethodName::Call),
735 b"__callStatic" => Ok(MagicMethodName::CallStatic),
736 b"__get" => Ok(MagicMethodName::Get),
737 b"__set" => Ok(MagicMethodName::Set),
738 b"__isset" => Ok(MagicMethodName::Isset),
739 b"__unset" => Ok(MagicMethodName::Unset),
740 b"__sleep" => Ok(MagicMethodName::Sleep),
741 b"__wakeup" => Ok(MagicMethodName::Wakeup),
742 b"__serialize" => Ok(MagicMethodName::Serialize),
743 b"__unserialize" => Ok(MagicMethodName::Unserialize),
744 b"__toString" => Ok(MagicMethodName::ToString),
745 b"__invoke" => Ok(MagicMethodName::Invoke),
746 b"__set_state" => Ok(MagicMethodName::SetState),
747 b"__clone" => Ok(MagicMethodName::Clone),
748 b"__debugInfo" => Ok(MagicMethodName::DebugInfo),
749 _ => Err(format!("Invalid magic method name: {}", value)),
750 }
751 }
752}
753
754impl Display for MagicMethodName {
755 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
756 write!(f, "{}", match self {
757 MagicMethodName::Construct => "__construct",
758 MagicMethodName::Destruct => "__destruct",
759 MagicMethodName::Call => "__call",
760 MagicMethodName::CallStatic => "__callStatic",
761 MagicMethodName::Get => "__get",
762 MagicMethodName::Set => "__set",
763 MagicMethodName::Isset => "__isset",
764 MagicMethodName::Unset => "__unset",
765 MagicMethodName::Sleep => "__sleep",
766 MagicMethodName::Wakeup => "__wakeup",
767 MagicMethodName::Serialize => "__serialize",
768 MagicMethodName::Unserialize => "__unserialize",
769 MagicMethodName::ToString => "__toString",
770 MagicMethodName::Invoke => "__invoke",
771 MagicMethodName::SetState => "__set_state",
772 MagicMethodName::Clone => "__clone",
773 MagicMethodName::DebugInfo => "__debugInfo",
774 })
775 }
776}
777
778#[derive(Debug, PartialEq, Clone, Serialize)]
779pub enum MagicName {
780 Class,
781 Dir,
782 File,
783 Function,
784 Line,
785 Method,
786 Namespace,
787 Trait,
788 Property,
789}
790
791impl TryFrom<&BString> for MagicName {
792 type Error = String;
793
794 fn try_from(value: &BString) -> Result<Self, Self::Error> {
795 match value.as_slice() {
796 b"__CLASS__" => Ok(MagicName::Class),
797 b"__DIR__" => Ok(MagicName::Dir),
798 b"__FILE__" => Ok(MagicName::File),
799 b"__FUNCTION__" => Ok(MagicName::Function),
800 b"__LINE__" => Ok(MagicName::Line),
801 b"__METHOD__" => Ok(MagicName::Method),
802 b"__NAMESPACE__" => Ok(MagicName::Namespace),
803 b"__TRAIT__" => Ok(MagicName::Trait),
804 b"__PROPERTY__" => Ok(MagicName::Property),
805 _ => Err(format!("Invalid magic name: {}", value)),
806 }
807 }
808}
809
810impl Display for MagicName {
811 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
812 write!(f, "{}", match self {
813 MagicName::Class => "__CLASS__",
814 MagicName::Dir => "__DIR__",
815 MagicName::File => "__FILE__",
816 MagicName::Function => "__FUNCTION__",
817 MagicName::Line => "__LINE__",
818 MagicName::Method => "__METHOD__",
819 MagicName::Namespace => "__NAMESPACE__",
820 MagicName::Trait => "__TRAIT__",
821 MagicName::Property => "__PROPERTY__",
822 })
823 }
824}
825#[derive(Debug, PartialEq, Clone, Serialize)]
826pub enum PreType {
827 Increment,
828 Decrement,
829 Addition,
830 Subtraction,
831}
832
833impl TryFrom<&BString> for PreType {
834 type Error = String;
835
836 fn try_from(value: &BString) -> Result<Self, Self::Error> {
837 match value.as_slice() {
838 b"++" => Ok(PreType::Increment),
839 b"--" => Ok(PreType::Decrement),
840 b"+" => Ok(PreType::Addition),
841 b"-" => Ok(PreType::Subtraction),
842 _ => Err(format!("Invalid pre type: {}", value)),
843 }
844 }
845}
846
847impl Display for PreType {
848 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
849 write!(f, "{}", match self {
850 PreType::Increment => "++",
851 PreType::Decrement => "--",
852 PreType::Addition => "+",
853 PreType::Subtraction => "-",
854 })
855 }
856}
857
858#[derive(Debug, PartialEq, Clone, Serialize)]
859pub enum PostType {
860 Increment,
861 Decrement,
862}
863
864impl TryFrom<&BString> for PostType {
865 type Error = String;
866
867 fn try_from(value: &BString) -> Result<Self, Self::Error> {
868 match value.as_slice() {
869 b"++" => Ok(PostType::Increment),
870 b"--" => Ok(PostType::Decrement),
871 _ => Err(format!("Invalid post type: {}", value)),
872 }
873 }
874}
875
876impl Display for PostType {
877 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
878 write!(f, "{}", match self {
879 PostType::Increment => "++",
880 PostType::Decrement => "--",
881 })
882 }
883}
884
885#[derive(Debug, PartialEq, Clone, Serialize)]
886pub enum CastType {
887 Int,
888 Integer,
889 Bool,
890 Boolean,
891 Float,
892 Double,
893 Real,
894 String,
895 Binary,
896 Array,
897 Object,
898 Unset,
899}
900
901impl TryFrom<&BString> for CastType {
902 type Error = String;
903
904 fn try_from(value: &BString) -> Result<Self, Self::Error> {
905 match value.as_slice() {
906 b"int" => Ok(CastType::Int),
907 b"integer" => Ok(CastType::Integer),
908 b"bool" => Ok(CastType::Bool),
909 b"boolean" => Ok(CastType::Boolean),
910 b"float" => Ok(CastType::Float),
911 b"double" => Ok(CastType::Double),
912 b"real" => Ok(CastType::Real),
913 b"string" => Ok(CastType::String),
914 b"binary" => Ok(CastType::Binary),
915 b"array" => Ok(CastType::Array),
916 b"object" => Ok(CastType::Object),
917 b"unset" => Ok(CastType::Unset),
918 _ => Err(format!("Invalid cast type: {}", value)),
919 }
920 }
921}
922
923impl Display for CastType {
924 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
925 write!(f, "{}", match self {
926 CastType::Int => "int",
927 CastType::Integer => "integer",
928 CastType::Bool => "bool",
929 CastType::Boolean => "boolean",
930 CastType::Float => "float",
931 CastType::Double => "double",
932 CastType::Real => "real",
933 CastType::String => "string",
934 CastType::Binary => "binary",
935 CastType::Array => "array",
936 CastType::Object => "object",
937 CastType::Unset => "unset",
938 })
939 }
940}
941
942#[derive(Debug, PartialEq, Clone, Serialize)]
943pub enum BinaryType {
944 Addition,
945 Subtraction,
946 Multiplication,
947 Division,
948 Modulus,
949 Exponentiation,
950 BitwiseAnd,
951 BitwiseOr,
952 BitwiseXor,
953 BitwiseShiftLeft,
954 BitwiseShiftRight,
955 IsEqual,
956 IsIdentical,
957 IsNotEqual,
958 IsNotIdentical,
959 IsLesser,
960 IsGreater,
961 IsLesserOrEqual,
962 IsGreaterOrEqual,
963 Spaceship,
964 Concatenation,
965 BooleanAnd,
966 BooleanOr,
967 BooleanXor,
968 Elvis,
969 Coalesce,
970 InstanceOf,
971}
972
973impl TryFrom<&BString> for BinaryType {
974 type Error = String;
975
976 fn try_from(value: &BString) -> Result<Self, Self::Error> {
977 match value.as_slice() {
978 b"+" => Ok(BinaryType::Addition),
979 b"-" => Ok(BinaryType::Subtraction),
980 b"*" => Ok(BinaryType::Multiplication),
981 b"/" => Ok(BinaryType::Division),
982 b"%" => Ok(BinaryType::Modulus),
983 b"**" => Ok(BinaryType::Exponentiation),
984 b"&" => Ok(BinaryType::BitwiseAnd),
985 b"|" => Ok(BinaryType::BitwiseOr),
986 b"^" => Ok(BinaryType::BitwiseXor),
987 b"<<" => Ok(BinaryType::BitwiseShiftLeft),
988 b">>" => Ok(BinaryType::BitwiseShiftRight),
989 b"==" => Ok(BinaryType::IsEqual),
990 b"===" => Ok(BinaryType::IsIdentical),
991 b"!=" => Ok(BinaryType::IsNotEqual),
992 b"!==" => Ok(BinaryType::IsNotIdentical),
993 b"<" => Ok(BinaryType::IsLesser),
994 b">" => Ok(BinaryType::IsGreater),
995 b"<=" => Ok(BinaryType::IsLesserOrEqual),
996 b">=" => Ok(BinaryType::IsGreaterOrEqual),
997 b"<=>" => Ok(BinaryType::Spaceship),
998 b"." => Ok(BinaryType::Concatenation),
999 b"&&" | b"and" => Ok(BinaryType::BooleanAnd),
1000 b"||" | b"or" => Ok(BinaryType::BooleanOr),
1001 b"xor" => Ok(BinaryType::BooleanXor),
1002 b"?:" => Ok(BinaryType::Elvis),
1003 b"??" => Ok(BinaryType::Coalesce),
1004 b"instanceof" => Ok(BinaryType::InstanceOf),
1005 _ => Err(format!("Invalid binary type: {}", value)),
1006 }
1007 }
1008}
1009
1010impl Display for BinaryType {
1011 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1012 write!(f, "{}", match self {
1013 BinaryType::Addition => "+",
1014 BinaryType::Subtraction => "-",
1015 BinaryType::Multiplication => "*",
1016 BinaryType::Division => "/",
1017 BinaryType::Modulus => "%",
1018 BinaryType::Exponentiation => "**",
1019 BinaryType::BitwiseAnd => "&",
1020 BinaryType::BitwiseOr => "|",
1021 BinaryType::BitwiseXor => "^",
1022 BinaryType::BitwiseShiftLeft => "<<",
1023 BinaryType::BitwiseShiftRight => ">>",
1024 BinaryType::IsEqual => "==",
1025 BinaryType::IsIdentical => "===",
1026 BinaryType::IsNotEqual => "!=",
1027 BinaryType::IsNotIdentical => "!==",
1028 BinaryType::IsLesser => "<",
1029 BinaryType::IsGreater => ">",
1030 BinaryType::IsLesserOrEqual => "<=",
1031 BinaryType::IsGreaterOrEqual => ">=",
1032 BinaryType::Spaceship => "<=>",
1033 BinaryType::Concatenation => ".",
1034 BinaryType::BooleanAnd => "&&",
1035 BinaryType::BooleanOr => "||",
1036 BinaryType::BooleanXor => "xor",
1037 BinaryType::Elvis => "?:",
1038 BinaryType::Coalesce => "??",
1039 BinaryType::InstanceOf => "instanceof",
1040 })
1041 }
1042}
1043
1044#[derive(Debug, PartialEq, Clone, Serialize)]
1045pub enum AssignmentType {
1046 Default,
1047 Reference,
1048 Coalesce,
1049 Concatenation,
1050 Addition,
1051 Subtraction,
1052 Multiplication,
1053 Division,
1054 Exponentiation,
1055 Modulus,
1056 BitwiseAnd,
1057 BitwiseOr,
1058 BitwiseXor,
1059 BitwiseShiftRight,
1060 BitwiseShiftLeft,
1061}
1062
1063impl TryFrom<&BString> for AssignmentType {
1064 type Error = String;
1065
1066 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1067 match value.as_slice() {
1068 b"=" => Ok(AssignmentType::Default),
1069 b"=&" => Ok(AssignmentType::Reference),
1070 b"??=" => Ok(AssignmentType::Coalesce),
1071 b".=" => Ok(AssignmentType::Concatenation),
1072 b"+=" => Ok(AssignmentType::Addition),
1073 b"-=" => Ok(AssignmentType::Subtraction),
1074 b"*=" => Ok(AssignmentType::Multiplication),
1075 b"/=" => Ok(AssignmentType::Division),
1076 b"**=" => Ok(AssignmentType::Exponentiation),
1077 b"%=" => Ok(AssignmentType::Modulus),
1078 b"&=" => Ok(AssignmentType::BitwiseAnd),
1079 b"|=" => Ok(AssignmentType::BitwiseOr),
1080 b"^=" => Ok(AssignmentType::BitwiseXor),
1081 b">>=" => Ok(AssignmentType::BitwiseShiftRight),
1082 b"<<=" => Ok(AssignmentType::BitwiseShiftLeft),
1083 _ => Err(format!("Invalid assignment type: {}", value)),
1084 }
1085 }
1086}
1087
1088impl Display for AssignmentType {
1089 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1090 write!(f, "{}", match self {
1091 AssignmentType::Default => "=",
1092 AssignmentType::Reference => "=&",
1093 AssignmentType::Coalesce => "??=",
1094 AssignmentType::Concatenation => ".=",
1095 AssignmentType::Addition => "+=",
1096 AssignmentType::Subtraction => "-=",
1097 AssignmentType::Multiplication => "*=",
1098 AssignmentType::Division => "/=",
1099 AssignmentType::Exponentiation => "**=",
1100 AssignmentType::Modulus => "%=",
1101 AssignmentType::BitwiseAnd => "&=",
1102 AssignmentType::BitwiseOr => "|=",
1103 AssignmentType::BitwiseXor => "^=",
1104 AssignmentType::BitwiseShiftRight => ">>=",
1105 AssignmentType::BitwiseShiftLeft => "<<=",
1106 })
1107 }
1108}
1109
1110#[derive(Debug, PartialEq, Clone, Serialize)]
1111pub enum UseItemModifier {
1112 Function,
1113 Const,
1114}
1115
1116impl TryFrom<&BString> for UseItemModifier {
1117 type Error = String;
1118
1119 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1120 match value.as_slice() {
1121 b"function" => Ok(UseItemModifier::Function),
1122 b"const" => Ok(UseItemModifier::Const),
1123 _ => Err(format!("Invalid use item modifier: {}", value)),
1124 }
1125 }
1126}
1127
1128impl Display for UseItemModifier {
1129 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1130 write!(f, "{}", match self {
1131 UseItemModifier::Function => "function",
1132 UseItemModifier::Const => "const",
1133 })
1134 }
1135}
1136
1137#[derive(Debug, PartialEq, Clone, Serialize)]
1138pub enum Modifier {
1139 Static,
1140 Readonly,
1141}
1142
1143impl TryFrom<&BString> for Modifier {
1144 type Error = String;
1145
1146 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1147 match value.as_slice() {
1148 b"static" => Ok(Modifier::Static),
1149 b"readonly" => Ok(Modifier::Readonly),
1150 _ => Err(format!("Invalid modifier: {}", value)),
1151 }
1152 }
1153}
1154
1155impl Display for Modifier {
1156 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1157 write!(f, "{}", match self {
1158 Modifier::Static => "static",
1159 Modifier::Readonly => "readonly",
1160 })
1161 }
1162}
1163
1164#[derive(Debug, PartialEq, Clone, Serialize)]
1165pub enum Quote {
1166 Single,
1167 Double,
1168 Backtick,
1169}
1170
1171impl TryFrom<&BString> for Quote {
1172 type Error = String;
1173
1174 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1175 match value.as_slice() {
1176 b"'" => Ok(Quote::Single),
1177 b"\"" => Ok(Quote::Double),
1178 b"`" => Ok(Quote::Backtick),
1179 _ => Err(format!("Invalid quote: {}", value)),
1180 }
1181 }
1182}
1183
1184impl Display for Quote {
1185 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1186 write!(f, "{}", match self {
1187 Quote::Single => "'",
1188 Quote::Double => "\"",
1189 Quote::Backtick => "`",
1190 })
1191 }
1192}
1193
1194#[derive(Debug, PartialEq, Clone, Serialize)]
1195pub enum Inheritance {
1196 Abstract,
1197 Final,
1198}
1199
1200impl TryFrom<&BString> for Inheritance {
1201 type Error = String;
1202
1203 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1204 match value.as_slice() {
1205 b"abstract" => Ok(Inheritance::Abstract),
1206 b"final" => Ok(Inheritance::Final),
1207 _ => Err(format!("Invalid inheritance: {}", value)),
1208 }
1209 }
1210}
1211
1212impl Display for Inheritance {
1213 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1214 write!(f, "{}", match self {
1215 Inheritance::Abstract => "abstract",
1216 Inheritance::Final => "final",
1217 })
1218 }
1219}
1220
1221#[derive(Debug, PartialEq, Clone, Serialize)]
1222pub enum Visibility {
1223 Public,
1224 PublicGet,
1225 PublicSet,
1226 Private,
1227 PrivateGet,
1228 PrivateSet,
1229 Protected,
1230 ProtectedGet,
1231 ProtectedSet,
1232}
1233
1234impl TryFrom<&BString> for Visibility {
1235 type Error = String;
1236
1237 fn try_from(value: &BString) -> Result<Self, Self::Error> {
1238 match value.as_slice() {
1239 b"public" => Ok(Visibility::Public),
1240 b"public(get)" => Ok(Visibility::PublicGet),
1241 b"public(set)" => Ok(Visibility::PublicSet),
1242 b"private" => Ok(Visibility::Private),
1243 b"private(get)" => Ok(Visibility::PrivateGet),
1244 b"private(set)" => Ok(Visibility::PrivateSet),
1245 b"protected" => Ok(Visibility::Protected),
1246 b"protected(get)" => Ok(Visibility::ProtectedGet),
1247 b"protected(set)" => Ok(Visibility::ProtectedSet),
1248 _ => Err(format!("Invalid visibility: {}", value)),
1249 }
1250 }
1251}
1252
1253impl Display for Visibility {
1254 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1255 write!(f, "{}", match self {
1256 Visibility::Public => "public",
1257 Visibility::PublicGet => "public(get)",
1258 Visibility::PublicSet => "public(set)",
1259 Visibility::Private => "private",
1260 Visibility::PrivateGet => "private(get)",
1261 Visibility::PrivateSet => "private(set)",
1262 Visibility::Protected => "protected",
1263 Visibility::ProtectedGet => "protected(get)",
1264 Visibility::ProtectedSet => "protected(set)",
1265 })
1266 }
1267}
1268
1269#[cfg(test)]
1270mod tests {
1271 use bstr::BString;
1272
1273 use crate::{
1274 AssignmentType,
1275 BinaryType,
1276 CastType,
1277 Inheritance,
1278 MagicMethodName,
1279 MagicName,
1280 Modifier,
1281 PostType,
1282 PreType,
1283 Quote,
1284 UseItemModifier,
1285 Visibility,
1286 };
1287
1288 #[test]
1289 fn magic_name() {
1290 assert_eq!(
1291 MagicName::try_from(&BString::new("__CLASS__".as_bytes().to_vec())),
1292 Ok(MagicName::Class)
1293 );
1294 assert_eq!(
1295 MagicName::try_from(&BString::new("__DIR__".as_bytes().to_vec())),
1296 Ok(MagicName::Dir)
1297 );
1298 assert_eq!(
1299 MagicName::try_from(&BString::new("__FILE__".as_bytes().to_vec())),
1300 Ok(MagicName::File)
1301 );
1302 assert_eq!(
1303 MagicName::try_from(&BString::new("__FUNCTION__".as_bytes().to_vec())),
1304 Ok(MagicName::Function)
1305 );
1306 assert_eq!(
1307 MagicName::try_from(&BString::new("__LINE__".as_bytes().to_vec())),
1308 Ok(MagicName::Line)
1309 );
1310 assert_eq!(
1311 MagicName::try_from(&BString::new("__METHOD__".as_bytes().to_vec())),
1312 Ok(MagicName::Method)
1313 );
1314 assert_eq!(
1315 MagicName::try_from(&BString::new("__NAMESPACE__".as_bytes().to_vec())),
1316 Ok(MagicName::Namespace)
1317 );
1318 assert_eq!(
1319 MagicName::try_from(&BString::new("__TRAIT__".as_bytes().to_vec())),
1320 Ok(MagicName::Trait)
1321 );
1322 assert_eq!(
1323 MagicName::try_from(&BString::new("__PROPERTY__".as_bytes().to_vec())),
1324 Ok(MagicName::Property)
1325 );
1326 assert!(MagicName::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1327
1328 assert_eq!("__CLASS__", format!("{}", MagicName::Class));
1329 assert_eq!("__DIR__", format!("{}", MagicName::Dir));
1330 assert_eq!("__FILE__", format!("{}", MagicName::File));
1331 assert_eq!("__FUNCTION__", format!("{}", MagicName::Function));
1332 assert_eq!("__LINE__", format!("{}", MagicName::Line));
1333 assert_eq!("__METHOD__", format!("{}", MagicName::Method));
1334 assert_eq!("__NAMESPACE__", format!("{}", MagicName::Namespace));
1335 assert_eq!("__TRAIT__", format!("{}", MagicName::Trait));
1336 assert_eq!("__PROPERTY__", format!("{}", MagicName::Property));
1337 }
1338
1339 #[test]
1340 fn magic_method_name() {
1341 assert_eq!(
1342 MagicMethodName::try_from(&BString::new("__construct".as_bytes().to_vec())),
1343 Ok(MagicMethodName::Construct)
1344 );
1345 assert_eq!(
1346 MagicMethodName::try_from(&BString::new("__destruct".as_bytes().to_vec())),
1347 Ok(MagicMethodName::Destruct)
1348 );
1349 assert_eq!(
1350 MagicMethodName::try_from(&BString::new("__call".as_bytes().to_vec())),
1351 Ok(MagicMethodName::Call)
1352 );
1353 assert_eq!(
1354 MagicMethodName::try_from(&BString::new("__callStatic".as_bytes().to_vec())),
1355 Ok(MagicMethodName::CallStatic)
1356 );
1357 assert_eq!(
1358 MagicMethodName::try_from(&BString::new("__get".as_bytes().to_vec())),
1359 Ok(MagicMethodName::Get)
1360 );
1361 assert_eq!(
1362 MagicMethodName::try_from(&BString::new("__set".as_bytes().to_vec())),
1363 Ok(MagicMethodName::Set)
1364 );
1365 assert_eq!(
1366 MagicMethodName::try_from(&BString::new("__isset".as_bytes().to_vec())),
1367 Ok(MagicMethodName::Isset)
1368 );
1369 assert_eq!(
1370 MagicMethodName::try_from(&BString::new("__unset".as_bytes().to_vec())),
1371 Ok(MagicMethodName::Unset)
1372 );
1373 assert_eq!(
1374 MagicMethodName::try_from(&BString::new("__sleep".as_bytes().to_vec())),
1375 Ok(MagicMethodName::Sleep)
1376 );
1377 assert_eq!(
1378 MagicMethodName::try_from(&BString::new("__wakeup".as_bytes().to_vec())),
1379 Ok(MagicMethodName::Wakeup)
1380 );
1381 assert_eq!(
1382 MagicMethodName::try_from(&BString::new("__serialize".as_bytes().to_vec())),
1383 Ok(MagicMethodName::Serialize)
1384 );
1385 assert_eq!(
1386 MagicMethodName::try_from(&BString::new("__unserialize".as_bytes().to_vec())),
1387 Ok(MagicMethodName::Unserialize)
1388 );
1389 assert_eq!(
1390 MagicMethodName::try_from(&BString::new("__toString".as_bytes().to_vec())),
1391 Ok(MagicMethodName::ToString)
1392 );
1393 assert_eq!(
1394 MagicMethodName::try_from(&BString::new("__invoke".as_bytes().to_vec())),
1395 Ok(MagicMethodName::Invoke)
1396 );
1397 assert_eq!(
1398 MagicMethodName::try_from(&BString::new("__set_state".as_bytes().to_vec())),
1399 Ok(MagicMethodName::SetState)
1400 );
1401 assert_eq!(
1402 MagicMethodName::try_from(&BString::new("__clone".as_bytes().to_vec())),
1403 Ok(MagicMethodName::Clone)
1404 );
1405 assert_eq!(
1406 MagicMethodName::try_from(&BString::new("__debugInfo".as_bytes().to_vec())),
1407 Ok(MagicMethodName::DebugInfo)
1408 );
1409 assert!(MagicMethodName::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1410
1411 assert_eq!("__construct", format!("{}", MagicMethodName::Construct));
1412 assert_eq!("__destruct", format!("{}", MagicMethodName::Destruct));
1413 assert_eq!("__call", format!("{}", MagicMethodName::Call));
1414 assert_eq!("__callStatic", format!("{}", MagicMethodName::CallStatic));
1415 assert_eq!("__get", format!("{}", MagicMethodName::Get));
1416 assert_eq!("__set", format!("{}", MagicMethodName::Set));
1417 assert_eq!("__isset", format!("{}", MagicMethodName::Isset));
1418 assert_eq!("__unset", format!("{}", MagicMethodName::Unset));
1419 assert_eq!("__sleep", format!("{}", MagicMethodName::Sleep));
1420 assert_eq!("__wakeup", format!("{}", MagicMethodName::Wakeup));
1421 assert_eq!("__serialize", format!("{}", MagicMethodName::Serialize));
1422 assert_eq!("__unserialize", format!("{}", MagicMethodName::Unserialize));
1423 assert_eq!("__toString", format!("{}", MagicMethodName::ToString));
1424 assert_eq!("__invoke", format!("{}", MagicMethodName::Invoke));
1425 assert_eq!("__set_state", format!("{}", MagicMethodName::SetState));
1426 assert_eq!("__clone", format!("{}", MagicMethodName::Clone));
1427 assert_eq!("__debugInfo", format!("{}", MagicMethodName::DebugInfo));
1428 }
1429
1430 #[test]
1431 fn pre_type() {
1432 assert_eq!(PreType::try_from(&BString::new("++".as_bytes().to_vec())), Ok(PreType::Increment));
1433 assert_eq!(PreType::try_from(&BString::new("--".as_bytes().to_vec())), Ok(PreType::Decrement));
1434 assert_eq!(PreType::try_from(&BString::new("+".as_bytes().to_vec())), Ok(PreType::Addition));
1435 assert_eq!(PreType::try_from(&BString::new("-".as_bytes().to_vec())), Ok(PreType::Subtraction));
1436 assert!(PreType::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1437
1438 assert_eq!("++", format!("{}", PreType::Increment));
1439 assert_eq!("--", format!("{}", PreType::Decrement));
1440 assert_eq!("+", format!("{}", PreType::Addition));
1441 assert_eq!("-", format!("{}", PreType::Subtraction));
1442 }
1443
1444 #[test]
1445 fn post_type() {
1446 assert_eq!(
1447 PostType::try_from(&BString::new("++".as_bytes().to_vec())),
1448 Ok(PostType::Increment)
1449 );
1450 assert_eq!(
1451 PostType::try_from(&BString::new("--".as_bytes().to_vec())),
1452 Ok(PostType::Decrement)
1453 );
1454 assert!(PostType::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1455
1456 assert_eq!("++", format!("{}", PostType::Increment));
1457 assert_eq!("--", format!("{}", PostType::Decrement));
1458 }
1459
1460 #[test]
1461 fn cast_type() {
1462 assert_eq!(CastType::try_from(&BString::new("int".as_bytes().to_vec())), Ok(CastType::Int));
1463 assert_eq!(
1464 CastType::try_from(&BString::new("integer".as_bytes().to_vec())),
1465 Ok(CastType::Integer)
1466 );
1467 assert_eq!(CastType::try_from(&BString::new("bool".as_bytes().to_vec())), Ok(CastType::Bool));
1468 assert_eq!(
1469 CastType::try_from(&BString::new("boolean".as_bytes().to_vec())),
1470 Ok(CastType::Boolean)
1471 );
1472 assert_eq!(CastType::try_from(&BString::new("float".as_bytes().to_vec())), Ok(CastType::Float));
1473 assert_eq!(
1474 CastType::try_from(&BString::new("double".as_bytes().to_vec())),
1475 Ok(CastType::Double)
1476 );
1477 assert_eq!(CastType::try_from(&BString::new("real".as_bytes().to_vec())), Ok(CastType::Real));
1478 assert_eq!(
1479 CastType::try_from(&BString::new("string".as_bytes().to_vec())),
1480 Ok(CastType::String)
1481 );
1482 assert_eq!(
1483 CastType::try_from(&BString::new("binary".as_bytes().to_vec())),
1484 Ok(CastType::Binary)
1485 );
1486 assert_eq!(CastType::try_from(&BString::new("array".as_bytes().to_vec())), Ok(CastType::Array));
1487 assert_eq!(
1488 CastType::try_from(&BString::new("object".as_bytes().to_vec())),
1489 Ok(CastType::Object)
1490 );
1491 assert_eq!(CastType::try_from(&BString::new("unset".as_bytes().to_vec())), Ok(CastType::Unset));
1492 assert!(CastType::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1493
1494 assert_eq!("int", format!("{}", CastType::Int));
1495 assert_eq!("integer", format!("{}", CastType::Integer));
1496 assert_eq!("bool", format!("{}", CastType::Bool));
1497 assert_eq!("boolean", format!("{}", CastType::Boolean));
1498 assert_eq!("float", format!("{}", CastType::Float));
1499 assert_eq!("double", format!("{}", CastType::Double));
1500 assert_eq!("real", format!("{}", CastType::Real));
1501 assert_eq!("string", format!("{}", CastType::String));
1502 assert_eq!("binary", format!("{}", CastType::Binary));
1503 assert_eq!("array", format!("{}", CastType::Array));
1504 assert_eq!("object", format!("{}", CastType::Object));
1505 assert_eq!("unset", format!("{}", CastType::Unset));
1506 }
1507
1508 #[test]
1509 fn binary_type() {
1510 assert_eq!(
1511 BinaryType::try_from(&BString::new("+".as_bytes().to_vec())),
1512 Ok(BinaryType::Addition)
1513 );
1514 assert_eq!(
1515 BinaryType::try_from(&BString::new("-".as_bytes().to_vec())),
1516 Ok(BinaryType::Subtraction)
1517 );
1518 assert_eq!(
1519 BinaryType::try_from(&BString::new("*".as_bytes().to_vec())),
1520 Ok(BinaryType::Multiplication)
1521 );
1522 assert_eq!(
1523 BinaryType::try_from(&BString::new("/".as_bytes().to_vec())),
1524 Ok(BinaryType::Division)
1525 );
1526 assert_eq!(
1527 BinaryType::try_from(&BString::new("%".as_bytes().to_vec())),
1528 Ok(BinaryType::Modulus)
1529 );
1530 assert_eq!(
1531 BinaryType::try_from(&BString::new("**".as_bytes().to_vec())),
1532 Ok(BinaryType::Exponentiation)
1533 );
1534 assert_eq!(
1535 BinaryType::try_from(&BString::new("&".as_bytes().to_vec())),
1536 Ok(BinaryType::BitwiseAnd)
1537 );
1538 assert_eq!(
1539 BinaryType::try_from(&BString::new("|".as_bytes().to_vec())),
1540 Ok(BinaryType::BitwiseOr)
1541 );
1542 assert_eq!(
1543 BinaryType::try_from(&BString::new("^".as_bytes().to_vec())),
1544 Ok(BinaryType::BitwiseXor)
1545 );
1546 assert_eq!(
1547 BinaryType::try_from(&BString::new("<<".as_bytes().to_vec())),
1548 Ok(BinaryType::BitwiseShiftLeft)
1549 );
1550 assert_eq!(
1551 BinaryType::try_from(&BString::new(">>".as_bytes().to_vec())),
1552 Ok(BinaryType::BitwiseShiftRight)
1553 );
1554 assert_eq!(
1555 BinaryType::try_from(&BString::new("==".as_bytes().to_vec())),
1556 Ok(BinaryType::IsEqual)
1557 );
1558 assert_eq!(
1559 BinaryType::try_from(&BString::new("===".as_bytes().to_vec())),
1560 Ok(BinaryType::IsIdentical)
1561 );
1562 assert_eq!(
1563 BinaryType::try_from(&BString::new("!=".as_bytes().to_vec())),
1564 Ok(BinaryType::IsNotEqual)
1565 );
1566 assert_eq!(
1567 BinaryType::try_from(&BString::new("!==".as_bytes().to_vec())),
1568 Ok(BinaryType::IsNotIdentical)
1569 );
1570 assert_eq!(
1571 BinaryType::try_from(&BString::new("<".as_bytes().to_vec())),
1572 Ok(BinaryType::IsLesser)
1573 );
1574 assert_eq!(
1575 BinaryType::try_from(&BString::new(">".as_bytes().to_vec())),
1576 Ok(BinaryType::IsGreater)
1577 );
1578 assert_eq!(
1579 BinaryType::try_from(&BString::new("<=".as_bytes().to_vec())),
1580 Ok(BinaryType::IsLesserOrEqual)
1581 );
1582 assert_eq!(
1583 BinaryType::try_from(&BString::new(">=".as_bytes().to_vec())),
1584 Ok(BinaryType::IsGreaterOrEqual)
1585 );
1586 assert_eq!(
1587 BinaryType::try_from(&BString::new("<=>".as_bytes().to_vec())),
1588 Ok(BinaryType::Spaceship)
1589 );
1590 assert_eq!(
1591 BinaryType::try_from(&BString::new(".".as_bytes().to_vec())),
1592 Ok(BinaryType::Concatenation)
1593 );
1594 assert_eq!(
1595 BinaryType::try_from(&BString::new("&&".as_bytes().to_vec())),
1596 Ok(BinaryType::BooleanAnd)
1597 );
1598 assert_eq!(
1599 BinaryType::try_from(&BString::new("and".as_bytes().to_vec())),
1600 Ok(BinaryType::BooleanAnd)
1601 );
1602 assert_eq!(
1603 BinaryType::try_from(&BString::new("||".as_bytes().to_vec())),
1604 Ok(BinaryType::BooleanOr)
1605 );
1606 assert_eq!(
1607 BinaryType::try_from(&BString::new("or".as_bytes().to_vec())),
1608 Ok(BinaryType::BooleanOr)
1609 );
1610 assert_eq!(
1611 BinaryType::try_from(&BString::new("xor".as_bytes().to_vec())),
1612 Ok(BinaryType::BooleanXor)
1613 );
1614 assert_eq!(
1615 BinaryType::try_from(&BString::new("?:".as_bytes().to_vec())),
1616 Ok(BinaryType::Elvis)
1617 );
1618 assert_eq!(
1619 BinaryType::try_from(&BString::new("??".as_bytes().to_vec())),
1620 Ok(BinaryType::Coalesce)
1621 );
1622 assert_eq!(
1623 BinaryType::try_from(&BString::new("instanceof".as_bytes().to_vec())),
1624 Ok(BinaryType::InstanceOf)
1625 );
1626 assert!(BinaryType::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1627
1628 assert_eq!("+", format!("{}", BinaryType::Addition));
1629 assert_eq!("-", format!("{}", BinaryType::Subtraction));
1630 assert_eq!("*", format!("{}", BinaryType::Multiplication));
1631 assert_eq!("/", format!("{}", BinaryType::Division));
1632 assert_eq!("%", format!("{}", BinaryType::Modulus));
1633 assert_eq!("**", format!("{}", BinaryType::Exponentiation));
1634 assert_eq!("&", format!("{}", BinaryType::BitwiseAnd));
1635 assert_eq!("|", format!("{}", BinaryType::BitwiseOr));
1636 assert_eq!("^", format!("{}", BinaryType::BitwiseXor));
1637 assert_eq!("<<", format!("{}", BinaryType::BitwiseShiftLeft));
1638 assert_eq!(">>", format!("{}", BinaryType::BitwiseShiftRight));
1639 assert_eq!("==", format!("{}", BinaryType::IsEqual));
1640 assert_eq!("===", format!("{}", BinaryType::IsIdentical));
1641 assert_eq!("!=", format!("{}", BinaryType::IsNotEqual));
1642 assert_eq!("!==", format!("{}", BinaryType::IsNotIdentical));
1643 assert_eq!("<", format!("{}", BinaryType::IsLesser));
1644 assert_eq!(">", format!("{}", BinaryType::IsGreater));
1645 assert_eq!("<=", format!("{}", BinaryType::IsLesserOrEqual));
1646 assert_eq!(">=", format!("{}", BinaryType::IsGreaterOrEqual));
1647 assert_eq!("<=>", format!("{}", BinaryType::Spaceship));
1648 assert_eq!(".", format!("{}", BinaryType::Concatenation));
1649 assert_eq!("&&", format!("{}", BinaryType::BooleanAnd));
1650 assert_eq!("||", format!("{}", BinaryType::BooleanOr));
1651 assert_eq!("xor", format!("{}", BinaryType::BooleanXor));
1652 assert_eq!("?:", format!("{}", BinaryType::Elvis));
1653 assert_eq!("??", format!("{}", BinaryType::Coalesce));
1654 assert_eq!("instanceof", format!("{}", BinaryType::InstanceOf));
1655 }
1656
1657 #[test]
1658 fn assignment_type() {
1659 assert_eq!(
1660 AssignmentType::try_from(&BString::new("=".as_bytes().to_vec())),
1661 Ok(AssignmentType::Default)
1662 );
1663 assert_eq!(
1664 AssignmentType::try_from(&BString::new("=&".as_bytes().to_vec())),
1665 Ok(AssignmentType::Reference)
1666 );
1667 assert_eq!(
1668 AssignmentType::try_from(&BString::new("??=".as_bytes().to_vec())),
1669 Ok(AssignmentType::Coalesce)
1670 );
1671 assert_eq!(
1672 AssignmentType::try_from(&BString::new("**=".as_bytes().to_vec())),
1673 Ok(AssignmentType::Exponentiation)
1674 );
1675 assert_eq!(
1676 AssignmentType::try_from(&BString::new("*=".as_bytes().to_vec())),
1677 Ok(AssignmentType::Multiplication)
1678 );
1679 assert_eq!(
1680 AssignmentType::try_from(&BString::new("/=".as_bytes().to_vec())),
1681 Ok(AssignmentType::Division)
1682 );
1683 assert_eq!(
1684 AssignmentType::try_from(&BString::new("+=".as_bytes().to_vec())),
1685 Ok(AssignmentType::Addition)
1686 );
1687 assert_eq!(
1688 AssignmentType::try_from(&BString::new("-=".as_bytes().to_vec())),
1689 Ok(AssignmentType::Subtraction)
1690 );
1691 assert_eq!(
1692 AssignmentType::try_from(&BString::new("%=".as_bytes().to_vec())),
1693 Ok(AssignmentType::Modulus)
1694 );
1695 assert_eq!(
1696 AssignmentType::try_from(&BString::new("&=".as_bytes().to_vec())),
1697 Ok(AssignmentType::BitwiseAnd)
1698 );
1699 assert_eq!(
1700 AssignmentType::try_from(&BString::new("|=".as_bytes().to_vec())),
1701 Ok(AssignmentType::BitwiseOr)
1702 );
1703 assert_eq!(
1704 AssignmentType::try_from(&BString::new("^=".as_bytes().to_vec())),
1705 Ok(AssignmentType::BitwiseXor)
1706 );
1707 assert_eq!(
1708 AssignmentType::try_from(&BString::new(">>=".as_bytes().to_vec())),
1709 Ok(AssignmentType::BitwiseShiftRight)
1710 );
1711 assert_eq!(
1712 AssignmentType::try_from(&BString::new("<<=".as_bytes().to_vec())),
1713 Ok(AssignmentType::BitwiseShiftLeft)
1714 );
1715 assert!(AssignmentType::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1716
1717 assert_eq!("=", format!("{}", AssignmentType::Default));
1718 assert_eq!("=&", format!("{}", AssignmentType::Reference));
1719 assert_eq!("??=", format!("{}", AssignmentType::Coalesce));
1720 assert_eq!("**=", format!("{}", AssignmentType::Exponentiation));
1721 assert_eq!("*=", format!("{}", AssignmentType::Multiplication));
1722 assert_eq!("/=", format!("{}", AssignmentType::Division));
1723 assert_eq!("+=", format!("{}", AssignmentType::Addition));
1724 assert_eq!("-=", format!("{}", AssignmentType::Subtraction));
1725 assert_eq!("%=", format!("{}", AssignmentType::Modulus));
1726 assert_eq!("&=", format!("{}", AssignmentType::BitwiseAnd));
1727 assert_eq!("|=", format!("{}", AssignmentType::BitwiseOr));
1728 assert_eq!("^=", format!("{}", AssignmentType::BitwiseXor));
1729 assert_eq!(">>=", format!("{}", AssignmentType::BitwiseShiftRight));
1730 assert_eq!("<<=", format!("{}", AssignmentType::BitwiseShiftLeft));
1731 }
1732
1733 #[test]
1734 fn use_item_modifier() {
1735 assert_eq!(
1736 UseItemModifier::try_from(&BString::new("const".as_bytes().to_vec())),
1737 Ok(UseItemModifier::Const)
1738 );
1739 assert_eq!(
1740 UseItemModifier::try_from(&BString::new("function".as_bytes().to_vec())),
1741 Ok(UseItemModifier::Function)
1742 );
1743 assert!(UseItemModifier::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1744
1745 assert_eq!("const", format!("{}", UseItemModifier::Const));
1746 assert_eq!("function", format!("{}", UseItemModifier::Function));
1747 }
1748
1749 #[test]
1750 fn modifier() {
1751 assert_eq!(
1752 Modifier::try_from(&BString::new("static".as_bytes().to_vec())),
1753 Ok(Modifier::Static)
1754 );
1755 assert_eq!(
1756 Modifier::try_from(&BString::new("readonly".as_bytes().to_vec())),
1757 Ok(Modifier::Readonly)
1758 );
1759 assert!(Modifier::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1760
1761 assert_eq!("static", format!("{}", Modifier::Static));
1762 assert_eq!("readonly", format!("{}", Modifier::Readonly));
1763 }
1764
1765 #[test]
1766 fn quote() {
1767 assert_eq!(Quote::try_from(&BString::new("'".as_bytes().to_vec())), Ok(Quote::Single));
1768 assert_eq!(Quote::try_from(&BString::new("\"".as_bytes().to_vec())), Ok(Quote::Double));
1769 assert_eq!(Quote::try_from(&BString::new("`".as_bytes().to_vec())), Ok(Quote::Backtick));
1770 assert!(Quote::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1771
1772 assert_eq!("'", format!("{}", Quote::Single));
1773 assert_eq!("\"", format!("{}", Quote::Double));
1774 assert_eq!("`", format!("{}", Quote::Backtick));
1775 }
1776
1777 #[test]
1778 fn inheritance() {
1779 assert_eq!(
1780 Inheritance::try_from(&BString::new("abstract".as_bytes().to_vec())),
1781 Ok(Inheritance::Abstract)
1782 );
1783 assert_eq!(
1784 Inheritance::try_from(&BString::new("final".as_bytes().to_vec())),
1785 Ok(Inheritance::Final)
1786 );
1787 assert!(Inheritance::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1788
1789 assert_eq!("abstract", format!("{}", Inheritance::Abstract));
1790 assert_eq!("final", format!("{}", Inheritance::Final));
1791 }
1792
1793 #[test]
1794 fn visibility() {
1795 assert_eq!(
1796 Visibility::try_from(&BString::new("private".as_bytes().to_vec())),
1797 Ok(Visibility::Private)
1798 );
1799 assert_eq!(
1800 Visibility::try_from(&BString::new("private(get)".as_bytes().to_vec())),
1801 Ok(Visibility::PrivateGet)
1802 );
1803 assert_eq!(
1804 Visibility::try_from(&BString::new("private(set)".as_bytes().to_vec())),
1805 Ok(Visibility::PrivateSet)
1806 );
1807 assert_eq!(
1808 Visibility::try_from(&BString::new("protected".as_bytes().to_vec())),
1809 Ok(Visibility::Protected)
1810 );
1811 assert_eq!(
1812 Visibility::try_from(&BString::new("protected(get)".as_bytes().to_vec())),
1813 Ok(Visibility::ProtectedGet)
1814 );
1815 assert_eq!(
1816 Visibility::try_from(&BString::new("protected(set)".as_bytes().to_vec())),
1817 Ok(Visibility::ProtectedSet)
1818 );
1819 assert_eq!(
1820 Visibility::try_from(&BString::new("public".as_bytes().to_vec())),
1821 Ok(Visibility::Public)
1822 );
1823 assert_eq!(
1824 Visibility::try_from(&BString::new("public(get)".as_bytes().to_vec())),
1825 Ok(Visibility::PublicGet)
1826 );
1827 assert_eq!(
1828 Visibility::try_from(&BString::new("public(set)".as_bytes().to_vec())),
1829 Ok(Visibility::PublicSet)
1830 );
1831 assert!(Visibility::try_from(&BString::new("none".as_bytes().to_vec())).is_err());
1832
1833 assert_eq!("private", format!("{}", Visibility::Private));
1834 assert_eq!("private(get)", format!("{}", Visibility::PrivateGet));
1835 assert_eq!("private(set)", format!("{}", Visibility::PrivateSet));
1836 assert_eq!("protected", format!("{}", Visibility::Protected));
1837 assert_eq!("protected(get)", format!("{}", Visibility::ProtectedGet));
1838 assert_eq!("protected(set)", format!("{}", Visibility::ProtectedSet));
1839 assert_eq!("public", format!("{}", Visibility::Public));
1840 assert_eq!("public(get)", format!("{}", Visibility::PublicGet));
1841 assert_eq!("public(set)", format!("{}", Visibility::PublicSet));
1842 }
1843}