1PPIx::Utils::Traversal(U3s)er Contributed Perl DocumentatPiPoInx::Utils::Traversal(3)
2
3
4

NAME

6       PPIx::Utils::Traversal - Utility functions for traversing PPI documents
7

SYNOPSIS

9           use PPIx::Utils::Traversal ':all';
10

DESCRIPTION

12       This package is a component of PPIx::Utils that contains functions for
13       traversal of PPI documents.
14

FUNCTIONS

16       All functions can be imported by name, or with the tag ":all".
17
18   first_arg
19           my $first_arg = first_arg($element);
20
21       Given a PPI::Element that is presumed to be a function call (which is
22       usually a PPI::Token::Word), return the first argument.  This is
23       similar of "parse_arg_list" and follows the same logic.  Note that for
24       the code:
25
26           int($x + 0.5)
27
28       this function will return just the $x, not the whole expression.  This
29       is different from the behavior of "parse_arg_list".  Another caveat is:
30
31           int(($x + $y) + 0.5)
32
33       which returns "($x + $y)" as a PPI::Structure::List instance.
34
35   parse_arg_list
36           my @args = parse_arg_list($element);
37
38       Given a PPI::Element that is presumed to be a function call (which is
39       usually a PPI::Token::Word), splits the argument expressions into
40       arrays of tokens.  Returns a list containing references to each of
41       those arrays.  This is useful because parentheses are optional when
42       calling a function, and PPI parses them very differently.  So this
43       method is a poor-man's parse tree of PPI nodes.  It's not bullet-proof
44       because it doesn't respect precedence. In general, I don't like the way
45       this function works, so don't count on it to be stable (or even
46       present).
47
48   split_nodes_on_comma
49           my @args = split_nodes_on_comma(@nodes);
50
51       This has the same return type as "parse_arg_list" but expects to be
52       passed the nodes that represent the interior of a list, like:
53
54           'foo', 1, 2, 'bar'
55
56   get_next_element_in_same_simple_statement
57           my $element = get_next_element_in_same_simple_statement($element);
58
59       Given a PPI::Element, this subroutine returns the next element in the
60       same simple statement as defined by "is_ppi_simple_statement" in
61       PPIx::Utils::Classification. If no next element can be found, this
62       subroutine simply returns "undef".
63
64       If the $element is undefined or unblessed, we simply return "undef".
65
66       If the $element satisfies "is_ppi_simple_statement" in
67       PPIx::Utils::Classification, we return "undef", unless it has a parent
68       which is a PPI::Structure::List.
69
70       If the $element is the last significant element in its PPI::Node, we
71       replace it with its parent and iterate again.
72
73       Otherwise, we return "$element->snext_sibling()".
74
75   get_previous_module_used_on_same_line
76           my $element = get_previous_module_used_on_same_line($element);
77
78       Given a PPI::Element, returns the PPI::Element representing the name of
79       the module included by the previous "use" or "require" on the same line
80       as the $element. If none is found, simply returns "undef".
81
82       For example, with the line
83
84           use version; our $VERSION = ...;
85
86       given the PPI::Token::Symbol instance for $VERSION, this will return
87       "version".
88
89       If the given element is in a "use" or <require>, the return is from the
90       previous "use" or "require" on the line, if any.
91
92   get_constant_name_elements_from_declaring_statement
93           my @constants = get_constant_name_elements_from_declaring_statement($statement);
94
95       Given a PPI::Statement, if the statement is a Readonly, ReadonlyX, or
96       Const::Fast declaration statement or a "use constant", returns the
97       names of the things being defined.
98
99       Given
100
101           use constant 1.16 FOO => 'bar';
102
103       this will return the PPI::Token::Word containing 'FOO'.  Given
104
105           use constant 1.16 { FOO => 'bar', 'BAZ' => 'burfle' };
106
107       this will return a list of the PPI::Tokens containing 'FOO' and 'BAZ'.
108       Similarly, given
109
110           Readonly::Hash my %FOO => ( bar => 'baz' );
111
112       or
113
114           const my %FOO => ( bar => 'baz' );
115
116       this will return the PPI::Token::Symbol containing '%FOO'.
117
118   split_ppi_node_by_namespace
119           my $subtrees = split_ppi_node_by_namespace($node);
120
121       Returns the sub-trees for each namespace in the node as a reference to
122       a hash of references to arrays of PPI::Nodes.  Say we've got the
123       following code:
124
125           #!perl
126
127           my $x = blah();
128
129           package Foo;
130
131           my $y = blah_blah();
132
133           {
134               say 'Whee!';
135
136               package Bar;
137
138               something();
139           }
140
141           thingy();
142
143           package Baz;
144
145           da_da_da();
146
147           package Foo;
148
149           foreach ( blrfl() ) {
150               ...
151           }
152
153       Calling this function on a PPI::Document for the above returns a value
154       that looks like this, using multi-line string literals for the actual
155       code parts instead of PPI trees to make this easier to read:
156
157           {
158               main    => [
159                   q<
160                       #!perl
161
162                       my $x = blah();
163                   >,
164               ],
165               Foo     => [
166                   q<
167                       package Foo;
168
169                       my $y = blah_blah();
170
171                       {
172                           say 'Whee!';
173
174                       }
175
176                       thingy();
177                   >,
178                   q<
179                       package Foo;
180
181                       foreach ( blrfl() ) {
182                           ...
183                       }
184                   >,
185               ],
186               Bar     => [
187                   q<
188                       package Bar;
189
190                       something();
191                   >,
192               ],
193               Baz     => [
194                   q<
195                       package Baz;
196
197                       da_da_da();
198                   >,
199               ],
200           }
201
202       Note that the return value contains copies of the original nodes, and
203       not the original nodes themselves due to the need to handle namespaces
204       that are not file-scoped.  (Notice how the first element for "Foo"
205       above differs from the original code.)
206

BUGS

208       Report any issues on the public bugtracker.
209

AUTHOR

211       Dan Book <dbook@cpan.org>
212
213       Code originally from Perl::Critic::Utils by Jeffrey Ryan Thalhammer
214       <jeff@imaginative-software.com>, Perl::Critic::Utils::PPI and
215       PPIx::Utilities::Node by Elliot Shank <perl@galumph.com>, and
216       PPIx::Utilities::Statement by Thomas R. Wyant, III <wyant@cpan.org>
217
219       This software is copyright (c) 2005-2011 Imaginative Software Systems,
220       2007-2011 Elliot Shank, 2009-2010 Thomas R. Wyant, III, 2017 Dan Book.
221
222       This is free software; you can redistribute it and/or modify it under
223       the same terms as the Perl 5 programming language system itself.
224

SEE ALSO

226       Perl::Critic::Utils, Perl::Critic::Utils::PPI, PPIx::Utilities
227
228
229
230perl v5.34.0                      2022-01-21         PPIx::Utils::Traversal(3)
Impressum