File Coverage

blib/lib/Fukurama/Class/Attributes/OOStandard.pm
Criterion Covered Total %
statement 54 56 96.4
branch 6 10 60.0
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 70 76 92.1


line stmt bran cond sub pod time code
1             package Fukurama::Class::Attributes::OOStandard;
2 4     4   23 use Fukurama::Class::Version(0.02);
  4         7  
  4         32  
3 4     4   23 use Fukurama::Class::Rigid;
  4         8  
  4         27  
4 4     4   21 use Fukurama::Class::Carp();
  4         9  
  4         63  
5 4     4   2703 use Fukurama::Class::Attributes::OOStandard::DefinitionCheck();
  4         15  
  4         3465  
6            
7             my $DEF_CHECK = 'Fukurama::Class::Attributes::OOStandard::DefinitionCheck';
8             my $SUB_DEF = qr/[a-z \t\n\r]*/;
9             my $RETURN_DEF = qr/[a-zA-Z_:, \t\n\r\[\]\(\)]*/;
10             my $PARAM_DEF = qr/[a-zA-Z_:, \t\n\r\[\]\(\)]*/;
11            
12             my $CONSTRUCTOR_DEF_CHECK = qr/^($SUB_DEF\|$PARAM_DEF;?$PARAM_DEF)$/;
13             my $METHOD_DEF_CHECK = qr/^($SUB_DEF\|$RETURN_DEF\@?$RETURN_DEF\|$PARAM_DEF;?$PARAM_DEF)$/;
14            
15             our $LEVEL_CHECK_NONE = 0;
16             our $LEVEL_CHECK_SYNTAX = 1;
17             our $LEVEL_CHECK_FORCE_INHERITATION = 2;
18             our $LEVEL_CHECK_FORCE_ATTRIBUTES = 3;
19            
20             our $CHECK_LEVEL = $LEVEL_CHECK_FORCE_ATTRIBUTES;
21             our $DISABLE_RUNTIME_CHECK;
22            
23             =head1 NAME
24            
25             Fukurama::Class::Attribute::OOStandard - Plugin for code attributes
26            
27             =head1 VERSION
28            
29             Version 0.02 (beta)
30            
31             =head1 SYNOPSIS
32            
33             package MyClass;
34             use Fukurama::Class::Attributes;
35            
36             sub my_sub : Method(static|boolean|string,hashref) {
37             my $class = $_[0];
38             my $string = $_[1];
39             my $hashref = $_[2];
40            
41             return 1;
42             }
43            
44             =head1 DESCRIPTION
45            
46             This plugin for Fukurama::Class::Attributes provides code attributes to declare and check
47             method an constructor definitions at compiletime and parameter and return value checks at runtime.
48            
49             =head1 CONFIG
50            
51             You can define the check-level which describes how the module will check your declarations for methods and constructors.
52             The following levels are allowed:
53            
54             =over 4
55            
56             =item $Fukurama::Class::Attributes::OOStandard::CHECK_LEVEL = $Fukurama::Class::Attributes::OOStandard::LEVEL_CHECK_NONE
57            
58             There is no check. This level is recommended for production.
59            
60             =item $Fukurama::Class::Attributes::OOStandard::CHECK_LEVEL = $Fukurama::Class::Attributes::OOStandard::LEVEL_CHECK_SYNTAX
61            
62             All registration processes are executed and the definitions of the code attributes would be checked at compiletime.
63             This level is only for the sake of completeness.
64            
65             =item $Fukurama::Class::Attributes::OOStandard::CHECK_LEVEL = $Fukurama::Class::Attributes::OOStandard::LEVEL_CHECK_FORCE_INHERITATION
66            
67             If you define a code attribute at the parent class, you have to define the same or extended in child class. You can only
68             extend optional parameters and thighten the method access level. All other woud fail at compiletime.
69            
70             =item $Fukurama::Class::Attributes::OOStandard::CHECK_LEVEL = $Fukurama::Class::Attributes::OOStandard::LEVEL_CHECK_FORCE_ATTRIBUTES
71            
72             The default behavior. You have to define code attributes for all methods in your class, except perl internals.
73            
74             =back
75            
76             The runtime check for parameter and return values can be disabled by saying:
77            
78             $Fukurama::Class::Attributes::OOStandard::DISABLE_RUNTIME_CHECK = 1;
79            
80             This is recommended for production.
81            
82             =head1 EXPORT
83            
84             -
85            
86             =head1 METHODS
87            
88             =over 4
89            
90             =item Constructor( subroutine_data:\HASH ) return:VOID
91            
92             Code attribute, which defines a constructor subroutine.
93            
94             =item Method( subroutine_data:\HASH ) return:VOID
95            
96             Code Attribute, which defines a method.
97            
98             =item check_inheritation( method_name:STRING, parent_class:CLASS, child_class:CLASS, inheritation_type:STRING ) return:VOID
99            
100             Helper method to compare every method declarations for code attributes in your class whith all in the parent methods.
101            
102             =back
103            
104             =head1 AUTHOR, BUGS, SUPPORT, ACKNOWLEDGEMENTS, COPYRIGHT & LICENSE
105            
106             see perldoc of L
107            
108             =cut
109            
110             # STATIC boolean
111             sub Constructor {
112 9     9 1 16 my $class = $_[0];
113 9         13 my $sub_data = $_[1];
114            
115 9         13 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
116 9         52 $DEF_CHECK->set_type('constructor');
117 9 50       70 if($sub_data->{'data'} !~ $CONSTRUCTOR_DEF_CHECK) {
118 0         0 $DEF_CHECK->throw_def_error($sub_data, "constructor syntax is wrong");
119             }
120            
121 9         34 my $def = $DEF_CHECK->resolve_def($sub_data);
122 9         22 my $sub_def = $def->[0]->[0];
123 9 100       22 if(!grep({$_->{'data'} eq 'static'} @$sub_def)) {
  11         42  
124 6         27 push(@$sub_def, {
125             'type' => '',
126             'data' => 'static',
127             });
128             }
129 9         16 @$sub_def = grep({$_->{'data'} ne ''} @$sub_def);
  17         49  
130 9         20 my $para_def = $def->[1]->[0];
131 9         17 my $opt_para_def = $def->[1]->[1];
132 9         29 my $result_def = [{
133             'type' => '',
134             'data' => $sub_data->{'class'},
135             }];
136 9         15 my $array_result_def = [];
137            
138 9         34 my $translated_def = $DEF_CHECK->get_translated_def($sub_data, $def, $sub_def, $result_def, $array_result_def, $para_def, $opt_para_def);
139 9         55 $DEF_CHECK->try_check_translated_def($sub_data, $translated_def, $def);
140 9 50       41 $DEF_CHECK->decorate_sub($translated_def) if(!$DISABLE_RUNTIME_CHECK);
141 9         62 return 1;
142             }
143             # STATIC boolean
144             sub Method {
145 18     18 1 31 my $class = $_[0];
146 18         21 my $sub_data = $_[1];
147            
148 18         25 local $Carp::CarpLevel = $Carp::CarpLevel + 1;
149 18         84 $DEF_CHECK->set_type('method');
150 18 50       180 if($sub_data->{'data'} !~ $METHOD_DEF_CHECK) {
151 0         0 $DEF_CHECK->throw_def_error($sub_data, "method syntax is wrong");
152             }
153            
154 18         72 my $def = $DEF_CHECK->resolve_def($sub_data);
155 18         39 my $sub_def = $def->[0]->[0];
156 18         27 my $result_def = $def->[1]->[0];
157 18         66 my $array_result_def = $def->[1]->[1];
158 18         32 my $para_def = $def->[2]->[0];
159 18         28 my $opt_para_def = $def->[2]->[1];
160            
161 18         74 my $translated_def = $DEF_CHECK->get_translated_def($sub_data, $def, $sub_def, $result_def, $array_result_def, $para_def, $opt_para_def);
162 18         75 $DEF_CHECK->try_check_translated_def($sub_data, $translated_def, $def);
163 18 50       86 $DEF_CHECK->decorate_sub($translated_def) if(!$DISABLE_RUNTIME_CHECK);
164 18         145 return 1;
165             }
166             # STATIC void
167             sub check_inheritation {
168 198     198 1 268 my $class = $_[0];
169 198         408 my $method_name = $_[1];
170 198         219 my $parent_class = $_[2];
171 198         211 my $child_class = $_[3];
172 198         195 my $inheritation_type = $_[4];
173            
174 198         707 $DEF_CHECK->check_inheritation($method_name, $parent_class, $child_class, $inheritation_type);
175 196         1066 return;
176             }
177             1;