Handle roles in ProhibitPublicBuilders
[gitmo/Perl-Critic-Dynamic-Moose.git] / lib / Perl / Critic / Policy / DynamicMoose.pm
CommitLineData
84a1bb62 1package Perl::Critic::Policy::DynamicMoose;
a3c86d00 2use Moose;
8f31d0d0 3use MooseX::NonMoose;
a3c86d00 4extends 'Perl::Critic::DynamicPolicy';
5
8f31d0d0 6has document => (
1e6decf8 7 is => 'rw',
8 isa => 'PPI::Document',
9 handles => [qw/ppi_document/],
8f31d0d0 10);
11
cc784ef4 12sub applies_to { 'PPI::Document' }
914f300c 13sub applies_to_metaclass { 'Class::MOP::Class', inner() }
8f31d0d0 14
15around violation => sub {
1e6decf8 16 my $orig = shift;
17 my $self = shift;
18 my $desc = shift;
19 my $expl = shift;
20 my $element = shift;
21
22 if (!$element) {
23 my $doc = $self->ppi_document;
24 $element = $doc->find('PPI::Element')->[0];
25 }
8f31d0d0 26
1e6decf8 27 return $self->$orig($desc, $expl, $element, @_);
8f31d0d0 28};
29
a3c86d00 30sub violates_dynamic {
31 my $self = shift;
32 my $doc = shift;
33
8f31d0d0 34 $self->document($doc);
35 $self->compile_document;
36
37 my @packages = $self->find_packages;
38
39 my @violations;
40 for my $package (@packages) {
c140dc59 41 my $meta = Class::MOP::class_of($package)
42 or next;
43
44 grep { $meta->isa($_) } $self->applies_to_metaclass
45 or next;
8f31d0d0 46
47 push @violations, $self->violates_metaclass($meta, $doc);
48 }
49
50 return @violations;
51}
52
53sub compile_document {
54 my $self = shift;
55 my $doc = $self->document;
56
1ad52929 57 my $source_code = $doc->content;
58
59 eval $source_code;
60
61 die "Unable to execute " . $doc->filename . ": $@" if $@;
8f31d0d0 62}
63
64sub find_packages {
65 my $self = shift;
66 my $doc = $self->document;
a3c86d00 67
8f31d0d0 68 return map { $_->namespace }
69 @{ $doc->find('PPI::Statement::Package') || [] };
a3c86d00 70}
71
a3c86d00 72no Moose;
73
741;
75