| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Perl/Critic/Policy/NamingConventions/Capitalization.pm |
| Statements | Executed 41 statements in 2.29ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 501µs | 27.3ms | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@29 |
| 1 | 1 | 1 | 231µs | 325µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@25 |
| 1 | 1 | 1 | 66µs | 78µs | Perl::Critic::Policy::NamingConventions::Capitalization::supported_parameters |
| 1 | 1 | 1 | 16µs | 16µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@10 |
| 1 | 1 | 1 | 9µs | 27µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@19 |
| 1 | 1 | 1 | 8µs | 22µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@20 |
| 1 | 1 | 1 | 8µs | 27µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@26 |
| 7 | 7 | 1 | 8µs | 8µs | Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr (opcode) |
| 1 | 1 | 1 | 8µs | 26µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@15 |
| 1 | 1 | 1 | 8µs | 63µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@33 |
| 1 | 1 | 1 | 7µs | 11µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@12 |
| 1 | 1 | 1 | 7µs | 138µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@17 |
| 1 | 1 | 1 | 7µs | 18µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@11 |
| 1 | 1 | 1 | 7µs | 366µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@14 |
| 1 | 1 | 1 | 7µs | 396µs | Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@21 |
| 1 | 1 | 1 | 6µs | 7µs | Perl::Critic::Policy::NamingConventions::Capitalization::default_severity |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::__ANON__[:250] |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_check_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_constant_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_derive_capitalization_exemption_test_regexes |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_derive_capitalization_test_regex_and_message |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_foreach_variable_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_is_directly_in_scope_block |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_is_not_real_label |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_label_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_name_is_exempt |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_package_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_subroutine_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::_variable_capitalization |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::applies_to |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::default_themes |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::initialize_if_enabled |
| 0 | 0 | 0 | 0s | 0s | Perl::Critic::Policy::NamingConventions::Capitalization::violates |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | ############################################################################## | ||||
| 2 | # $URL$ | ||||
| 3 | # $Date$ | ||||
| 4 | # $Author$ | ||||
| 5 | # $Revision$ | ||||
| 6 | ############################################################################## | ||||
| 7 | |||||
| 8 | package Perl::Critic::Policy::NamingConventions::Capitalization; | ||||
| 9 | |||||
| 10 | 2 | 42µs | 1 | 16µs | # spent 16µs within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@10 which was called:
# once (16µs+0s) by Module::Pluggable::Object::_require at line 10 # spent 16µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@10 |
| 11 | 2 | 20µs | 2 | 30µs | # spent 18µs (7+11) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@11 which was called:
# once (7µs+11µs) by Module::Pluggable::Object::_require at line 11 # spent 18µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@11
# spent 11µs making 1 call to strict::import |
| 12 | 2 | 21µs | 2 | 15µs | # spent 11µs (7+4) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@12 which was called:
# once (7µs+4µs) by Module::Pluggable::Object::_require at line 12 # spent 11µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@12
# spent 4µs making 1 call to warnings::import |
| 13 | |||||
| 14 | 2 | 22µs | 2 | 724µs | # spent 366µs (7+358) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@14 which was called:
# once (7µs+358µs) by Module::Pluggable::Object::_require at line 14 # spent 366µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@14
# spent 358µs making 1 call to English::import |
| 15 | 2 | 22µs | 2 | 45µs | # spent 26µs (8+19) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@15 which was called:
# once (8µs+19µs) by Module::Pluggable::Object::_require at line 15 # spent 26µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@15
# spent 19µs making 1 call to Exporter::import |
| 16 | |||||
| 17 | 2 | 22µs | 2 | 268µs | # spent 138µs (7+130) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@17 which was called:
# once (7µs+130µs) by Module::Pluggable::Object::_require at line 17 # spent 138µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@17
# spent 130µs making 1 call to Exporter::Tiny::import |
| 18 | |||||
| 19 | 2 | 21µs | 2 | 46µs | # spent 27µs (9+18) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@19 which was called:
# once (9µs+18µs) by Module::Pluggable::Object::_require at line 19 # spent 27µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@19
# spent 18µs making 1 call to Exporter::import |
| 20 | 2 | 24µs | 2 | 35µs | # spent 22µs (8+14) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@20 which was called:
# once (8µs+14µs) by Module::Pluggable::Object::_require at line 20 # spent 22µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@20
# spent 14µs making 1 call to Exporter::import |
| 21 | 1 | 200ns | # spent 396µs (7+390) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@21 which was called:
# once (7µs+390µs) by Module::Pluggable::Object::_require at line 24 | ||
| 22 | :booleans :characters :severities | ||||
| 23 | hashify is_perl_global | ||||
| 24 | 1 | 24µs | 2 | 786µs | >; # spent 396µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@21
# spent 390µs making 1 call to Exporter::import |
| 25 | 2 | 92µs | 2 | 353µs | # spent 325µs (231+94) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@25 which was called:
# once (231µs+94µs) by Module::Pluggable::Object::_require at line 25 # spent 325µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@25
# spent 28µs making 1 call to Exporter::import |
| 26 | 1 | 400ns | # spent 27µs (8+19) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@26 which was called:
# once (8µs+19µs) by Module::Pluggable::Object::_require at line 28 | ||
| 27 | is_in_subroutine | ||||
| 28 | 1 | 22µs | 2 | 46µs | >; # spent 27µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@26
# spent 19µs making 1 call to Exporter::import |
| 29 | 1 | 66µs | # spent 27.3ms (501µs+26.8) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@29 which was called:
# once (501µs+26.8ms) by Module::Pluggable::Object::_require at line 31 | ||
| 30 | get_constant_name_elements_from_declaring_statement | ||||
| 31 | 1 | 31µs | 2 | 27.3ms | >; # spent 27.3ms making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@29
# spent 30µs making 1 call to Exporter::import |
| 32 | |||||
| 33 | 2 | 1.72ms | 2 | 118µs | # spent 63µs (8+55) within Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@33 which was called:
# once (8µs+55µs) by Module::Pluggable::Object::_require at line 33 # spent 63µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::BEGIN@33
# spent 55µs making 1 call to base::import |
| 34 | |||||
| 35 | 1 | 600ns | our $VERSION = '1.121'; | ||
| 36 | |||||
| 37 | #----------------------------------------------------------------------------- | ||||
| 38 | |||||
| 39 | # Don't worry about leading digits-- let perl/PPI do that. | ||||
| 40 | 1 | 11µs | 2 | 44µs | Readonly::Scalar my $ALL_ONE_CASE_REGEX => # spent 42µs making 1 call to Readonly::Scalar
# spent 2µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 41 | qr< \A [@%\$]? (?: [[:lower:]_\d]+ | [[:upper:]_\d]+ ) \z >xms; | ||||
| 42 | 1 | 5µs | 2 | 23µs | Readonly::Scalar my $ALL_LOWER_REGEX => qr< \A [[:lower:]_\d]+ \z >xms; # spent 22µs making 1 call to Readonly::Scalar
# spent 1µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 43 | 1 | 4µs | 2 | 21µs | Readonly::Scalar my $ALL_UPPER_REGEX => qr< \A [[:upper:]_\d]+ \z >xms; # spent 20µs making 1 call to Readonly::Scalar
# spent 900ns making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 44 | 1 | 4µs | 2 | 21µs | Readonly::Scalar my $STARTS_WITH_LOWER_REGEX => qr< \A _* [[:lower:]\d] >xms; # spent 20µs making 1 call to Readonly::Scalar
# spent 900ns making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 45 | 1 | 4µs | 2 | 21µs | Readonly::Scalar my $STARTS_WITH_UPPER_REGEX => qr< \A _* [[:upper:]\d] >xms; # spent 20µs making 1 call to Readonly::Scalar
# spent 900ns making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 46 | 1 | 4µs | 2 | 21µs | Readonly::Scalar my $NO_RESTRICTION_REGEX => qr< . >xms; # spent 20µs making 1 call to Readonly::Scalar
# spent 900ns making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 47 | |||||
| 48 | 1 | 27µs | 13 | 186µs | Readonly::Hash my %CAPITALIZATION_SCHEME_TAGS => ( # spent 174µs making 1 call to Readonly::Hash
# spent 12µs making 12 calls to Readonly::Scalar::FETCH, avg 1µs/call |
| 49 | ':single_case' => { | ||||
| 50 | regex => $ALL_ONE_CASE_REGEX, | ||||
| 51 | regex_violation => 'is not all lower case or all upper case', | ||||
| 52 | }, | ||||
| 53 | ':all_lower' => { | ||||
| 54 | regex => $ALL_LOWER_REGEX, | ||||
| 55 | regex_violation => 'is not all lower case', | ||||
| 56 | }, | ||||
| 57 | ':all_upper' => { | ||||
| 58 | regex => $ALL_UPPER_REGEX, | ||||
| 59 | regex_violation => 'is not all upper case', | ||||
| 60 | }, | ||||
| 61 | ':starts_with_lower' => { | ||||
| 62 | regex => $STARTS_WITH_LOWER_REGEX, | ||||
| 63 | regex_violation => 'does not start with a lower case letter', | ||||
| 64 | }, | ||||
| 65 | ':starts_with_upper' => { | ||||
| 66 | regex => $STARTS_WITH_UPPER_REGEX, | ||||
| 67 | regex_violation => 'does not start with a upper case letter', | ||||
| 68 | }, | ||||
| 69 | ':no_restriction' => { | ||||
| 70 | regex => $NO_RESTRICTION_REGEX, | ||||
| 71 | regex_violation => 'there is a bug in Perl::Critic if you are reading this', | ||||
| 72 | }, | ||||
| 73 | ); | ||||
| 74 | |||||
| 75 | 1 | 6µs | 2 | 23µs | Readonly::Scalar my $PACKAGE_REGEX => qr/ :: | ' /xms; # spent 22µs making 1 call to Readonly::Scalar
# spent 1µs making 1 call to Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr |
| 76 | |||||
| 77 | 1 | 1µs | 1 | 29µs | Readonly::Hash my %NAME_FOR_TYPE => ( # spent 29µs making 1 call to Readonly::Hash |
| 78 | package => 'Package', | ||||
| 79 | subroutine => 'Subroutine', | ||||
| 80 | local_lexical_variable => 'Local lexical variable', | ||||
| 81 | scoped_lexical_variable => 'Scoped lexical variable', | ||||
| 82 | file_lexical_variable => 'File lexical variable', | ||||
| 83 | global_variable => 'Global variable', | ||||
| 84 | constant => 'Constant', | ||||
| 85 | label => 'Label', | ||||
| 86 | ); | ||||
| 87 | |||||
| 88 | 1 | 3µs | 2 | 33µs | Readonly::Hash my %IS_COMMA => hashify( $COMMA, $FATCOMMA ); # spent 20µs making 1 call to Readonly::Hash
# spent 14µs making 1 call to Perl::Critic::Utils::hashify |
| 89 | |||||
| 90 | 1 | 2µs | 1 | 49µs | Readonly::Scalar my $EXPL => [ 45, 46 ]; # spent 49µs making 1 call to Readonly::Scalar |
| 91 | |||||
| 92 | #----------------------------------------------------------------------------- | ||||
| 93 | |||||
| 94 | # Can't handle named parameters yet. | ||||
| 95 | # spent 78µs (66+13) within Perl::Critic::Policy::NamingConventions::Capitalization::supported_parameters which was called:
# once (66µs+13µs) by Perl::Critic::Policy::new at line 88 of Perl/Critic/Policy.pm | ||||
| 96 | return ( | ||||
| 97 | { | ||||
| 98 | 1 | 53µs | 11 | 13µs | name => 'packages', # spent 13µs making 11 calls to Readonly::Scalar::FETCH, avg 1µs/call |
| 99 | description => 'How package name components should be capitalized. Valid values are :single_case, :all_lower, :all_upper:, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 100 | default_string => ':starts_with_upper', | ||||
| 101 | behavior => 'string', | ||||
| 102 | }, | ||||
| 103 | { | ||||
| 104 | name => 'package_exemptions', | ||||
| 105 | description => 'Package names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 106 | default_string => 'main', | ||||
| 107 | behavior => 'string list', | ||||
| 108 | }, | ||||
| 109 | { | ||||
| 110 | name => 'subroutines', | ||||
| 111 | description => 'How subroutine names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 112 | default_string => ':single_case', # Matches ProhibitMixedCaseSubs | ||||
| 113 | behavior => 'string', | ||||
| 114 | }, | ||||
| 115 | { | ||||
| 116 | name => 'subroutine_exemptions', | ||||
| 117 | description => 'Subroutine names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 118 | default_string => | ||||
| 119 | join ( | ||||
| 120 | $SPACE, | ||||
| 121 | qw< | ||||
| 122 | |||||
| 123 | AUTOLOAD BUILD BUILDARGS CLEAR CLOSE | ||||
| 124 | DELETE DEMOLISH DESTROY EXISTS EXTEND | ||||
| 125 | FETCH FETCHSIZE FIRSTKEY GETC NEXTKEY | ||||
| 126 | POP PRINT PRINTF PUSH READ | ||||
| 127 | READLINE SCALAR SHIFT SPLICE STORE | ||||
| 128 | STORESIZE TIEARRAY TIEHANDLE TIEHASH TIESCALAR | ||||
| 129 | UNSHIFT UNTIE WRITE | ||||
| 130 | |||||
| 131 | >, | ||||
| 132 | ), | ||||
| 133 | behavior => 'string list', | ||||
| 134 | }, | ||||
| 135 | { | ||||
| 136 | name => 'local_lexical_variables', | ||||
| 137 | description => 'How local lexical variables names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 138 | default_string => ':single_case', # Matches ProhibitMixedCaseVars | ||||
| 139 | behavior => 'string', | ||||
| 140 | }, | ||||
| 141 | { | ||||
| 142 | name => 'local_lexical_variable_exemptions', | ||||
| 143 | description => 'Local lexical variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 144 | default_string => $EMPTY, | ||||
| 145 | behavior => 'string list', | ||||
| 146 | }, | ||||
| 147 | { | ||||
| 148 | name => 'scoped_lexical_variables', | ||||
| 149 | description => 'How lexical variables that are scoped to a subset of subroutines, should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 150 | default_string => ':single_case', # Matches ProhibitMixedCaseVars | ||||
| 151 | behavior => 'string', | ||||
| 152 | }, | ||||
| 153 | { | ||||
| 154 | name => 'scoped_lexical_variable_exemptions', | ||||
| 155 | description => 'Names for variables in anonymous blocks that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 156 | default_string => $EMPTY, | ||||
| 157 | behavior => 'string list', | ||||
| 158 | }, | ||||
| 159 | { | ||||
| 160 | name => 'file_lexical_variables', | ||||
| 161 | description => 'How lexical variables at the file level should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 162 | default_string => ':single_case', # Matches ProhibitMixedCaseVars | ||||
| 163 | behavior => 'string', | ||||
| 164 | }, | ||||
| 165 | { | ||||
| 166 | name => 'file_lexical_variable_exemptions', | ||||
| 167 | description => 'File-scope lexical variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 168 | default_string => $EMPTY, | ||||
| 169 | behavior => 'string list', | ||||
| 170 | }, | ||||
| 171 | { | ||||
| 172 | name => 'global_variables', | ||||
| 173 | description => 'How global (package) variables should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 174 | default_string => ':single_case', # Matches ProhibitMixedCaseVars | ||||
| 175 | behavior => 'string', | ||||
| 176 | }, | ||||
| 177 | { | ||||
| 178 | name => 'global_variable_exemptions', | ||||
| 179 | description => 'Global variable names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 180 | default_string => '\$VERSION @ISA @EXPORT(?:_OK)? %EXPORT_TAGS \$AUTOLOAD %ENV %SIG \$TODO', ## no critic (RequireInterpolation) | ||||
| 181 | behavior => 'string list', | ||||
| 182 | }, | ||||
| 183 | { | ||||
| 184 | name => 'constants', | ||||
| 185 | description => 'How constant names should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 186 | default_string => ':all_upper', | ||||
| 187 | behavior => 'string', | ||||
| 188 | }, | ||||
| 189 | { | ||||
| 190 | name => 'constant_exemptions', | ||||
| 191 | description => 'Constant names that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 192 | default_string => $EMPTY, | ||||
| 193 | behavior => 'string list', | ||||
| 194 | }, | ||||
| 195 | { | ||||
| 196 | name => 'labels', | ||||
| 197 | description => 'How labels should be capitalized. Valid values are :single_case, :all_lower, :all_upper, :starts_with_lower, :starts_with_upper, :no_restriction, or a regex.', | ||||
| 198 | default_string => ':all_upper', | ||||
| 199 | behavior => 'string', | ||||
| 200 | }, | ||||
| 201 | { | ||||
| 202 | name => 'label_exemptions', | ||||
| 203 | description => 'Labels that are exempt from capitalization rules. The values here are regexes that will be surrounded by \A and \z.', | ||||
| 204 | default_string => $EMPTY, | ||||
| 205 | behavior => 'string list', | ||||
| 206 | }, | ||||
| 207 | ); | ||||
| 208 | } | ||||
| 209 | |||||
| 210 | 1 | 2µs | # spent 7µs (6+1) within Perl::Critic::Policy::NamingConventions::Capitalization::default_severity which was called:
# once (6µs+1µs) by Perl::Critic::Policy::get_severity at line 331 of Perl/Critic/Policy.pm | ||
| 211 | sub default_themes { return qw< core pbp cosmetic > } | ||||
| 212 | sub applies_to { return qw< PPI::Statement PPI::Token::Label > } | ||||
| 213 | |||||
| 214 | #----------------------------------------------------------------------------- | ||||
| 215 | |||||
| 216 | sub initialize_if_enabled { | ||||
| 217 | my ($self, $config) = @_; | ||||
| 218 | |||||
| 219 | my $configuration_exceptions = | ||||
| 220 | Perl::Critic::Exception::AggregateConfiguration->new(); | ||||
| 221 | |||||
| 222 | KIND: | ||||
| 223 | foreach my $kind_of_name ( qw< | ||||
| 224 | package subroutine | ||||
| 225 | local_lexical_variable scoped_lexical_variable | ||||
| 226 | file_lexical_variable global_variable | ||||
| 227 | constant label | ||||
| 228 | > ) { | ||||
| 229 | my ($capitalization_regex, $message) = | ||||
| 230 | $self->_derive_capitalization_test_regex_and_message( | ||||
| 231 | $kind_of_name, $configuration_exceptions, | ||||
| 232 | ); | ||||
| 233 | my $exemption_regexes = | ||||
| 234 | $self->_derive_capitalization_exemption_test_regexes( | ||||
| 235 | $kind_of_name, $configuration_exceptions, | ||||
| 236 | ); | ||||
| 237 | |||||
| 238 | # Keep going, despite problems, so that all problems can be reported | ||||
| 239 | # at one go, rather than the user fixing one problem, receiving a new | ||||
| 240 | # error, etc.. | ||||
| 241 | next KIND if $configuration_exceptions->has_exceptions(); | ||||
| 242 | |||||
| 243 | $self->{"_${kind_of_name}_test"} = sub { | ||||
| 244 | my ($name) = @_; | ||||
| 245 | |||||
| 246 | return if _name_is_exempt($name, $exemption_regexes); | ||||
| 247 | |||||
| 248 | return $message if $name !~ m/$capitalization_regex/xms; | ||||
| 249 | return; | ||||
| 250 | } | ||||
| 251 | } | ||||
| 252 | |||||
| 253 | if ( $configuration_exceptions->has_exceptions() ) { | ||||
| 254 | $configuration_exceptions->throw(); | ||||
| 255 | } | ||||
| 256 | |||||
| 257 | return $TRUE; | ||||
| 258 | } | ||||
| 259 | |||||
| 260 | sub _derive_capitalization_test_regex_and_message { | ||||
| 261 | my ($self, $kind_of_name, $configuration_exceptions) = @_; | ||||
| 262 | |||||
| 263 | my $capitalization_option = "${kind_of_name}s"; | ||||
| 264 | my $capitalization = $self->{"_$capitalization_option"}; | ||||
| 265 | |||||
| 266 | if ( my $tag_properties = $CAPITALIZATION_SCHEME_TAGS{$capitalization} ) { | ||||
| 267 | return @{$tag_properties}{ qw< regex regex_violation > }; | ||||
| 268 | } | ||||
| 269 | elsif ($capitalization =~ m< \A : >xms) { | ||||
| 270 | $configuration_exceptions->add_exception( | ||||
| 271 | Perl::Critic::Exception::Configuration::Option::Policy::ParameterValue->new( | ||||
| 272 | policy => $self, | ||||
| 273 | option_name => $capitalization_option, | ||||
| 274 | option_value => $capitalization, | ||||
| 275 | message_suffix => | ||||
| 276 | 'is not a known capitalization scheme tag. Valid tags are: ' | ||||
| 277 | . (join q<, >, sort keys %CAPITALIZATION_SCHEME_TAGS) | ||||
| 278 | . $PERIOD, | ||||
| 279 | ) | ||||
| 280 | ); | ||||
| 281 | return; | ||||
| 282 | } | ||||
| 283 | |||||
| 284 | my $regex; | ||||
| 285 | eval { $regex = qr< \A $capitalization \z >xms; } | ||||
| 286 | or do { | ||||
| 287 | $configuration_exceptions->add_exception( | ||||
| 288 | Perl::Critic::Exception::Configuration::Option::Policy::ParameterValue->new( | ||||
| 289 | policy => $self, | ||||
| 290 | option_name => $capitalization_option, | ||||
| 291 | option_value => $capitalization, | ||||
| 292 | message_suffix => | ||||
| 293 | "is not a valid regular expression: $EVAL_ERROR", | ||||
| 294 | ) | ||||
| 295 | ); | ||||
| 296 | return; | ||||
| 297 | }; | ||||
| 298 | |||||
| 299 | return $regex, qq<does not match "\\A$capitalization\\z".>; | ||||
| 300 | } | ||||
| 301 | |||||
| 302 | sub _derive_capitalization_exemption_test_regexes { | ||||
| 303 | my ($self, $kind_of_name, $configuration_exceptions) = @_; | ||||
| 304 | |||||
| 305 | my $exemptions_option = "${kind_of_name}_exemptions"; | ||||
| 306 | my $exemptions = $self->{"_$exemptions_option"}; | ||||
| 307 | |||||
| 308 | my @regexes; | ||||
| 309 | |||||
| 310 | PATTERN: | ||||
| 311 | foreach my $pattern ( keys %{$exemptions} ) { | ||||
| 312 | my $regex; | ||||
| 313 | eval { $regex = qr< \A $pattern \z >xms; } | ||||
| 314 | or do { | ||||
| 315 | $configuration_exceptions->add_exception( | ||||
| 316 | Perl::Critic::Exception::Configuration::Option::Policy::ParameterValue->new( | ||||
| 317 | policy => $self, | ||||
| 318 | option_name => $exemptions_option, | ||||
| 319 | option_value => $pattern, | ||||
| 320 | message_suffix => | ||||
| 321 | "is not a valid regular expression: $EVAL_ERROR", | ||||
| 322 | ) | ||||
| 323 | ); | ||||
| 324 | next PATTERN; | ||||
| 325 | }; | ||||
| 326 | |||||
| 327 | push @regexes, $regex; | ||||
| 328 | } | ||||
| 329 | |||||
| 330 | return \@regexes; | ||||
| 331 | } | ||||
| 332 | |||||
| 333 | sub _name_is_exempt { | ||||
| 334 | my ($name, $exemption_regexes) = @_; | ||||
| 335 | |||||
| 336 | foreach my $regex ( @{$exemption_regexes} ) { | ||||
| 337 | return $TRUE if $name =~ m/$regex/xms; | ||||
| 338 | } | ||||
| 339 | |||||
| 340 | return $FALSE; | ||||
| 341 | } | ||||
| 342 | |||||
| 343 | #----------------------------------------------------------------------------- | ||||
| 344 | |||||
| 345 | sub violates { | ||||
| 346 | my ( $self, $elem, undef ) = @_; | ||||
| 347 | |||||
| 348 | # Want given. Want 5.10. Gimme gimme gimme. :] | ||||
| 349 | if ( $elem->isa('PPI::Statement::Variable') ) { | ||||
| 350 | return $self->_variable_capitalization($elem); | ||||
| 351 | } | ||||
| 352 | |||||
| 353 | if ( $elem->isa('PPI::Statement::Sub') ) { | ||||
| 354 | return $self->_subroutine_capitalization($elem); | ||||
| 355 | } | ||||
| 356 | |||||
| 357 | if ( | ||||
| 358 | my @names = get_constant_name_elements_from_declaring_statement($elem) | ||||
| 359 | ) { | ||||
| 360 | return ( grep { $_ } | ||||
| 361 | map { $self->_constant_capitalization( $elem, $_ ) } @names ) | ||||
| 362 | } | ||||
| 363 | |||||
| 364 | if ( $elem->isa('PPI::Statement::Package') ) { | ||||
| 365 | return $self->_package_capitalization($elem); | ||||
| 366 | } | ||||
| 367 | |||||
| 368 | if ( | ||||
| 369 | $elem->isa('PPI::Statement::Compound') and $elem->type() eq 'foreach' | ||||
| 370 | ) { | ||||
| 371 | return $self->_foreach_variable_capitalization($elem); | ||||
| 372 | } | ||||
| 373 | |||||
| 374 | if ( $elem->isa('PPI::Token::Label') ) { | ||||
| 375 | return $self->_label_capitalization($elem); | ||||
| 376 | } | ||||
| 377 | |||||
| 378 | return; | ||||
| 379 | } | ||||
| 380 | |||||
| 381 | sub _variable_capitalization { | ||||
| 382 | my ($self, $elem) = @_; | ||||
| 383 | |||||
| 384 | my @violations; | ||||
| 385 | |||||
| 386 | NAME: | ||||
| 387 | for my $name ( map { $_->symbol() } $elem->symbols() ) { | ||||
| 388 | if ($elem->type() eq 'local') { | ||||
| 389 | # Fully qualified names are exempt because we can't be responsible | ||||
| 390 | # for other people's symbols. | ||||
| 391 | next NAME if $name =~ m/$PACKAGE_REGEX/xms; | ||||
| 392 | next NAME if is_perl_global($name); | ||||
| 393 | |||||
| 394 | push | ||||
| 395 | @violations, | ||||
| 396 | $self->_check_capitalization( | ||||
| 397 | symbol_without_sigil($name), | ||||
| 398 | $name, | ||||
| 399 | 'global_variable', | ||||
| 400 | $elem, | ||||
| 401 | ); | ||||
| 402 | } | ||||
| 403 | elsif ($elem->type() eq 'our') { | ||||
| 404 | push | ||||
| 405 | @violations, | ||||
| 406 | $self->_check_capitalization( | ||||
| 407 | symbol_without_sigil($name), | ||||
| 408 | $name, | ||||
| 409 | 'global_variable', | ||||
| 410 | $elem, | ||||
| 411 | ); | ||||
| 412 | } | ||||
| 413 | else { | ||||
| 414 | # Got my or state | ||||
| 415 | my $parent = $elem->parent(); | ||||
| 416 | if ( not $parent or $parent->isa('PPI::Document') ) { | ||||
| 417 | push | ||||
| 418 | @violations, | ||||
| 419 | $self->_check_capitalization( | ||||
| 420 | symbol_without_sigil($name), | ||||
| 421 | $name, | ||||
| 422 | 'file_lexical_variable', | ||||
| 423 | $elem, | ||||
| 424 | ); | ||||
| 425 | } | ||||
| 426 | else { | ||||
| 427 | if ( _is_directly_in_scope_block($elem) ) { | ||||
| 428 | push | ||||
| 429 | @violations, | ||||
| 430 | $self->_check_capitalization( | ||||
| 431 | symbol_without_sigil($name), | ||||
| 432 | $name, | ||||
| 433 | 'scoped_lexical_variable', | ||||
| 434 | $elem, | ||||
| 435 | ); | ||||
| 436 | } | ||||
| 437 | else { | ||||
| 438 | push | ||||
| 439 | @violations, | ||||
| 440 | $self->_check_capitalization( | ||||
| 441 | symbol_without_sigil($name), | ||||
| 442 | $name, | ||||
| 443 | 'local_lexical_variable', | ||||
| 444 | $elem, | ||||
| 445 | ); | ||||
| 446 | } | ||||
| 447 | } | ||||
| 448 | } | ||||
| 449 | } | ||||
| 450 | |||||
| 451 | return @violations; | ||||
| 452 | } | ||||
| 453 | |||||
| 454 | sub _subroutine_capitalization { | ||||
| 455 | my ($self, $elem) = @_; | ||||
| 456 | |||||
| 457 | # These names are fixed and you've got no choice what to call them. | ||||
| 458 | return if $elem->isa('PPI::Statement::Scheduled'); | ||||
| 459 | |||||
| 460 | my $name = $elem->name(); | ||||
| 461 | $name =~ s{ .* :: }{}smx; # Allow for "sub Some::Package::foo {}" | ||||
| 462 | |||||
| 463 | return $self->_check_capitalization($name, $name, 'subroutine', $elem); | ||||
| 464 | } | ||||
| 465 | |||||
| 466 | sub _constant_capitalization { | ||||
| 467 | my ($self, $elem, $name) = @_; | ||||
| 468 | |||||
| 469 | return $self->_check_capitalization( | ||||
| 470 | symbol_without_sigil($name), $name, 'constant', $elem, | ||||
| 471 | ); | ||||
| 472 | } | ||||
| 473 | |||||
| 474 | sub _package_capitalization { | ||||
| 475 | my ($self, $elem) = @_; | ||||
| 476 | |||||
| 477 | my $namespace = $elem->namespace(); | ||||
| 478 | my @components = split m/::/xms, $namespace; | ||||
| 479 | |||||
| 480 | foreach my $component (@components) { | ||||
| 481 | my $violation = | ||||
| 482 | $self->_check_capitalization( | ||||
| 483 | $component, $namespace, 'package', $elem, | ||||
| 484 | ); | ||||
| 485 | return $violation if $violation; | ||||
| 486 | } | ||||
| 487 | |||||
| 488 | return; | ||||
| 489 | } | ||||
| 490 | |||||
| 491 | sub _foreach_variable_capitalization { | ||||
| 492 | my ($self, $elem) = @_; | ||||
| 493 | |||||
| 494 | my $type; | ||||
| 495 | my $symbol; | ||||
| 496 | my $second_element = $elem->schild(1); | ||||
| 497 | return if not $second_element; | ||||
| 498 | |||||
| 499 | if ($second_element->isa('PPI::Token::Word')) { | ||||
| 500 | $type = $second_element->content(); | ||||
| 501 | $symbol = $second_element->snext_sibling(); | ||||
| 502 | } else { | ||||
| 503 | $type = 'my'; | ||||
| 504 | $symbol = $second_element; | ||||
| 505 | } | ||||
| 506 | |||||
| 507 | return if not $symbol; | ||||
| 508 | return if not $symbol->isa('PPI::Token::Symbol'); | ||||
| 509 | |||||
| 510 | my $name = $symbol->symbol(); | ||||
| 511 | |||||
| 512 | if ($type eq 'local') { | ||||
| 513 | # Fully qualified names are exempt because we can't be responsible | ||||
| 514 | # for other people's symbols. | ||||
| 515 | return if $name =~ m/$PACKAGE_REGEX/xms; | ||||
| 516 | return if is_perl_global($name); | ||||
| 517 | |||||
| 518 | return $self->_check_capitalization( | ||||
| 519 | symbol_without_sigil($name), $name, 'global_variable', $elem, | ||||
| 520 | ); | ||||
| 521 | } | ||||
| 522 | elsif ($type eq 'our') { | ||||
| 523 | return $self->_check_capitalization( | ||||
| 524 | symbol_without_sigil($name), $name, 'global_variable', $elem, | ||||
| 525 | ); | ||||
| 526 | } | ||||
| 527 | |||||
| 528 | # Got my or state: treat as local lexical variable | ||||
| 529 | return $self->_check_capitalization( | ||||
| 530 | symbol_without_sigil($name), $name, 'local_lexical_variable', $elem, | ||||
| 531 | ); | ||||
| 532 | } | ||||
| 533 | |||||
| 534 | sub _label_capitalization { | ||||
| 535 | my ($self, $elem, $name) = @_; | ||||
| 536 | |||||
| 537 | return if _is_not_real_label($elem); | ||||
| 538 | ( my $label = $elem->content() ) =~ s< \s* : \z ><>xms; | ||||
| 539 | return $self->_check_capitalization($label, $label, 'label', $elem); | ||||
| 540 | } | ||||
| 541 | |||||
| 542 | sub _check_capitalization { | ||||
| 543 | my ($self, $to_match, $full_name, $name_type, $elem) = @_; | ||||
| 544 | |||||
| 545 | my $test = $self->{"_${name_type}_test"}; | ||||
| 546 | if ( my $message = $test->($to_match) ) { | ||||
| 547 | return $self->violation( | ||||
| 548 | qq<$NAME_FOR_TYPE{$name_type} "$full_name" $message>, | ||||
| 549 | $EXPL, | ||||
| 550 | $elem, | ||||
| 551 | ); | ||||
| 552 | } | ||||
| 553 | |||||
| 554 | return; | ||||
| 555 | } | ||||
| 556 | |||||
| 557 | |||||
| 558 | # { my $x } parses as | ||||
| 559 | # PPI::Document | ||||
| 560 | # PPI::Statement::Compound | ||||
| 561 | # PPI::Structure::Block { ... } | ||||
| 562 | # PPI::Statement::Variable | ||||
| 563 | # PPI::Token::Word 'my' | ||||
| 564 | # PPI::Token::Symbol '$x' | ||||
| 565 | # PPI::Token::Structure ';' | ||||
| 566 | # | ||||
| 567 | # Also, type() on the PPI::Statement::Compound returns "continue". *sigh* | ||||
| 568 | # | ||||
| 569 | # The parameter is expected to be the PPI::Statement::Variable. | ||||
| 570 | sub _is_directly_in_scope_block { | ||||
| 571 | my ($elem) = @_; | ||||
| 572 | |||||
| 573 | |||||
| 574 | return if is_in_subroutine($elem); | ||||
| 575 | |||||
| 576 | my $parent = $elem->parent(); | ||||
| 577 | return if not $parent->isa('PPI::Structure::Block'); | ||||
| 578 | |||||
| 579 | my $grand_parent = $parent->parent(); | ||||
| 580 | return $TRUE if not $grand_parent; | ||||
| 581 | return $TRUE if $grand_parent->isa('PPI::Document'); | ||||
| 582 | |||||
| 583 | return if not $grand_parent->isa('PPI::Statement::Compound'); | ||||
| 584 | |||||
| 585 | my $type = $grand_parent->type(); | ||||
| 586 | return if not $type; | ||||
| 587 | return if $type ne 'continue'; | ||||
| 588 | |||||
| 589 | my $great_grand_parent = $grand_parent->parent(); | ||||
| 590 | return if | ||||
| 591 | $great_grand_parent and not $great_grand_parent->isa('PPI::Document'); | ||||
| 592 | |||||
| 593 | # Make sure we aren't really in a continue block. | ||||
| 594 | my $prior_to_grand_parent = $grand_parent->sprevious_sibling(); | ||||
| 595 | return $TRUE if not $prior_to_grand_parent; | ||||
| 596 | return $TRUE if not $prior_to_grand_parent->isa('PPI::Token::Word'); | ||||
| 597 | return $prior_to_grand_parent->content() ne 'continue'; | ||||
| 598 | } | ||||
| 599 | |||||
| 600 | sub _is_not_real_label { | ||||
| 601 | my $elem = shift; | ||||
| 602 | |||||
| 603 | # PPI misparses part of a ternary expression as a label | ||||
| 604 | # when the token to the left of the ":" is a bareword. | ||||
| 605 | # See http://rt.cpan.org/Ticket/Display.html?id=41170 | ||||
| 606 | # For example... | ||||
| 607 | # | ||||
| 608 | # $foo = $condition ? undef : 1; | ||||
| 609 | # | ||||
| 610 | # PPI thinks that "undef" is a label. To workaround this, | ||||
| 611 | # I'm going to check that whatever PPI thinks is the label, | ||||
| 612 | # actually is the first token in the statement. I believe | ||||
| 613 | # this should be true for all real labels. | ||||
| 614 | |||||
| 615 | my $stmnt = $elem->statement() || return; | ||||
| 616 | my $first_child = $stmnt->schild(0) || return; | ||||
| 617 | return $first_child ne $elem; | ||||
| 618 | } | ||||
| 619 | |||||
| 620 | 1 | 14µs | 1; | ||
| 621 | |||||
| 622 | __END__ | ||||
# spent 8µs within Perl::Critic::Policy::NamingConventions::Capitalization::CORE:qr which was called 7 times, avg 1µs/call:
# once (2µs+0s) by Module::Pluggable::Object::_require at line 40
# once (1µs+0s) by Module::Pluggable::Object::_require at line 42
# once (1µs+0s) by Module::Pluggable::Object::_require at line 75
# once (900ns+0s) by Module::Pluggable::Object::_require at line 45
# once (900ns+0s) by Module::Pluggable::Object::_require at line 43
# once (900ns+0s) by Module::Pluggable::Object::_require at line 46
# once (900ns+0s) by Module::Pluggable::Object::_require at line 44 |