Code-ART

 view release on metacpan or  search on metacpan

lib/Code/ART/API/Vim.pm  view on Meta::CPAN

}

sub refactor_to_sub {
    # Unpack any options...
    my $opt_ref = shift // {};

    # Grab the source code, which will be sent through the input filestream...
    my $source = do{ local $/; readline(*ARGV) };

    # Ask Code::ART to do the actual refactoring...
    my $refactoring = Code::ART::refactor_to_sub($source, $opt_ref);

#    if ($refactoring->{failed}) {
#        $refactoring->{reason} = $refactoring->{failed};
#        $refactoring->{failed} = 1;
#    }

    say _Perl_to_VimScript( $refactoring );
}

sub analyze_code {
    # Load code to be analyzed...
    my $source = do { local $/; readline(*ARGV); };

    # Do the full classification...
    my $classification = Code::ART::classify_all_vars_in($source);
    print _Perl_to_VimScript($classification) and return if $classification->{failed};

    # Generate a pattern to match all variables with various interesting properties...
    my (@cacograms, @undeclared_vars, @unused_vars);
    for my $var (values %{$classification->{vars}}) {
        # Collect cacograms (names that don't help you understand)...
        if ($var->{is_cacogram} && $var->{declared_at}) {
            push @cacograms, _line_and_column_from_ID($source, [$var->{declared_at}])
                             . $var->{sigil} . $var->{raw_name};
        }

        # Collect undeclared variables...
        if ($var->{declared_at} < 0 && !$var->{is_builtin} && $var->{raw_name} !~ /[:']/) {
            push @undeclared_vars, _line_and_column_from_ID($source, [keys %{ $var->{used_at}}])
                                 . $var->{sigil} . $var->{raw_name};
        }
        # Collect unused variables...
        elsif (!keys %{$var->{used_at}}) {
            push @unused_vars, _line_and_column_from_ID($source, [$var->{declared_at}])
                             . $var->{sigil} . $var->{raw_name};
        }
    }

    # Output all the gathered information...
    print _Perl_to_VimScript({
        cacograms       => join('\|', @cacograms),
        undeclared_vars => join('\|', @undeclared_vars),
        unused_vars     => join('\|', @unused_vars),
    });
}

my $VimOWS = '\%(\_s*\%(#.*\_s*\)*\)';
sub classify_var_at {
    # Unpack the specified variable position (i.e. the byte number in the buffer)
    my ($cursor_byte) = @_;

    # Grab the source code, which will be sent through the input filestream...
    my $source = do { local $/; readline(*ARGV); };

    # Ask Code::ART to do the actual classification
    # (making allowance for the fact that Vim byte numbers start at 1,
    #  but Perl string indexes start at zero)...
    my $info = Code::ART::_classify_var_at($source, $cursor_byte - 1);

    # Make sure the resulting information has valid 'sigil' entry...
    $info->{sigil}  //= q{};

    # Convert the various locations found to Vim line/column coordinates...
    $info->{matchloc} = _line_and_column_from_ID($source,
                                                 [$info->{declared_at}, keys %{$info->{used_at}}]);
    $info->{declloc}  = _line_and_column_from_ID($source, [$info->{declared_at}]);

    # Convert scope details to Vim formats...
    my $min_scope
        = $info->{declared_at} >= 0 ? _linenum_from_ID($source, $info->{declared_at})
                                    : 1;
    my $max_scope = _linenum_from_ID($source, $info->{end_of_scope});
    $info->{scopeloc} = '\%>' . ($min_scope-1) . 'l'
                      . '\%<' . ($max_scope+1) . 'l';
    $info->{scope_size} = $max_scope - $min_scope + 1;

    # Work out the correct Vim regex to match the valid sigils
    # of the various declinations of the variable...
    my $sigil_matcher = $info->{sigil} eq '@' ? '\%(\$#\|[@$%]\)'
                      : $info->{sigil} eq '%' ? '[%$@]'
                      : $info->{sigil} eq '$' ? '\$#\@!'
                      :                         '';

    # Build the complete Vim regex for matching any instance of the variable...
    $info->{matchname}
        = $info->{failed}
            ? q{}
            : $sigil_matcher.$VimOWS.'\%('.$info->{raw_name}
             .'\|{'.$VimOWS.$info->{raw_name}.$VimOWS.'}\)'
        ;

    # Build the complete Vim regex for matching just the name of any instance of the variable...
    $info->{matchnameonly}
        = $info->{failed}
            ? q{}
            : $sigil_matcher.$VimOWS.'\%(\zs'.$info->{raw_name}
             .'\ze\|{'.$VimOWS.'\zs'.$info->{raw_name}.'\ze'.$VimOWS.'}\)'
        ;

    # Convert homogram and parogram data to searchable regexes...
    for my $gram_type (qw< homograms parograms >) {
        my $grams = $info->{$gram_type};
        use Data::Dump 'ddx';
        $info->{$gram_type}
            = join('\|', map { my $gram = $grams->{$_};
                               my $from = _linenum_from_ID($source, $gram->{from}) - 1;
                               my $to   = _linenum_from_ID($source, $gram->{to}  ) + 1;
                               '\%>'.$from.'l\%<'.$to.'l\%($#\?\|[%@]\)'.$VimOWS.$_;
                             }
                             keys %{$grams});
    }

    # Convert all that information to a Vim dictionary, and output it...
    say _Perl_to_VimScript($info);
}

sub find_expr_scope {
    my ($from, $to, $match_all) = @_;



( run in 1.553 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )