Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can we catch side comments using Perl::Tidy or Perl::Critic?

My department is currently settling on some general code best practices, which we would like to somewhat enforce, providing developers with Perl::Tidy and Perl::Critic configurations.

Now we are having problems with side comments. The side comment is this:

my $counter = 0;  # Reset counter

We would prefer to not have side comments at all, since in most cases they can be written above the code in question, where they are more easily read. If at all possible, a Perl::Tidy solution would be perfect, which would move a side comment to the line above it, second-best would be a Perl::Critic policy (which I haven't found at CPAN either) and third-best and last would be developers taking care to point those comments out when they do code reviews.

Is it possible to implement with Perl::Tidy or Perl::Critic?

like image 393
Nikolai Prokoschenko Avatar asked Sep 04 '09 11:09

Nikolai Prokoschenko


1 Answers

I think this should work for you (if I understood what you want):

package Perl::Critic::Policy::CodeLayout::NoSideComments;

use strict;
use warnings;

use Readonly;

use Perl::Critic::Utils qw{ :severities :classification :ppi };
use parent 'Perl::Critic::Policy';

our $VERSION = 20090904;

Readonly::Scalar my $DESC => "side comments are not allowed";
Readonly::Scalar my $EXPL => "put the comment above the line, not next to it";

sub supported_parameters { return                       }
sub default_severity     { return 5                     }
sub default_themes       { return qw( custom )          }
sub applies_to           { return 'PPI::Token::Comment' }

sub violates {
    my ($self, $elem) = @_;

    #look backwards until you find whitespace that contains a 
    #newline (good) or something other than whitespace (error)

    my $prev = $elem->previous_sibling;
    while ($prev) {
        return $self->violation( $DESC, $EXPL, $elem )
            unless $prev->isa("PPI::Token::Whitespace");
        return if $prev->content =~ /\n/;
        $prev = $prev->previous_sibling;
    }

    #catch # after a block start, but leave the #! line alone
    return $self->violation( $DESC, $EXPL, $elem )
        unless $elem->parent->isa("PPI::Document");
    return;
}

1;
like image 191
Chas. Owens Avatar answered Sep 28 '22 01:09

Chas. Owens