Login
Change the test in t/08_document.t which tests
[gknop/Perl-Critic.git] / lib / Perl / Critic / Document.pm
CommitLineData
6036a254 1##############################################################################
a73f4a71
JRT
2# $URL$
3# $Date$
4# $Author$
5# $Revision$
6036a254 6##############################################################################
5bf96118
CD
7
8package Perl::Critic::Document;
9
df6dee2b 10use 5.006001;
5bf96118 11use strict;
58a9e587 12use warnings;
267b39b4 13
d5835ca8 14use Carp qw< confess >;
2d2fd196 15
81e74a91 16use List::Util qw< reduce >;
d5835ca8 17use Scalar::Util qw< blessed weaken >;
267b39b4 18use version;
5bf96118 19
013aa3aa
ES
20use PPI::Document;
21use PPI::Document::File;
22use PPIx::Utilities::Node qw< split_ppi_node_by_namespace >;
23
d5835ca8 24use Perl::Critic::Annotation;
d533eee5 25use Perl::Critic::Exception::Parse qw< throw_parse >;
48b61139 26use Perl::Critic::Utils qw< :booleans :characters shebang_line >;
d5835ca8 27
6036a254 28#-----------------------------------------------------------------------------
58a9e587 29
c263f914 30our $VERSION = '1.108';
5bf96118 31
6036a254 32#-----------------------------------------------------------------------------
5bf96118
CD
33
34our $AUTOLOAD;
937b8de0 35sub AUTOLOAD { ## no critic (ProhibitAutoloading,ArgUnpacking)
6e7d6c9f
CD
36 my ( $function_name ) = $AUTOLOAD =~ m/ ([^:\']+) \z /xms;
37 return if $function_name eq 'DESTROY';
38 my $self = shift;
39 return $self->{_doc}->$function_name(@_);
5bf96118
CD
40}
41
6036a254 42#-----------------------------------------------------------------------------
5bf96118 43
58a9e587 44sub new {
d5835ca8 45 my ($class, @args) = @_;
013aa3aa
ES
46
47 my $self = bless {}, $class;
48
49 $self->_init_common();
50 $self->_init_from_external_source(@args);
51
52 return $self;
53}
54
55#-----------------------------------------------------------------------------
56
57sub _new_for_parent_document {
58 my ($class, $ppi_document, $parent_document) = @_;
59
937b8de0 60 my $self = bless {}, $class;
013aa3aa
ES
61
62 $self->_init_common();
63
64 $self->{_doc} = $ppi_document;
65 $self->{_is_module} = $parent_document->is_module();
66
67 return $self;
d5835ca8
JRT
68}
69
70#-----------------------------------------------------------------------------
71
013aa3aa
ES
72sub _init_common {
73 my ($self) = @_;
74 my %args;
75
76 $self->{_annotations} = [];
77 $self->{_suppressed_violations} = [];
78 $self->{_disabled_line_map} = {};
79
80 return;
81}
82
83#-----------------------------------------------------------------------------
d5835ca8 84
013aa3aa 85sub _init_from_external_source { ## no critic (Subroutines::RequireArgUnpacking)
d533eee5
ES
86 my $self = shift;
87 my %args;
013aa3aa 88
d533eee5
ES
89 if (@_ == 1) {
90 warnings::warnif(
91 'deprecated',
92 'Perl::Critic::Document->new($source) deprecated, use Perl::Critic::Document->new(-source => $source) instead.' ## no critic (ValuesAndExpressions::RequireInterpolationOfMetachars)
93 );
94 %args = ('-source' => shift);
95 } else {
96 %args = @_;
97 }
013aa3aa 98
d533eee5 99 my $source_code = $args{'-source'};
d5835ca8
JRT
100
101 # $source_code can be a file name, or a reference to a
102 # PPI::Document, or a reference to a scalar containing source
103 # code. In the last case, PPI handles the translation for us.
104
013aa3aa
ES
105 my $ppi_document =
106 _is_ppi_doc($source_code)
107 ? $source_code
108 : ref $source_code
109 ? PPI::Document->new($source_code)
110 : PPI::Document::File->new($source_code);
d5835ca8
JRT
111
112 # Bail on error
013aa3aa 113 if (not defined $ppi_document) {
d5835ca8
JRT
114 my $errstr = PPI::Document::errstr();
115 my $file = ref $source_code ? undef : $source_code;
116 throw_parse
117 message => qq<Can't parse code: $errstr>,
118 file_name => $file;
119 }
120
013aa3aa 121 $self->{_doc} = $ppi_document;
d5835ca8
JRT
122 $self->index_locations();
123 $self->_disable_shebang_fix();
48b61139 124 $self->{_is_module} = $self->_determine_is_module(\%args);
d5835ca8 125
013aa3aa 126 return;
5bf96118
CD
127}
128
6036a254 129#-----------------------------------------------------------------------------
58a9e587 130
d5835ca8
JRT
131sub _is_ppi_doc {
132 my ($ref) = @_;
133 return blessed($ref) && $ref->isa('PPI::Document');
134}
135
136#-----------------------------------------------------------------------------
137
2b6293b2
CD
138sub ppi_document {
139 my ($self) = @_;
140 return $self->{_doc};
141}
142
143#-----------------------------------------------------------------------------
144
47e1ff34 145sub isa {
6e7d6c9f
CD
146 my ($self, @args) = @_;
147 return $self->SUPER::isa(@args)
148 || ( (ref $self) && $self->{_doc} && $self->{_doc}->isa(@args) );
47e1ff34
CD
149}
150
6036a254 151#-----------------------------------------------------------------------------
47e1ff34 152
5bf96118 153sub find {
6e7d6c9f 154 my ($self, $wanted, @more_args) = @_;
5bf96118 155
58a9e587
JRT
156 # This method can only find elements by their class names. For
157 # other types of searches, delegate to the PPI::Document
5bf96118 158 if ( ( ref $wanted ) || !$wanted || $wanted !~ m/ \A PPI:: /xms ) {
6e7d6c9f 159 return $self->{_doc}->find($wanted, @more_args);
5bf96118 160 }
58a9e587
JRT
161
162 # Build the class cache if it doesn't exist. This happens at most
163 # once per Perl::Critic::Document instance. %elements of will be
164 # populated as a side-effect of calling the $finder_sub coderef
165 # that is produced by the caching_finder() closure.
5bf96118 166 if ( !$self->{_elements_of} ) {
389109ec 167
58a9e587 168 my %cache = ( 'PPI::Document' => [ $self ] );
389109ec
JRT
169
170 # The cache refers to $self, and $self refers to the cache. This
171 # creates a circular reference that leaks memory (i.e. $self is not
172 # destroyed until execution is complete). By weakening the reference,
173 # we allow perl to collect the garbage properly.
174 weaken( $cache{'PPI::Document'}->[0] );
175
58a9e587
JRT
176 my $finder_coderef = _caching_finder( \%cache );
177 $self->{_doc}->find( $finder_coderef );
178 $self->{_elements_of} = \%cache;
179 }
180
181 # find() must return false-but-defined on fail
182 return $self->{_elements_of}->{$wanted} || q{};
183}
184
6036a254 185#-----------------------------------------------------------------------------
58a9e587 186
fb21e21e 187sub find_first {
6e7d6c9f 188 my ($self, $wanted, @more_args) = @_;
fb21e21e
CD
189
190 # This method can only find elements by their class names. For
191 # other types of searches, delegate to the PPI::Document
192 if ( ( ref $wanted ) || !$wanted || $wanted !~ m/ \A PPI:: /xms ) {
6e7d6c9f 193 return $self->{_doc}->find_first($wanted, @more_args);
fb21e21e
CD
194 }
195
196 my $result = $self->find($wanted);
197 return $result ? $result->[0] : $result;
198}
199
6036a254 200#-----------------------------------------------------------------------------
fb21e21e 201
f5eeac3b 202sub find_any {
6e7d6c9f 203 my ($self, $wanted, @more_args) = @_;
f5eeac3b
CD
204
205 # This method can only find elements by their class names. For
206 # other types of searches, delegate to the PPI::Document
207 if ( ( ref $wanted ) || !$wanted || $wanted !~ m/ \A PPI:: /xms ) {
6e7d6c9f 208 return $self->{_doc}->find_any($wanted, @more_args);
f5eeac3b
CD
209 }
210
211 my $result = $self->find($wanted);
212 return $result ? 1 : $result;
213}
214
6036a254 215#-----------------------------------------------------------------------------
f5eeac3b 216
013aa3aa
ES
217sub namespaces {
218 my ($self) = @_;
219
220 return keys %{ $self->_nodes_by_namespace() };
221}
222
223#-----------------------------------------------------------------------------
224
225sub subdocuments_for_namespace {
226 my ($self, $namespace) = @_;
227
228 my $subdocuments = $self->_nodes_by_namespace()->{$namespace};
229
230 return $subdocuments ? @{$subdocuments} : ();
231}
232
233#-----------------------------------------------------------------------------
234
60108aef
CD
235sub filename {
236 my ($self) = @_;
013aa3aa 237
c73ba7f3 238 my $doc = $self->{_doc};
013aa3aa 239
c73ba7f3 240 return $doc->can('filename') ? $doc->filename() : undef;
60108aef
CD
241}
242
6036a254 243#-----------------------------------------------------------------------------
60108aef 244
267b39b4
ES
245sub highest_explicit_perl_version {
246 my ($self) = @_;
247
248 my $highest_explicit_perl_version =
249 $self->{_highest_explicit_perl_version};
250
251 if ( not exists $self->{_highest_explicit_perl_version} ) {
252 my $includes = $self->find( \&_is_a_version_statement );
253
254 if ($includes) {
81e74a91
ES
255 # Note: this doesn't use List::Util::max() because that function
256 # doesn't use the overloaded ">=" etc of a version object. The
257 # reduce() style lets version.pm take care of all comparing.
df9f8d80
ES
258 #
259 # For reference, max() ends up looking at the string converted to
260 # an NV, or something like that. An underscore like "5.005_04"
261 # provokes a warning and is chopped off at "5.005" thus losing the
262 # minor part from the comparison.
263 #
264 # An underscore "5.005_04" is supposed to mean an alpha release
81e74a91
ES
265 # and shouldn't be used in a perl version. But it's shown in
266 # perlfunc under "use" (as a number separator), and appears in
267 # several modules supplied with perl 5.10.0 (like version.pm
268 # itself!). At any rate if version.pm can understand it then
269 # that's enough for here.
267b39b4 270 $highest_explicit_perl_version =
81e74a91 271 reduce { $a >= $b ? $a : $b }
901273dd
ES
272 map { version->new( $_->version() ) }
273 @{$includes};
267b39b4
ES
274 }
275 else {
276 $highest_explicit_perl_version = undef;
277 }
278
279 $self->{_highest_explicit_perl_version} =
280 $highest_explicit_perl_version;
281 }
282
283 return $highest_explicit_perl_version if $highest_explicit_perl_version;
284 return;
285}
286
937b8de0
JRT
287#-----------------------------------------------------------------------------
288
76b854e4
ES
289sub uses_module {
290 my ($self, $module_name) = @_;
291
292 return exists $self->_modules_used()->{$module_name};
293}
294
295#-----------------------------------------------------------------------------
296
d5835ca8
JRT
297sub process_annotations {
298 my ($self) = @_;
937b8de0 299
d5835ca8
JRT
300 my @annotations = Perl::Critic::Annotation->create_annotations($self);
301 $self->add_annotation(@annotations);
937b8de0
JRT
302 return $self;
303}
304
305#-----------------------------------------------------------------------------
306
d5835ca8
JRT
307sub line_is_disabled_for_policy {
308 my ($self, $line, $policy) = @_;
309 my $policy_name = ref $policy || $policy;
2d2fd196
JRT
310
311 # HACK: This Policy is special. If it is active, it cannot be
d1237298 312 # disabled by a "## no critic" annotation. Rather than create a general
2d2fd196 313 # hook in Policy.pm for enabling this behavior, we chose to hack
d5835ca8 314 # it here, since this isn't the kind of thing that most policies do
2f4b6b33
JRT
315
316 return 0 if $policy_name eq
2d2fd196
JRT
317 'Perl::Critic::Policy::Miscellanea::ProhibitUnrestrictedNoCritic';
318
d5835ca8
JRT
319 return 1 if $self->{_disabled_line_map}->{$line}->{$policy_name};
320 return 1 if $self->{_disabled_line_map}->{$line}->{ALL};
937b8de0
JRT
321 return 0;
322}
323
324#-----------------------------------------------------------------------------
325
d5835ca8
JRT
326sub add_annotation {
327 my ($self, @annotations) = @_;
328
329 # Add annotation to our private map for quick lookup
330 for my $annotation (@annotations) {
331
332 my ($start, $end) = $annotation->effective_range();
333 my @affected_policies = $annotation->disables_all_policies ?
334 qw(ALL) : $annotation->disabled_policies();
335
336 # TODO: Find clever way to do this with hash slices
337 for my $line ($start .. $end) {
338 for my $policy (@affected_policies) {
339 $self->{_disabled_line_map}->{$line}->{$policy} = 1;
340 }
341 }
342 }
343
344 push @{ $self->{_annotations} }, @annotations;
2d2fd196
JRT
345 return $self;
346}
4880392e 347
2d2fd196 348#-----------------------------------------------------------------------------
4880392e 349
d5835ca8 350sub annotations {
2d2fd196 351 my ($self) = @_;
d5835ca8
JRT
352 return @{ $self->{_annotations} };
353}
4880392e 354
d5835ca8 355#-----------------------------------------------------------------------------
4880392e 356
d5835ca8
JRT
357sub add_suppressed_violation {
358 my ($self, $violation) = @_;
359 push @{$self->{_suppressed_violations}}, $violation;
360 return $self;
361}
4880392e 362
d5835ca8 363#-----------------------------------------------------------------------------
2d2fd196 364
d5835ca8
JRT
365sub suppressed_violations {
366 my ($self) = @_;
367 return @{ $self->{_suppressed_violations} };
95ebf9b0
JRT
368}
369
370#-----------------------------------------------------------------------------
d533eee5 371
1b936936 372sub is_program {
d533eee5 373 my ($self) = @_;
48b61139
ES
374
375 return not $self->is_module();
d533eee5
ES
376}
377
378#-----------------------------------------------------------------------------
379
380sub is_module {
381 my ($self) = @_;
48b61139
ES
382
383 return $self->{_is_module};
d533eee5
ES
384}
385
386#-----------------------------------------------------------------------------
d5835ca8 387# PRIVATE functions & methods
95ebf9b0 388
267b39b4
ES
389sub _is_a_version_statement {
390 my (undef, $element) = @_;
391
392 return 0 if not $element->isa('PPI::Statement::Include');
393 return 1 if $element->version();
394 return 0;
395}
396
397#-----------------------------------------------------------------------------
398
58a9e587 399sub _caching_finder {
58a9e587
JRT
400 my $cache_ref = shift; # These vars will persist for the life
401 my %isa_cache = (); # of the code ref that this sub returns
402
403
404 # Gather up all the PPI elements and sort by @ISA. Note: if any
405 # instances used multiple inheritance, this implementation would
406 # lead to multiple copies of $element in the $elements_of lists.
407 # However, PPI::* doesn't do multiple inheritance, so we are safe
408
409 return sub {
6e7d6c9f 410 my (undef, $element) = @_;
58a9e587
JRT
411 my $classes = $isa_cache{ref $element};
412 if ( !$classes ) {
413 $classes = [ ref $element ];
414 # Use a C-style loop because we append to the classes array inside
415 for ( my $i = 0; $i < @{$classes}; $i++ ) { ## no critic(ProhibitCStyleForLoops)
416 no strict 'refs'; ## no critic(ProhibitNoStrict)
417 push @{$classes}, @{"$classes->[$i]::ISA"};
418 $cache_ref->{$classes->[$i]} ||= [];
5bf96118 419 }
58a9e587
JRT
420 $isa_cache{$classes->[0]} = $classes;
421 }
5bf96118 422
58a9e587
JRT
423 for my $class ( @{$classes} ) {
424 push @{$cache_ref->{$class}}, $element;
425 }
5bf96118 426
58a9e587
JRT
427 return 0; # 0 tells find() to keep traversing, but not to store this $element
428 };
5bf96118
CD
429}
430
6036a254 431#-----------------------------------------------------------------------------
58a9e587 432
d5835ca8 433sub _disable_shebang_fix {
2d2fd196
JRT
434 my ($self) = @_;
435
1b936936 436 # When you install a program using ExtUtils::MakeMaker or Module::Build, it
937b8de0 437 # inserts some magical code into the top of the file (just after the
1b936936 438 # shebang). This code allows people to call your program using a shell,
937b8de0 439 # like `sh my_script`. Unfortunately, this code causes several Policy
d1237298 440 # violations, so we disable them as if they had "## no critic" annotations.
937b8de0 441
d5835ca8 442 my $first_stmnt = $self->schild(0) || return;
937b8de0
JRT
443
444 # Different versions of MakeMaker and Build use slightly different shebang
445 # fixing strings. This matches most of the ones I've found in my own Perl
446 # distribution, but it may not be bullet-proof.
447
5d6f7fbc 448 my $fixin_rx = qr<^eval 'exec .* \$0 \${1[+]"\$@"}'\s*[\r\n]\s*if.+;>ms; ## no critic (ExtendedFormatting)
937b8de0 449 if ( $first_stmnt =~ $fixin_rx ) {
d5835ca8
JRT
450 my $line = $first_stmnt->location->[0];
451 $self->{_disabled_line_map}->{$line}->{ALL} = 1;
452 $self->{_disabled_line_map}->{$line + 1}->{ALL} = 1;
937b8de0
JRT
453 }
454
2d2fd196 455 return $self;
937b8de0
JRT
456}
457
458#-----------------------------------------------------------------------------
459
48b61139 460sub _determine_is_module {
d533eee5
ES
461 my ($self, $args) = @_;
462
463 my $file_name = $self->filename();
1b936936
ES
464 if (
465 defined $file_name
466 and ref $args->{'-program-extensions'} eq 'ARRAY'
467 ) {
468 foreach my $ext ( @{ $args->{'-program-extensions'} } ) {
469 my $regex =
470 ref $ext eq 'Regexp'
471 ? $ext
472 : qr< @{ [ quotemeta $ext ] } \z >xms;
473
48b61139 474 return $FALSE if $file_name =~ m/$regex/smx;
d533eee5
ES
475 }
476 }
477
48b61139
ES
478 return $FALSE if shebang_line($self);
479 return $FALSE if defined $file_name && $file_name =~ m/ [.] PL \z /smx;
d533eee5 480
48b61139 481 return $TRUE;
d533eee5
ES
482}
483
484#-----------------------------------------------------------------------------
485
013aa3aa
ES
486sub _nodes_by_namespace {
487 my ($self) = @_;
488
489 my $nodes = $self->{_nodes_by_namespace};
490
491 return $nodes if $nodes;
492
493 my $ppi_document = $self->ppi_document();
494 if (not $ppi_document) {
495 return $self->{_nodes_by_namespace} = {};
496 }
497
498 my $raw_nodes_map = split_ppi_node_by_namespace($ppi_document);
499
500 my %wrapped_nodes;
501 while ( my ($namespace, $raw_nodes) = each %{$raw_nodes_map} ) {
ef89e7fc 502 $wrapped_nodes{$namespace} = [
013aa3aa 503 map { __PACKAGE__->_new_for_parent_document($_, $self) }
ef89e7fc
ES
504 @{$raw_nodes}
505 ];
013aa3aa
ES
506 }
507
508 return $self->{_nodes_by_namespace} = \%wrapped_nodes;
509}
510
511#-----------------------------------------------------------------------------
512
76b854e4
ES
513# Note: must use exists on return value to determine membership because all
514# the values are false, unlike the result of hashify().
515sub _modules_used {
516 my ($self) = @_;
517
518 my $mapping = $self->{_modules_used};
519
520 return $mapping if $mapping;
521
522 my $includes = $self->find('PPI::Statement::Include');
2187a8d2
ES
523 if (not $includes) {
524 return $self->{_modules_used} = {};
525 }
76b854e4
ES
526
527 my %mapping;
528 for my $module (
529 grep { $_ } map { $_->module() || $_->pragma() } @{$includes}
530 ) {
531 # Significanly ess memory than $h{$k} => 1. Thanks Mr. Lembark.
532 $mapping{$module} = ();
533 }
534
535 return $self->{_modules_used} = \%mapping;
536}
537
538#-----------------------------------------------------------------------------
539
5bf96118 5401;
58a9e587 541
5bf96118
CD
542__END__
543
a73f4a71
JRT
544=pod
545
546=for stopwords pre-caches
547
5bf96118
CD
548=head1 NAME
549
c728943a 550Perl::Critic::Document - Caching wrapper around a PPI::Document.
5bf96118 551
267b39b4 552
5bf96118
CD
553=head1 SYNOPSIS
554
555 use PPI::Document;
556 use Perl::Critic::Document;
557 my $doc = PPI::Document->new('Foo.pm');
d533eee5 558 $doc = Perl::Critic::Document->new(-source => $doc);
5bf96118
CD
559 ## Then use the instance just like a PPI::Document
560
267b39b4 561
5bf96118
CD
562=head1 DESCRIPTION
563
564Perl::Critic does a lot of iterations over the PPI document tree via
565the C<PPI::Document::find()> method. To save some time, this class
566pre-caches a lot of the common C<find()> calls in a single traversal.
567Then, on subsequent requests we return the cached data.
568
569This is implemented as a facade, where method calls are handed to the
570stored C<PPI::Document> instance.
571
267b39b4 572
5bf96118
CD
573=head1 CAVEATS
574
575This facade does not implement the overloaded operators from
11f53956
ES
576L<PPI::Document|PPI::Document> (that is, the C<use overload ...>
577work). Therefore, users of this facade must not rely on that syntactic
578sugar. So, for example, instead of C<my $source = "$doc";> you should
579write C<my $source = $doc->content();>
5bf96118
CD
580
581Perhaps there is a CPAN module out there which implements a facade
582better than we do here?
583
267b39b4 584
4444d94d
ES
585=head1 INTERFACE SUPPORT
586
587This is considered to be a public class. Any changes to its interface
588will go through a deprecation cycle.
589
590
267b39b4
ES
591=head1 CONSTRUCTOR
592
593=over
594
1b936936 595=item C<< new(-source => $source_code, '-program-extensions' => [program_extensions]) >>
267b39b4 596
d5835ca8
JRT
597Create a new instance referencing a PPI::Document instance. The
598C<$source_code> can be the name of a file, a reference to a scalar
0e4a0ae1
TW
599containing actual source code, or a L<PPI::Document|PPI::Document> or
600L<PPI::Document::File|PPI::Document::File>.
267b39b4 601
48b61139
ES
602The '-program-extensions' argument is optional, and is a reference to a list
603of strings and/or regular expressions. The strings will be made into regular
604expressions matching the end of a file name, and any document whose file name
605matches one of the regular expressions will be considered a program.
d533eee5 606
1b936936 607If -program-extensions is not specified, or if it does not determine the
48b61139
ES
608document type, the document will be considered to be a program if the source
609has a shebang line or its file name (if any) matches C<< m/ [.] PL \z /smx >>.
d533eee5 610
267b39b4
ES
611=back
612
5bf96118
CD
613=head1 METHODS
614
615=over
616
267b39b4 617=item C<< ppi_document() >>
2b6293b2 618
11f53956
ES
619Accessor for the wrapped PPI::Document instance. Note that altering
620this instance in any way can cause unpredictable failures in
621Perl::Critic's subsequent analysis because some caches may fall out of
622date.
2b6293b2 623
5bf96118 624
267b39b4
ES
625=item C<< find($wanted) >>
626
627=item C<< find_first($wanted) >>
fb21e21e 628
267b39b4 629=item C<< find_any($wanted) >>
f5eeac3b 630
76b854e4
ES
631Caching wrappers around the PPI methods. If C<$wanted> is a simple PPI class
632name, then the cache is employed. Otherwise we forward the call to the
633corresponding method of the C<PPI::Document> instance.
5bf96118 634
267b39b4 635
013aa3aa
ES
636=item C<< namespaces() >>
637
638Returns a list of the namespaces (package names) in the document.
639
640
641=item C<< subdocuments_for_namespace($namespace) >>
642
643Returns a list of sub-documents containing the elements in the given
644namespace. For example, given that the current document is for the source
645
646 foo();
647 package Foo;
648 package Bar;
649 package Foo;
650
651this method will return two L<Perl::Critic::Document|Perl::Critic::Document>s
652for a parameter of C<"Foo">. For more, see
653L<PPIx::Utilities::Node/split_ppi_node_by_namespace>.
654
655
267b39b4 656=item C<< filename() >>
e7f2d995
CD
657
658Returns the filename for the source code if applicable
659(PPI::Document::File) or C<undef> otherwise (PPI::Document).
660
267b39b4
ES
661
662=item C<< isa( $classname ) >>
242f7b08 663
11f53956
ES
664To be compatible with other modules that expect to get a
665PPI::Document, the Perl::Critic::Document class masquerades as the
666PPI::Document class.
242f7b08 667
267b39b4
ES
668
669=item C<< highest_explicit_perl_version() >>
670
11f53956
ES
671Returns a L<version|version> object for the highest Perl version
672requirement declared in the document via a C<use> or C<require>
673statement. Returns nothing if there is no version statement.
267b39b4 674
013aa3aa 675
76b854e4
ES
676=item C<< uses_module($module_or_pragma_name) >>
677
678Answers whether there is a C<use>, C<require>, or C<no> of the given name in
679this document. Note that there is no differentiation of modules vs. pragmata
680here.
681
682
d5835ca8 683=item C<< process_annotations() >>
267b39b4 684
d5835ca8
JRT
685Causes this Document to scan itself and mark which lines &
686policies are disabled by the C<"## no critic"> annotations.
937b8de0 687
013aa3aa 688
d5835ca8 689=item C<< line_is_disabled_for_policy($line, $policy_object) >>
937b8de0 690
fcb2381b 691Returns true if the given C<$policy_object> or C<$policy_name> has
d5835ca8 692been disabled for at C<$line> in this Document. Otherwise, returns false.
937b8de0 693
013aa3aa 694
d5835ca8 695=item C<< add_annotation( $annotation ) >>
937b8de0 696
d5835ca8 697Adds an C<$annotation> object to this Document.
2d2fd196 698
013aa3aa 699
d5835ca8 700=item C<< annotations() >>
2d2fd196 701
0e4a0ae1
TW
702Returns a list containing all the
703L<Perl::Critic::Annotation|Perl::Critic::Annotation>s that
d5835ca8 704were found in this Document.
2d2fd196 705
013aa3aa 706
d5835ca8 707=item C<< add_suppressed_violation($violation) >>
2d2fd196 708
fcb2381b 709Informs this Document that a C<$violation> was found but not reported
d5835ca8
JRT
710because it fell on a line that had been suppressed by a C<"## no critic">
711annotation. Returns C<$self>.
95ebf9b0 712
013aa3aa 713
d5835ca8 714=item C<< suppressed_violations() >>
95ebf9b0 715
0e4a0ae1
TW
716Returns a list of references to all the
717L<Perl::Critic::Violation|Perl::Critic::Violation>s
d5835ca8 718that were found in this Document but were suppressed.
937b8de0 719
d533eee5 720
1b936936
ES
721=item C<< is_program() >>
722
723Returns whether this document is considered to be a program.
d533eee5 724
d533eee5
ES
725
726=item C<< is_module() >>
727
1b936936 728Returns whether this document is considered to be a Perl module.
d533eee5 729
5bf96118
CD
730=back
731
732=head1 AUTHOR
733
2f4b6b33 734Chris Dolan <cdolan@cpan.org>
5bf96118
CD
735
736=head1 COPYRIGHT
737
072692c8 738Copyright (c) 2006-2010 Chris Dolan.
5bf96118
CD
739
740This program is free software; you can redistribute it and/or modify
741it under the same terms as Perl itself. The full text of this license
742can be found in the LICENSE file included with this module.
743
744=cut
737d3b65 745
d5835ca8 746##############################################################################
737d3b65
CD
747# Local Variables:
748# mode: cperl
749# cperl-indent-level: 4
750# fill-column: 78
751# indent-tabs-mode: nil
752# c-indentation-style: bsd
753# End:
96fed375 754# ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :