123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- #!/usr/bin/perl
- # Daniel "Trizen" Șuteu
- # License: GPLv3
- # Date: 24 June 2017
- # https://github.com/trizen
- use 5.014;
- use strict;
- use autodie;
- use warnings;
- use File::Find qw(find);
- use File::Basename qw(basename);
- use Text::Levenshtein::XS qw(distance);
- my $dir = shift() // die "usage: $0 [lib dir]\n";
- if (basename($dir) ne 'lib') {
- die "error: '$dir' is not a lib directory!";
- }
- my $typo_dist = 1; # maximum typo distance
- my %invokants;
- my %declarations;
- find {
- no_chdir => 1,
- wanted => sub {
- /\.pm\z/ || return;
- my $content = do {
- local $/;
- open my $fh, '<:utf8', $_;
- <$fh>;
- };
- if ($content =~ /\bpackage\h+(Sidef(::\w+)*)/) {
- undef $declarations{$1};
- }
- else {
- warn "Unable to extract the package name from: $_\n";
- }
- while ($content =~ /\b(Sidef(::\w+)+)/g) {
- my $name = $1;
- push @{$invokants{$name}}, $_;
- if ($name =~ /^(.+)::/) { # handle function calls
- push @{$invokants{$1}}, $_;
- }
- }
- },
- } => $dir;
- my @invokants = keys(%invokants);
- my @declarations = keys(%declarations);
- foreach my $invo (@invokants) {
- next if exists($declarations{$invo});
- foreach my $decl (@declarations) {
- if (abs(length($invo) - length($decl)) <= $typo_dist
- and distance($invo, $decl) <= $typo_dist) {
- say "Possible typo: <<$invo>> instead of <<$decl>> in:";
- say "\t", join(
- "\n\t",
- do {
- my %seen;
- grep { !$seen{$_}++ } @{$invokants{$invo}};
- }
- ),
- "\n";
- }
- }
- }
|