Filename | /Users/ap13/perl5/lib/perl5/darwin-2level/Moose/Meta/Role/Application/RoleSummation.pm |
Statements | Executed 20 statements in 1.69ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 22µs | 74µs | BEGIN@8 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 16µs | 34µs | BEGIN@4 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 10µs | 33µs | BEGIN@9 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 9µs | 40µs | BEGIN@13 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 9µs | 183µs | BEGIN@15 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 8µs | 14µs | BEGIN@5 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 8µs | 522µs | BEGIN@6 | Moose::Meta::Role::Application::RoleSummation::
1 | 1 | 1 | 7µs | 7µs | BEGIN@11 | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | __ANON__[:19] | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | __ANON__[:273] | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | __ANON__[:283] | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | __ANON__[:308] | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | apply_attributes | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | apply_method_modifiers | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | apply_methods | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | apply_overloading | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | apply_override_method_modifiers | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | check_required_attributes | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | check_required_methods | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | check_role_exclusions | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | get_exclusions_for_role | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | get_method_aliases_for_role | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | is_aliased_method | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | is_method_aliased | Moose::Meta::Role::Application::RoleSummation::
0 | 0 | 0 | 0s | 0s | is_method_excluded | Moose::Meta::Role::Application::RoleSummation::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Moose::Meta::Role::Application::RoleSummation; | ||||
2 | 1 | 700ns | our $VERSION = '2.1403'; | ||
3 | |||||
4 | 2 | 26µs | 2 | 51µs | # spent 34µs (16+17) within Moose::Meta::Role::Application::RoleSummation::BEGIN@4 which was called:
# once (16µs+17µs) by Moose::BEGIN@35 at line 4 # spent 34µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@4
# spent 17µs making 1 call to strict::import |
5 | 2 | 22µs | 2 | 20µs | # spent 14µs (8+6) within Moose::Meta::Role::Application::RoleSummation::BEGIN@5 which was called:
# once (8µs+6µs) by Moose::BEGIN@35 at line 5 # spent 14µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@5
# spent 6µs making 1 call to warnings::import |
6 | 2 | 35µs | 2 | 1.04ms | # spent 522µs (8+514) within Moose::Meta::Role::Application::RoleSummation::BEGIN@6 which was called:
# once (8µs+514µs) by Moose::BEGIN@35 at line 6 # spent 522µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@6
# spent 514µs making 1 call to metaclass::import |
7 | |||||
8 | 3 | 49µs | 3 | 99µs | # spent 74µs (22+52) within Moose::Meta::Role::Application::RoleSummation::BEGIN@8 which was called:
# once (22µs+52µs) by Moose::BEGIN@35 at line 8 # spent 74µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@8
# spent 12µs making 1 call to UNIVERSAL::VERSION
# spent 12µs making 1 call to List::Util::import |
9 | 2 | 26µs | 2 | 57µs | # spent 33µs (10+24) within Moose::Meta::Role::Application::RoleSummation::BEGIN@9 which was called:
# once (10µs+24µs) by Moose::BEGIN@35 at line 9 # spent 33µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@9
# spent 24µs making 1 call to Exporter::import |
10 | |||||
11 | 2 | 28µs | 1 | 7µs | # spent 7µs within Moose::Meta::Role::Application::RoleSummation::BEGIN@11 which was called:
# once (7µs+0s) by Moose::BEGIN@35 at line 11 # spent 7µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@11 |
12 | |||||
13 | 2 | 34µs | 2 | 70µs | # spent 40µs (9+31) within Moose::Meta::Role::Application::RoleSummation::BEGIN@13 which was called:
# once (9µs+31µs) by Moose::BEGIN@35 at line 13 # spent 40µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@13
# spent 30µs making 1 call to parent::import |
14 | |||||
15 | 2 | 1.45ms | 2 | 358µs | # spent 183µs (9+174) within Moose::Meta::Role::Application::RoleSummation::BEGIN@15 which was called:
# once (9µs+174µs) by Moose::BEGIN@35 at line 15 # spent 183µs making 1 call to Moose::Meta::Role::Application::RoleSummation::BEGIN@15
# spent 174µs making 1 call to Sub::Exporter::__ANON__[Sub/Exporter.pm:337] |
16 | |||||
17 | __PACKAGE__->meta->add_attribute('role_params' => ( | ||||
18 | reader => 'role_params', | ||||
19 | default => sub { {} }, | ||||
20 | 1 | 8µs | 3 | 407µs | Class::MOP::_definition_context(), # spent 381µs making 1 call to Class::MOP::Mixin::HasAttributes::add_attribute
# spent 19µs making 1 call to Moose::Meta::Role::Application::RoleSummation::meta
# spent 6µs making 1 call to Class::MOP::_definition_context |
21 | )); | ||||
22 | |||||
23 | sub get_exclusions_for_role { | ||||
24 | my ($self, $role) = @_; | ||||
25 | $role = $role->name if blessed $role; | ||||
26 | my $excludes_key = exists $self->role_params->{$role}->{'-excludes'} ? | ||||
27 | '-excludes' : 'excludes'; | ||||
28 | if ($self->role_params->{$role} && defined $self->role_params->{$role}->{$excludes_key}) { | ||||
29 | if (ref $self->role_params->{$role}->{$excludes_key} eq 'ARRAY') { | ||||
30 | return $self->role_params->{$role}->{$excludes_key}; | ||||
31 | } | ||||
32 | return [ $self->role_params->{$role}->{$excludes_key} ]; | ||||
33 | } | ||||
34 | return []; | ||||
35 | } | ||||
36 | |||||
37 | sub get_method_aliases_for_role { | ||||
38 | my ($self, $role) = @_; | ||||
39 | $role = $role->name if blessed $role; | ||||
40 | my $alias_key = exists $self->role_params->{$role}->{'-alias'} ? | ||||
41 | '-alias' : 'alias'; | ||||
42 | if ($self->role_params->{$role} && defined $self->role_params->{$role}->{$alias_key}) { | ||||
43 | return $self->role_params->{$role}->{$alias_key}; | ||||
44 | } | ||||
45 | return {}; | ||||
46 | } | ||||
47 | |||||
48 | sub is_method_excluded { | ||||
49 | my ($self, $role, $method_name) = @_; | ||||
50 | foreach ($self->get_exclusions_for_role($role->name)) { | ||||
51 | return 1 if $_ eq $method_name; | ||||
52 | } | ||||
53 | return 0; | ||||
54 | } | ||||
55 | |||||
56 | sub is_method_aliased { | ||||
57 | my ($self, $role, $method_name) = @_; | ||||
58 | exists $self->get_method_aliases_for_role($role->name)->{$method_name} ? 1 : 0 | ||||
59 | } | ||||
60 | |||||
61 | sub is_aliased_method { | ||||
62 | my ($self, $role, $method_name) = @_; | ||||
63 | my %aliased_names = reverse %{$self->get_method_aliases_for_role($role->name)}; | ||||
64 | exists $aliased_names{$method_name} ? 1 : 0; | ||||
65 | } | ||||
66 | |||||
67 | sub check_role_exclusions { | ||||
68 | my ($self, $c) = @_; | ||||
69 | |||||
70 | my %excluded_roles; | ||||
71 | for my $role (@{ $c->get_roles }) { | ||||
72 | my $name = $role->name; | ||||
73 | |||||
74 | for my $excluded ($role->get_excluded_roles_list) { | ||||
75 | push @{ $excluded_roles{$excluded} }, $name; | ||||
76 | } | ||||
77 | } | ||||
78 | |||||
79 | foreach my $role (@{$c->get_roles}) { | ||||
80 | foreach my $excluded (keys %excluded_roles) { | ||||
81 | next unless $role->does_role($excluded); | ||||
82 | |||||
83 | my @excluding = @{ $excluded_roles{$excluded} }; | ||||
84 | |||||
85 | throw_exception( RoleExclusionConflict => roles => \@excluding, | ||||
86 | role_name => $excluded | ||||
87 | ); | ||||
88 | } | ||||
89 | } | ||||
90 | |||||
91 | $c->add_excluded_roles(keys %excluded_roles); | ||||
92 | } | ||||
93 | |||||
94 | sub check_required_methods { | ||||
95 | my ($self, $c) = @_; | ||||
96 | |||||
97 | my %all_required_methods = | ||||
98 | map { $_->name => $_ } | ||||
99 | map { $_->get_required_method_list } | ||||
100 | @{$c->get_roles}; | ||||
101 | |||||
102 | foreach my $role (@{$c->get_roles}) { | ||||
103 | foreach my $required (keys %all_required_methods) { | ||||
104 | |||||
105 | delete $all_required_methods{$required} | ||||
106 | if $role->has_method($required) | ||||
107 | || $self->is_aliased_method($role, $required); | ||||
108 | } | ||||
109 | } | ||||
110 | |||||
111 | $c->add_required_methods(values %all_required_methods); | ||||
112 | } | ||||
113 | |||||
114 | sub check_required_attributes { | ||||
115 | |||||
116 | } | ||||
117 | |||||
118 | sub apply_attributes { | ||||
119 | my ($self, $c) = @_; | ||||
120 | |||||
121 | my @all_attributes; | ||||
122 | |||||
123 | for my $role ( @{ $c->get_roles } ) { | ||||
124 | push @all_attributes, | ||||
125 | map { $role->get_attribute($_) } $role->get_attribute_list; | ||||
126 | } | ||||
127 | |||||
128 | my %seen; | ||||
129 | foreach my $attr (@all_attributes) { | ||||
130 | my $name = $attr->name; | ||||
131 | |||||
132 | if ( exists $seen{$name} ) { | ||||
133 | next if $seen{$name}->is_same_as($attr); | ||||
134 | |||||
135 | my $role1 = $seen{$name}->associated_role->name; | ||||
136 | my $role2 = $attr->associated_role->name; | ||||
137 | |||||
138 | throw_exception( AttributeConflictInSummation => attribute_name => $name, | ||||
139 | role_name => $role1, | ||||
140 | second_role_name => $role2, | ||||
141 | ); | ||||
142 | } | ||||
143 | |||||
144 | $seen{$name} = $attr; | ||||
145 | } | ||||
146 | |||||
147 | foreach my $attr (@all_attributes) { | ||||
148 | $c->add_attribute( $attr->clone ); | ||||
149 | } | ||||
150 | } | ||||
151 | |||||
152 | sub apply_methods { | ||||
153 | my ($self, $c) = @_; | ||||
154 | |||||
155 | my @all_methods = map { | ||||
156 | my $role = $_; | ||||
157 | my $aliases = $self->get_method_aliases_for_role($role); | ||||
158 | my %excludes = map { $_ => undef } @{ $self->get_exclusions_for_role($role) }; | ||||
159 | ( | ||||
160 | (map { | ||||
161 | exists $excludes{$_} ? () : | ||||
162 | +{ | ||||
163 | role => $role, | ||||
164 | name => $_, | ||||
165 | method => $role->get_method($_), | ||||
166 | } | ||||
167 | } map { $_->name } | ||||
168 | grep { !$_->isa('Class::MOP::Method::Meta') } | ||||
169 | $role->_get_local_methods), | ||||
170 | (map { | ||||
171 | +{ | ||||
172 | role => $role, | ||||
173 | name => $aliases->{$_}, | ||||
174 | method => $role->get_method($_), | ||||
175 | } | ||||
176 | } keys %$aliases) | ||||
177 | ); | ||||
178 | } @{$c->get_roles}; | ||||
179 | |||||
180 | my (%seen, %conflicts, %method_map); | ||||
181 | foreach my $method (@all_methods) { | ||||
182 | next if $conflicts{$method->{name}}; | ||||
183 | my $seen = $seen{$method->{name}}; | ||||
184 | |||||
185 | if ($seen) { | ||||
186 | if ($seen->{method}->body != $method->{method}->body) { | ||||
187 | $c->add_conflicting_method( | ||||
188 | name => $method->{name}, | ||||
189 | roles => [$method->{role}->name, $seen->{role}->name], | ||||
190 | ); | ||||
191 | |||||
192 | delete $method_map{$method->{name}}; | ||||
193 | $conflicts{$method->{name}} = 1; | ||||
194 | next; | ||||
195 | } | ||||
196 | } | ||||
197 | |||||
198 | $seen{$method->{name}} = $method; | ||||
199 | $method_map{$method->{name}} = $method->{method}; | ||||
200 | } | ||||
201 | |||||
202 | $c->add_method($_ => $method_map{$_}) for keys %method_map; | ||||
203 | } | ||||
204 | |||||
205 | sub apply_override_method_modifiers { | ||||
206 | my ($self, $c) = @_; | ||||
207 | |||||
208 | my @all_overrides = map { | ||||
209 | my $role = $_; | ||||
210 | map { | ||||
211 | +{ | ||||
212 | name => $_, | ||||
213 | method => $role->get_override_method_modifier($_), | ||||
214 | } | ||||
215 | } $role->get_method_modifier_list('override'); | ||||
216 | } @{$c->get_roles}; | ||||
217 | |||||
218 | my %seen; | ||||
219 | foreach my $override (@all_overrides) { | ||||
220 | my @role_names = map { $_->name } @{$c->get_roles}; | ||||
221 | if ( $c->has_method($override->{name}) ){ | ||||
222 | throw_exception( OverrideConflictInSummation => role_names => \@role_names, | ||||
223 | role_application => $self, | ||||
224 | method_name => $override->{name} | ||||
225 | ); | ||||
226 | } | ||||
227 | if (exists $seen{$override->{name}}) { | ||||
228 | if ( $seen{$override->{name}} != $override->{method} ) { | ||||
229 | throw_exception( OverrideConflictInSummation => role_names => \@role_names, | ||||
230 | role_application => $self, | ||||
231 | method_name => $override->{name}, | ||||
232 | two_overrides_found => 1 | ||||
233 | ); | ||||
234 | } | ||||
235 | } | ||||
236 | $seen{$override->{name}} = $override->{method}; | ||||
237 | } | ||||
238 | |||||
239 | $c->add_override_method_modifier( | ||||
240 | $_->{name}, $_->{method} | ||||
241 | ) for @all_overrides; | ||||
242 | |||||
243 | } | ||||
244 | |||||
245 | sub apply_method_modifiers { | ||||
246 | my ($self, $modifier_type, $c) = @_; | ||||
247 | my $add = "add_${modifier_type}_method_modifier"; | ||||
248 | my $get = "get_${modifier_type}_method_modifiers"; | ||||
249 | foreach my $role (@{$c->get_roles}) { | ||||
250 | foreach my $method_name ($role->get_method_modifier_list($modifier_type)) { | ||||
251 | $c->$add( | ||||
252 | $method_name, | ||||
253 | $_ | ||||
254 | ) foreach $role->$get($method_name); | ||||
255 | } | ||||
256 | } | ||||
257 | } | ||||
258 | |||||
259 | sub apply_overloading { | ||||
260 | my ( $self, $c ) = @_; | ||||
261 | |||||
262 | my @overloaded_roles = grep { $_->is_overloaded } @{ $c->get_roles }; | ||||
263 | return unless @overloaded_roles; | ||||
264 | |||||
265 | my %fallback; | ||||
266 | for my $role (@overloaded_roles) { | ||||
267 | $fallback{ $role->name } = $role->get_overload_fallback_value; | ||||
268 | } | ||||
269 | |||||
270 | for my $role_name ( keys %fallback ) { | ||||
271 | for my $other_role_name ( grep { $_ ne $role_name } keys %fallback ) { | ||||
272 | my @fb_values = @fallback{ $role_name, $other_role_name }; | ||||
273 | if ( all {defined} @fb_values ) { | ||||
274 | next if $fallback{$role_name} eq $fallback{$other_role_name}; | ||||
275 | throw_exception( | ||||
276 | 'OverloadConflictInSummation', | ||||
277 | role_names => [ $role_name, $other_role_name ], | ||||
278 | role_application => $self, | ||||
279 | overloaded_op => 'fallback', | ||||
280 | ); | ||||
281 | } | ||||
282 | |||||
283 | next if all { !defined } @fb_values; | ||||
284 | throw_exception( | ||||
285 | 'OverloadConflictInSummation', | ||||
286 | role_names => [ $role_name, $other_role_name ], | ||||
287 | role_application => $self, | ||||
288 | overloaded_op => 'fallback', | ||||
289 | ); | ||||
290 | } | ||||
291 | } | ||||
292 | |||||
293 | if ( keys %fallback ) { | ||||
294 | $c->set_overload_fallback_value( ( values %fallback )[0] ); | ||||
295 | } | ||||
296 | |||||
297 | my %overload_map; | ||||
298 | for my $role (@overloaded_roles) { | ||||
299 | for my $overload ( $role->get_all_overloaded_operators ) { | ||||
300 | $overload_map{ $overload->operator }{ $role->name } = $overload; | ||||
301 | } | ||||
302 | } | ||||
303 | |||||
304 | for my $op_name ( keys %overload_map ) { | ||||
305 | my @roles = keys %{ $overload_map{$op_name} }; | ||||
306 | my $overload = $overload_map{$op_name}{ $roles[0] }; | ||||
307 | |||||
308 | if ( @roles > 1 && !all { $overload->_is_equal_to($_) } | ||||
309 | values %{ $overload_map{$op_name} } ) { | ||||
310 | |||||
311 | throw_exception( | ||||
312 | 'OverloadConflictInSummation', | ||||
313 | role_names => [ @roles[ 0, 1 ] ], | ||||
314 | role_application => $self, | ||||
315 | overloaded_op => $op_name, | ||||
316 | ); | ||||
317 | } | ||||
318 | |||||
319 | $c->add_overloaded_operator( | ||||
320 | $op_name => $overload_map{$op_name}{ $roles[0] } ); | ||||
321 | } | ||||
322 | } | ||||
323 | |||||
324 | 1 | 7µs | 1; | ||
325 | |||||
326 | # ABSTRACT: Combine two or more roles | ||||
327 | |||||
328 | __END__ |