line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Perl6::Export::Attrs; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
33850
|
use version; $VERSION = qv('0.0.3'); |
|
1
|
|
|
|
|
3657
|
|
|
1
|
|
|
|
|
7
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
101
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
38
|
|
6
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
13
|
|
|
1
|
|
|
|
|
31
|
|
7
|
1
|
|
|
1
|
|
6
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
211
|
|
8
|
1
|
|
|
1
|
|
1602
|
use Attribute::Handlers; |
|
1
|
|
|
|
|
8933
|
|
|
1
|
|
|
|
|
7
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub import { |
11
|
1
|
|
|
1
|
|
12
|
my $caller = caller; |
12
|
1
|
|
|
1
|
|
59
|
no strict 'refs'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
627
|
|
13
|
1
|
|
|
|
|
3
|
*{$caller.'::import'} = \&_generic_import; |
|
1
|
|
|
|
|
16
|
|
14
|
1
|
|
|
|
|
2
|
*{$caller.'::MODIFY_CODE_ATTRIBUTES'} = \&_generic_MCA; |
|
1
|
|
|
|
|
7
|
|
15
|
1
|
|
|
|
|
11
|
return; |
16
|
|
|
|
|
|
|
} |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
my %tagsets_for; |
19
|
|
|
|
|
|
|
my %is_exported_from; |
20
|
|
|
|
|
|
|
my %named_tagsets_for; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
my $IDENT = '[^\W\d]\w*'; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
sub _generic_MCA { |
25
|
0
|
|
|
0
|
|
|
my ($package, $referent, @attrs) = @_; |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
ATTR: |
28
|
0
|
|
|
|
|
|
for my $attr (@attrs) { |
29
|
|
|
|
|
|
|
|
30
|
0
|
0
|
0
|
|
|
|
($attr||=q{}) =~ s/\A Export (?: \( (.*) \) )? \z/$1||q{}/exms |
|
0
|
0
|
|
|
|
|
|
31
|
|
|
|
|
|
|
or next ATTR; |
32
|
|
|
|
|
|
|
|
33
|
0
|
|
|
|
|
|
my @tagsets = grep {length $_} split m/ \s+,?\s* | ,\s* /xms, $attr; |
|
0
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
0
|
|
|
|
|
|
my (undef, $file, $line) = caller(); |
36
|
0
|
|
|
|
|
|
$file =~ s{.*/}{}xms; |
37
|
|
|
|
|
|
|
|
38
|
0
|
0
|
|
|
|
|
if (my @bad_tags = grep {!m/\A :$IDENT \z/xms} @tagsets) { |
|
0
|
|
|
|
|
|
|
39
|
0
|
0
|
|
|
|
|
die 'Bad tagset', |
40
|
|
|
|
|
|
|
(@bad_tags==1?' ':'s '), |
41
|
|
|
|
|
|
|
"in :Export attribute at '$file' line $line: [@bad_tags]\n"; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
0
|
|
0
|
|
|
|
my $tagsets = $tagsets_for{$package} ||= {}; |
45
|
|
|
|
|
|
|
|
46
|
0
|
|
|
|
|
|
for my $tagset (@tagsets) { |
47
|
0
|
|
|
|
|
|
push @{ $tagsets->{$tagset} }, $referent; |
|
0
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
} |
49
|
0
|
|
|
|
|
|
push @{ $tagsets->{':ALL'} }, $referent; |
|
0
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
51
|
0
|
|
|
|
|
|
$is_exported_from{$package}{$referent} = 1; |
52
|
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
undef $attr |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
0
|
|
|
|
|
|
return grep {defined $_} @attrs; |
|
0
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub _invert_tagset { |
60
|
0
|
|
|
0
|
|
|
my ($package, $tagset) = @_; |
61
|
0
|
|
|
|
|
|
my %inverted_tagset; |
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
for my $tag (keys %{$tagset}) { |
|
0
|
|
|
|
|
|
|
64
|
0
|
|
|
|
|
|
for my $sub_ref (@{$tagset->{$tag}}) { |
|
0
|
|
|
|
|
|
|
65
|
0
|
0
|
|
|
|
|
my $sym = Attribute::Handlers::findsym($package, $sub_ref, 'CODE') |
66
|
|
|
|
|
|
|
or die "Internal error: missing symbol for $sub_ref"; |
67
|
0
|
|
|
|
|
|
$inverted_tagset{$tag}{*{$sym}{NAME}} = $sub_ref;; |
|
0
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
0
|
|
|
|
|
|
return \%inverted_tagset; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# Reusable import() subroutine for all packages... |
75
|
|
|
|
|
|
|
sub _generic_import { |
76
|
0
|
|
|
0
|
|
|
my $package = shift; |
77
|
|
|
|
|
|
|
|
78
|
0
|
|
0
|
|
|
|
my $tagset |
79
|
|
|
|
|
|
|
= $named_tagsets_for{$package} |
80
|
|
|
|
|
|
|
||= _invert_tagset($package, $tagsets_for{$package}); |
81
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
my $is_exported = $is_exported_from{$package}; |
83
|
|
|
|
|
|
|
|
84
|
0
|
|
|
|
|
|
my $errors; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my %request; |
87
|
0
|
|
|
|
|
|
my @pass_on_list; |
88
|
0
|
|
|
|
|
|
my $subs_ref; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
REQUEST: |
91
|
0
|
|
|
|
|
|
for my $request (@_) { |
92
|
0
|
0
|
0
|
|
|
|
if (my ($sub_name) = $request =~ m/\A &? ($IDENT) (?:\(\))? \z/xms) { |
|
|
0
|
|
|
|
|
|
93
|
0
|
0
|
|
|
|
|
next REQUEST if exists $request{$sub_name}; |
94
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
35
|
|
95
|
1
|
|
|
1
|
|
5
|
no warnings 'once'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
158
|
|
96
|
0
|
0
|
|
|
|
|
if (my $sub_ref = *{$package.'::'.$sub_name}{CODE}) { |
|
0
|
|
|
|
|
|
|
97
|
0
|
0
|
|
|
|
|
if ($is_exported->{$sub_ref}) { |
98
|
0
|
|
|
|
|
|
$request{$sub_name} = $sub_ref; |
99
|
0
|
|
|
|
|
|
next REQUEST; |
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
elsif ($request =~ m/\A :$IDENT \z/xms |
104
|
|
|
|
|
|
|
and $subs_ref = $tagset->{$request}) { |
105
|
0
|
|
|
|
|
|
@request{keys %{$subs_ref}} = values %{$subs_ref}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
next REQUEST; |
107
|
|
|
|
|
|
|
} |
108
|
0
|
|
|
|
|
|
$errors .= " $request"; |
109
|
0
|
|
|
|
|
|
push @pass_on_list, $request; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
# Report unexportable requests... |
113
|
0
|
|
|
|
|
|
my $real_import = do{ |
114
|
1
|
|
|
1
|
|
6
|
no strict 'refs'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
34
|
|
115
|
1
|
|
|
1
|
|
5
|
no warnings 'once'; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
164
|
|
116
|
0
|
|
|
|
|
|
*{$package.'::IMPORT'}{CODE}; |
|
0
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
}; |
118
|
0
|
0
|
0
|
|
|
|
croak "$package does not export:$errors\nuse $package failed" |
119
|
|
|
|
|
|
|
if $errors && !$real_import; |
120
|
|
|
|
|
|
|
|
121
|
0
|
0
|
|
|
|
|
if (!@_) { |
122
|
0
|
|
0
|
|
|
|
%request = %{$tagset->{':DEFAULT'}||={}} |
|
0
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
0
|
|
0
|
|
|
|
my $mandatory = $tagset->{':MANDATORY'} ||= {}; |
126
|
0
|
|
|
|
|
|
@request{ keys %{$mandatory} } = values %{$mandatory}; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
|
128
|
0
|
|
|
|
|
|
my $caller = caller; |
129
|
0
|
|
|
|
|
|
for my $sub_name (keys %request) { |
130
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
103
|
|
131
|
0
|
|
|
|
|
|
*{$caller.'::'.$sub_name} = $request{$sub_name}; |
|
0
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
0
|
0
|
|
|
|
|
goto &{$real_import} if $real_import; |
|
0
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
return; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
139
|
|
|
|
|
|
|
__END__ |