5
Perl6::Metamodel::RoleToRoleApplier
9
Applies roles to another role.
15
=item apply(target, composees)
17
Applies all of the composees to target.
21
class Perl6::Metamodel::RoleToRoleApplier;
23
method apply($target, @composees) {
24
# Aggregate all of the methods sharing names.
27
my @methods := $_.HOW.methods($_);
32
if pir::defined(%meth_info{$name}) {
33
@meth_list := %meth_info{$name};
36
%meth_info{$name} := @meth_list;
45
@meth_list.push($meth);
50
# Also need methods of target.
52
my @target_meths := $target.HOW.methods($target);
54
%target_meth_info{~$_} := $_;
57
# Process method list.
60
my @add_meths := %meth_info{$name};
62
# Do we already have a method of this name? If so, ignore all of the
63
# methods we have from elsewhere unless it's multi.
64
if pir::defined(%target_meth_info{$name}) {
65
if %target_meth_info{$name}.multi {
68
$target.HOW.add_method($target, $name, $_);
73
# No methods in the target role. If only one, it's easy...
75
$target.HOW.add_method($target, $name, @add_meths[0]);
78
# More than one - add to collisions list unless all multi.
81
if $_.multi { $num_multi := $num_multi + 1; }
83
if +@add_meths == $num_multi {
85
$target.HOW.add_method($target, $name, $_);
89
$target.HOW.add_collision($target, $name);
95
# Now do the other bits.
100
# Compose is any attributes, unless there's a conflict.
101
my @attributes := $how.attributes($_);
105
my @cur_attrs := $target.HOW.attributes($target, :local(1));
107
if $_ =:= $add_attr {
111
if $_.name eq $add_attr.name {
112
pir::die("Attribute '" ~ $_.name ~ "' conflicts in role composition");
117
$target.HOW.add_attribute($target, $add_attr);
121
# Pass along any requirements.
122
my @requirements := $how.requirements($_);
124
$target.HOW.add_requirement($target, $_);
127
# Pass along any parents.
128
my @parents := $how.parents($_);
130
$target.HOW.add_parent($target, $_);
133
# Build up full list.
134
my @composees := $how.composees($_, :transitive(1));
136
@all_composees.push($_);
140
return @all_composees;