File Coverage

blib/lib/File/PackageIndexer/PPI/ClassXSAccessor.pm
Criterion Covered Total %
statement 52 52 100.0
branch 32 42 76.1
condition 6 9 66.6
subroutine 4 4 100.0
pod 0 1 0.0
total 94 108 87.0


line stmt bran cond sub pod time code
1             package File::PackageIndexer::PPI::ClassXSAccessor;
2              
3 9     9   220 use 5.008001;
  9         35  
  9         415  
4 9     9   54 use strict;
  9         33  
  9         329  
5 9     9   54 use warnings;
  9         19  
  9         5724  
6              
7             our $VERSION = '0.01';
8              
9              
10             # The Class::XSAccessor special case
11             sub handle_class_xsaccessor {
12 31     31 0 58 my $indexer = shift;
13 31         40 my $statement = shift;
14 31         80 my $curpkg = shift;
15 31         34 my $pkgs = shift;
16              
17 31         43 my @subs;
18 31 100       113 my $class = defined($curpkg) ? $curpkg->{name} : $indexer->default_package;
19 31         45 my $started = 0;
20 31         49 my $state = "key";
21 31         39 my $key;
22 31         102 my @tokens = $statement->schildren();
23 31         780 pop @tokens; # remove ;
24              
25 31         92 while (@tokens) {
26 351         680 my $token = shift @tokens;
27 351 50       909 next if $token->class eq 'PPI::Token::Whitespace';
28 351 100 100     1938 $started = 1, next if not $started and $token->content =~ /^Class::XSAccessor(?:::Array)?$/;
29 320 100       839 next if not $started;
30              
31             # handle embedded ()'s
32 289 100       1440 if ($token->isa("PPI::Structure::List")) {
33 2         25 my @t = $token->schildren;
34 2         20 foreach my $t (@t) {
35 2 50       12 unshift @tokens, ($t->isa("PPI::Statement::Expression") ? $t->schildren() : $t);
36             }
37 2         51 next;
38             }
39              
40 287 100       802 if ($state eq 'key') {
    100          
    50          
41 79         246 my $keyname = File::PackageIndexer::PPI::Util::get_keyname($token);
42 79 50       441 return() if not defined $keyname; # broken usage?
43 79         96 $key = $keyname;
44 79         219 $state = 'comma';
45             }
46             elsif ($state eq 'comma') {
47 129 50       416 return() unless $token->isa("PPI::Token::Operator");
48 129 50       297 last if $token->content eq ';';
49 129 50       1722 return() unless $token->content =~ /^(?:,|=>)$/; # are there other valid comma-likes?
50 129 100       999 $state = defined($key) ? 'value' : 'key';
51             }
52             elsif ($state eq 'value') {
53 79 100       377 if ($key eq 'class') {
    100          
    100          
    50          
54 8 50       62 $class = $token->isa("PPI::Token::Quote") ? $token->string : $token->content;
55             }
56             elsif ($key =~ /^(?:chained|replace)$/) {
57             # option, do nothing
58             }
59             elsif ($token->isa("PPI::Structure::Constructor")) {
60 51         162 my $struct = File::PackageIndexer::PPI::Util::constructor_to_structure($token);
61 51 100 66     357 if ($struct and ref($struct) eq 'ARRAY') {
    50 33        
62 17         61 push @subs, @$struct;
63             }
64             elsif ($struct and ref($struct) eq 'HASH') {
65 34         136 push @subs, keys %$struct;
66             }
67             }
68             elsif ($token->isa("PPI::Token::Quote")) {
69 2         12 push @subs, $token->string;
70             }
71 79         225 $key = undef;
72 79         215 $state = 'comma';
73             } # end if value
74              
75             } # end while tokens
76              
77 31         162 my $pkg = $indexer->lazy_create_pkg($class, $pkgs);
78 31         64 my $subs = $pkg->{subs};
79 31         183 $pkg->{subs}{$_} = 1 for @subs;
80 31         148 return();
81             }
82              
83              
84              
85             1;
86              
87             __END__