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

« back to all changes in this revision

Viewing changes to src/how/RoleToClassApplier.nqp

  • 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 -> $name {
 
37
            unless has_method($target, $name, 1) {
 
38
                nqp::die("Method '$name' collides and a resolution must be provided by the class '" ~
 
39
                    $target.HOW.name($target) ~ "'");
 
40
            }
 
41
        }
 
42
 
 
43
        # Compose in any methods.
 
44
        my @methods := $to_compose_meta.methods($to_compose);
 
45
        for @methods {
 
46
            my $name := nqp::can($_, 'name') ?? $_.name !! nqp::getcodename($_);
 
47
            unless has_method($target, $name, 0) {
 
48
                $target.HOW.add_method($target, $name, $_);
 
49
            }
 
50
        }
 
51
 
 
52
        # Compose in any role attributes.
 
53
        my @attributes := $to_compose_meta.attributes($to_compose);
 
54
        for @attributes {
 
55
            if has_attribute($target, $_.name) {
 
56
                nqp::die("Attribute '" ~ $_.name ~ "' already exists in the class '" ~
 
57
                    $target.HOW.name($target) ~  "', but a role also wishes to compose it");
 
58
            }
 
59
            $target.HOW.add_attribute($target, $_);
 
60
        }
 
61
 
 
62
        # The full list of done roles is just the list of the one role we have
 
63
        # composed in.
 
64
        # XXX TODO
 
65
        my @done;
 
66
        @done[0] := $to_compose;
 
67
    }
 
68
}