1
class Attribute is Any;
11
method new(:$name, :$type, :$build, :$has_accessor, :$rw, :$handles) {
12
my $attr := pir::new__PS('Attribute');
13
pir::setattribute__vPSP($attr, '$!name', $name);
14
pir::setattribute__vPSP($attr, '$!type', $type);
15
pir::setattribute__vPSP($attr, '$!build', $build);
16
pir::setattribute__vPSP($attr, '$!has_accessor', $has_accessor);
17
pir::setattribute__vPSP($attr, '$!rw', $rw);
18
pir::setattribute__vPSP($attr, '$!handles', $handles);
34
method has_accessor() {
39
$!rw ?? Bool::True !! Bool::False
50
method apply_traits($metaclass, $container) {
52
my $decl := AttributeDeclarand.new(
53
container => $container,
57
$!trait_applier($decl);
61
method compose($package) {
64
# Generate an accessor, if we need one.
66
# Accessor helper subs. We make sure they are surrounded
67
# by annotations to make the backtrace printer ignore them,
68
# or otherwise we get line numbers from this file, which is
69
# totally useless to the dear programmer trying to debug their
71
sub dummy_1() { Q:PIR { .annotate 'invizible_frame', 1 }; }
72
sub accessor_helper_ro($self) {
73
pir::new__PsP('Perl6Scalar', pir::getattribute__PPS($self, $name))
75
sub accessor_helper_rw($self) {
76
pir::getattribute__PPS($self, $name)
78
sub dummy_2() { Q:PIR { .annotate 'invizible_frame', 0 }; }
80
# XXX check there isn't already one...
82
# Decide whether we want an rw one or not.
83
my $is_rw := pir::defined($!rw) ?? $!rw !!
84
pir::can__ips($package, 'rw') ?? $package.rw !! 0;
85
my $meth := pir::find_lex__ps($is_rw ?? 'accessor_helper_rw' !! 'accessor_helper_ro');
86
$meth := pir::clone($meth);
88
# introspection looks at the actual sub name, so set it
89
# to the value the user expects
90
# set $P0, $S0 is parrot's clunky PIR API for setting the sub name.
91
my $meth_name := pir::substr__SSi($name, 2);
92
pir::set__vps($meth, $meth_name);
93
$package.add_method($package, $meth_name, $meth);
96
# If we've a handles, pass it along to the handles setup helper.
97
unless pir::isa__ips($!handles, 'Undef') {
98
Rakudo::Guts.add_handles_method($package, $!name, $!handles);