line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Fukurama::Class::Attributes;
|
2
|
4
|
|
|
4
|
|
28547
|
use Fukurama::Class::Version(0.01);
|
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
27
|
|
3
|
4
|
|
|
4
|
|
23
|
use Fukurama::Class::Rigid;
|
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
25
|
|
4
|
4
|
|
|
4
|
|
19
|
use Fukurama::Class::Carp;
|
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
31
|
|
5
|
|
|
|
|
|
|
|
6
|
4
|
|
|
4
|
|
650
|
use Fukurama::Class::Tree();
|
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
80
|
|
7
|
4
|
|
|
4
|
|
2329
|
use Fukurama::Class::AttributesHandler();
|
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
76
|
|
8
|
4
|
|
|
4
|
|
2631
|
use Fukurama::Class::Attributes::OOStandard();
|
|
4
|
|
|
|
|
15
|
|
|
4
|
|
|
|
|
129
|
|
9
|
4
|
|
|
4
|
|
1046
|
use Fukurama::Class::Extends();
|
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
75
|
|
10
|
4
|
|
|
4
|
|
763
|
use Fukurama::Class::Implements();
|
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
348
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our $LEVEL_CHECK_NONE = 0;
|
13
|
|
|
|
|
|
|
our $LEVEL_CHECK_ALL = 1;
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $CHECK_LEVEL = $LEVEL_CHECK_ALL;
|
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
my $INIT;
|
18
|
|
|
|
|
|
|
my $REGISTERED_ATTRIBUTE_HANDLER;
|
19
|
|
|
|
|
|
|
my $REGISTERED_CLASSES;
|
20
|
|
|
|
|
|
|
my $INHERITATION_CHECK_SUBS;
|
21
|
|
|
|
|
|
|
my $INHERIT_METHOD_NAME;
|
22
|
|
|
|
|
|
|
BEGIN {
|
23
|
4
|
|
|
4
|
|
15
|
$REGISTERED_ATTRIBUTE_HANDLER = {
|
24
|
|
|
|
|
|
|
'Fukurama::Class::Attributes::OOStandard' => 0,
|
25
|
|
|
|
|
|
|
};
|
26
|
4
|
|
|
|
|
10
|
$REGISTERED_CLASSES = {};
|
27
|
4
|
|
|
|
|
9
|
$INHERITATION_CHECK_SUBS = {};
|
28
|
4
|
|
|
|
|
9671
|
$INHERIT_METHOD_NAME = 'check_inheritation';
|
29
|
|
|
|
|
|
|
}
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head1 NAME
|
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
Fukurama::Class::Attributes - Pragma like module to extend code attributes
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head1 VERSION
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
Version 0.01 (beta)
|
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
package MyAttributeClass;
|
42
|
|
|
|
|
|
|
sub MyFirstCodeAttribute {
|
43
|
|
|
|
|
|
|
my $class = $_[0];
|
44
|
|
|
|
|
|
|
my $subroutine_data = $_[1];
|
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
... do some checks or what you want ...
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
return;
|
49
|
|
|
|
|
|
|
}
|
50
|
|
|
|
|
|
|
sub check_inheritation {
|
51
|
|
|
|
|
|
|
my $class = $_[0];
|
52
|
|
|
|
|
|
|
my $method_name = $_[1];
|
53
|
|
|
|
|
|
|
my $parent_class = $_[2];
|
54
|
|
|
|
|
|
|
my $child_class = $_[3];
|
55
|
|
|
|
|
|
|
my $inheritation_type = $_[4];
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
return;
|
58
|
|
|
|
|
|
|
}
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
package MyClass;
|
61
|
|
|
|
|
|
|
BEGIN {
|
62
|
|
|
|
|
|
|
use Fukurama::Class::Attributes();
|
63
|
|
|
|
|
|
|
Fukurama::Class::Attributes->add_attribute_handler('MyAttributeClass');
|
64
|
|
|
|
|
|
|
}
|
65
|
|
|
|
|
|
|
use Fukurama::Class::Attributes;
|
66
|
|
|
|
|
|
|
sub my_method : Method(static|void|) {
|
67
|
|
|
|
|
|
|
return;
|
68
|
|
|
|
|
|
|
}
|
69
|
|
|
|
|
|
|
sub other_sub : MyFirstCodeAttribute() {
|
70
|
|
|
|
|
|
|
...
|
71
|
|
|
|
|
|
|
}
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
This pragma-like module provides functions to extend code attributes for yourself and check
|
76
|
|
|
|
|
|
|
the inheritation. It includes Fukurama::Attributes::OOStandard, which enables Method and Constructor
|
77
|
|
|
|
|
|
|
definitoins for subroutines. Use Fukurama::Class instead, to get all the features for OO.
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 CONFIG
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
You can disables all checks, which includes syntax and inheritation check by saying:
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
$Fukurama::Class::Attributes::CHECK_LEVEL = $Fukurama::Class::Attributes::LEVEL_CHECK_NONE;
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
=head1 EXPORT
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
-
|
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head1 METHODS
|
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
=over 4
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=item add_attribute_handler( handler_class:CLASS ) return:BOOLEAN
|
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Add all defined attribute-methods of the given class, so you can use their code attributes in
|
96
|
|
|
|
|
|
|
all of your subroutines. See section L for the rules.
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
=item remove_attribute_handler( handler_class:CLASS ) return:BOOLEAN
|
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
Remove all defined attribute-methods of the given class, so you can't use their anymore as code attributes.
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
=item register_class( export_to_class:CLASS ) return:BOOLEAN
|
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
Export all code attributes to the given class so you can use all registered code attributes in there.
|
105
|
|
|
|
|
|
|
Every child of the given class can even use this behavior.
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=item run_check( ) return:VOID
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Helper method for static perl (see Fukurama::Class > BUGS)
|
110
|
|
|
|
|
|
|
Its calls Fukurama::Class::AttributeHandler->run_check(), which check the correct syntax of all registered
|
111
|
|
|
|
|
|
|
code attributes and check some defined conventions.
|
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
E.g. for code attribute B: it will check that the access level of child class methods are the same or
|
114
|
|
|
|
|
|
|
stricter than the parent class method.
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=back
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head1 CREATE AN OWN ATTRIBUTE CLASS
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
An "attribute class" describe one (or many) code attributes, which you can use like B
|
121
|
|
|
|
|
|
|
There are the following rules for the class-methods:
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
-Every Attribute has to start with an uppercase letter
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
-Only on other method can be there, the subroutine B
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
-All these methods have to be void
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Attribute methods take on parameter, a hash reference, which contain informations about the method, which uses
|
130
|
|
|
|
|
|
|
the actual code-attribute. For every subroutine which contains this code attribute, the corresponding
|
131
|
|
|
|
|
|
|
method in your attribute class would be called. The parameter contain the following data:
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
resolved => BOOLEAN, # the subroutine is resolved (only internal use to avoid calls without the name of the subroutine)
|
134
|
|
|
|
|
|
|
data => STRING, # the attribute-data. If you say B it youd contain B
|
135
|
|
|
|
|
|
|
sub_name => STRING, # the name of the subroutine, which call this attribute
|
136
|
|
|
|
|
|
|
executed => BOOLEAN, # this attribute for this subroutine is allways called (only internal use to avoid double callings)
|
137
|
|
|
|
|
|
|
attribute => STRING, # the name of the attribute. Its the same like the name of your code-attribute-method.
|
138
|
|
|
|
|
|
|
handler => HASHREF, # Contain a reference to your code-attribute method and class. Only for internal use.
|
139
|
|
|
|
|
|
|
sub => CODEREF, # The code referense of the subroutine, which contain the code attribute.
|
140
|
|
|
|
|
|
|
class => STRING, # The class in which the subroutine is declared, which contain the code attribute.
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
There are many things which you can do with code attributes, e.g. the Method and Constructor definitions from
|
143
|
|
|
|
|
|
|
Fukurama::Class::Attributes::OOStandard or some simple things like in Catalyst. So, do what you need.
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
The check_inheritation() method is optional, check the code attribute inheritation for each class and take the following parameters:
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
$method_name : STRING # the methodname which is checked
|
148
|
|
|
|
|
|
|
$parent_class : STRING # the parent class of the actual checked class
|
149
|
|
|
|
|
|
|
$child_class : STRING # the actual checked class
|
150
|
|
|
|
|
|
|
$inheritation_type : STRING # the type of inheritation. extend is standard, implement even exists
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
With this method you can compare every subroutine, which contain a code attribute, with all parents. If you use multi
|
153
|
|
|
|
|
|
|
inheritation or interfaces there can be more than one parent. And it even compares in the same way all grandparents etc.
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=head1 AUTHOR, BUGS, SUPPORT, ACKNOWLEDGEMENTS, COPYRIGHT & LICENSE
|
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
see perldoc of L
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
=cut
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# STATIC boolean
|
162
|
|
|
|
|
|
|
sub add_attribute_handler {
|
163
|
0
|
|
|
0
|
1
|
0
|
my $class = $_[0];
|
164
|
0
|
|
|
|
|
0
|
my $handler_class = $_[1];
|
165
|
|
|
|
|
|
|
|
166
|
0
|
|
0
|
|
|
0
|
$REGISTERED_ATTRIBUTE_HANDLER ||= {};
|
167
|
0
|
0
|
|
|
|
0
|
return 0 if(defined($REGISTERED_ATTRIBUTE_HANDLER->{$handler_class}));
|
168
|
0
|
|
|
|
|
0
|
$REGISTERED_ATTRIBUTE_HANDLER->{$handler_class} = 1;
|
169
|
0
|
|
|
|
|
0
|
return 1;
|
170
|
|
|
|
|
|
|
}
|
171
|
|
|
|
|
|
|
# STATIC boolean
|
172
|
|
|
|
|
|
|
sub remove_attribute_handler {
|
173
|
0
|
|
|
0
|
1
|
0
|
my $class = $_[0];
|
174
|
0
|
|
|
|
|
0
|
my $handler_class = $_[1];
|
175
|
|
|
|
|
|
|
|
176
|
0
|
0
|
0
|
|
|
0
|
return 0 if(!$REGISTERED_ATTRIBUTE_HANDLER || !defined($REGISTERED_ATTRIBUTE_HANDLER->{$handler_class})
|
|
|
|
0
|
|
|
|
|
177
|
|
|
|
|
|
|
|| $REGISTERED_ATTRIBUTE_HANDLER->{$handler_class});
|
178
|
0
|
|
|
|
|
0
|
delete($REGISTERED_ATTRIBUTE_HANDLER->{$handler_class});
|
179
|
0
|
|
|
|
|
0
|
return 1;
|
180
|
|
|
|
|
|
|
}
|
181
|
|
|
|
|
|
|
# AUTOMAGIC void
|
182
|
|
|
|
|
|
|
sub import {
|
183
|
|
|
|
|
|
|
|
184
|
4
|
|
|
4
|
|
1224
|
my $caller_class = caller();
|
185
|
4
|
|
|
|
|
10
|
__PACKAGE__->register_class($caller_class);
|
186
|
4
|
|
|
|
|
146
|
return;
|
187
|
|
|
|
|
|
|
}
|
188
|
|
|
|
|
|
|
# STATIC void
|
189
|
|
|
|
|
|
|
sub register_class {
|
190
|
28
|
|
|
28
|
1
|
43
|
my $class = $_[0];
|
191
|
28
|
|
|
|
|
37
|
my $export_to_class = $_[1];
|
192
|
|
|
|
|
|
|
|
193
|
28
|
100
|
|
|
|
65
|
if(!$INIT) {
|
194
|
3
|
|
|
|
|
49
|
$class->_init();
|
195
|
3
|
|
|
|
|
5
|
$INIT = 1;
|
196
|
|
|
|
|
|
|
}
|
197
|
|
|
|
|
|
|
|
198
|
28
|
|
|
|
|
118
|
foreach my $handler_class (keys(%$REGISTERED_ATTRIBUTE_HANDLER)) {
|
199
|
28
|
100
|
|
|
|
122
|
next if($REGISTERED_ATTRIBUTE_HANDLER->{$handler_class});
|
200
|
3
|
|
|
|
|
16
|
Fukurama::Class::AttributesHandler->register_attributes($handler_class);
|
201
|
|
|
|
|
|
|
|
202
|
4
|
|
|
4
|
|
44
|
no strict 'refs';
|
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
4098
|
|
203
|
|
|
|
|
|
|
|
204
|
3
|
|
|
|
|
5
|
my $inheritation_sub = *{$handler_class . '::' . $INHERIT_METHOD_NAME}{'CODE'};
|
|
3
|
|
|
|
|
13
|
|
205
|
3
|
|
|
|
|
9
|
$INHERITATION_CHECK_SUBS->{$handler_class} = $inheritation_sub;
|
206
|
3
|
|
|
|
|
15
|
$REGISTERED_ATTRIBUTE_HANDLER->{$handler_class} = 1;
|
207
|
|
|
|
|
|
|
}
|
208
|
|
|
|
|
|
|
|
209
|
28
|
|
|
|
|
75
|
$REGISTERED_CLASSES->{$export_to_class} = 1;
|
210
|
28
|
|
|
|
|
130
|
Fukurama::Class::AttributesHandler->export($export_to_class);
|
211
|
28
|
|
|
|
|
60
|
return;
|
212
|
|
|
|
|
|
|
}
|
213
|
|
|
|
|
|
|
# STATIC void
|
214
|
|
|
|
|
|
|
sub _init {
|
215
|
3
|
|
|
3
|
|
6
|
my $class = $_[0];
|
216
|
|
|
|
|
|
|
|
217
|
3
|
|
|
|
|
28
|
Fukurama::Class::AttributesHandler->register_helper_method($INHERIT_METHOD_NAME);
|
218
|
3
|
50
|
|
|
|
15
|
return if($CHECK_LEVEL == $LEVEL_CHECK_NONE);
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
my $CHECK_HANDLER = sub {
|
221
|
1601
|
|
|
1601
|
|
1809
|
my $classname = $_[0];
|
222
|
1601
|
|
|
|
|
1687
|
my $classdef = $_[1];
|
223
|
|
|
|
|
|
|
|
224
|
1601
|
50
|
|
|
|
2910
|
return if($CHECK_LEVEL == $LEVEL_CHECK_NONE);
|
225
|
1601
|
|
|
|
|
3367
|
__PACKAGE__->_check_inheritation($classname, $classdef);
|
226
|
1599
|
|
|
|
|
4133
|
return;
|
227
|
3
|
|
|
|
|
18
|
};
|
228
|
|
|
|
|
|
|
|
229
|
3
|
|
|
|
|
26
|
Fukurama::Class::Extends->register_class_tree();
|
230
|
3
|
|
|
|
|
22
|
Fukurama::Class::Implements->register_class_tree();
|
231
|
3
|
|
|
|
|
11
|
Fukurama::Class::Tree->register_check_handler($CHECK_HANDLER);
|
232
|
3
|
|
|
|
|
6
|
return;
|
233
|
|
|
|
|
|
|
}
|
234
|
|
|
|
|
|
|
# STATIC void
|
235
|
|
|
|
|
|
|
sub _check_inheritation {
|
236
|
1601
|
|
|
1601
|
|
1740
|
my $class = $_[0];
|
237
|
1601
|
|
|
|
|
1581
|
my $classname = $_[1];
|
238
|
1601
|
|
|
|
|
1693
|
my $classdef= $_[2];
|
239
|
|
|
|
|
|
|
|
240
|
1601
|
|
|
|
|
1549
|
foreach my $inherit_data (@{$class->_get_parent_classes($classname, $classdef)}) {
|
|
1601
|
|
|
|
|
3001
|
|
241
|
751
|
|
|
|
|
1735
|
my $filtered_inherit_path = $class->_get_registered_parents($inherit_data->{'path'});
|
242
|
751
|
100
|
|
|
|
2174
|
next if(!scalar(@$filtered_inherit_path));
|
243
|
39
|
|
|
|
|
59
|
push(@$filtered_inherit_path, $classname);
|
244
|
|
|
|
|
|
|
|
245
|
39
|
|
|
|
|
58
|
my $parent_path = [];
|
246
|
39
|
|
|
|
|
100
|
while(scalar(@$filtered_inherit_path) > 1) {
|
247
|
64
|
|
|
|
|
102
|
my $parent = shift(@$filtered_inherit_path);
|
248
|
64
|
|
|
|
|
126
|
my $child = $filtered_inherit_path->[0];
|
249
|
|
|
|
|
|
|
|
250
|
64
|
|
|
|
|
185
|
$class->_merge_class_definition($parent, $child, $parent_path, $inherit_data->{'type'});
|
251
|
62
|
|
|
|
|
270
|
push(@$parent_path, $parent);
|
252
|
|
|
|
|
|
|
}
|
253
|
|
|
|
|
|
|
}
|
254
|
1599
|
|
|
|
|
3066
|
return;
|
255
|
|
|
|
|
|
|
}
|
256
|
|
|
|
|
|
|
# STATIC void
|
257
|
|
|
|
|
|
|
sub _merge_class_definition {
|
258
|
64
|
|
|
64
|
|
96
|
my $class = $_[0];
|
259
|
64
|
|
|
|
|
75
|
my $parent = $_[1];
|
260
|
64
|
|
|
|
|
78
|
my $child = $_[2];
|
261
|
64
|
|
|
|
|
68
|
my $parent_path = $_[3];
|
262
|
64
|
|
|
|
|
77
|
my $inheritation_type = $_[4];
|
263
|
|
|
|
|
|
|
|
264
|
64
|
|
|
|
|
83
|
my $parent_methods = {};
|
265
|
64
|
|
|
|
|
129
|
foreach my $parent_class (@$parent_path, $parent) {
|
266
|
99
|
|
|
|
|
317
|
foreach my $parent_method (Fukurama::Class::Tree->get_all_subs($parent_class)) {
|
267
|
267
|
|
|
|
|
596
|
$parent_methods->{$parent_method} = $parent_class;
|
268
|
|
|
|
|
|
|
}
|
269
|
|
|
|
|
|
|
}
|
270
|
|
|
|
|
|
|
|
271
|
64
|
|
|
|
|
91
|
my $child_methods = {};
|
272
|
64
|
|
|
|
|
231
|
foreach my $child_method (Fukurama::Class::Tree->get_all_subs($child)) {
|
273
|
147
|
|
|
|
|
303
|
$child_methods->{$child_method} = $child;
|
274
|
|
|
|
|
|
|
}
|
275
|
|
|
|
|
|
|
|
276
|
64
|
|
|
|
|
269
|
my @all_methods = (keys(%$child_methods), keys(%$parent_methods));
|
277
|
64
|
|
|
|
|
124
|
my %unique_methods = ();
|
278
|
64
|
|
|
|
|
282
|
@unique_methods{@all_methods} = (1) x scalar(@all_methods);
|
279
|
|
|
|
|
|
|
|
280
|
64
|
|
|
|
|
139
|
foreach my $method (keys(%unique_methods)) {
|
281
|
198
|
|
66
|
|
|
731
|
my $parent_class = $parent_methods->{$method} || $parent;
|
282
|
198
|
|
|
|
|
376
|
foreach my $handler_class (keys(%$INHERITATION_CHECK_SUBS)) {
|
283
|
198
|
|
|
|
|
217
|
&{$INHERITATION_CHECK_SUBS->{$handler_class}}($handler_class, $method, $parent_class, $child, $inheritation_type);
|
|
198
|
|
|
|
|
1213
|
|
284
|
|
|
|
|
|
|
}
|
285
|
|
|
|
|
|
|
}
|
286
|
62
|
|
|
|
|
338
|
return;
|
287
|
|
|
|
|
|
|
}
|
288
|
|
|
|
|
|
|
# STATIC string[]
|
289
|
|
|
|
|
|
|
sub _get_parent_classes {
|
290
|
1601
|
|
|
1601
|
|
1759
|
my $class = $_[0];
|
291
|
1601
|
|
|
|
|
1633
|
my $check_class = $_[1];
|
292
|
1601
|
|
|
|
|
1549
|
my $classdef = $_[2];
|
293
|
|
|
|
|
|
|
|
294
|
1601
|
|
|
|
|
1928
|
my @all_paths = ();
|
295
|
1601
|
|
|
|
|
4178
|
foreach my $type (keys(%$classdef)) {
|
296
|
551
|
|
|
|
|
573
|
foreach my $inherit_path (@{$classdef->{$type}}) {
|
|
551
|
|
|
|
|
1112
|
|
297
|
751
|
|
|
|
|
3011
|
push(@all_paths, {
|
298
|
|
|
|
|
|
|
type => $type,
|
299
|
|
|
|
|
|
|
path => $inherit_path,
|
300
|
|
|
|
|
|
|
});
|
301
|
|
|
|
|
|
|
}
|
302
|
|
|
|
|
|
|
}
|
303
|
1601
|
|
|
|
|
4374
|
return \@all_paths;
|
304
|
|
|
|
|
|
|
}
|
305
|
|
|
|
|
|
|
# STATIC string[]
|
306
|
|
|
|
|
|
|
sub _get_registered_parents {
|
307
|
751
|
|
|
751
|
|
854
|
my $class = $_[0];
|
308
|
751
|
|
|
|
|
835
|
my $path = $_[1];
|
309
|
|
|
|
|
|
|
|
310
|
751
|
|
|
|
|
911
|
my @filtered_path = ();
|
311
|
751
|
|
|
|
|
809
|
my $was_registered = 0;
|
312
|
751
|
|
|
|
|
1098
|
foreach my $parent (reverse(@$path)) {
|
313
|
2308
|
100
|
66
|
|
|
8211
|
next if(!$was_registered && !$REGISTERED_CLASSES->{$parent});
|
314
|
64
|
|
|
|
|
70
|
$was_registered = 1;
|
315
|
64
|
|
|
|
|
137
|
push(@filtered_path, $parent);
|
316
|
|
|
|
|
|
|
}
|
317
|
751
|
|
|
|
|
1649
|
return \@filtered_path;
|
318
|
|
|
|
|
|
|
}
|
319
|
|
|
|
|
|
|
# STATIC void
|
320
|
|
|
|
|
|
|
sub run_check {
|
321
|
0
|
|
|
0
|
1
|
|
Fukurama::Class::AttributesHandler->run_check();
|
322
|
|
|
|
|
|
|
}
|
323
|
|
|
|
|
|
|
|
324
|
4
|
|
|
4
|
|
39
|
no warnings 'void'; # avoid 'Too late to run CHECK/INIT block'
|
|
4
|
|
|
|
|
18
|
|
|
4
|
|
|
|
|
475
|
|
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# AUTOMAGIC
|
327
|
|
|
|
|
|
|
CHECK {
|
328
|
4
|
|
|
4
|
|
4017
|
Fukurama::Class::AttributesHandler->run_check();
|
329
|
|
|
|
|
|
|
}
|
330
|
|
|
|
|
|
|
# AUTOMAGIC
|
331
|
|
|
|
|
|
|
END {
|
332
|
4
|
|
|
4
|
|
2986
|
Fukurama::Class::AttributesHandler->run_check();
|
333
|
|
|
|
|
|
|
}
|
334
|
|
|
|
|
|
|
1;
|