| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Attribute::Final; |
|
2
|
1
|
|
|
1
|
|
37057
|
use 5.006; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
42
|
|
|
3
|
1
|
|
|
1
|
|
4
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
69
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
88
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '1.3'; |
|
6
|
|
|
|
|
|
|
our %marked; |
|
7
|
|
|
|
|
|
|
my @all_packages; |
|
8
|
1
|
|
|
1
|
|
6
|
use B qw(svref_2object); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
114
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub fill_packages { |
|
11
|
1
|
|
|
1
|
|
5
|
no strict 'refs'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
152
|
|
|
12
|
179
|
|
|
179
|
0
|
259
|
my $root = shift; |
|
13
|
179
|
|
|
|
|
189
|
my @subs = grep s/::$//, keys %{$root."::"}; |
|
|
179
|
|
|
|
|
3303
|
|
|
14
|
179
|
|
|
|
|
462
|
push @all_packages, $root; |
|
15
|
179
|
|
|
|
|
458
|
for (@subs) { |
|
16
|
179
|
100
|
100
|
|
|
487
|
next if $root eq "main" and $_ eq "main"; # Loop |
|
17
|
178
|
|
|
|
|
531
|
fill_packages($root."::".$_); |
|
18
|
|
|
|
|
|
|
} |
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub check { |
|
22
|
1
|
|
|
1
|
|
4
|
no strict 'refs'; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
252
|
|
|
23
|
2
|
100
|
|
2
|
0
|
1257
|
fill_packages("main") unless @all_packages; |
|
24
|
2
|
|
|
|
|
8
|
for my $derived_pack (@all_packages) { |
|
25
|
210
|
100
|
|
|
|
222
|
next unless @{$derived_pack."::ISA"}; |
|
|
210
|
|
|
|
|
2533
|
|
|
26
|
74
|
|
|
|
|
137
|
for my $marked_pack (keys %marked) { |
|
27
|
74
|
100
|
|
|
|
1079
|
next unless $derived_pack->isa($marked_pack); |
|
28
|
2
|
|
|
|
|
4
|
for my $meth (@{$marked{$marked_pack}}) { |
|
|
2
|
|
|
|
|
7
|
|
|
29
|
2
|
|
|
|
|
3
|
my $glob_ref = \*{$derived_pack."::".$meth}; |
|
|
2
|
|
|
|
|
10
|
|
|
30
|
2
|
100
|
|
|
|
3
|
if (*{$glob_ref}{CODE}) { |
|
|
2
|
|
|
|
|
12
|
|
|
31
|
1
|
|
|
|
|
5
|
my $name = $marked_pack."::".$meth; |
|
32
|
1
|
|
|
|
|
10
|
my $b = svref_2object($glob_ref); |
|
33
|
1
|
|
|
|
|
17
|
die "Cannot override final method $name at ". |
|
34
|
|
|
|
|
|
|
$b->FILE. ", line ".$b->LINE."\n"; |
|
35
|
|
|
|
|
|
|
} |
|
36
|
|
|
|
|
|
|
} |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
} |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
1
|
|
|
1
|
|
11
|
CHECK { Attribute::Final->check() } |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
package UNIVERSAL; |
|
44
|
1
|
|
|
1
|
|
1853
|
use Attribute::Handlers; |
|
|
1
|
|
|
|
|
6843
|
|
|
|
1
|
|
|
|
|
7
|
|
|
45
|
|
|
|
|
|
|
sub final :ATTR(CODE) { |
|
46
|
1
|
|
|
1
|
0
|
6752
|
my ($pack, $ref) = @_; |
|
47
|
1
|
|
|
|
|
2
|
push @{$marked{$pack}}, *{$ref}{NAME}; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
4
|
|
|
48
|
1
|
|
|
1
|
|
90
|
} |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
# Preloaded methods go here. |
|
51
|
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
1; |
|
53
|
|
|
|
|
|
|
__END__ |