File Coverage

blib/lib/MooseX/Declare/Syntax/Keyword/Role.pm
Criterion Covered Total %
statement 38 39 97.4
branch 6 8 75.0
condition n/a
subroutine 11 12 91.6
pod 1 2 50.0
total 56 61 91.8


line stmt bran cond sub pod time code
1             package MooseX::Declare::Syntax::Keyword::Role;
2             # ABSTRACT: Role declarations
3              
4             our $VERSION = '0.43';
5              
6 24     24   15533 use Moose;
  24         39  
  24         188  
7 24     24   112706 use Moose::Util qw(does_role find_meta);
  24         36  
  24         182  
8 24     24   5148 use aliased 'Parse::Method::Signatures' => 'PMS';
  24         40  
  24         137  
9 24     24   3059 use aliased 'MooseX::Declare::Syntax::MethodDeclaration';
  24         41  
  24         78  
10 24     24   2892 use aliased 'Parse::Method::Signatures::Param::Placeholder';
  24         36  
  24         74  
11 24     24   2686 use aliased 'MooseX::Declare::Context::Parameterized', 'ParameterizedCtx';
  24         37  
  24         82  
12 24     24   2580 use aliased 'MooseX::Declare::Syntax::MethodDeclaration::Parameterized', 'ParameterizedMethod';
  24         32  
  24         95  
13              
14 24     24   1865 use namespace::autoclean;
  24         54  
  24         91  
15              
16             #pod =head1 CONSUMES
17             #pod
18             #pod =for :list
19             #pod * L<MooseX::Declare::Syntax::MooseSetup>
20             #pod * L<MooseX::Declare::Syntax::RoleApplication>
21             #pod
22             #pod =cut
23              
24             with qw(
25             MooseX::Declare::Syntax::MooseSetup
26             MooseX::Declare::Syntax::RoleApplication
27             );
28              
29             #pod =head1 MODIFIED METHODS
30             #pod
31             #pod =head2 imported_moose_symbols
32             #pod
33             #pod List Object->imported_moose_symbols ()
34             #pod
35             #pod Extends the existing L<MooseX::Declare::Syntax::MooseSetup/imported_moose_symbols>
36             #pod with C<requires>, C<extends>, C<has>, C<inner> and C<super>.
37             #pod
38             #pod =cut
39              
40             around imported_moose_symbols => sub { shift->(@_), qw( requires excludes extends has inner super ) };
41              
42             #pod =head2 import_symbols_from
43             #pod
44             #pod Str Object->import_symbols_from ()
45             #pod
46             #pod Will return L<Moose::Role> instead of the default L<Moose>.
47             #pod
48             #pod =cut
49              
50             around import_symbols_from => sub {
51             my ($next, $self, $ctx) = @_;
52             return $ctx->has_parameter_signature
53             ? 'MooseX::Role::Parameterized'
54             : 'Moose::Role';
55             };
56              
57             #pod =head2 make_anon_metaclass
58             #pod
59             #pod Object Object->make_anon_metaclass ()
60             #pod
61             #pod This will return an anonymous instance of L<Moose::Meta::Role>.
62             #pod
63             #pod =cut
64              
65             around make_anon_metaclass => sub { Moose::Meta::Role->create_anon_role };
66              
67             around context_traits => sub { shift->(@_), ParameterizedCtx };
68              
69             around default_inner => sub {
70             my ($next, $self, $stack) = @_;
71             my $inner = $self->$next;
72             return $inner
73             if !@{ $stack || [] } || !$stack->[-1]->is_parameterized;
74              
75             ParameterizedMethod->meta->apply($_)
76             for grep { does_role($_, MethodDeclaration) } @{ $inner };
77              
78             return $inner;
79             };
80              
81             #pod =method generate_export
82             #pod
83             #pod CodeRef Object->generate_export ()
84             #pod
85             #pod Returns a closure with a call to L</make_anon_metaclass>.
86             #pod
87             #pod =cut
88              
89 0     0 1 0 sub generate_export { my $self = shift; sub { $self->make_anon_metaclass } }
  87     87   156  
  87         333  
90              
91             after parse_namespace_specification => sub {
92             my ($self, $ctx) = @_;
93             $ctx->strip_parameter_signature;
94             };
95              
96             after add_namespace_customizations => sub {
97             my ($self, $ctx, $package, $options) = @_;
98             $self->add_parameterized_customizations($ctx, $package, $options)
99             if $ctx->has_parameter_signature;
100             };
101              
102             sub add_parameterized_customizations {
103 1     1 0 3 my ($self, $ctx, $package, $options) = @_;
104              
105 1         5 my $sig = PMS->signature(
106 1         30 input => "(${\$ctx->parameter_signature})",
107             from_namespace => $ctx->get_curstash_name,
108             );
109 1 50       209787 confess 'Positional parameters are not allowed in parameterized roles'
110             if $sig->has_positional_params;
111              
112             my @vars = map {
113 1 100       55 does_role($_, Placeholder)
  2 50       1009  
114             ? ()
115             : {
116             var => $_->variable_name,
117             name => $_->label,
118             tc => $_->meta_type_constraint,
119             ($_->has_default_value
120             ? (default => $_->default_value)
121             : ()),
122             },
123             } $sig->named_params;
124              
125             $ctx->add_preamble_code_parts(
126             sprintf 'my (%s) = map { $_[0]->$_ } qw(%s);',
127 2         5 join(',', map { $_->{var} } @vars),
128 1         793 join(' ', map { $_->{name} } @vars),
  2         41  
129             );
130              
131 1         3 for my $var (@vars) {
132             $ctx->add_parameter($var->{name} => {
133             is => 'ro',
134             isa => $var->{tc},
135             (exists $var->{default}
136 1     1   634 ? (default => sub { eval $var->{default} })
137 2 100       78 : ()),
138             });
139             }
140             }
141              
142             after handle_post_parsing => sub {
143             my ($self, $ctx, $package, $class) = @_;
144             return unless $ctx->has_parameter_signature;
145             $ctx->shadow(sub (&) {
146             my $meta = find_meta($class);
147             $meta->add_parameter($_->[0], %{ $_->[1] })
148             for $ctx->get_parameters;
149             $meta->role_generator($_[0]);
150             return $class;
151             });
152             };
153              
154             #pod =head1 SEE ALSO
155             #pod
156             #pod =for :list
157             #pod * L<MooseX::Declare>
158             #pod * L<MooseX::Declare::Syntax::Keyword::Class>
159             #pod * L<MooseX::Declare::Syntax::RoleApplication>
160             #pod * L<MooseX::Declare::Syntax::MooseSetup>
161             #pod
162             #pod =cut
163              
164             1;
165              
166             __END__
167              
168             =pod
169              
170             =encoding UTF-8
171              
172             =head1 NAME
173              
174             MooseX::Declare::Syntax::Keyword::Role - Role declarations
175              
176             =head1 VERSION
177              
178             version 0.43
179              
180             =head1 METHODS
181              
182             =head2 generate_export
183              
184             CodeRef Object->generate_export ()
185              
186             Returns a closure with a call to L</make_anon_metaclass>.
187              
188             =head1 CONSUMES
189              
190             =over 4
191              
192             =item *
193              
194             L<MooseX::Declare::Syntax::MooseSetup>
195              
196             =item *
197              
198             L<MooseX::Declare::Syntax::RoleApplication>
199              
200             =back
201              
202             =head1 MODIFIED METHODS
203              
204             =head2 imported_moose_symbols
205              
206             List Object->imported_moose_symbols ()
207              
208             Extends the existing L<MooseX::Declare::Syntax::MooseSetup/imported_moose_symbols>
209             with C<requires>, C<extends>, C<has>, C<inner> and C<super>.
210              
211             =head2 import_symbols_from
212              
213             Str Object->import_symbols_from ()
214              
215             Will return L<Moose::Role> instead of the default L<Moose>.
216              
217             =head2 make_anon_metaclass
218              
219             Object Object->make_anon_metaclass ()
220              
221             This will return an anonymous instance of L<Moose::Meta::Role>.
222              
223             =head1 SEE ALSO
224              
225             =over 4
226              
227             =item *
228              
229             L<MooseX::Declare>
230              
231             =item *
232              
233             L<MooseX::Declare::Syntax::Keyword::Class>
234              
235             =item *
236              
237             L<MooseX::Declare::Syntax::RoleApplication>
238              
239             =item *
240              
241             L<MooseX::Declare::Syntax::MooseSetup>
242              
243             =back
244              
245             =head1 AUTHOR
246              
247             Florian Ragwitz <rafl@debian.org>
248              
249             =head1 COPYRIGHT AND LICENSE
250              
251             This software is copyright (c) 2008 by Florian Ragwitz.
252              
253             This is free software; you can redistribute it and/or modify it under
254             the same terms as the Perl 5 programming language system itself.
255              
256             =cut