File Coverage

blib/lib/Compiler/Lexer.pm
Criterion Covered Total %
statement 56 59 94.9
branch 17 20 85.0
condition 4 6 66.6
subroutine 11 12 91.6
pod 3 4 75.0
total 91 101 90.1


line stmt bran cond sub pod time code
1             package Compiler::Lexer;
2 19     19   337627 use strict;
  19         145  
  19         587  
3 19     19   107 use warnings;
  19         38  
  19         462  
4 19     19   452 use 5.008_001;
  19         76  
5 19     19   111 use File::Find;
  19         50  
  19         1851  
6 19     19   8078 use Compiler::Lexer::Token;
  19         61  
  19         553  
7 19     19   8079 use Compiler::Lexer::Constants;
  19         51  
  19         11824  
8              
9             require Exporter;
10             our @ISA = qw(Exporter);
11             our %EXPORT_TAGS = ( 'all' => [ qw() ] );
12             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
13             our @EXPORT = qw();
14             our $VERSION = '0.23';
15             require XSLoader;
16             XSLoader::load(__PACKAGE__, $VERSION);
17              
18             my $inc;
19              
20             sub new {
21 27     27 1 14988 my ($class, $args) = @_;
22 27         68 my $options = +{};
23 27 100       173 if (ref $args eq 'HASH') {
    50          
24 1         3 $options = $args;
25             } elsif (ref $args eq 'SCALAR') {
26 0         0 $options->{filename} = $args;
27             }
28 27   50     196 $options->{filename} ||= '-';
29 27   100     143 $options->{verbose} ||= 0;
30 27         3223 return $class->_new($options);
31             }
32              
33             sub set_library_path {
34 0     0 1 0 my ($self, $_inc) = @_;
35 0         0 $inc = $_inc;
36             }
37              
38             sub load_module {
39 12     12 0 43 my ($self, $name) = @_;
40 12         76 $name =~ s|::|/|g;
41 12 50       124 my @include_path = ($inc) ? @$inc : @INC;
42 12         22 my $module_path = '';
43 12         29 foreach my $path (@include_path) {
44 114 50       1814 next unless -e $path;
45             find(sub {
46 107903 100   107903   439072 return if ($module_path);
47 100648         143949 my $absolute_path = $File::Find::name;
48 100648 100       2820835 if ($absolute_path =~ "$name.pm") {
49 9         173 $module_path = $absolute_path;
50             }
51 114         7699 }, $path);
52 114 100       986 last if ($module_path);
53             }
54 12 100       62 return undef unless $module_path;
55 9         502 open my $fh, '<', $module_path;
56 9         33 return do { local $/; <$fh> };
  9         75  
  9         912  
57             }
58              
59             sub recursive_tokenize {
60 2     2 1 8 my ($self, $script) = @_;
61 2         6 my %results;
62 2         10 $self->__recursive_tokenize(\%results, $script);
63 2         237 $results{main} = $self->tokenize($script);
64 2         14 return \%results;
65             }
66              
67             sub __recursive_tokenize {
68 11     11   49 my ($self, $results, $script) = @_;
69 11         15182 my $modules = $self->get_used_modules($script);
70 11         111 foreach my $module (@$modules) {
71 25         73 my $name = $module->{name};
72 25 100       117 next if (defined $results->{$name});
73 12   50     116 $results->{$name} ||= [];
74 12         54 my $code = $self->load_module($name);
75 12 100       58 next unless ($code);
76 9         25654 $results->{$name} = $self->tokenize($code);
77 9         424 $self->__recursive_tokenize($results, $code);
78             }
79             }
80              
81             1;
82             __END__
83              
84             =encoding utf-8
85              
86             =head1 NAME
87              
88             Compiler::Lexer - Lexical Analyzer for Perl5
89              
90             =head1 SYNOPSIS
91              
92             use Compiler::Lexer;
93             use Data::Dumper;
94              
95             my $filename = $ARGV[0];
96             open my $fh, '<', $filename or die "Cannot open $filename: $!";
97             my $script = do { local $/; <$fh> };
98              
99             my $lexer = Compiler::Lexer->new($filename);
100             my $tokens = $lexer->tokenize($script);
101             print Dumper $tokens;
102              
103             my $modules = $lexer->get_used_modules($script);
104             print Dumper $modules;
105              
106             =head1 METHODS
107              
108             =over 4
109              
110             =item my $lexer = Compiler::Lexer->new($options);
111              
112             create new instance.
113             You can create object from $options in hash reference.
114              
115             B<options list>
116              
117             =over 4
118              
119             =item filename
120              
121             =item verbose : includes token of Pod, Comment and WhiteSpace
122              
123             =back
124              
125             =item $lexer->tokenize($script);
126              
127             get token objects includes parameter of 'name' or 'type' or 'line' and so on.
128             This method requires perl source code in string.
129              
130             =item $lexer->set_library_path(['path1', 'path2' ...])
131              
132             set libraries path for reading recursively. Default paths are @INC.
133              
134             =item $lexer->recursive_tokenize($script)
135              
136             get hash reference like { 'module_nameA' => [], 'module_nameB' => [] ... }.
137             This method requires per source code in string.
138              
139             =item $lexer->get_used_modules($script);
140              
141             get names of used module.
142             This method requires perl source code in string.
143              
144             =back
145              
146             =head1 AUTHOR
147              
148             Masaaki Goshima (goccy) E<lt>goccy(at)cpan.orgE<gt>
149              
150             =head1 CONTRIBUTORS
151              
152             tokuhirom: Tokuhiro Matsuno
153              
154             =head1 LICENSE AND COPYRIGHT
155              
156             Copyright (c) 2013, Masaaki Goshima (goccy). All rights reserved.
157              
158             This library is free software; you can redistribute it and/or modify
159             it under the same terms as Perl itself.
160              
161             =cut