~ubuntu-branches/ubuntu/vivid/nqp/vivid-proposed

« back to all changes in this revision

Viewing changes to src/how/RoleToClassApplier.pm

  • Committer: Package Import Robot
  • Author(s): Alessandro Ghedini
  • Date: 2013-11-01 12:09:18 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20131101120918-kx51sl0sxl3exsxi
Tags: 2013.10-1
* New upstream release
* Bump versioned (Build-)Depends on parrot
* Update patches
* Install new README.pod
* Fix vcs-field-not-canonical
* Do not install rubyish examples
* Do not Depends on parrot-devel anymore
* Add 07_disable-serialization-tests.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
knowhow RoleToClassApplier {
2
 
 
3
 
    sub has_method($target, $name, $local) {
4
 
        my %mt := $target.HOW.method_table($target);
5
 
        nqp::existskey(%mt, $name);
6
 
    }
7
 
 
8
 
    sub has_attribute($target, $name) {
9
 
        my @attributes := $target.HOW.attributes($target, :local(1));
10
 
        for @attributes {
11
 
            if $_.name eq $name { return 1; }
12
 
        }
13
 
        return 0;
14
 
    }
15
 
 
16
 
    method apply($target, @roles) {
17
 
        # If we have many things to compose, then get them into a single helper
18
 
        # role first.
19
 
        my $to_compose;
20
 
        my $to_compose_meta;
21
 
        if nqp::elems(@roles) == 1 {
22
 
            $to_compose := @roles[0];
23
 
            $to_compose_meta := $to_compose.HOW;
24
 
        }
25
 
        else {
26
 
            $to_compose := NQPConcreteRoleHOW.new_type(:instance_of(NQPMu));
27
 
            $to_compose_meta := $to_compose.HOW;
28
 
            for @roles {
29
 
                $to_compose_meta.add_role($to_compose, $_);
30
 
            }
31
 
            $to_compose := $to_compose_meta.compose($to_compose);
32
 
        }
33
 
 
34
 
        # Collisions?
35
 
        my @collisions := $to_compose_meta.collisions($to_compose);
36
 
        for @collisions {
37
 
            my $name := nqp::can($_, 'name') ?? $_.name !! nqp::getcodename($_);
38
 
            unless has_method($target, $name, 1) {
39
 
                nqp::die("Method '$name' collides and a resolution must be provided by the class '" ~
40
 
                    $target.HOW.name($target) ~ "'");
41
 
            }
42
 
        }
43
 
 
44
 
        # Compose in any methods.
45
 
        my @methods := $to_compose_meta.methods($to_compose);
46
 
        for @methods {
47
 
            my $name := nqp::can($_, 'name') ?? $_.name !! nqp::getcodename($_);
48
 
            unless has_method($target, $name, 0) {
49
 
                $target.HOW.add_method($target, $name, $_);
50
 
            }
51
 
        }
52
 
 
53
 
        # Compose in any role attributes.
54
 
        my @attributes := $to_compose_meta.attributes($to_compose);
55
 
        for @attributes {
56
 
            if has_attribute($target, $_.name) {
57
 
                nqp::die("Attribute '" ~ $_.name ~ "' already exists in the class '" ~
58
 
                    $target.HOW.name($target) ~  "', but a role also wishes to compose it");
59
 
            }
60
 
            $target.HOW.add_attribute($target, $_);
61
 
        }
62
 
 
63
 
        # The full list of done roles is just the list of the one role we have
64
 
        # composed in.
65
 
        # XXX TODO
66
 
        my @done;
67
 
        @done[0] := $to_compose;
68
 
    }
69
 
}