File Coverage

blib/lib/Perl/Critic/Policy/CodeLayout/ProhibitHardTabs.pm
Criterion Covered Total %
statement 34 34 100.0
branch 14 14 100.0
condition 9 9 100.0
subroutine 13 13 100.0
pod 4 5 80.0
total 74 75 98.6


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::CodeLayout::ProhibitHardTabs;
2              
3 40     40   33512 use 5.010001;
  40         184  
4 40     40   301 use strict;
  40         131  
  40         883  
5 40     40   241 use warnings;
  40         100  
  40         1154  
6 40     40   236 use Readonly;
  40         155  
  40         2269  
7              
8 40     40   333 use Perl::Critic::Utils qw{ :booleans :severities };
  40         111  
  40         2201  
9 40     40   7053 use parent 'Perl::Critic::Policy';
  40         143  
  40         290  
10              
11             our $VERSION = '1.146';
12              
13             #-----------------------------------------------------------------------------
14              
15             Readonly::Scalar my $DESC => q{Hard tabs used};
16             Readonly::Scalar my $EXPL => [ 20 ];
17              
18             #-----------------------------------------------------------------------------
19              
20             # The following regex should probably be "qr{^ .* [^\t]+ \t}xms" but it doesn't
21             # match when I expect it to. I haven't figured out why, so I used "\S" to
22             # approximately mean "not a tab", and that seemed to work.
23              
24             Readonly::Scalar my $NON_LEADING_TAB_REGEX => qr{^ .* \S+ \t }xms;
25              
26             #-----------------------------------------------------------------------------
27              
28             sub supported_parameters {
29             return (
30             {
31 100     100 0 2143 name => 'allow_leading_tabs',
32             description => 'Allow hard tabs before first non-whitespace character.',
33             default_string => '1',
34             behavior => 'boolean',
35             },
36             );
37             }
38              
39 84     84 1 432 sub default_severity { return $SEVERITY_MEDIUM }
40 84     84 1 361 sub default_themes { return qw( core cosmetic pbp ) }
41 40     40 1 152 sub applies_to { return 'PPI::Token' }
42              
43             #-----------------------------------------------------------------------------
44              
45             sub violates {
46 2371     2371 1 4108 my ( $self, $elem, undef ) = @_;
47 2371 100       4241 $elem =~ m{ \t }xms || return;
48              
49             # The __DATA__ element is exempt
50 19 100       180 return if $elem->parent->isa('PPI::Statement::Data');
51              
52             # If allowed, permit leading tabs in situations where whitespace s not significant.
53 18 100       183 if ( $self->_allow_leading_tabs() ) {
54              
55 12 100       49 return if $elem->location->[1] == 1;
56              
57 8 100 100     137 return if _is_extended_regex($elem)
58             && $elem !~ $NON_LEADING_TAB_REGEX;
59              
60 6 100 100     75 return if $elem->isa('PPI::Token::QuoteLike::Words')
61             && $elem !~ $NON_LEADING_TAB_REGEX;
62             }
63              
64             # If we get here, then it must be a violation...
65 11         65 return $self->violation( $DESC, $EXPL, $elem );
66             }
67              
68             #-----------------------------------------------------------------------------
69              
70             sub _allow_leading_tabs {
71 18     18   52 my ( $self ) = @_;
72 18         50 return $self->{_allow_leading_tabs};
73             }
74              
75             #-----------------------------------------------------------------------------
76              
77             sub _is_extended_regex {
78 8     8   18 my ($elem) = @_;
79              
80 8 100 100     68 $elem->isa('PPI::Token::Regexp')
81             || $elem->isa('PPI::Token::QuoteLike::Regexp')
82             || return;
83              
84             # Look for the /x modifier near the end
85 5         15 return $elem =~ m{\b [gimso]* x [gimso]* $}xms;
86             }
87              
88             1;
89              
90             __END__
91              
92             #-----------------------------------------------------------------------------
93              
94             =head1 NAME
95              
96             Perl::Critic::Policy::CodeLayout::ProhibitHardTabs - Use spaces instead of tabs.
97              
98              
99             =head1 AFFILIATION
100              
101             This Policy is part of the core L<Perl::Critic|Perl::Critic>
102             distribution.
103              
104              
105             =head1 DESCRIPTION
106              
107             Putting hard tabs in your source code (or POD) is one of the worst
108             things you can do to your co-workers and colleagues, especially if
109             those tabs are anywhere other than a leading position. Because
110             various applications and devices represent tabs differently, they can
111             cause you code to look vastly different to other people. Any decent
112             editor can be configured to expand tabs into spaces.
113             L<Perl::Tidy|Perl::Tidy> also does this for you.
114              
115             This Policy catches all tabs in your source code, including POD,
116             quotes, and HEREDOCs. The contents of the C<__DATA__> section are not
117             examined.
118              
119              
120             =head1 CONFIGURATION
121              
122             Hard tabs in a string are always forbidden (use "\t" instead). But
123             hard tabs in a leading position are allowed when they are used to indent
124             code statements, C<qw()> word lists, and regular expressions with the C</x>
125             modifier. However, if you want to forbid all tabs everywhere, then add
126             this to your F<.perlcriticrc> file:
127              
128             [CodeLayout::ProhibitHardTabs]
129             allow_leading_tabs = 0
130              
131              
132             =head1 NOTES
133              
134             Beware that Perl::Critic may report the location of the string that
135             contains the tab, not the actual location of the tab, so you may need
136             to do some hunting. I'll try and fix this in the future.
137              
138              
139             =head1 AUTHOR
140              
141             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
142              
143              
144             =head1 COPYRIGHT
145              
146             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
147              
148             This program is free software; you can redistribute it and/or modify
149             it under the same terms as Perl itself. The full text of this license
150             can be found in the LICENSE file included with this module.
151              
152             =cut
153              
154             ##############################################################################
155             # Local Variables:
156             # mode: cperl
157             # cperl-indent-level: 4
158             # fill-column: 78
159             # indent-tabs-mode: nil
160             # c-indentation-style: bsd
161             # End:
162             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :